From 6031e97bb558321943d6783d6f1cd4efe029ca1c Mon Sep 17 00:00:00 2001 From: Floze <88098863+floze-the-genius@users.noreply.github.com> Date: Fri, 14 Aug 2026 17:24:06 +0400 Subject: [PATCH] docs(providers): add generated capability matrix --- README.md | 26 ++++++++ package.json | 2 + scripts/generate-provider-matrix.ts | 98 +++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 scripts/generate-provider-matrix.ts diff --git a/README.md b/README.md index ec51dcb9..4c3f36f9 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,32 @@ npx shadcn@latest add https://tinte.dev/api/preset/one-hunter configs (Alacritty, Kitty, Warp, Windows Terminal), and 19+ formats from the same source of truth. +## Provider capability matrix + +This table is generated from the legacy web provider list and the provider +modules. Run `bun run generate:provider-matrix` after changing either source. + + +| Provider | Status | Module | +| --- | --- | --- | +| shadcn/ui | Implemented | `packages/providers/src/providers/shadcn.ts` | +| VS Code | Implemented | `packages/providers/src/providers/vscode.ts` | +| Cursor | Planned | — | +| Shiki | Implemented | `packages/providers/src/providers/shiki.ts` | +| Zed | Implemented | `packages/providers/src/providers/zed.ts` | +| Warp | Implemented | `packages/providers/src/providers/warp.ts` | +| Alacritty | Implemented | `packages/providers/src/providers/alacritty.ts` | +| Windows Terminal | Implemented | `packages/providers/src/providers/windows-terminal.ts` | +| Kitty | Implemented | `packages/providers/src/providers/kitty.ts` | +| Ghostty | Planned | — | +| JetBrains | Planned | — | +| Slack | Implemented | `packages/providers/src/providers/slack.ts` | +| Replit | Planned | — | +| Neovim | Planned | — | +| Obsidian | Planned | — | +| GIMP | Implemented | `packages/providers/src/providers/gimp.ts` | + + ## Preset API (shadcn v4) Every public Tinte theme is installable as a shadcn `registry:base` item: diff --git a/package.json b/package.json index fcf41a21..d3cfd198 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "generate:design": "bun run generate:artifacts && bun run generate:plugin", "generate:artifacts": "bun packages/cli/src/cli.ts build --config ./tinte.config.json --out ./apps/web/public/design", "generate:plugin": "bun packages/cli/src/cli.ts build --plugin --config ./tinte.config.json --out ./apps/web/public/plugin", + "generate:provider-matrix": "bun scripts/generate-provider-matrix.ts", + "check:provider-matrix": "bun scripts/generate-provider-matrix.ts --check", "check:staged": "biome check --write --staged", "validate:commit-msg": "node scripts/validate-commit-msg.mjs", "prepare": "simple-git-hooks" diff --git a/scripts/generate-provider-matrix.ts b/scripts/generate-provider-matrix.ts new file mode 100644 index 00000000..2f731782 --- /dev/null +++ b/scripts/generate-provider-matrix.ts @@ -0,0 +1,98 @@ +import { readdir, readFile, writeFile } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const providerConfigPath = join(root, "apps/web/src/config/providers.ts"); +const providerModulesPath = join(root, "packages/providers/src/providers"); +const readmePath = join(root, "README.md"); +const startMarker = ""; +const endMarker = ""; +const aliases: Record = { + "shadcn/ui": "shadcn", + "VS Code": "vscode", + "Windows Terminal": "windows-terminal", +}; + +function providerFileStem(provider: string) { + return ( + aliases[provider] ?? + provider + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, "") + ); +} + +function readProviderNames(source: string) { + const match = source.match( + /export const ALL_PROVIDERS = \[([\s\S]*?)\]\s+as const;/, + ); + if (!match) { + throw new Error("Could not find ALL_PROVIDERS in the web provider config"); + } + + const providers = [...match[1].matchAll(/"([^"]+)"/g)].map( + ([, provider]) => provider, + ); + if (providers.length === 0 || new Set(providers).size !== providers.length) { + throw new Error("ALL_PROVIDERS must contain unique provider names"); + } + return providers; +} + +function renderMatrix(providers: string[], providerModules: Set) { + const rows = providers.map((provider) => { + const stem = providerFileStem(provider); + const implemented = providerModules.has(stem); + const module = implemented + ? `\`packages/providers/src/providers/${stem}.ts\`` + : "—"; + return `| ${provider} | ${implemented ? "Implemented" : "Planned"} | ${module} |`; + }); + + return [ + startMarker, + "| Provider | Status | Module |", + "| --- | --- | --- |", + ...rows, + endMarker, + ].join("\n"); +} + +const [providerConfig, providerEntries, readme] = await Promise.all([ + readFile(providerConfigPath, "utf8"), + readdir(providerModulesPath, { withFileTypes: true }), + readFile(readmePath, "utf8"), +]); +const providers = readProviderNames(providerConfig); +const providerModules = new Set( + providerEntries + .filter((entry) => entry.isFile() && entry.name.endsWith(".ts")) + .map((entry) => entry.name.slice(0, -3)), +); +const start = readme.indexOf(startMarker); +const end = readme.indexOf(endMarker); +if (start === -1 || end === -1 || end < start) { + throw new Error("README provider matrix markers are missing or out of order"); +} + +const matrix = renderMatrix(providers, providerModules); +const updatedReadme = `${readme.slice(0, start)}${matrix}${readme.slice( + end + endMarker.length, +)}`; + +if (process.argv.includes("--check")) { + if (updatedReadme !== readme) { + console.error("Provider capability matrix is out of date"); + process.exit(1); + } + console.log( + `Provider capability matrix is current (${providers.length} providers)`, + ); +} else { + await writeFile(readmePath, updatedReadme); + console.log( + `Updated provider capability matrix (${providers.length} providers)`, + ); +}