@bridge-ds/core 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-spec-cvrSvIZj.js","sources":["../src/types.ts","../src/previews.ts","../src/teams.ts","../src/rights.ts","../src/config.ts","../src/json-ast.ts","../src/dtcg-codec.ts","../src/token-set.ts","../src/resolver.ts","../src/scopes.ts","../src/wcag.ts","../src/diff-engine.ts","../src/risk.ts","../src/pr-composer.ts","../src/changeset.ts","../src/token-edits.ts","../src/layered-review.ts","../src/governance.ts","../src/history.ts","../src/component-spec.ts"],"sourcesContent":["// Shared domain types for the token side of DS Bridge (no Figma or DOM dependency).\n\n/** Extension key holding a stable token id across renames. */\nexport const EXT_ID = 'com.dsbridge.id';\n/** Extension key holding Figma variable scopes. */\nexport const EXT_SCOPES = 'com.figma.scopes';\n\n/** Mode key of single-mode tiers (primitives, base semantic, component tokens). */\nexport const PRIMITIVE_MODE = 'value';\nexport const SINGLE_MODE = PRIMITIVE_MODE;\n\n/**\n * Token tiers, in dependency order (docs/ARCHITECTURE.md):\n * primitive primitives/*.tokens.json raw scales, one value\n * brand brands/<brand>.tokens.json palette, radius and font roles, one value per brand\n * base semantic/base.tokens.json theme-independent semantic (motion, layers, icons), one value\n * semantic semantic/<theme>.tokens.json purpose aliases of palette.*, one value per theme\n * density density/<density>.tokens.json control heights and paddings, one value per density\n * component components/*.tokens.json component hooks aliasing semantic tokens, one value\n */\nexport type Tier = 'primitive' | 'brand' | 'base' | 'semantic' | 'density' | 'component';\nexport const TIER_ORDER: Tier[] = ['primitive', 'brand', 'base', 'semantic', 'density', 'component'];\n\n/** The dimension a multi-mode tier varies along. */\nexport type Axis = 'brand' | 'theme' | 'density';\nexport const TIER_AXIS: Record<Tier, Axis | undefined> = {\n primitive: undefined,\n brand: 'brand',\n base: undefined,\n semantic: 'theme',\n density: 'density',\n component: undefined,\n};\nexport const isMultiMode = (tier: Tier) => TIER_AXIS[tier] !== undefined;\n\n/** Display name of each tier. The Figma plugin uses the same names for its collections. */\nexport const TIER_NAMES: Record<Tier, string> = {\n primitive: 'Primitives',\n brand: 'Brand',\n base: 'Base',\n semantic: 'Semantic',\n density: 'Density',\n component: 'Component',\n};\n\n/** \"light\" -> \"Light\". */\nexport const modeDisplayName = (mode: string) => mode.charAt(0).toUpperCase() + mode.slice(1);\n\n/** One token as written in one DTCG file. */\nexport interface FlatToken {\n path: string;\n /** Resolved `$type`, including the type inherited from parent groups. */\n type: string | undefined;\n /** `$type` written on the token itself (undefined when inherited). */\n ownType: string | undefined;\n value: unknown;\n description: string | undefined;\n extensions: Record<string, unknown> | undefined;\n file: string;\n}\n\nexport interface ModeFile {\n mode: string;\n file: string;\n}\n\n/** A brand's semantic override file for one theme: brands/<brand>.<theme>.tokens.json. */\nexport interface OverrideFile {\n brand: string;\n theme: string;\n file: string;\n}\n\n/** Which files hold which tier (relative to the tokens path). */\nexport interface RepoLayout {\n primitiveFiles: string[];\n brands: ModeFile[];\n baseFiles: string[];\n themes: ModeFile[];\n overrides: OverrideFile[];\n densities: ModeFile[];\n componentFiles: string[];\n}\n\n/**\n * A token as the user thinks about it: one name, one value per mode of its tier. Brand tokens\n * have one value per brand, semantic tokens one per theme, density tokens one per density;\n * the other tiers have a single value under SINGLE_MODE.\n */\nexport interface LogicalToken {\n id: string;\n path: string;\n type: string;\n tier: Tier;\n /** mode key -> DTCG `$value` (alias string like \"{palette.primary.600}\" or a literal). */\n values: Record<string, unknown>;\n description: string | undefined;\n /** Figma scopes from `$extensions[\"com.figma.scopes\"]`, undefined when not declared. */\n scopes: string[] | undefined;\n /** mode key -> file the value lives in. */\n files: Record<string, string>;\n}\n\n/** A brand's per-theme value for a semantic token (code-only: Figma has no brand x theme mode). */\nexport interface ThemeOverride {\n brand: string;\n theme: string;\n path: string;\n type: string | undefined;\n value: unknown;\n file: string;\n}\n\nexport type TokenMap = Map<string, LogicalToken>;\n","// Branch previews: where a design system branch can be tried before it merges. Pure URL and text building, shared\n// by the PR comment workflow (.github/workflows/preview-packages.yml) and the docs site Branches page, so both\n// print the same links. See docs/PREVIEWS.md.\n\n/** Apps deployed once per branch. Values are URL templates (see `previewUrl`). */\nexport interface PreviewApps {\n docs?: string | undefined;\n storybook?: string | undefined;\n admin?: string | undefined;\n}\n\nexport interface PreviewsConfig {\n /** Packages published as snapshots for every PR commit (pkg.pr.new). */\n packages: string[];\n /** Per-branch deploy URL templates. Missing entries mean \"not set up\". */\n apps: PreviewApps;\n /** Production URL of each app (the default branch's deploy), fixed URLs without placeholders. */\n production?: PreviewApps | undefined;\n}\n\nexport const PREVIEW_APP_LABELS: Record<keyof PreviewApps, string> = { docs: 'Docs', storybook: 'Storybook', admin: 'Admin demo' };\nexport const PREVIEW_PLACEHOLDERS = ['branch', 'rawBranch', 'pr', 'sha', 'sha7'] as const;\n\nexport interface PreviewContext {\n branch: string;\n pr?: number | undefined;\n sha?: string | undefined;\n}\n\n/**\n * Vercel's branch alias slug: lowercase, every run of characters outside [a-z0-9] becomes one dash, no dash at\n * either end. `feat/Branch_previews` -> `feat-branch-previews`.\n */\nexport function branchSlug(branch: string): string {\n return branch\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\n/**\n * Fills a URL template. Placeholders: `{branch}` (slug), `{rawBranch}` (URL-encoded), `{pr}`, `{sha}`, `{sha7}`.\n * Returns null when the template needs a value the context lacks, when the result is not an http(s) URL, or when\n * a host label exceeds 63 characters (Vercel then shortens the alias with a hash nobody can predict: read the\n * URL from the Vercel bot comment on the PR instead).\n */\nexport function previewUrl(template: string | undefined, ctx: PreviewContext): string | null {\n if (!template) return null;\n const values: Record<string, string | undefined> = {\n branch: branchSlug(ctx.branch),\n rawBranch: encodeURIComponent(ctx.branch),\n pr: ctx.pr === undefined ? undefined : String(ctx.pr),\n sha: ctx.sha,\n sha7: ctx.sha?.slice(0, 7),\n };\n let missing = false;\n const filled = template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const v = values[key];\n if (!v) missing = true;\n return v ?? '';\n });\n if (missing) return null;\n let url: URL;\n try {\n url = new URL(filled);\n } catch {\n return null;\n }\n if (url.protocol !== 'https:' && url.protocol !== 'http:') return null;\n if (url.hostname.split('.').some((label) => label.length > 63)) return null;\n return url.href;\n}\n\n/** All configured app previews for a branch, in a stable order. Unconfigured or unbuildable ones are left out. */\nexport function previewLinks(apps: PreviewApps, ctx: PreviewContext): { app: keyof PreviewApps; label: string; url: string }[] {\n const out: { app: keyof PreviewApps; label: string; url: string }[] = [];\n for (const app of Object.keys(PREVIEW_APP_LABELS) as (keyof PreviewApps)[]) {\n const url = previewUrl(apps[app], ctx);\n if (url) out.push({ app, label: PREVIEW_APP_LABELS[app], url });\n }\n return out;\n}\n\n/**\n * Where an app lives for a build: its branch preview on any branch other than the default one, its production URL\n * on the default branch or when the branch is unknown (local builds). Falls back to the other one when only one is\n * set up, and returns null when neither is. Trailing slash removed, for joining paths.\n */\nexport function appUrl(\n previews: Pick<PreviewsConfig, 'apps' | 'production'> | undefined,\n app: keyof PreviewApps,\n ctx: { branch?: string | undefined; defaultBranch?: string | undefined } = {},\n): string | null {\n const main = ctx.defaultBranch ?? 'main';\n const production = previewUrl(previews?.production?.[app], { branch: main });\n const onPreview = !!ctx.branch && ctx.branch !== main;\n const url = onPreview\n ? (previewUrl(previews?.apps[app], { branch: ctx.branch! }) ?? production)\n : (production ?? previewUrl(previews?.apps[app], { branch: main }));\n return url ? url.replace(/\\/$/, '') : null;\n}\n\n/**\n * pkg.pr.new snapshot URL for a package at a commit (or a PR number, which pkg.pr.new resolves to its latest\n * commit). Long form `https://pkg.pr.new/<owner>/<repo>/<package>@<ref>`, which works before the package is on npm.\n */\nexport function snapshotUrl(owner: string, repo: string, pkg: string, ref: string | number): string {\n return `https://pkg.pr.new/${owner}/${repo}/${pkg}@${ref}`;\n}\n\n/** One install command for several packages, so internal dependencies resolve to the same snapshot. */\nexport function installCommand(urls: string[], pm: 'npm' | 'pnpm' | 'yarn' = 'npm'): string {\n const verb = pm === 'npm' ? 'npm i' : pm === 'pnpm' ? 'pnpm add' : 'yarn add';\n return `${verb} ${urls.join(' ')}`;\n}\n\n/** Release asset name the fallback workflow uploads (`@bridge-ds/react` -> `bridge-ds-react-<sha7>.tgz`). */\nexport function tarballAssetName(pkg: string, sha: string): string {\n return `${pkg.replace(/^@/, '').replace(/\\//g, '-')}-${sha.slice(0, 7)}.tgz`;\n}\n\n/** Download URL of a fallback tarball attached to the `preview-pr-<n>` prerelease. */\nexport function tarballUrl(owner: string, repo: string, pr: number, pkg: string, sha: string): string {\n return `https://github.com/${owner}/${repo}/releases/download/preview-pr-${pr}/${tarballAssetName(pkg, sha)}`;\n}\n\nexport const PREVIEW_COMMENT_MARKER = '<!-- bridge-branch-preview -->';\n\nexport interface PreviewCommentInput {\n owner: string;\n repo: string;\n pr: number;\n branch: string;\n sha: string;\n /** Snapshot URLs by package, from pkg.pr.new or the tarball fallback. Empty when publishing failed. */\n packages: { name: string; url: string }[];\n /** Where the snapshots come from, for the note under the table. */\n source: 'pkg.pr.new' | 'release' | 'none';\n apps: PreviewApps;\n /** An exploration (`explore/*` branch or `exploration` label): staging only, never merged as is (docs/EXPLORATIONS.md). */\n exploration?: boolean | undefined;\n /**\n * The previews as Vercel reports them (`resolveBranchPreviews` over the deployments, statuses and the Vercel\n * comment). Without it, only template URLs Vercel cannot have shortened are written.\n */\n previews?: BranchPreview[] | undefined;\n}\n\n/** The sticky PR comment: install commands for each package, then the per-branch previews. Markdown, no HTML. */\nexport function previewComment(input: PreviewCommentInput): string {\n const sha7 = input.sha.slice(0, 7);\n const lines = [PREVIEW_COMMENT_MARKER, input.exploration ? '## Try this exploration in your product' : '## Try this DS branch in your product', ''];\n lines.push(`Snapshot of \\`${sha7}\\` on \\`${input.branch}\\`. Install it in a product branch that deploys to staging; production keeps the released version.`, '');\n if (input.exploration) lines.push('This is an exploration: it is never merged as is. Use it for a prototype, a user test, a demo or an A/B idea, then promote it to review or close it.', '');\n\n if (input.packages.length) {\n // Explorations install as `name@url`, so the product's package.json keeps the package names.\n lines.push('```sh', installCommand(input.packages.map((p) => (input.exploration ? `${p.name}@${p.url}` : p.url))), '```', '');\n lines.push('| Package | Install this package only |', '| --- | --- |');\n for (const p of input.packages) lines.push(`| \\`${p.name}\\` | \\`npm i ${p.url}\\` |`);\n lines.push('');\n lines.push(\n input.source === 'release'\n ? `Tarballs from the [\\`preview-pr-${input.pr}\\` prerelease](https://github.com/${input.owner}/${input.repo}/releases/tag/preview-pr-${input.pr}) (pkg.pr.new is not set up). Only the latest commit is kept.`\n : 'Snapshots on [pkg.pr.new](https://pkg.pr.new), one per commit. Swap the commit for the PR number to always get the latest.',\n );\n } else {\n lines.push('No package snapshot for this commit: the publish step failed. See the workflow run.');\n }\n lines.push('');\n\n const ctx = { branch: input.branch, pr: input.pr, sha: input.sha };\n const previews = input.previews ?? resolveBranchPreviews(input.apps, ctx);\n lines.push('### Previews', '');\n if (previews.length) {\n lines.push('| App | Preview |', '| --- | --- |');\n // A URL Vercel shortened is never guessed: its own comment on this pull request has the link.\n for (const p of previews) lines.push(`| ${p.label} | ${p.url ?? 'Link in the Vercel comment on this pull request'} |`);\n const docs = previews.find((p) => p.app === 'docs')?.url;\n if (docs) {\n lines.push('');\n lines.push(`Tokens only, no reinstall: open your staging with \\`?bridge-tokens=${new URL('tokens.css', docs).href}\\` (the staging app must allow this origin, see docs/PREVIEWS.md).`);\n }\n } else {\n lines.push('Preview deploys are not set up: add `previews.apps` to `bridge.config.json` (docs/PREVIEWS.md).');\n }\n return lines.join('\\n') + '\\n';\n}\n\n/** What the sticky comment says about installing a snapshot, read back by tools (plugin, Studio). */\nexport interface PreviewCommentInstall {\n /** The command of the first ```sh block, exactly as the workflow wrote it. Null when publishing failed. */\n command: string | null;\n /** The commit the snapshot was built from (`Snapshot of \\`1a2b3c4\\``), or null when the comment does not say. */\n sha7: string | null;\n /** Where the snapshots live, from the command's URLs. */\n source: 'pkg.pr.new' | 'release' | 'other' | 'none';\n}\n\n/**\n * The install command of a `<!-- bridge-branch-preview -->` comment: the first ```sh block, its lines joined (a\n * trailing `\\` continues a line). Null when the body is not that comment or has no command (the publish failed).\n * This is the command that works: pkg.pr.new when the workflow published there, the prerelease tarballs otherwise.\n */\nexport function installCommandFromPreviewComment(body: string | null | undefined): string | null {\n if (!body || !body.trimStart().startsWith(PREVIEW_COMMENT_MARKER)) return null;\n const m = /```(?:sh|bash|shell)[^\\n]*\\n([\\s\\S]*?)```/.exec(body);\n if (!m) return null;\n const command = m[1]!\n .split('\\n')\n .map((l) => l.trim())\n .filter((l) => l && !l.startsWith('#'))\n .join(' ')\n .replace(/\\s*\\\\\\s+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n return command || null;\n}\n\n/** Reads a sticky preview comment back: its command, the commit it was built from, where the snapshots live. */\nexport function readPreviewComment(body: string | null | undefined): PreviewCommentInstall | null {\n if (!body || !body.trimStart().startsWith(PREVIEW_COMMENT_MARKER)) return null;\n const command = installCommandFromPreviewComment(body);\n const sha7 = /Snapshot of `([0-9a-f]{7,40})`/.exec(body)?.[1]?.slice(0, 7) ?? null;\n const source = !command ? 'none' : command.includes('https://pkg.pr.new/') ? 'pkg.pr.new' : /\\/releases\\/download\\/preview-pr-\\d+\\//.test(command) ? 'release' : 'other';\n return { command, sha7, source };\n}\n\n/** The sticky preview comment among a pull request's comments (the last one, if a run ever posted twice). */\nexport function findPreviewComment<T extends { body?: string | null | undefined }>(comments: T[]): T | undefined {\n return [...comments].reverse().find((c) => !!c.body && c.body.trimStart().startsWith(PREVIEW_COMMENT_MARKER));\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Real branch preview URLs. Vercel shortens a branch alias whose first host label would pass 63 characters\n// (`bridge-admin-git-explore-button-norm-0ed5ba-peterbonos-projects.vercel.app`), with a hash nobody can predict, so\n// tools read the URL Vercel reports instead of filling the template: GitHub deployments, then the Vercel commit\n// statuses, then the Vercel bot comment on the pull request, and the template only when its host labels fit.\n\n/** Where a preview URL comes from, most trusted first. */\nexport type PreviewUrlSource = 'deployment' | 'status' | 'vercel-comment' | 'template';\n/** Whether the preview of the latest commit can be opened. `unknown` when only the template says where it is. */\nexport type PreviewState = 'ready' | 'building' | 'failed' | 'unknown';\n\nexport interface BranchPreview {\n app: keyof PreviewApps;\n label: string;\n /** Null when nothing reports it yet and the template cannot be trusted (a host label over 63 characters). */\n url: string | null;\n state: PreviewState;\n source: PreviewUrlSource | null;\n}\n\n/** A GitHub deployment with its latest status, as `GitHubClient.listDeployments` returns it. */\nexport interface DeploymentLike {\n environment: string;\n state?: string | null | undefined;\n environmentUrl?: string | null | undefined;\n}\n\n/** A commit status (`GET /commits/{sha}/statuses`), newest first like GitHub returns them. */\nexport interface CommitStatusLike {\n context: string;\n state: string;\n target_url?: string | null | undefined;\n}\n\n/** One project of the Vercel bot comment. */\nexport interface VercelCommentProject {\n name: string;\n /** https URL of the branch alias, as Vercel built it (shortened when long). */\n previewUrl: string | null;\n /** `DEPLOYED`, `PENDING`, `BUILDING`, `IGNORED`, `FAILED`... as Vercel writes it. */\n status: string | null;\n}\n\nconst httpsUrl = (raw: string | null | undefined): string | null => {\n if (!raw || typeof raw !== 'string') return null;\n try {\n const u = new URL(/^https?:\\/\\//i.test(raw) ? raw : `https://${raw}`);\n return u.protocol === 'https:' || u.protocol === 'http:' ? u.href : null;\n } catch {\n return null;\n }\n};\n\nconst decodeBase64 = (b64: string): string => {\n const bin = atob(b64.replace(/\\s/g, ''));\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return new TextDecoder('utf-8').decode(bytes);\n};\n\n/** True for the comment the Vercel GitHub app posts (and edits) on a pull request. */\nexport const isVercelComment = (body: string | null | undefined): boolean => !!body && /^\\[vc\\]: #[^:\\s]*:[A-Za-z0-9+/=]+/m.test(body);\n\n/**\n * The projects of a Vercel bot comment, from its hidden header `[vc]: #<hash>:<base64 JSON>` (projects[].name and\n * previewUrl). Null when the body is not that comment or the header does not decode.\n */\nexport function parseVercelComment(body: string | null | undefined): VercelCommentProject[] | null {\n if (!body) return null;\n const m = /^\\[vc\\]: #[^:\\s]*:([A-Za-z0-9+/=]+)/m.exec(body);\n if (!m) return null;\n let data: { projects?: { name?: unknown; previewUrl?: unknown; nextCommitStatus?: unknown }[] };\n try {\n data = JSON.parse(decodeBase64(m[1]!));\n } catch {\n return null;\n }\n if (!data || !Array.isArray(data.projects)) return null;\n return data.projects\n .filter((p) => p && typeof p.name === 'string')\n .map((p) => ({ name: p.name as string, previewUrl: httpsUrl(typeof p.previewUrl === 'string' ? p.previewUrl : null), status: typeof p.nextCommitStatus === 'string' ? p.nextCommitStatus : null }));\n}\n\n/** The Vercel bot comment among a pull request's comments (the last one, if there were ever two). */\nexport function findVercelComment<T extends { body?: string | null | undefined }>(comments: T[]): T | undefined {\n return [...comments].reverse().find((c) => isVercelComment(c.body));\n}\n\n/** The first host label of a template, up to its first placeholder: `bridge-admin-git-` for the admin template. */\nfunction templateHostPrefix(template: string | undefined): string | null {\n if (!template) return null;\n const host = /^https?:\\/\\/([^/?#]+)/i.exec(template)?.[1];\n if (!host) return null;\n return host.split('.')[0]!.split('{')[0]!.toLowerCase();\n}\n\n/**\n * The app (`docs`, `storybook`, `admin`) a Vercel project serves, from the host its template starts with: project\n * `bridge-admin` serves the app whose template host starts with `bridge-admin-git-` (Vercel's branch alias shape),\n * else with `bridge-admin-` when only one template does. Null when no template names it.\n */\nexport function appForProject(project: string, apps: PreviewApps): keyof PreviewApps | null {\n const name = project.trim().toLowerCase();\n if (!name) return null;\n const keys = Object.keys(PREVIEW_APP_LABELS) as (keyof PreviewApps)[];\n const prefixes = keys.map((app) => [app, templateHostPrefix(apps[app])] as const);\n const exact = prefixes.find(([, p]) => p === `${name}-git-` || p === name);\n if (exact) return exact[0];\n // Otherwise one template must start with `<project>-`; several (a project name that prefixes others) name none.\n const loose = prefixes.filter(([, p]) => p !== null && p.startsWith(`${name}-`));\n return loose.length === 1 ? loose[0]![0] : null;\n}\n\n/** The project a deployment environment or a status context names: `Preview – bridge-admin` -> `bridge-admin`. */\nexport function projectOfLabel(label: string): string | null {\n const m = /^\\s*(?:preview|vercel)\\s*[\\u2013\\u2014-]\\s*(.+?)\\s*$/i.exec(label);\n return m ? m[1]! : null;\n}\n\nconst STATE_OF: Record<string, PreviewState> = {\n success: 'ready',\n inactive: 'ready',\n deployed: 'ready',\n ready: 'ready',\n ignored: 'ready', // Vercel skipped the build (nothing changed for this app): the branch alias serves the last one.\n pending: 'building',\n queued: 'building',\n in_progress: 'building',\n building: 'building',\n initializing: 'building',\n failure: 'failed',\n error: 'failed',\n failed: 'failed',\n canceled: 'failed',\n};\nconst stateOf = (s: string | null | undefined): PreviewState => STATE_OF[(s ?? '').toLowerCase()] ?? 'unknown';\nconst isInspectorUrl = (u: string) => /^https:\\/\\/(?:www\\.)?vercel\\.com\\//i.test(u);\n\nexport interface BranchPreviewSources {\n /** GitHub deployments of the head commit, each with its latest status. */\n deployments?: DeploymentLike[] | undefined;\n /** Commit statuses of the head commit, newest first. */\n statuses?: CommitStatusLike[] | undefined;\n /** The pull request's comments (the Vercel bot comment is read from them). */\n comments?: { body?: string | null | undefined }[] | undefined;\n}\n\n/**\n * The preview of each configured app, real URL first: a GitHub deployment's environment URL, then a Vercel commit\n * status pointing at the deployment (not at the inspector), then the Vercel bot comment, and the config template only\n * when its host labels fit in 63 characters (else Vercel shortened it: url null until a real source reports it).\n * The state comes from the freshest signal: commit status, then deployment, then the comment.\n */\nexport function resolveBranchPreviews(apps: PreviewApps, ctx: PreviewContext, sources: BranchPreviewSources = {}): BranchPreview[] {\n type Seen = { url?: string; urlSource?: PreviewUrlSource; state?: PreviewState; stateRank?: number };\n const seen = new Map<keyof PreviewApps, Seen>();\n const at = (app: keyof PreviewApps) => seen.get(app) ?? (seen.set(app, {}), seen.get(app)!);\n const offer = (app: keyof PreviewApps | null, url: string | null, urlSource: PreviewUrlSource, state: PreviewState, stateRank: number) => {\n if (!app) return;\n const s = at(app);\n if (url && !s.url) Object.assign(s, { url, urlSource });\n if (state !== 'unknown' && (s.stateRank === undefined || stateRank < s.stateRank)) Object.assign(s, { state, stateRank });\n };\n\n // 1. Commit statuses (Vercel – <project>): newest first, so the first one per context is current.\n const contexts = new Set<string>();\n for (const st of sources.statuses ?? []) {\n if (contexts.has(st.context)) continue;\n contexts.add(st.context);\n const project = projectOfLabel(st.context);\n if (!project) continue;\n const url = httpsUrl(st.target_url);\n offer(appForProject(project, apps), url && !isInspectorUrl(url) ? url : null, 'status', stateOf(st.state), 0);\n }\n // 2. Deployments (Preview – <project>): their URL beats the status's.\n for (const d of sources.deployments ?? []) {\n const project = projectOfLabel(d.environment);\n const app = project ? appForProject(project, apps) : null;\n if (!app) continue;\n const url = httpsUrl(d.environmentUrl);\n const s = at(app);\n if (url && s.urlSource !== 'deployment') Object.assign(s, { url, urlSource: 'deployment' as const });\n const state = stateOf(d.state);\n if (state !== 'unknown' && (s.stateRank === undefined || 1 < s.stateRank)) Object.assign(s, { state, stateRank: 1 });\n }\n // 3. The Vercel bot comment.\n for (const p of parseVercelComment(findVercelComment(sources.comments ?? [])?.body) ?? []) offer(appForProject(p.name, apps), p.previewUrl, 'vercel-comment', stateOf(p.status), 2);\n\n const out: BranchPreview[] = [];\n for (const app of Object.keys(PREVIEW_APP_LABELS) as (keyof PreviewApps)[]) {\n if (!apps[app]) continue;\n const s = seen.get(app) ?? {};\n // 4. The template, only when Vercel would not have shortened it (previewUrl returns null over 63 characters).\n const url = s.url ?? previewUrl(apps[app], ctx);\n const source: PreviewUrlSource | null = s.url ? s.urlSource! : url ? 'template' : null;\n out.push({ app, label: PREVIEW_APP_LABELS[app], url, state: s.state ?? 'unknown', source });\n }\n return out;\n}\n\n/** The previews that have a URL, as links (`{ app, label, url }`), in the stable app order. */\nexport const previewLinksOf = (previews: BranchPreview[]): { app: keyof PreviewApps; label: string; url: string }[] =>\n previews.filter((p): p is BranchPreview & { url: string } => !!p.url).map((p) => ({ app: p.app, label: p.label, url: p.url }));\n\n/** True when every configured app has its URL and a finished build (ready or failed): polling can stop. */\nexport const previewsSettled = (previews: BranchPreview[]): boolean => previews.every((p) => !!p.url && (p.state === 'ready' || p.state === 'failed'));\n","// Roles by team: an owner entry in `governance.owners` is a person (`peterbono`, `@peterbono`) or a GitHub team\n// (`@acme/design`). Membership is managed in GitHub; Bridge reads it, never stores it. Still no database.\n//\n// Parsing and the pure helpers below need no network. TeamDirectory expands teams to logins through any client\n// with the TeamReader methods (GitHubClient has them), with a cache. A team it cannot read is a typed\n// \"unreadable\" state with the reason and the fix, never an empty list: an empty owner list means \"any reviewer\n// counts\", so silently emptying a team would open the gate. An unreadable team keeps its \"@org/slug\" key in the\n// expanded lists instead: it holds the place, and no login ever matches it (logins have no \"/\").\n\nimport type { Owners } from './config';\n\nexport type OwnerEntry = { kind: 'person'; login: string } | { kind: 'team'; org: string; slug: string };\n\n// GitHub logins: letters, digits and single hyphens, no leading or trailing hyphen, 39 characters at most.\nconst LOGIN = /^[A-Za-z0-9](?:[A-Za-z0-9]|-(?=[A-Za-z0-9])){0,38}$/;\n// Team slugs: lowercase letters, digits, hyphens, underscores and dots as GitHub generates them; case-insensitive here.\nconst SLUG = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;\n\n/** A person or a team, or null when `raw` is neither. Accepts a leading @ on both. */\nexport function parseOwnerEntry(raw: string): OwnerEntry | null {\n if (typeof raw !== 'string') return null;\n const s = raw.trim().replace(/^@/, '');\n const slash = s.indexOf('/');\n if (slash < 0) return LOGIN.test(s) ? { kind: 'person', login: s } : null;\n const org = s.slice(0, slash);\n const slug = s.slice(slash + 1);\n return LOGIN.test(org) && SLUG.test(slug) ? { kind: 'team', org, slug } : null;\n}\n\n/** \"@acme/design\" for a team, \"peterbono\" for a person: the form Bridge writes back to bridge.config.json. */\nexport function formatOwnerEntry(e: OwnerEntry): string {\n return e.kind === 'team' ? `@${e.org}/${e.slug}` : e.login;\n}\n\n/** Whether a raw entry names a team. */\nexport const isTeamEntry = (raw: string): boolean => parseOwnerEntry(raw)?.kind === 'team';\n\n/** Case-insensitive key of a team: \"@acme/design\". */\nexport const teamKey = (org: string, slug: string): string => `@${org.toLowerCase()}/${slug.toLowerCase()}`;\n\n/** Key of a raw team entry, undefined for a person or a malformed entry. */\nexport function teamKeyOf(raw: string): string | undefined {\n const e = parseOwnerEntry(raw);\n return e?.kind === 'team' ? teamKey(e.org, e.slug) : undefined;\n}\n\n/**\n * Problems in the raw owner lists, in the words loadConfig reports. Each malformed entry is named with the two\n * accepted forms, so the fix is in the message.\n */\nexport function ownerEntryProblems(raw: unknown): string[] {\n if (raw === undefined) return [];\n const isObj = (x: unknown): x is Record<string, unknown> => Boolean(x) && typeof x === 'object' && !Array.isArray(x);\n if (!isObj(raw)) return ['\"governance.owners\" must be { \"design\": [people or teams], \"tech\": [people or teams] }'];\n const out: string[] = [];\n for (const [k, v] of Object.entries(raw)) {\n if (k !== 'design' && k !== 'tech') {\n out.push(`\"governance.owners.${k}\" is not an owner group (design, tech)`);\n continue;\n }\n if (!Array.isArray(v)) {\n out.push(`\"governance.owners.${k}\" must be a list of people or teams`);\n continue;\n }\n v.forEach((x, i) => {\n if (typeof x !== 'string' || !parseOwnerEntry(x))\n out.push(`\"governance.owners.${k}[${i}]\" (${JSON.stringify(x)}) is not a GitHub login or team. Write a person as \"peterbono\" or \"@peterbono\", a team as \"@org/team-slug\".`);\n });\n }\n return out;\n}\n\n/** Why a team's members cannot be read, each with its own fix (teamUnreadableMessage). */\nexport type TeamUnreadableReason =\n /** The repository owner (or the org named) is a personal account: GitHub teams only exist in organizations. */\n | 'personal-account'\n /** The token works but may not read the organization's teams (classic: read:org; fine-grained: Members, read). */\n | 'missing-permission'\n /** No token, or GitHub refused it: GitHub never shows team members anonymously. */\n | 'no-token'\n /** GitHub says the team does not exist, or hides it from this token. */\n | 'not-found'\n /** GitHub did not answer (network, rate limit, server error). */\n | 'unreachable';\n\nexport interface TeamRef {\n /** \"@acme/design\", lowercase. */\n key: string;\n org: string;\n slug: string;\n}\n\nexport type TeamState =\n | (TeamRef & { status: 'ok'; members: string[] })\n | (TeamRef & { status: 'unreadable'; reason: TeamUnreadableReason; message: string });\n\n/** Team states by key (\"@acme/design\"). */\nexport type TeamStates = Record<string, TeamState>;\n\n/** The one sentence that says why a team cannot be read and how to fix it. */\nexport function teamUnreadableMessage(team: { org: string; slug: string }, reason: TeamUnreadableReason): string {\n const name = `@${team.org}/${team.slug}`;\n switch (reason) {\n case 'personal-account':\n return `${name} cannot be used: ${team.org} is a personal GitHub account, and teams only exist in organizations. List people instead, or move the repository to an organization.`;\n case 'missing-permission':\n return `The members of ${name} cannot be read: the GitHub token needs read:org (classic token) or Members: Read on the ${team.org} organization (fine-grained token).`;\n case 'no-token':\n return `The members of ${name} cannot be read without a working GitHub token. Connect GitHub with a token that has read:org.`;\n case 'not-found':\n return `${name} was not found. Check the team slug on GitHub, or give the token read:org so it can see the team.`;\n case 'unreachable':\n return `The members of ${name} cannot be read right now: GitHub did not answer. Try again in a moment.`;\n }\n}\n\n/** Distinct teams named in the owner lists, in order. */\nexport function teamsIn(owners: Partial<Owners> | readonly string[]): TeamRef[] {\n const all = Array.isArray(owners) ? (owners as string[]) : [...((owners as Partial<Owners>).design ?? []), ...((owners as Partial<Owners>).tech ?? [])];\n const out = new Map<string, TeamRef>();\n for (const raw of all) {\n const e = parseOwnerEntry(raw);\n if (e?.kind === 'team') out.set(teamKey(e.org, e.slug), { key: teamKey(e.org, e.slug), org: e.org, slug: e.slug });\n }\n return [...out.values()];\n}\n\nconst norm = (x: string) => x.trim().toLowerCase().replace(/^@/, '');\n\n/**\n * Logins of a list of entries: people as they are, a readable team as its members. An unreadable team, or one not\n * resolved yet, stays as its \"@org/slug\" key: never empty, never matching a login.\n */\nexport function expandEntries(entries: readonly string[], teams?: TeamStates | null): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n const add = (x: string) => {\n const k = norm(x);\n if (k && !seen.has(k)) {\n seen.add(k);\n out.push(x.replace(/^@(?=[^/]+$)/, ''));\n }\n };\n for (const raw of entries) {\n const e = parseOwnerEntry(raw);\n if (!e) continue;\n if (e.kind === 'person') add(e.login);\n else {\n const state = teams?.[teamKey(e.org, e.slug)];\n if (state?.status === 'ok') state.members.forEach(add);\n else add(teamKey(e.org, e.slug));\n }\n }\n return out;\n}\n\n/** Both owner lists expanded (expandEntries). */\nexport function expandOwners(owners: Owners, teams?: TeamStates | null): Owners {\n return { design: expandEntries(owners.design, teams), tech: expandEntries(owners.tech, teams) };\n}\n\nconst people = (n: number) => `${n} ${n === 1 ? 'person' : 'people'}`;\n\n/** How an entry reads in a sentence: \"@peterbono\", \"@acme/design (4 people)\", \"@acme/design\" while unknown. */\nexport function entryLabel(raw: string, teams?: TeamStates | null): string {\n const e = parseOwnerEntry(raw);\n if (!e) return raw;\n if (e.kind === 'person') return `@${e.login}`;\n const state = teams?.[teamKey(e.org, e.slug)];\n const name = `@${e.org}/${e.slug}`;\n return state?.status === 'ok' ? `${name} (${people(state.members.length)})` : name;\n}\n\n/**\n * The entries to name for a set of logins (someone who can still act): each person among them, each team with a\n * member among them, and each team whose members are unknown (it may hold one). Labels as entryLabel.\n */\nexport function entriesFor(entries: readonly string[], logins: readonly string[], teams?: TeamStates | null): string[] {\n const want = new Set(logins.map(norm));\n const out: string[] = [];\n for (const raw of entries) {\n const e = parseOwnerEntry(raw);\n if (!e) continue;\n if (e.kind === 'person') {\n if (want.has(norm(e.login))) out.push(entryLabel(raw, teams));\n continue;\n }\n const state = teams?.[teamKey(e.org, e.slug)];\n if (state?.status !== 'ok' || state.members.some((m) => want.has(norm(m)))) out.push(entryLabel(raw, teams));\n }\n return [...new Set(out)];\n}\n\n/** Teams that could not be read, in order. */\nexport function unreadableTeams(teams: TeamStates | null | undefined): Extract<TeamState, { status: 'unreadable' }>[] {\n return Object.values(teams ?? {}).filter((t): t is Extract<TeamState, { status: 'unreadable' }> => t.status === 'unreadable');\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Reading teams from GitHub\n\n/** What TeamDirectory needs from a GitHub client. GitHubClient implements it. */\nexport interface TeamReader {\n /** Whether a token is sent: GitHub never lists team members anonymously. */\n readonly hasToken: boolean;\n /** Every member login of a team (GET /orgs/{org}/teams/{slug}/members, all pages). */\n listTeamMembers(org: string, slug: string): Promise<string[]>;\n /** A user's membership of a team (GET /orgs/{org}/teams/{slug}/memberships/{user}): \"active\", \"pending\", or null when not a member. */\n getTeamMembership(org: string, slug: string, login: string): Promise<'active' | 'pending' | null>;\n /** \"User\" or \"Organization\" (GET /users/{login}), null when unknown. */\n getAccountType(login: string): Promise<'User' | 'Organization' | null>;\n /** The organization's teams the token can see (GET /orgs/{org}/teams, all pages). */\n listOrgTeams(org: string): Promise<{ slug: string; name: string }[]>;\n}\n\n/** The parts of a GitHub error TeamDirectory reads (GitHubError has them). */\ninterface ErrorLike {\n status?: number;\n auth?: string;\n}\n\nexport interface TeamDirectoryOptions {\n /** How long a team read is kept, in ms. Default 5 minutes. */\n ttlMs?: number;\n now?: () => number;\n}\n\n/** Whether one person may act through a list of entries, and which teams could not be checked. */\nexport interface MembershipResult {\n member: boolean;\n /** Teams whose membership could not be read: when `member` is false, the answer may be wrong for them. */\n unreadable: Extract<TeamState, { status: 'unreadable' }>[];\n}\n\n/**\n * Expands teams to logins through a TeamReader, with a cache: each team is read once per `ttlMs`, concurrent reads\n * of one team share the request. Every failure becomes an \"unreadable\" state with its reason.\n */\nexport class TeamDirectory {\n private readonly teams = new Map<string, { at: number; value: Promise<TeamState> }>();\n private readonly accounts = new Map<string, Promise<'User' | 'Organization' | null>>();\n private readonly memberships = new Map<string, { at: number; value: Promise<boolean | TeamState> }>();\n private readonly ttl: number;\n private readonly now: () => number;\n\n constructor(\n private readonly reader: TeamReader,\n opts: TeamDirectoryOptions = {},\n ) {\n this.ttl = opts.ttlMs ?? 5 * 60_000;\n this.now = opts.now ?? Date.now;\n }\n\n private accountType(org: string): Promise<'User' | 'Organization' | null> {\n const k = org.toLowerCase();\n let p = this.accounts.get(k);\n if (!p) {\n p = this.reader.getAccountType(org).catch(() => null);\n this.accounts.set(k, p);\n }\n return p;\n }\n\n /** The reason a read of `org` failed, as a state. A 404 on a personal account says so; a 403 is a missing permission. */\n private async failure(ref: TeamRef, err: unknown): Promise<TeamState> {\n const e = (err ?? {}) as ErrorLike;\n let reason: TeamUnreadableReason;\n if (!this.reader.hasToken) reason = (await this.accountType(ref.org)) === 'User' ? 'personal-account' : 'no-token';\n else if (e.status === 401) reason = 'no-token';\n else if (e.status === 403 || e.auth === 'missing-permission') reason = 'missing-permission';\n else if (e.status === 404) reason = (await this.accountType(ref.org)) === 'User' ? 'personal-account' : 'not-found';\n else reason = 'unreachable';\n return { ...ref, status: 'unreadable', reason, message: teamUnreadableMessage(ref, reason) };\n }\n\n /** Members of one team, or why they cannot be read. Cached. */\n team(org: string, slug: string): Promise<TeamState> {\n const ref: TeamRef = { key: teamKey(org, slug), org, slug };\n const hit = this.teams.get(ref.key);\n if (hit && this.now() - hit.at < this.ttl) return hit.value;\n const value = (async (): Promise<TeamState> => {\n if (!this.reader.hasToken) return this.failure(ref, undefined);\n try {\n const members = await this.reader.listTeamMembers(org, slug);\n return { ...ref, status: 'ok', members };\n } catch (err) {\n return this.failure(ref, err);\n }\n })();\n this.teams.set(ref.key, { at: this.now(), value });\n // A failure GitHub may fix in a moment is not kept.\n void value.then((s) => {\n if (s.status === 'unreadable' && s.reason === 'unreachable') this.teams.delete(ref.key);\n });\n return value;\n }\n\n /** Every team named in the owner lists, read in parallel. Empty object when no team is named (no request). */\n async resolve(owners: Partial<Owners> | readonly string[]): Promise<TeamStates> {\n const refs = teamsIn(owners);\n const states = await Promise.all(refs.map((r) => this.team(r.org, r.slug)));\n return Object.fromEntries(states.map((s) => [s.key, s]));\n }\n\n /**\n * Whether `login` is an active member of one team: from the cached member list when there is one, else one\n * membership read (GET /orgs/{org}/teams/{slug}/memberships/{user}). An unreadable team returns its state.\n */\n async isMember(org: string, slug: string, login: string): Promise<boolean | TeamState> {\n const ref: TeamRef = { key: teamKey(org, slug), org, slug };\n const cached = this.teams.get(ref.key);\n if (cached && this.now() - cached.at < this.ttl) {\n const s = await cached.value;\n if (s.status === 'ok') return s.members.some((m) => norm(m) === norm(login));\n }\n const k = `${ref.key}#${norm(login)}`;\n const hit = this.memberships.get(k);\n if (hit && this.now() - hit.at < this.ttl) return hit.value;\n const value = (async (): Promise<boolean | TeamState> => {\n if (!this.reader.hasToken) return this.failure(ref, undefined);\n try {\n return (await this.reader.getTeamMembership(org, slug, login)) === 'active';\n } catch (err) {\n return this.failure(ref, err);\n }\n })();\n this.memberships.set(k, { at: this.now(), value });\n return value;\n }\n\n /**\n * Whether `login` holds a right given to `entries` (people and teams): a person entry matches directly, a team\n * through its membership. Teams are only read when no person entry matches.\n */\n async memberOfAny(entries: readonly string[], login: string): Promise<MembershipResult> {\n const unreadable: MembershipResult['unreadable'] = [];\n const parsed = entries.map(parseOwnerEntry).filter((e): e is OwnerEntry => Boolean(e));\n if (parsed.some((e) => e.kind === 'person' && norm(e.login) === norm(login))) return { member: true, unreadable };\n for (const e of parsed) {\n if (e.kind !== 'team') continue;\n const r = await this.isMember(e.org, e.slug, login);\n if (r === true) return { member: true, unreadable };\n if (typeof r === 'object' && r.status === 'unreadable') unreadable.push(r);\n }\n return { member: false, unreadable };\n }\n\n /** The organization's teams for a picker, or why they cannot be listed (a personal account has none). */\n async orgTeams(org: string): Promise<{ status: 'ok'; teams: { slug: string; name: string }[] } | { status: 'unreadable'; reason: TeamUnreadableReason }> {\n if ((await this.accountType(org)) === 'User') return { status: 'unreadable', reason: 'personal-account' };\n if (!this.reader.hasToken) return { status: 'unreadable', reason: 'no-token' };\n try {\n return { status: 'ok', teams: await this.reader.listOrgTeams(org) };\n } catch (err) {\n const s = await this.failure({ key: teamKey(org, '*'), org, slug: '*' }, err);\n return { status: 'unreadable', reason: s.status === 'unreadable' ? s.reason : 'unreachable' };\n }\n }\n\n /** Drops every cached read (after the token changes). */\n clear(): void {\n this.teams.clear();\n this.accounts.clear();\n this.memberships.clear();\n }\n}\n","// Roles and their rights: which owner group may approve the design side, approve the tech side and ship (merge a\n// pull request, which publishes the change to the products). `governance.rights` in bridge.config.json; each team\n// edits it in Studio Settings. Pure functions, shared by Studio Reviews, Settings, the CLI and the MCP server.\n//\n// Backward compatible: a config without `rights` behaves as before it existed. Approvals follow the owner lists,\n// and anyone with write access to the repo may ship. DEFAULT_RIGHTS is what Settings proposes and what new\n// configs get: design owners approve design, tech owners approve tech, tech owners ship.\n//\n// Owner entries may be GitHub teams (\"@acme/design\", teams.ts). Pass the team states (TeamDirectory.resolve) to the\n// functions below and teams count as their members; without them, or for a team that cannot be read, the team keeps\n// its \"@org/slug\" place in the lists so they never turn empty, and no login matches it.\n\nimport type { Owners } from './config';\nimport { entryLabel, expandEntries, expandOwners, unreadableTeams, type TeamState, type TeamStates } from './teams';\n\n/** An owner group from `governance.owners`. */\nexport type OwnerGroup = 'design' | 'tech';\n\nexport const OWNER_GROUPS: readonly OwnerGroup[] = ['design', 'tech'];\n\n/** The three rights, each held by one or more owner groups. */\nexport interface Rights {\n approveDesign: OwnerGroup[];\n approveTech: OwnerGroup[];\n ship: OwnerGroup[];\n}\n\nexport type Right = keyof Rights;\n\nexport const RIGHTS: readonly Right[] = ['approveDesign', 'approveTech', 'ship'];\n\n/** Plain names of each right, for Settings and the gate messages. \"Ship\" means publish to the products. */\nexport const RIGHT_LABEL: Record<Right, string> = {\n approveDesign: 'Approve design',\n approveTech: 'Approve tech',\n ship: 'Ship',\n};\n\nexport const DEFAULT_RIGHTS: Rights = { approveDesign: ['design'], approveTech: ['tech'], ship: ['tech'] };\n\nconst norm = (x: string) => x.trim().toLowerCase().replace(/^@/, '');\nconst uniq = <T>(xs: T[]) => [...new Set(xs)];\n\n/** Rights with every missing entry filled from DEFAULT_RIGHTS, groups deduplicated in design, tech order. */\nexport function normalizeRights(input: Partial<Record<Right, readonly string[]>> | null | undefined): Rights {\n const pick = (r: Right): OwnerGroup[] => {\n const v = input?.[r];\n if (!Array.isArray(v)) return [...DEFAULT_RIGHTS[r]];\n return OWNER_GROUPS.filter((g) => v.includes(g));\n };\n return { approveDesign: pick('approveDesign'), approveTech: pick('approveTech'), ship: pick('ship') };\n}\n\n/** Problems in a raw `governance.rights` value, in the words loadConfig reports. Empty: valid. */\nexport function rightsProblems(raw: unknown): string[] {\n if (raw === undefined) return [];\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return ['\"governance.rights\" must be { \"approveDesign\": [groups], \"approveTech\": [groups], \"ship\": [groups] }'];\n const out: string[] = [];\n for (const [k, v] of Object.entries(raw as Record<string, unknown>)) {\n if (!(RIGHTS as readonly string[]).includes(k)) out.push(`\"governance.rights.${k}\" is not a right (${RIGHTS.join(', ')})`);\n else if (!Array.isArray(v) || v.length === 0 || !v.every((g) => (OWNER_GROUPS as readonly unknown[]).includes(g)))\n out.push(`\"governance.rights.${k}\" must list one or more of \"design\", \"tech\"`);\n }\n return out;\n}\n\n/** The entries (people and teams) holding a right: the union of the owner lists of its groups. Empty when those lists are empty. */\nexport function holdersOf(right: Right, owners: Owners, rights: Rights | null | undefined): string[] {\n const groups = (rights ?? DEFAULT_RIGHTS)[right];\n return uniq(groups.flatMap((g) => owners[g] ?? []));\n}\n\n/**\n * Owner lists to count approvals against (summarizeApprovals): who may approve design, who may approve tech.\n * Without `rights`, the owner lists as they are.\n */\nexport function approverLists(owners: Owners, rights: Rights | null | undefined, teams?: TeamStates | null): Owners {\n const entries = approverEntries(owners, rights);\n return teams === undefined ? entries : expandOwners(entries, teams);\n}\n\n/** approverLists before team expansion: the entries as the config names them, for sentences. */\nexport function approverEntries(owners: Owners, rights: Rights | null | undefined): Owners {\n if (!rights) return { design: [...owners.design], tech: [...owners.tech] };\n return { design: holdersOf('approveDesign', owners, rights), tech: holdersOf('approveTech', owners, rights) };\n}\n\n/** Who may ship, or null when nobody is singled out (no `rights`, or its groups list no logins): anyone with write access. */\nexport interface ShipPolicy {\n /** Logins allowed to ship: people, and team members once read. A team not read keeps its \"@org/slug\" key. */\n logins: string[];\n /** Owner groups holding the right, for the sentence (\"the tech owner\", \"a design or tech owner\"). */\n groups: OwnerGroup[];\n /** The entries as the config names them (people and teams), for the sentence. Absent: `logins`. */\n entries?: string[];\n /** Team states known when the policy was built, for the sentence (\"@acme/design (4 people)\"). */\n teams?: TeamStates;\n}\n\n/**\n * Who may ship. With `teams` (TeamDirectory.resolve), team members count; a team that cannot be read still holds\n * the right, so the policy is never dropped to \"anyone with write access\" because a team was not read.\n */\nexport function shipPolicy(owners: Owners, rights: Rights | null | undefined, teams?: TeamStates | null): ShipPolicy | null {\n if (!rights) return null;\n const entries = holdersOf('ship', owners, rights);\n if (!entries.length) return null;\n const logins = expandEntries(entries, teams);\n return { logins, groups: [...rights.ship], entries, ...(teams ? { teams } : {}) };\n}\n\n/** Teams in a ship policy that could not be read: the gate names them with the fix. */\nexport function unreadableShipTeams(policy: ShipPolicy | null | undefined): TeamState[] {\n if (!policy?.teams) return [];\n const keys = new Set((policy.entries ?? []).map((e) => e.trim().toLowerCase().replace(/^@?/, '@')));\n return unreadableTeams(policy.teams).filter((t) => keys.has(t.key));\n}\n\n/** Whether `login` may ship. No policy: yes (GitHub write access still decides). */\nexport function canShip(login: string | null | undefined, policy: ShipPolicy | null | undefined): boolean {\n if (!policy) return true;\n // A login never holds a \"/\": the \"@org/slug\" place of a team not read cannot be matched.\n if (!login || login.includes('/')) return false;\n return policy.logins.map(norm).includes(norm(login));\n}\n\n/** \"the tech owner\", \"the design owner\", \"a design or tech owner\". */\nexport function groupsPhrase(groups: readonly OwnerGroup[]): string {\n const g = OWNER_GROUPS.filter((x) => groups.includes(x));\n if (g.length === 1) return `the ${g[0]} owner`;\n return `a ${g.join(' or ')} owner`;\n}\n\n/** The sentence a blocked viewer reads: \"Only the tech owner can ship this.\" */\n/** Teams are named as teams, with their size when known: \"Only the tech owner can ship this (@acme/web (4 people)).\" */\nexport function whoCanShipSentence(policy: ShipPolicy): string {\n const names = (policy.entries ?? policy.logins).map((l) => entryLabel(l, policy.teams)).join(', ');\n return `Only ${groupsPhrase(policy.groups)} can ship this${names ? ` (${names})` : ''}.`;\n}\n\n/** Visual before and after: on every pull request that touches tokens or components, or only when asked. */\nexport type VisualImpactMode = 'auto' | 'on-demand';\n\nexport interface VisualImpactConfig {\n mode: VisualImpactMode;\n}\n\nexport const DEFAULT_VISUAL_IMPACT: VisualImpactConfig = { mode: 'auto' };\n\n/** Label that asks the visual impact workflow to run in on-demand mode. */\nexport const VISUAL_CHECK_LABEL = 'visual-check';\n\nexport function visualImpactProblems(raw: unknown): string[] {\n if (raw === undefined) return [];\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return ['\"visualImpact\" must be { \"mode\": \"auto\" | \"on-demand\" }'];\n const out: string[] = [];\n for (const [k, v] of Object.entries(raw as Record<string, unknown>)) {\n if (k !== 'mode') out.push(`\"visualImpact.${k}\" is not a setting (mode)`);\n else if (v !== 'auto' && v !== 'on-demand') out.push('\"visualImpact.mode\" must be \"auto\" or \"on-demand\"');\n }\n return out;\n}\n","// bridge.config.json: where a design system repo keeps its tokens, which modes it has, and how Bridge may\n// propose changes to it. One file, one schema (packages/core/bridge.config.schema.json), read by\n// @bridge-ds/core, the DS Bridge Figma plugin, the docs site, the CLI and the MCP server.\n//\n// The canonical form names tiers, ordered layers and modes:\n//\n// tokens.root directory holding every token file (repo-relative)\n// tokens.include token file globs, relative to root (default **/*.tokens.json)\n// tokens.tiers tier -> directories or files, relative to root\n// tokens.layers resolution order, lowest first; {mode} placeholders pick the file per mode value\n// modes mode name -> { values, default, parity }\n// contrast.path contrast pairs: { \"pairs\": [[fg, bg, min], ...] } (repo-relative)\n//\n// The older flat form (tokens.primitives/brands/semantic/base/density/components/contrastChecks and\n// modes.brands/themes/densities/defaults) is still read, so commits from before the merge load too.\n// loadConfig normalizes both into one BridgeConfig.\n\nimport type { IntegrationsConfig } from './requests';\nimport { PREVIEW_APP_LABELS, type PreviewApps, type PreviewsConfig } from './previews';\nimport { normalizeRights, rightsProblems, visualImpactProblems, type Rights, type VisualImpactConfig } from './rights';\nimport { ownerEntryProblems } from './teams';\n\n/** File name Bridge looks for at the repository root. */\nexport const CONFIG_FILE = 'bridge.config.json';\n\nexport interface RepoRef {\n owner: string;\n name: string;\n /** Branch pull requests target and pulls read from. Bridge never writes to it. */\n defaultBranch: string;\n}\n\n/** Tier folders, relative to `root`. Derived from `tiers` when the canonical form is used. */\nexport interface TokenPaths {\n root: string;\n primitives: string;\n brands: string;\n semantic: string;\n /** Stem of the theme-independent semantic file inside `semantic` (\"base\" -> semantic/base.tokens.json). */\n base: string;\n density: string;\n components: string;\n /** Contrast checks file, relative to `root` (see `contrast.path` for the repo-relative path). */\n contrastChecks: string;\n}\n\nexport interface TokenLayer {\n /** Glob relative to tokens.root. `{mode}` placeholders pick the file for a mode value; `*` and `**` match many. */\n files: string;\n /** A missing file is fine (brand overrides only some brands have). */\n optional: boolean;\n}\n\nexport interface TokenConfig extends TokenPaths {\n include: string[];\n exclude: string[];\n /** Tier name -> directories or files relative to root. First match wins. */\n tiers: Record<string, string[]>;\n layers: TokenLayer[];\n}\n\nexport interface ModeAxis {\n values: string[];\n default: string;\n /** Every token defined for one value must exist for the others (light and dark). */\n parity: boolean;\n}\n\n/** Brand, theme and density lists (default first), as the tier model and the Figma plugin use them. */\nexport interface ModeConfig {\n brands: string[];\n themes: string[];\n densities: string[];\n defaults: { brand?: string | undefined; theme?: string | undefined; density?: string | undefined };\n}\n\nexport interface ComponentsConfig {\n /** Code components directory, repo-relative. */\n dir: string;\n docsSuffix: string;\n styleSuffix: string;\n /** Component whose docs.json keys new components copy. */\n reference?: string | undefined;\n /** Barrel file new components are exported from. */\n index?: string | undefined;\n /** Generated component specs the Figma plugin pulls (default packages/react/component-specs.json). */\n specs?: string | undefined;\n}\n\n/**\n * Design and tech owners. Each entry is a person (\"peterbono\" or \"@peterbono\") or a GitHub team (\"@acme/design\"),\n * whose members GitHub manages (teams.ts expands them).\n */\nexport interface Owners {\n design: string[];\n tech: string[];\n}\n\n/** Who may merge past missing approvals, from Bridge, with a written reason. Absent: nobody. */\nexport interface OverridePolicy {\n /** GitHub logins allowed to merge as owner override. */\n allowed: string[];\n /** Ask for a written reason, posted on the pull request before the merge. Default true. */\n requireReason: boolean;\n /** Shortest accepted reason, in characters. Default 20. */\n minReasonLength: number;\n}\n\nexport const DEFAULT_OVERRIDE: OverridePolicy = { allowed: [], requireReason: true, minReasonLength: 20 };\n\nexport interface GovernanceConfig {\n /** Branches no Bridge surface writes to (the default branch is always added). */\n protectedBranches: string[];\n /** Prefix of branches Bridge creates for proposals made by agents (MCP, CLI). */\n branchPrefix: string;\n /** Labels added to pull requests Bridge opens from an agent. */\n labels: string[];\n /** Files whose change is Tier 3 on its own, repo-relative; a trailing \"/\" matches a directory. */\n guardrails: string[];\n /** People and teams that count as design and tech owners. Empty: two distinct approvers stand in. */\n owners: Owners;\n /** Owner override for missing approvals only (never CI, changes requested or drafts). Absent: no override. */\n override?: OverridePolicy | undefined;\n /**\n * Which owner group may approve design, approve tech and ship (see rights.ts). Absent: approvals follow `owners`\n * and anyone with write access may ship, as before the field existed.\n */\n rights?: Rights | undefined;\n}\n\n/** `bridge audit` settings: how product code that consumes the design system is measured. */\nexport interface AuditConfig {\n /** Packages the DS components are imported from. Default: the package that holds components.dir, plus @bridge-ds/react. */\n packages?: string[] | undefined;\n /** Extra import prefixes counted as foreign UI libraries (MUI, antd, Chakra, Radix... are built in). */\n foreignLibraries?: string[] | undefined;\n /** Native elements that should be DS components. Default: button, input, select, textarea, dialog, table, a (with href), img. */\n nativeElements?: string[] | undefined;\n /** Path globs (relative to the audited folder) to skip. */\n exclude?: string[] | undefined;\n}\n\nexport interface BridgeConfig {\n /** GitHub repository. Undefined only for a detected config of a repo with no known remote. */\n repo: RepoRef | undefined;\n tokens: TokenConfig;\n /** Named modes, in the order layers and contrast checks iterate them. */\n axes: Record<string, ModeAxis>;\n /** Brand, theme and density view of `axes`. */\n modes: ModeConfig;\n contrast: { path: string; modes?: string[] | undefined } | undefined;\n components?: ComponentsConfig | undefined;\n docs: { designLanguage?: string | undefined; guidelines?: string | undefined; governance?: string | undefined };\n /** Package a token changeset bumps and where changesets go; no changeset is written without it. */\n changesets: { dir: string; package: string } | undefined;\n /** Same package, under the older name. */\n changeset?: { package: string } | undefined;\n cssVar: { prefix: string; separator: string };\n governance: GovernanceConfig;\n audit?: AuditConfig | undefined;\n /** Branch previews: snapshot packages, per-branch deploy URL templates and production URLs (see previews.ts). */\n previews?: PreviewsConfig | undefined;\n /** Where component change requests go besides the GitHub issue (see requests.ts). */\n integrations?: IntegrationsConfig | undefined;\n /** Visual before and after on pull requests: automatic (default) or on demand (label `visual-check`). */\n visualImpact?: VisualImpactConfig | undefined;\n}\n\ntype Partialish<T> = { [K in keyof T]?: T[K] | undefined };\n\n/** What a config file may contain (canonical or flat form). Everything is optional. */\nexport interface BridgeConfigInput {\n $schema?: string;\n version?: number;\n repo?: (Partial<RepoRef> & { owner: string; name: string }) | string;\n /** Flat form: base branch. */\n branch?: string;\n tokens?: Partialish<TokenPaths> & {\n include?: string[];\n exclude?: string[];\n tiers?: Record<string, string | string[]>;\n layers?: (string | { files: string; optional?: boolean })[];\n };\n modes?:\n | (Partial<Omit<ModeConfig, 'defaults'>> & { defaults?: ModeConfig['defaults'] })\n | Record<string, { values: string[]; default?: string; parity?: boolean }>;\n contrast?: { path: string; modes?: string[] };\n components?: Partial<ComponentsConfig> & { dir: string };\n docs?: BridgeConfig['docs'];\n changesets?: { dir?: string; package: string };\n changeset?: { package: string };\n cssVar?: Partial<BridgeConfig['cssVar']>;\n governance?: Partial<Omit<GovernanceConfig, 'owners' | 'override' | 'rights'>> & { owners?: Partial<Owners>; override?: Partial<OverridePolicy>; rights?: Partial<Rights> };\n audit?: AuditConfig;\n previews?: { packages?: string[]; apps?: PreviewApps; production?: PreviewApps };\n integrations?: IntegrationsConfig;\n visualImpact?: Partial<VisualImpactConfig>;\n}\n\nexport const DEFAULT_TOKEN_PATHS: TokenPaths = {\n root: 'tokens',\n primitives: 'primitives',\n brands: 'brands',\n semantic: 'semantic',\n base: 'base',\n density: 'density',\n components: 'components',\n contrastChecks: 'contrast.checks.json',\n};\n\nexport const DEFAULT_GOVERNANCE: GovernanceConfig = {\n protectedBranches: ['main', 'master'],\n branchPrefix: 'bridge/',\n labels: ['source: mcp'],\n guardrails: ['AGENTS.md', 'CLAUDE.md', 'docs/GOVERNANCE.md', '.stylelintrc.json', '.github/', CONFIG_FILE],\n owners: { design: [], tech: [] },\n};\n\nconst FLAT_TOKEN_KEYS = ['primitives', 'brands', 'semantic', 'base', 'density', 'components', 'contrastChecks'] as const;\nconst CANONICAL_TOKEN_KEYS = ['root', 'include', 'exclude', 'tiers', 'layers'];\nconst FLAT_MODE_KEYS = ['brands', 'themes', 'densities', 'defaults'];\nconst AXIS_OF: Record<string, 'brand' | 'theme' | 'density'> = { brands: 'brand', themes: 'theme', densities: 'density' };\n\nexport class ConfigError extends Error {\n constructor(readonly problems: string[]) {\n super(`${CONFIG_FILE} is invalid: ${problems.join('; ')}`);\n this.name = 'ConfigError';\n }\n}\n\nconst trimSlashes = (p: string) => p.trim().replace(/^\\.?\\/+|\\/+$/g, '');\nconst list = (v: string | string[] | undefined) => (v === undefined ? [] : Array.isArray(v) ? v : [v]);\nconst isFlatModes = (m: NonNullable<BridgeConfigInput['modes']>): m is Partial<ModeConfig> =>\n Object.keys(m).some((k) => FLAT_MODE_KEYS.includes(k)) || Object.keys(m).length === 0;\n\nfunction parseRepoInput(repo: BridgeConfigInput['repo'], branch: string | undefined): RepoRef | undefined {\n if (!repo) return undefined;\n if (typeof repo === 'string') {\n const [owner, name] = repo.split('/');\n return { owner: owner!, name: name!, defaultBranch: branch ?? 'main' };\n }\n return { owner: repo.owner, name: repo.name, defaultBranch: repo.defaultBranch ?? branch ?? 'main' };\n}\n\n/** Layers of the conventional layout, for flat configs that do not list them. */\nfunction conventionalLayers(p: TokenPaths): TokenLayer[] {\n return [\n { files: `${p.primitives}/*.tokens.json`, optional: false },\n { files: `${p.semantic}/${p.base}.tokens.json`, optional: true },\n { files: `${p.brands}/{brand}.tokens.json`, optional: false },\n { files: `${p.semantic}/{theme}.tokens.json`, optional: false },\n { files: `${p.brands}/{brand}.{theme}.tokens.json`, optional: true },\n { files: `${p.density}/{density}.tokens.json`, optional: false },\n { files: `${p.components}/*.tokens.json`, optional: false },\n ];\n}\n\n/** Fill defaults and normalize either form. Typed helper for configs written in code. */\nexport function defineConfig(input: BridgeConfigInput): BridgeConfig {\n const t = input.tokens ?? {};\n const root = trimSlashes(t.root ?? DEFAULT_TOKEN_PATHS.root) || '.';\n const tiersIn = t.tiers ? Object.fromEntries(Object.entries(t.tiers).map(([k, v]) => [k, list(v).map(trimSlashes)])) : undefined;\n const firstDir = (tier: string) => tiersIn?.[tier]?.find((d) => !d.endsWith('.json'));\n const baseFile = tiersIn?.base?.find((d) => d.endsWith('.json'));\n const contrastPath = input.contrast?.path ? trimSlashes(input.contrast.path) : undefined;\n const underRoot = (p: string) => (root === '.' ? p : p.startsWith(`${root}/`) ? p.slice(root.length + 1) : undefined);\n const paths: TokenPaths = {\n root,\n primitives: trimSlashes(t.primitives ?? firstDir('primitive') ?? DEFAULT_TOKEN_PATHS.primitives),\n brands: trimSlashes(t.brands ?? firstDir('brand') ?? DEFAULT_TOKEN_PATHS.brands),\n semantic: trimSlashes(t.semantic ?? firstDir('semantic') ?? DEFAULT_TOKEN_PATHS.semantic),\n base: trimSlashes(t.base ?? (baseFile ? baseFile.split('/').pop()!.replace(/(\\.tokens)?\\.json$/, '') : DEFAULT_TOKEN_PATHS.base)),\n density: trimSlashes(t.density ?? firstDir('density') ?? DEFAULT_TOKEN_PATHS.density),\n components: trimSlashes(t.components ?? firstDir('component') ?? DEFAULT_TOKEN_PATHS.components),\n contrastChecks: trimSlashes(t.contrastChecks ?? (contrastPath ? (underRoot(contrastPath) ?? contrastPath) : DEFAULT_TOKEN_PATHS.contrastChecks)),\n };\n const tiers = tiersIn ?? {\n primitive: [paths.primitives],\n brand: [paths.brands],\n base: [`${paths.semantic}/${paths.base}.tokens.json`],\n semantic: [paths.semantic],\n density: [paths.density],\n component: [paths.components],\n };\n const layers = t.layers?.length\n ? t.layers.map((l) => (typeof l === 'string' ? { files: l, optional: false } : { files: l.files, optional: l.optional ?? false }))\n : conventionalLayers(paths);\n\n // Modes: named axes (canonical) or brand/theme/density lists (flat).\n const axes: Record<string, ModeAxis> = {};\n const m = input.modes ?? {};\n if (isFlatModes(m)) {\n for (const key of ['brands', 'themes', 'densities'] as const) {\n const values = m[key] ?? [];\n if (!values.length) continue;\n const axis = AXIS_OF[key]!;\n const def = m.defaults?.[axis] ?? values[0]!;\n axes[axis] = { values, default: def, parity: axis === 'theme' };\n }\n } else {\n for (const [name, a] of Object.entries(m)) axes[name] = { values: a.values, default: a.default ?? a.values[0]!, parity: a.parity ?? false };\n }\n const ordered = (axis: string) => {\n const a = axes[axis];\n return a ? [a.default, ...a.values.filter((v) => v !== a.default)] : [];\n };\n const modes: ModeConfig = {\n brands: ordered('brand'),\n themes: ordered('theme'),\n densities: ordered('density'),\n defaults: { brand: axes.brand?.default, theme: axes.theme?.default, density: axes.density?.default },\n };\n\n const pkg = input.changesets?.package ?? input.changeset?.package;\n const g = input.governance ?? {};\n const contrastFile = contrastPath ?? [root === '.' ? '' : root, paths.contrastChecks].filter(Boolean).join('/');\n return {\n repo: parseRepoInput(input.repo, input.branch),\n tokens: { ...paths, include: input.tokens?.include ?? ['**/*.tokens.json'], exclude: input.tokens?.exclude ?? [], tiers, layers },\n axes,\n modes,\n contrast: { path: contrastFile, modes: input.contrast?.modes },\n components: input.components\n ? {\n dir: trimSlashes(input.components.dir),\n docsSuffix: input.components.docsSuffix ?? '.docs.json',\n styleSuffix: input.components.styleSuffix ?? '.module.css',\n reference: input.components.reference,\n index: input.components.index,\n specs: input.components.specs,\n }\n : undefined,\n docs: { ...input.docs },\n changesets: pkg ? { dir: trimSlashes(input.changesets?.dir ?? '.changeset'), package: pkg } : undefined,\n changeset: pkg ? { package: pkg } : undefined,\n cssVar: { prefix: input.cssVar?.prefix ?? '--', separator: input.cssVar?.separator ?? '-' },\n governance: {\n protectedBranches: g.protectedBranches ?? DEFAULT_GOVERNANCE.protectedBranches,\n branchPrefix: g.branchPrefix ?? DEFAULT_GOVERNANCE.branchPrefix,\n labels: g.labels ?? DEFAULT_GOVERNANCE.labels,\n guardrails: g.guardrails ?? [...DEFAULT_GOVERNANCE.guardrails, contrastFile],\n owners: { design: g.owners?.design ?? [], tech: g.owners?.tech ?? [] },\n ...(g.override\n ? {\n override: {\n allowed: g.override.allowed ?? DEFAULT_OVERRIDE.allowed,\n requireReason: g.override.requireReason ?? DEFAULT_OVERRIDE.requireReason,\n minReasonLength: g.override.minReasonLength ?? DEFAULT_OVERRIDE.minReasonLength,\n },\n }\n : {}),\n ...(g.rights ? { rights: normalizeRights(g.rights) } : {}),\n },\n ...(input.audit ? { audit: { ...input.audit } } : {}),\n ...(input.visualImpact ? { visualImpact: { mode: input.visualImpact.mode === 'on-demand' ? 'on-demand' : 'auto' } } : {}),\n ...(input.integrations ? { integrations: { ...input.integrations } } : {}),\n ...(input.previews\n ? {\n previews: {\n packages: input.previews.packages ?? [],\n apps: { ...input.previews.apps },\n ...(input.previews.production ? { production: { ...input.previews.production } } : {}),\n },\n }\n : {}),\n };\n}\n\nconst isStr = (x: unknown): x is string => typeof x === 'string' && x.trim().length > 0;\nconst isStrList = (x: unknown): x is string[] => Array.isArray(x) && x.every(isStr);\nconst isObj = (x: unknown): x is Record<string, unknown> => !!x && typeof x === 'object' && !Array.isArray(x);\n\n/** Parse and validate bridge.config.json (text or parsed object). Throws ConfigError listing every problem. */\nexport function loadConfig(source: string | unknown): BridgeConfig {\n let data: unknown = source;\n if (typeof source === 'string') {\n try {\n data = JSON.parse(source);\n } catch (err) {\n throw new ConfigError([`not valid JSON (${(err as Error).message})`]);\n }\n }\n if (!isObj(data)) throw new ConfigError(['top level must be an object']);\n const problems: string[] = [];\n const d = data;\n\n const repo = d.repo;\n if (typeof repo === 'string') {\n if (!/^[\\w.-]+\\/[\\w.-]+$/.test(repo)) problems.push('\"repo\" must be \"owner/name\" or { \"owner\", \"name\" }');\n } else if (repo !== undefined) {\n if (!isObj(repo)) problems.push('\"repo\" must be \"owner/name\" or { \"owner\", \"name\" }');\n else {\n if (!isStr(repo.owner)) problems.push('\"repo.owner\" must be a non-empty string');\n if (!isStr(repo.name)) problems.push('\"repo.name\" must be a non-empty string');\n if (repo.defaultBranch !== undefined && !isStr(repo.defaultBranch)) problems.push('\"repo.defaultBranch\" must be a non-empty string');\n }\n }\n if (d.branch !== undefined && !isStr(d.branch)) problems.push('\"branch\" must be a non-empty string');\n\n const tokens = d.tokens;\n if (tokens !== undefined) {\n if (!isObj(tokens)) problems.push('\"tokens\" must be an object');\n else\n for (const [k, v] of Object.entries(tokens)) {\n if ((FLAT_TOKEN_KEYS as readonly string[]).includes(k) || k === 'root') {\n if (!isStr(v)) problems.push(`\"tokens.${k}\" must be a non-empty string`);\n } else if (k === 'include' || k === 'exclude') {\n if (!isStrList(v)) problems.push(`\"tokens.${k}\" must be a list of globs`);\n } else if (k === 'tiers') {\n if (!isObj(v) || !Object.values(v).every((x) => isStr(x) || isStrList(x))) problems.push('\"tokens.tiers\" must map tier names to directories');\n } else if (k === 'layers') {\n if (!Array.isArray(v) || !v.length || !v.every((l) => isStr(l) || (isObj(l) && isStr(l.files) && (l.optional === undefined || typeof l.optional === 'boolean'))))\n problems.push('\"tokens.layers\" must be a non-empty list of { \"files\", \"optional\"? }');\n } else if (!CANONICAL_TOKEN_KEYS.includes(k)) problems.push(`\"tokens.${k}\" is not a known key`);\n }\n }\n\n const modes = d.modes;\n let axisNames: string[] = [];\n if (modes !== undefined) {\n if (!isObj(modes)) problems.push('\"modes\" must be an object');\n else if (isFlatModes(modes as never)) {\n for (const k of ['brands', 'themes', 'densities']) {\n if (modes[k] !== undefined && !isStrList(modes[k])) problems.push(`\"modes.${k}\" must be a list of names`);\n }\n const defs = modes.defaults as Record<string, unknown> | undefined;\n const lists: Record<string, string> = { brand: 'brands', theme: 'themes', density: 'densities' };\n for (const [k, l] of Object.entries(lists)) {\n const v = defs?.[k];\n if (v === undefined) continue;\n if (!isStr(v)) problems.push(`\"modes.defaults.${k}\" must be a string`);\n else if (isStrList(modes[l]) && !(modes[l] as string[]).includes(v)) problems.push(`\"modes.defaults.${k}\" (\"${v}\") is not in \"modes.${l}\"`);\n }\n axisNames = Object.entries(lists).filter(([, l]) => isStrList(modes[l]) && (modes[l] as string[]).length).map(([k]) => k);\n } else {\n for (const [name, a] of Object.entries(modes)) {\n if (!isObj(a) || !isStrList(a.values) || !a.values.length) {\n problems.push(`\"modes.${name}.values\" must be a non-empty list of names`);\n continue;\n }\n if (a.default !== undefined && (!isStr(a.default) || !a.values.includes(a.default))) problems.push(`\"modes.${name}.default\" (\"${String(a.default)}\") is not in \"modes.${name}.values\"`);\n if (a.parity !== undefined && typeof a.parity !== 'boolean') problems.push(`\"modes.${name}.parity\" must be true or false`);\n axisNames.push(name);\n }\n }\n }\n if (isObj(tokens) && Array.isArray(tokens.layers)) {\n for (const l of tokens.layers) {\n const files = typeof l === 'string' ? l : isObj(l) ? String(l.files) : '';\n for (const ph of files.match(/\\{([^}]+)\\}/g) ?? []) {\n if (!axisNames.includes(ph.slice(1, -1))) problems.push(`layer \"${files}\" uses ${ph} but \"modes.${ph.slice(1, -1)}\" is not defined`);\n }\n }\n }\n\n const contrast = d.contrast;\n if (contrast !== undefined && (!isObj(contrast) || !isStr(contrast.path) || (contrast.modes !== undefined && !isStrList(contrast.modes))))\n problems.push('\"contrast\" must be { \"path\", \"modes\"? }');\n const comps = d.components;\n if (comps !== undefined && (!isObj(comps) || !isStr(comps.dir))) problems.push('\"components.dir\" must be a non-empty string');\n const cs = d.changeset;\n if (cs !== undefined && (!isObj(cs) || !isStr(cs.package))) problems.push('\"changeset.package\" must be a non-empty string');\n const css = d.changesets;\n if (css !== undefined && (!isObj(css) || !isStr(css.package))) problems.push('\"changesets.package\" must be a non-empty string');\n const gov = d.governance;\n if (gov !== undefined) {\n if (!isObj(gov)) problems.push('\"governance\" must be an object');\n else {\n for (const k of ['protectedBranches', 'labels', 'guardrails']) if (gov[k] !== undefined && !(Array.isArray(gov[k]) && (gov[k] as unknown[]).every((x) => typeof x === 'string'))) problems.push(`\"governance.${k}\" must be a list of strings`);\n if (gov.branchPrefix !== undefined && !isStr(gov.branchPrefix)) problems.push('\"governance.branchPrefix\" must be a non-empty string');\n problems.push(...ownerEntryProblems(gov.owners));\n const ov = gov.override;\n if (ov !== undefined) {\n if (!isObj(ov)) problems.push('\"governance.override\" must be an object');\n else {\n if (ov.allowed !== undefined && !isStrList(ov.allowed)) problems.push('\"governance.override.allowed\" must be a list of GitHub logins');\n if (ov.requireReason !== undefined && typeof ov.requireReason !== 'boolean') problems.push('\"governance.override.requireReason\" must be true or false');\n if (ov.minReasonLength !== undefined && !(Number.isInteger(ov.minReasonLength) && (ov.minReasonLength as number) >= 0)) problems.push('\"governance.override.minReasonLength\" must be a whole number, 0 or more');\n }\n }\n problems.push(...rightsProblems(gov.rights));\n }\n }\n problems.push(...visualImpactProblems(d.visualImpact));\n const audit = d.audit;\n if (audit !== undefined) {\n if (!isObj(audit)) problems.push('\"audit\" must be an object');\n else for (const k of ['packages', 'foreignLibraries', 'nativeElements', 'exclude']) if (audit[k] !== undefined && !isStrList(audit[k])) problems.push(`\"audit.${k}\" must be a list of strings`);\n }\n const pv = d.previews;\n if (pv !== undefined) {\n if (!isObj(pv)) problems.push('\"previews\" must be an object');\n else {\n if (pv.packages !== undefined && !isStrList(pv.packages)) problems.push('\"previews.packages\" must be a list of package names');\n for (const field of ['apps', 'production'] as const) {\n const apps = pv[field];\n if (apps === undefined) continue;\n if (!isObj(apps)) {\n problems.push(`\"previews.${field}\" must be an object`);\n continue;\n }\n for (const [k, v] of Object.entries(apps)) {\n if (!(k in PREVIEW_APP_LABELS)) problems.push(`\"previews.${field}.${k}\" is not a known app (${Object.keys(PREVIEW_APP_LABELS).join(', ')})`);\n else if (!isStr(v) || !/^https?:\\/\\//.test(v)) problems.push(`\"previews.${field}.${k}\" must be an http(s) URL${field === 'apps' ? ' template' : ''}`);\n else if (field === 'production' && /\\{\\w+\\}/.test(v)) problems.push(`\"previews.production.${k}\" is a fixed URL: placeholders such as {branch} belong in \"previews.apps\"`);\n }\n }\n }\n }\n if (problems.length) throw new ConfigError(problems);\n return defineConfig(d as unknown as BridgeConfigInput);\n}\n\n/** Path of a file under the tokens root, relative to the repository root. */\nexport const tokensPath = (config: BridgeConfig, rel = '') => [config.tokens.root === '.' ? '' : config.tokens.root, rel].filter(Boolean).join('/');\n\n/** Branches no write may target: the configured protected list plus the default branch. */\nexport const protectedBranchesOf = (config: BridgeConfig): string[] => [...new Set([...config.governance.protectedBranches, ...(config.repo ? [config.repo.defaultBranch] : [])])];\n\n/** The base branch proposals target. */\nexport const baseBranchOf = (config: BridgeConfig): string => config.repo?.defaultBranch ?? 'main';\n\n/** Plain-JSON form of a config, in the canonical shape (what `bridge init` writes). */\nexport function toConfigJson(config: BridgeConfig, schema = './packages/core/bridge.config.schema.json'): Record<string, unknown> {\n return {\n $schema: schema,\n version: 1,\n ...(config.repo ? { repo: config.repo } : {}),\n tokens: { root: config.tokens.root, include: config.tokens.include, ...(config.tokens.exclude.length ? { exclude: config.tokens.exclude } : {}), tiers: config.tokens.tiers, layers: config.tokens.layers.map((l) => (l.optional ? l : { files: l.files })) },\n modes: Object.fromEntries(Object.entries(config.axes).map(([k, a]) => [k, a.parity ? a : { values: a.values, default: a.default }])),\n ...(config.contrast ? { contrast: config.contrast.modes ? config.contrast : { path: config.contrast.path } } : {}),\n ...(config.components ? { components: Object.fromEntries(Object.entries(config.components).filter(([, v]) => v !== undefined)) } : {}),\n docs: Object.fromEntries(Object.entries(config.docs).filter(([, v]) => v !== undefined)),\n ...(config.changesets ? { changesets: config.changesets } : {}),\n cssVar: config.cssVar,\n governance: config.governance,\n ...(config.audit ? { audit: config.audit } : {}),\n ...(config.previews ? { previews: config.previews } : {}),\n ...(config.visualImpact ? { visualImpact: config.visualImpact } : {}),\n };\n}\n","// Format-preserving JSON AST.\n//\n// Every parsed node keeps the exact source slice it came from (`raw`). Serializing an untouched\n// document therefore reproduces the input byte for byte. Edits clear `raw` on the edited node and\n// its ancestors only, so a one-token change produces a one-token diff, in the file's own style\n// (inline vs multi-line objects and arrays, indent width, padding inside inline braces).\n\nexport type JsonNode = JsonObject | JsonArray | JsonScalar;\n\ninterface NodeBase {\n /** Exact source text of this node. Present only while the node is untouched. */\n raw?: string | undefined;\n}\n\nexport interface JsonEntry {\n key: string;\n value: JsonNode;\n}\n\nexport interface JsonObject extends NodeBase {\n kind: 'object';\n entries: JsonEntry[];\n /** Written on a single line in the source (or should be, for new nodes). */\n inline: boolean;\n}\n\nexport interface JsonArray extends NodeBase {\n kind: 'array';\n items: JsonNode[];\n inline: boolean;\n}\n\nexport interface JsonScalar extends NodeBase {\n kind: 'string' | 'number' | 'boolean' | 'null';\n value: string | number | boolean | null;\n}\n\nexport interface JsonStyle {\n indent: string;\n newline: '\\n' | '\\r\\n';\n /** `{ \"a\": 1 }` (true) vs `{\"a\": 1}` (false) for inline objects. */\n objectPadding: boolean;\n /** `[ 1, 2 ]` (true) vs `[1, 2]` (false) for inline arrays. */\n arrayPadding: boolean;\n}\n\nexport interface JsonDocument {\n root: JsonNode;\n leading: string;\n trailing: string;\n style: JsonStyle;\n}\n\nexport class JsonParseError extends Error {\n constructor(\n message: string,\n readonly offset: number,\n ) {\n super(message);\n this.name = 'JsonParseError';\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Parsing\n\nexport function parseJson(text: string): JsonDocument {\n let i = 0;\n const n = text.length;\n\n const isWs = (c: string | undefined) => c === ' ' || c === '\\t' || c === '\\n' || c === '\\r';\n const skipWs = () => {\n while (i < n && isWs(text[i])) i++;\n };\n const fail = (msg: string): never => {\n throw new JsonParseError(`${msg} at offset ${i}`, i);\n };\n\n const parseString = (): string => {\n if (text[i] !== '\"') fail('Expected string');\n const start = i;\n i++;\n while (i < n) {\n const c = text[i];\n if (c === '\\\\') {\n i += 2;\n continue;\n }\n if (c === '\"') {\n i++;\n return JSON.parse(text.slice(start, i)) as string;\n }\n i++;\n }\n return fail('Unterminated string');\n };\n\n const parseValue = (): JsonNode => {\n skipWs();\n const start = i;\n const c = text[i];\n let node: JsonNode;\n if (c === '{') {\n i++;\n const entries: JsonEntry[] = [];\n skipWs();\n if (text[i] === '}') {\n i++;\n } else {\n for (;;) {\n skipWs();\n const key = parseString();\n skipWs();\n if (text[i] !== ':') fail('Expected \":\"');\n i++;\n const value = parseValue();\n entries.push({ key, value });\n skipWs();\n if (text[i] === ',') {\n i++;\n continue;\n }\n if (text[i] === '}') {\n i++;\n break;\n }\n fail('Expected \",\" or \"}\"');\n }\n }\n const raw = text.slice(start, i);\n node = { kind: 'object', entries, inline: !raw.includes('\\n'), raw };\n } else if (c === '[') {\n i++;\n const items: JsonNode[] = [];\n skipWs();\n if (text[i] === ']') {\n i++;\n } else {\n for (;;) {\n items.push(parseValue());\n skipWs();\n if (text[i] === ',') {\n i++;\n continue;\n }\n if (text[i] === ']') {\n i++;\n break;\n }\n fail('Expected \",\" or \"]\"');\n }\n }\n const raw = text.slice(start, i);\n node = { kind: 'array', items, inline: !raw.includes('\\n'), raw };\n } else if (c === '\"') {\n const value = parseString();\n node = { kind: 'string', value, raw: text.slice(start, i) };\n } else if (c === 't' && text.startsWith('true', i)) {\n i += 4;\n node = { kind: 'boolean', value: true, raw: 'true' };\n } else if (c === 'f' && text.startsWith('false', i)) {\n i += 5;\n node = { kind: 'boolean', value: false, raw: 'false' };\n } else if (c === 'n' && text.startsWith('null', i)) {\n i += 4;\n node = { kind: 'null', value: null, raw: 'null' };\n } else {\n const m = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/.exec(text.slice(i, i + 64));\n if (!m) return fail('Unexpected token');\n i += m[0].length;\n node = { kind: 'number', value: Number(m[0]), raw: m[0] };\n }\n return node;\n };\n\n const leadingEnd = (() => {\n let j = 0;\n while (j < n && isWs(text[j])) j++;\n return j;\n })();\n const leading = text.slice(0, leadingEnd);\n i = leadingEnd;\n const root = parseValue();\n const trailingStart = i;\n skipWs();\n if (i < n) fail('Unexpected content after JSON value');\n const trailing = text.slice(trailingStart);\n\n return { root, leading, trailing, style: detectStyle(text, root) };\n}\n\nfunction detectStyle(text: string, root: JsonNode): JsonStyle {\n const newline: '\\n' | '\\r\\n' = text.includes('\\r\\n') ? '\\r\\n' : '\\n';\n const indentMatch = /\\n([ \\t]+)\\S/.exec(text);\n const indent = indentMatch?.[1] ?? ' ';\n let objectPadding: boolean | undefined;\n let arrayPadding: boolean | undefined;\n const visit = (node: JsonNode) => {\n if (node.kind === 'object') {\n if (node.inline && node.entries.length > 0 && objectPadding === undefined && node.raw) {\n objectPadding = node.raw.startsWith('{ ');\n }\n node.entries.forEach((e) => visit(e.value));\n } else if (node.kind === 'array') {\n if (node.inline && node.items.length > 0 && arrayPadding === undefined && node.raw) {\n arrayPadding = node.raw.startsWith('[ ');\n }\n node.items.forEach(visit);\n }\n };\n visit(root);\n return { indent, newline, objectPadding: objectPadding ?? true, arrayPadding: arrayPadding ?? false };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Serializing\n\nexport function serializeJson(doc: JsonDocument): string {\n return doc.leading + serializeNode(doc.root, 0, doc.style, false) + doc.trailing;\n}\n\nexport function formatNumber(value: number): string {\n if (!Number.isFinite(value)) throw new Error(`Cannot serialize non-finite number ${value}`);\n return JSON.stringify(value);\n}\n\nfunction serializeNode(node: JsonNode, depth: number, style: JsonStyle, forceInline: boolean): string {\n if (node.raw !== undefined && (!forceInline || !node.raw.includes('\\n'))) return node.raw;\n switch (node.kind) {\n case 'string':\n return JSON.stringify(node.value);\n case 'number':\n return formatNumber(node.value as number);\n case 'boolean':\n return node.value ? 'true' : 'false';\n case 'null':\n return 'null';\n case 'object': {\n if (node.entries.length === 0) return '{}';\n const inline = forceInline || node.inline;\n if (inline) {\n const body = node.entries\n .map((e) => `${JSON.stringify(e.key)}: ${serializeNode(e.value, depth + 1, style, true)}`)\n .join(', ');\n return style.objectPadding ? `{ ${body} }` : `{${body}}`;\n }\n const pad = style.indent.repeat(depth + 1);\n const body = node.entries\n .map((e) => `${pad}${JSON.stringify(e.key)}: ${serializeNode(e.value, depth + 1, style, false)}`)\n .join(`,${style.newline}`);\n return `{${style.newline}${body}${style.newline}${style.indent.repeat(depth)}}`;\n }\n case 'array': {\n if (node.items.length === 0) return '[]';\n const inline = forceInline || node.inline;\n if (inline) {\n const body = node.items.map((v) => serializeNode(v, depth + 1, style, true)).join(', ');\n return style.arrayPadding ? `[ ${body} ]` : `[${body}]`;\n }\n const pad = style.indent.repeat(depth + 1);\n const body = node.items.map((v) => `${pad}${serializeNode(v, depth + 1, style, false)}`).join(`,${style.newline}`);\n return `[${style.newline}${body}${style.newline}${style.indent.repeat(depth)}]`;\n }\n }\n}\n\n// ---------------------------------------------------------------------------------------------\n// Conversions and helpers\n\nexport type Plain = string | number | boolean | null | Plain[] | { [key: string]: Plain };\n\n/** Plain JS value of a node. Object key order follows the source (except integer-like keys, see JS rules). */\nexport function toPlain(node: JsonNode): Plain {\n switch (node.kind) {\n case 'object': {\n const out: { [key: string]: Plain } = {};\n for (const e of node.entries) out[e.key] = toPlain(e.value);\n return out;\n }\n case 'array':\n return node.items.map(toPlain);\n default:\n return node.value as Plain;\n }\n}\n\n/**\n * Build a node from a plain value. When `template` is given (for example the node being replaced\n * or a sibling token), inline/multi-line layout is copied from it key by key so new content looks\n * like its neighbours.\n */\nexport function fromPlain(value: unknown, template?: JsonNode, inlineDefault = false): JsonNode {\n if (value === null || value === undefined) return { kind: 'null', value: null };\n if (typeof value === 'string') return { kind: 'string', value };\n if (typeof value === 'number') return { kind: 'number', value };\n if (typeof value === 'boolean') return { kind: 'boolean', value };\n if (Array.isArray(value)) {\n const inline = template?.kind === 'array' ? template.inline : inlineDefault || value.every((v) => typeof v !== 'object' || v === null);\n const tItem = template?.kind === 'array' ? template.items[0] : undefined;\n return { kind: 'array', inline, items: value.map((v) => fromPlain(v, tItem, inline)) };\n }\n if (typeof value === 'object') {\n const inline = template?.kind === 'object' ? template.inline : inlineDefault;\n const entries: JsonEntry[] = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .map(([key, v]) => {\n const t = template?.kind === 'object' ? getEntry(template, key)?.value : undefined;\n return { key, value: fromPlain(v, t, inline) };\n });\n return { kind: 'object', inline, entries };\n }\n throw new Error(`Unsupported value type ${typeof value}`);\n}\n\nexport function getEntry(obj: JsonObject, key: string): JsonEntry | undefined {\n return obj.entries.find((e) => e.key === key);\n}\n\nexport function getChild(node: JsonNode | undefined, key: string): JsonNode | undefined {\n if (!node || node.kind !== 'object') return undefined;\n return getEntry(node, key)?.value;\n}\n\n/** Remove cached source text from a node and all its descendants (after moving it to another depth). */\nexport function clearRawDeep(node: JsonNode): void {\n node.raw = undefined;\n if (node.kind === 'object') node.entries.forEach((e) => clearRawDeep(e.value));\n if (node.kind === 'array') node.items.forEach(clearRawDeep);\n}\n\n/** Deep structural equality of two nodes, ignoring layout. */\nexport function nodesEqual(a: JsonNode, b: JsonNode): boolean {\n return plainEqual(toPlain(a), toPlain(b));\n}\n\nexport function plainEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b || a === null || b === null || typeof a !== 'object') return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((v, idx) => plainEqual(v, b[idx]));\n }\n const ka = Object.keys(a as object);\n const kb = Object.keys(b as object);\n if (ka.length !== kb.length) return false;\n return ka.every((k) => plainEqual((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k]));\n}\n","// DTCG 2025.10 codec: read token files into flat tokens, and edit them in place without\n// disturbing anything that did not change (key order, layout, number spelling, descriptions,\n// $extensions). Built on the format-preserving JSON AST.\n\nimport {\n type JsonDocument,\n type JsonEntry,\n type JsonNode,\n type JsonObject,\n clearRawDeep,\n fromPlain,\n getEntry,\n parseJson,\n plainEqual,\n serializeJson,\n toPlain,\n} from './json-ast';\nimport type { FlatToken } from './types';\n\nexport interface TokenDocument {\n file: string;\n json: JsonDocument;\n}\n\nexport function parseTokenFile(file: string, text: string): TokenDocument {\n const json = parseJson(text);\n if (json.root.kind !== 'object') throw new Error(`${file}: top level must be a JSON object`);\n return { file, json };\n}\n\nexport function serializeTokenFile(doc: TokenDocument): string {\n return serializeJson(doc.json);\n}\n\nconst isTokenNode = (node: JsonNode): node is JsonObject => node.kind === 'object' && getEntry(node, '$value') !== undefined;\nconst isGroupKey = (key: string) => !key.startsWith('$');\n\n/** All tokens in a document, in source order, with `$type` inherited from groups. */\nexport function flattenTokens(doc: TokenDocument): FlatToken[] {\n const out: FlatToken[] = [];\n const walk = (node: JsonObject, path: string[], inheritedType: string | undefined) => {\n const ownGroupType = stringEntry(node, '$type');\n const groupType = ownGroupType ?? inheritedType;\n for (const entry of node.entries) {\n if (!isGroupKey(entry.key) || entry.value.kind !== 'object') continue;\n const childPath = [...path, entry.key];\n if (isTokenNode(entry.value)) {\n out.push(readToken(entry.value, childPath.join('.'), groupType, doc.file));\n } else {\n walk(entry.value, childPath, groupType);\n }\n }\n };\n walk(doc.json.root as JsonObject, [], undefined);\n return out;\n}\n\nfunction readToken(node: JsonObject, path: string, inheritedType: string | undefined, file: string): FlatToken {\n const ownType = stringEntry(node, '$type');\n const ext = getEntry(node, '$extensions')?.value;\n return {\n path,\n type: ownType ?? inheritedType,\n ownType,\n value: toPlain(getEntry(node, '$value')!.value),\n description: stringEntry(node, '$description'),\n extensions: ext && ext.kind === 'object' ? (toPlain(ext) as Record<string, unknown>) : undefined,\n file,\n };\n}\n\nfunction stringEntry(node: JsonObject, key: string): string | undefined {\n const v = getEntry(node, key)?.value;\n return v && v.kind === 'string' ? (v.value as string) : undefined;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Navigation\n\ninterface Located {\n node: JsonObject;\n /** Root first, parent group last. */\n ancestors: JsonObject[];\n}\n\nexport function findToken(doc: TokenDocument, path: string): Located | undefined {\n const segments = path.split('.');\n const ancestors: JsonObject[] = [];\n let current = doc.json.root as JsonObject;\n for (const seg of segments) {\n ancestors.push(current);\n const next = getEntry(current, seg)?.value;\n if (!next || next.kind !== 'object') return undefined;\n current = next;\n }\n return isTokenNode(current) ? { node: current, ancestors } : undefined;\n}\n\n/** `$type` that a token at `path` would inherit from its groups (ignoring its own `$type`). */\nexport function inheritedTypeAt(doc: TokenDocument, path: string): string | undefined {\n const segments = path.split('.').slice(0, -1);\n let current: JsonNode | undefined = doc.json.root;\n let type: string | undefined;\n for (let idx = 0; idx <= segments.length; idx++) {\n if (!current || current.kind !== 'object') break;\n type = stringEntry(current, '$type') ?? type;\n const seg = segments[idx];\n if (seg === undefined) break;\n current = getEntry(current, seg)?.value;\n }\n return type;\n}\n\nconst touch = (nodes: JsonNode[]) => nodes.forEach((n) => (n.raw = undefined));\n\n// Canonical position for keys we insert into a token object.\nconst KEY_RANK: Record<string, number> = { $type: 0, $description: 1, $value: 2, $deprecated: 3, $extensions: 4 };\nconst rank = (key: string) => KEY_RANK[key] ?? 5;\n\nfunction insertEntry(obj: JsonObject, entry: JsonEntry): void {\n // `$` keys go before the first `$` key that ranks higher, and before any child group.\n const r = rank(entry.key);\n const at = obj.entries.findIndex((e) => !e.key.startsWith('$') || rank(e.key) > r);\n if (at === -1) obj.entries.push(entry);\n else obj.entries.splice(at, 0, entry);\n}\n\nfunction findTemplateToken(group: JsonObject, doc: TokenDocument): JsonObject | undefined {\n const sibling = group.entries.find((e) => isGroupKey(e.key) && isTokenNode(e.value))?.value;\n if (sibling && sibling.kind === 'object') return sibling;\n let found: JsonObject | undefined;\n const walk = (node: JsonNode) => {\n if (found || node.kind !== 'object') return;\n if (getEntry(node, '$value')) {\n found = node;\n return;\n }\n node.entries.forEach((e) => isGroupKey(e.key) && walk(e.value));\n };\n walk(doc.json.root);\n return found;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Edits\n\nexport interface TokenFields {\n /** Effective $type; undefined leaves the type to the groups (or, for an alias, to its target). */\n type: string | undefined;\n value: unknown;\n description: string | undefined;\n /** Extension keys to set (value) or delete (undefined). Other keys are preserved. */\n extensions?: Record<string, unknown | undefined>;\n}\n\n/**\n * Create or update the token at `path`. Returns true when the document changed.\n * Values equal to the current ones are left untouched, so the file text stays identical.\n * `template` (for example the node of a renamed token) controls the layout of new nodes.\n */\nexport function upsertToken(doc: TokenDocument, path: string, fields: TokenFields, template?: JsonObject): boolean {\n const existing = findToken(doc, path);\n if (existing) return updateTokenNode(doc, existing, path, fields);\n\n const segments = path.split('.');\n const name = segments.pop()!;\n const ancestors: JsonObject[] = [];\n let group = doc.json.root as JsonObject;\n for (const seg of segments) {\n ancestors.push(group);\n let next = getEntry(group, seg)?.value;\n if (!next) {\n next = { kind: 'object', inline: false, entries: [] };\n group.entries.push({ key: seg, value: next });\n } else if (next.kind !== 'object' || isTokenNode(next)) {\n throw new Error(`${doc.file}: cannot create \"${path}\" because \"${seg}\" is a token, not a group`);\n }\n group = next;\n }\n ancestors.push(group);\n const layout = template ?? findTemplateToken(group, doc);\n const node: JsonObject = { kind: 'object', inline: layout?.inline ?? false, entries: [] };\n const inherited = inheritedTypeAt(doc, path);\n if (fields.type !== undefined && fields.type !== inherited) node.entries.push({ key: '$type', value: { kind: 'string', value: fields.type } });\n if (fields.description) node.entries.push({ key: '$description', value: { kind: 'string', value: fields.description } });\n const valueTemplate = layout ? getEntry(layout, '$value')?.value : undefined;\n node.entries.push({ key: '$value', value: fromPlain(fields.value, valueTemplate, node.inline) });\n const ext = cleanExtensions(fields.extensions);\n if (ext) {\n const extTemplate = layout ? getEntry(layout, '$extensions')?.value : undefined;\n node.entries.push({ key: '$extensions', value: fromPlain(ext, extTemplate, node.inline) });\n }\n group.entries.push({ key: name, value: node });\n touch(ancestors);\n return true;\n}\n\nfunction cleanExtensions(ext: Record<string, unknown | undefined> | undefined): Record<string, unknown> | undefined {\n if (!ext) return undefined;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(ext)) if (v !== undefined) out[k] = v;\n return Object.keys(out).length ? out : undefined;\n}\n\nfunction updateTokenNode(doc: TokenDocument, loc: Located, path: string, fields: TokenFields): boolean {\n const { node } = loc;\n let changed = false;\n\n // $type: only written when it differs from what the groups already say.\n const ownType = stringEntry(node, '$type');\n const inherited = inheritedTypeAt(doc, path);\n if (fields.type !== undefined && (ownType ?? inherited) !== fields.type) {\n const entry = getEntry(node, '$type');\n if (fields.type === inherited && entry) node.entries.splice(node.entries.indexOf(entry), 1);\n else if (entry) entry.value = { kind: 'string', value: fields.type };\n else insertEntry(node, { key: '$type', value: { kind: 'string', value: fields.type } });\n changed = true;\n }\n\n const valueEntry = getEntry(node, '$value')!;\n if (!plainEqual(toPlain(valueEntry.value), fields.value)) {\n valueEntry.value = fromPlain(fields.value, valueEntry.value, node.inline);\n changed = true;\n }\n\n const desc = stringEntry(node, '$description');\n if ((desc ?? '') !== (fields.description ?? '')) {\n const entry = getEntry(node, '$description');\n if (!fields.description) node.entries.splice(node.entries.indexOf(entry!), 1);\n else if (entry) entry.value = { kind: 'string', value: fields.description };\n else insertEntry(node, { key: '$description', value: { kind: 'string', value: fields.description } });\n changed = true;\n }\n\n if (fields.extensions) {\n let extEntry = getEntry(node, '$extensions');\n for (const [key, value] of Object.entries(fields.extensions)) {\n const ext = extEntry?.value.kind === 'object' ? extEntry.value : undefined;\n const current = ext ? getEntry(ext, key) : undefined;\n if (value === undefined) {\n if (ext && current) {\n ext.entries.splice(ext.entries.indexOf(current), 1);\n ext.raw = undefined;\n changed = true;\n }\n continue;\n }\n if (current && plainEqual(toPlain(current.value), value)) continue;\n if (!extEntry || !ext) {\n extEntry = { key: '$extensions', value: { kind: 'object', inline: node.inline, entries: [] } };\n insertEntry(node, extEntry);\n }\n const target = extEntry.value as JsonObject;\n if (current) current.value = fromPlain(value, current.value, target.inline);\n else target.entries.push({ key, value: fromPlain(value, undefined, target.inline) });\n target.raw = undefined;\n changed = true;\n }\n if (extEntry && extEntry.value.kind === 'object' && extEntry.value.entries.length === 0) {\n node.entries.splice(node.entries.indexOf(extEntry), 1);\n changed = true;\n }\n }\n\n if (changed) touch([...loc.ancestors, node]);\n return changed;\n}\n\n/** Remove a token and any group left empty by its removal. Returns true when something was removed. */\nexport function removeToken(doc: TokenDocument, path: string): boolean {\n const loc = findToken(doc, path);\n if (!loc) return false;\n const segments = path.split('.');\n let child: JsonNode = loc.node;\n for (let idx = loc.ancestors.length - 1; idx >= 0; idx--) {\n const parent = loc.ancestors[idx]!;\n const key = segments[idx]!;\n const entry = getEntry(parent, key);\n if (!entry || entry.value !== child) break;\n parent.entries.splice(parent.entries.indexOf(entry), 1);\n const hasChildren = parent.entries.some((e) => isGroupKey(e.key));\n if (hasChildren || idx === 0) break;\n child = parent;\n }\n touch(loc.ancestors);\n return true;\n}\n\n/** Raw token node at `path` (for use as a layout template when moving a token). */\nexport function tokenNode(doc: TokenDocument, path: string): JsonObject | undefined {\n return findToken(doc, path)?.node;\n}\n\n/** The token at `path` as written in this file (with inherited type), if any. */\nexport function readTokenAt(doc: TokenDocument, path: string): FlatToken | undefined {\n const loc = findToken(doc, path);\n return loc ? readToken(loc.node, path, inheritedTypeAt(doc, path), doc.file) : undefined;\n}\n\n/** A new, empty token file. */\nexport function emptyTokenFile(file: string): TokenDocument {\n return {\n file,\n json: {\n root: { kind: 'object', inline: false, entries: [] },\n leading: '',\n trailing: '\\n',\n style: { indent: ' ', newline: '\\n', objectPadding: true, arrayPadding: false },\n },\n };\n}\n\n/**\n * Move the token node at `from` to `to` inside the same file, keeping every field it has\n * ($description, $extensions from other tools, $deprecated...). Returns false when `from` is missing.\n */\nexport function moveToken(doc: TokenDocument, from: string, to: string): boolean {\n const loc = findToken(doc, from);\n if (!loc || findToken(doc, to)) return false;\n const node = loc.node;\n const fromType = stringEntry(node, '$type') ?? inheritedTypeAt(doc, from);\n removeToken(doc, from);\n const segments = to.split('.');\n const name = segments.pop()!;\n const ancestors: JsonObject[] = [];\n let group = doc.json.root as JsonObject;\n for (const seg of segments) {\n ancestors.push(group);\n let next = getEntry(group, seg)?.value;\n if (!next) {\n next = { kind: 'object', inline: false, entries: [] };\n group.entries.push({ key: seg, value: next });\n } else if (next.kind !== 'object' || isTokenNode(next)) {\n throw new Error(`${doc.file}: cannot move to \"${to}\" because \"${seg}\" is a token, not a group`);\n }\n group = next;\n }\n ancestors.push(group);\n clearRawDeep(node);\n group.entries.push({ key: name, value: node });\n touch(ancestors);\n // Keep the effective type: write $type when the new groups would infer something else.\n const inherited = inheritedTypeAt(doc, to);\n const typeEntry = getEntry(node, '$type');\n if (fromType && fromType !== inherited && !typeEntry) insertEntry(node, { key: '$type', value: { kind: 'string', value: fromType } });\n if (typeEntry && typeEntry.value.kind === 'string' && typeEntry.value.value === inherited) node.entries.splice(node.entries.indexOf(typeEntry), 1);\n return true;\n}\n","// Build the logical token set (one entry per token, values per mode of its tier) from the repo's\n// DTCG files. The tier of a file comes from where it lives (see RepoLayout in types.ts).\n\nimport { type BridgeConfig, DEFAULT_TOKEN_PATHS, type TokenPaths } from './config';\nimport { type TokenDocument, flattenTokens, parseTokenFile } from './dtcg-codec';\nimport type { ResolveContext } from './resolver';\nimport {\n EXT_ID,\n EXT_SCOPES,\n type LogicalToken,\n type ModeFile,\n type RepoLayout,\n SINGLE_MODE,\n TIER_AXIS,\n type ThemeOverride,\n type Tier,\n type TokenMap,\n} from './types';\n\nexport interface TokenSet {\n tokens: TokenMap;\n byPath: Map<string, LogicalToken>;\n docs: Map<string, TokenDocument>;\n layout: RepoLayout;\n /** Tier directories and mode order the set was read with. */\n options: LayoutOptions;\n /** Brand x theme overrides of semantic tokens (brands/<brand>.<theme>.tokens.json). */\n overrides: ThemeOverride[];\n /** overrideKey(brand, theme, path) -> value. */\n overrideIndex: Map<string, unknown>;\n /** Problems found while reading (duplicate paths, missing types, parse errors). */\n problems: string[];\n}\n\nexport const isTokenFile = (file: string) => file.endsWith('.tokens.json');\n\n/** Default id of a token that does not declare `com.dsbridge.id`. */\nexport const pathId = (path: string) => `path:${path}`;\n\nexport const overrideKey = (brand: string, theme: string, path: string) => `${brand}|${theme}|${path}`;\n\n/** Where each tier lives (relative to the tokens root) and the preferred mode order (default first). */\nexport interface LayoutOptions {\n dirs?: Partial<Pick<TokenPaths, 'primitives' | 'brands' | 'semantic' | 'base' | 'density' | 'components'>> | undefined;\n order?: { brand?: string[] | undefined; theme?: string[] | undefined; density?: string[] | undefined } | undefined;\n}\n\n/** Layout options from a bridge.config.json: tier directories and mode order (defaults first). */\nexport function layoutOptions(config: BridgeConfig): LayoutOptions {\n const first = (list: string[], def: string | undefined) => (def ? [def, ...list.filter((m) => m !== def)] : list);\n return {\n dirs: config.tokens,\n order: {\n brand: first(config.modes.brands, config.modes.defaults.brand),\n theme: first(config.modes.themes, config.modes.defaults.theme),\n density: first(config.modes.densities, config.modes.defaults.density),\n },\n };\n}\n\nconst FALLBACK_ORDER = { theme: ['light', 'dark'], brand: [] as string[], density: [] as string[] };\nconst stem = (file: string) => file.slice(file.lastIndexOf('/') + 1).replace(/\\.tokens\\.json$/, '');\n\nfunction ordered(list: ModeFile[], pref: string[]): ModeFile[] {\n const rank = (m: string) => (pref.indexOf(m) === -1 ? 99 : pref.indexOf(m));\n return list.sort((a, b) => rank(a.mode) - rank(b.mode) || a.mode.localeCompare(b.mode));\n}\n\n/**\n * Sort token files (paths relative to the tokens root) into tiers. Files outside every tier\n * directory are treated as primitives, so a flat legacy layout still loads.\n */\nexport function detectLayout(files: string[], options: LayoutOptions = {}): RepoLayout {\n const d = { ...DEFAULT_TOKEN_PATHS, ...options.dirs };\n const inDir = (file: string, dir: string) => file.startsWith(`${dir}/`) && !file.slice(dir.length + 1).includes('/');\n const layout: RepoLayout = { primitiveFiles: [], brands: [], baseFiles: [], themes: [], overrides: [], densities: [], componentFiles: [] };\n for (const file of files.filter(isTokenFile).sort()) {\n const name = stem(file);\n if (inDir(file, d.brands)) {\n const parts = name.split('.');\n if (parts.length === 2) layout.overrides.push({ brand: parts[0]!, theme: parts[1]!, file });\n else layout.brands.push({ mode: name, file });\n } else if (inDir(file, d.semantic)) {\n if (name === d.base) layout.baseFiles.push(file);\n else layout.themes.push({ mode: name, file });\n } else if (inDir(file, d.density)) layout.densities.push({ mode: name, file });\n else if (file.startsWith(`${d.components}/`)) layout.componentFiles.push(file);\n else layout.primitiveFiles.push(file);\n }\n ordered(layout.brands, options.order?.brand ?? FALLBACK_ORDER.brand);\n ordered(layout.themes, options.order?.theme ?? FALLBACK_ORDER.theme);\n ordered(layout.densities, options.order?.density ?? FALLBACK_ORDER.density);\n return layout;\n}\n\n/** Mode keys of a tier in this repo, in display order. */\nexport function modesOf(layout: RepoLayout, tier: Tier): string[] {\n switch (TIER_AXIS[tier]) {\n case 'brand':\n return layout.brands.map((b) => b.mode);\n case 'theme':\n return layout.themes.map((t) => t.mode);\n case 'density':\n return layout.densities.map((d) => d.mode);\n default:\n return [SINGLE_MODE];\n }\n}\n\n/** File holding a multi-mode tier's value for `mode`. */\nexport function modeFile(layout: RepoLayout, tier: Tier, mode: string): string | undefined {\n const list = TIER_AXIS[tier] === 'brand' ? layout.brands : TIER_AXIS[tier] === 'theme' ? layout.themes : TIER_AXIS[tier] === 'density' ? layout.densities : [];\n return list.find((m) => m.mode === mode)?.file;\n}\n\n/** Default file for a new single-mode token at `path` (relative to the tokens root). */\nexport function defaultFile(tier: Tier, path: string, dirs: LayoutOptions['dirs'] = {}): string {\n const d = { ...DEFAULT_TOKEN_PATHS, ...dirs };\n const head = path.split('.')[0];\n if (tier === 'base') return `${d.semantic}/${d.base}.tokens.json`;\n if (tier === 'component') return `${d.components}/${head}.tokens.json`;\n return `${d.primitives}/${head}.tokens.json`;\n}\n\n/** Default resolution context: first brand, first theme, first density, with overrides. */\nexport function defaultContext(set: Pick<TokenSet, 'layout' | 'overrideIndex'>): ResolveContext {\n return {\n brand: set.layout.brands[0]?.mode,\n theme: set.layout.themes[0]?.mode,\n density: set.layout.densities[0]?.mode,\n overrides: set.overrideIndex,\n };\n}\n\n/** Context to describe a token's value in one mode of its own tier (other axes at their default). */\nexport function contextFor(set: Pick<TokenSet, 'layout' | 'overrideIndex'>, tier: Tier, mode: string): ResolveContext {\n const ctx = defaultContext(set);\n const axis = TIER_AXIS[tier];\n if (axis) ctx[axis] = mode;\n return ctx;\n}\n\nfunction readScopes(ext: Record<string, unknown> | undefined): string[] | undefined {\n const s = ext?.[EXT_SCOPES];\n return Array.isArray(s) && s.every((x) => typeof x === 'string') ? (s as string[]) : undefined;\n}\n\nfunction readId(ext: Record<string, unknown> | undefined): string | undefined {\n const id = ext?.[EXT_ID];\n return typeof id === 'string' && id ? id : undefined;\n}\n\nconst TIER_LABEL: Record<Tier, string> = {\n primitive: 'a primitive',\n brand: 'a brand token',\n base: 'a base semantic token',\n semantic: 'a semantic token',\n density: 'a density token',\n component: 'a component token',\n};\n\n/** `files` maps paths relative to the tokens root to file contents. */\nexport function buildTokenSet(files: Record<string, string>, options: LayoutOptions = {}): TokenSet {\n const problems: string[] = [];\n const docs = new Map<string, TokenDocument>();\n for (const [file, text] of Object.entries(files)) {\n if (!isTokenFile(file)) continue;\n try {\n docs.set(file, parseTokenFile(file, text));\n } catch (err) {\n problems.push(`${file} is not valid JSON: ${(err as Error).message}`);\n }\n }\n const layout = detectLayout([...docs.keys()], options);\n const tokens: TokenMap = new Map();\n const byPath = new Map<string, LogicalToken>();\n\n const add = (t: LogicalToken) => {\n if (tokens.has(t.id)) {\n problems.push(`Two tokens share the id \"${t.id}\" (${tokens.get(t.id)!.path} and ${t.path}).`);\n return;\n }\n tokens.set(t.id, t);\n byPath.set(t.path, t);\n };\n\n const single = (tier: Tier, fileList: string[]) => {\n for (const file of fileList) {\n for (const flat of flattenTokens(docs.get(file)!)) {\n const prev = byPath.get(flat.path);\n if (prev) {\n problems.push(\n prev.tier === tier\n ? `${flat.path} is defined twice (${prev.files[SINGLE_MODE]} and ${file}).`\n : `${flat.path} exists both as ${TIER_LABEL[prev.tier]} and as ${TIER_LABEL[tier]} (${file}).`,\n );\n continue;\n }\n if (!flat.type) problems.push(`${flat.path} in ${file} has no $type.`);\n add({\n id: readId(flat.extensions) ?? pathId(flat.path),\n path: flat.path,\n type: flat.type ?? 'unknown',\n tier,\n values: { [SINGLE_MODE]: flat.value },\n description: flat.description,\n scopes: readScopes(flat.extensions),\n files: { [SINGLE_MODE]: file },\n });\n }\n }\n };\n\n const multi = (tier: Tier, modes: ModeFile[]) => {\n const merged = new Map<string, LogicalToken>();\n for (const { mode, file } of modes) {\n for (const flat of flattenTokens(docs.get(file)!)) {\n let t = merged.get(flat.path);\n if (!t) {\n const prev = byPath.get(flat.path);\n if (prev) {\n problems.push(`${flat.path} exists both as ${TIER_LABEL[prev.tier]} and as ${TIER_LABEL[tier]} (${file}).`);\n continue;\n }\n t = {\n id: readId(flat.extensions) ?? pathId(flat.path),\n path: flat.path,\n type: flat.type ?? 'unknown',\n tier,\n values: {},\n description: flat.description,\n scopes: readScopes(flat.extensions),\n files: {},\n };\n merged.set(flat.path, t);\n if (!flat.type) problems.push(`${flat.path} in ${file} has no $type.`);\n } else if (flat.type && t.type !== flat.type) {\n problems.push(`${flat.path} has type ${t.type} in one mode and ${flat.type} in ${file}.`);\n }\n t.values[mode] = flat.value;\n t.files[mode] = file;\n t.description ??= flat.description;\n t.scopes ??= readScopes(flat.extensions);\n }\n }\n merged.forEach(add);\n };\n\n single('primitive', layout.primitiveFiles);\n multi('brand', layout.brands);\n single('base', layout.baseFiles);\n multi('semantic', layout.themes);\n multi('density', layout.densities);\n single('component', layout.componentFiles);\n\n const overrides: ThemeOverride[] = [];\n const overrideIndex = new Map<string, unknown>();\n for (const o of layout.overrides) {\n for (const flat of flattenTokens(docs.get(o.file)!)) {\n overrides.push({ brand: o.brand, theme: o.theme, path: flat.path, type: flat.type, value: flat.value, file: o.file });\n overrideIndex.set(overrideKey(o.brand, o.theme, flat.path), flat.value);\n }\n }\n return { tokens, byPath, docs, layout, options, overrides, overrideIndex, problems };\n}\n\nexport function indexByPath(tokens: Iterable<LogicalToken>): Map<string, LogicalToken> {\n const m = new Map<string, LogicalToken>();\n for (const t of tokens) m.set(t.path, t);\n return m;\n}\n","// Alias resolution: follows \"{a.b.c}\" chains across tiers, detects cycles and broken references.\n//\n// Each tier varies along its own axis (types.ts): brand tokens per brand, semantic tokens per\n// theme, density tokens per density. A context picks one mode on every axis, so\n// semantic -> palette -> primitive resolves to the value for, say, ocean x dark. A semantic token\n// that a brand overrides for a theme (brands/<brand>.<theme>.tokens.json) takes the override.\n\nimport { type Axis, type LogicalToken, SINGLE_MODE, TIER_AXIS } from './types';\nimport { aliasTarget, collectRefs, isAlias } from './values';\n\nexport interface ResolveContext {\n brand?: string | undefined;\n theme?: string | undefined;\n density?: string | undefined;\n /** overrideKey(brand, theme, path) -> value, from TokenSet.overrideIndex. */\n overrides?: Map<string, unknown> | undefined;\n}\n\nexport type StepSource = 'token' | 'override';\n\nexport interface Resolution {\n /** Final literal value, when resolution succeeded. */\n value?: unknown;\n /** Token paths visited, starting with the requested token. */\n chain: string[];\n /** Where each visited value came from (parallel to `chain`; shorter when resolution stopped). */\n via: StepSource[];\n error?: 'cycle' | 'broken' | 'missing-mode';\n /** Path that could not be found (broken) or that closes the loop (cycle). */\n at?: string;\n}\n\nexport type PathIndex = Map<string, LogicalToken>;\n\n/** Value of a token in a context, and whether a brand override supplied it. */\nexport function valueIn(t: LogicalToken, ctx: ResolveContext): { value: unknown; via: StepSource } {\n const axis = TIER_AXIS[t.tier];\n if (!axis) return { value: t.values[SINGLE_MODE], via: 'token' };\n if (t.tier === 'semantic' && ctx.overrides && ctx.brand && ctx.theme) {\n const o = ctx.overrides.get(`${ctx.brand}|${ctx.theme}|${t.path}`);\n if (o !== undefined) return { value: o, via: 'override' };\n }\n const mode = ctx[axis];\n return { value: mode === undefined ? undefined : t.values[mode], via: 'token' };\n}\n\n/** Resolve the value of `path` in a brand x theme x density context. */\nexport function resolve(index: PathIndex, path: string, ctx: ResolveContext): Resolution {\n const chain: string[] = [];\n const via: StepSource[] = [];\n const seen = new Set<string>();\n let current = path;\n for (;;) {\n if (seen.has(current)) return { chain: [...chain, current], via, error: 'cycle', at: current };\n seen.add(current);\n chain.push(current);\n const t = index.get(current);\n if (!t) return { chain, via, error: 'broken', at: current };\n const v = valueIn(t, ctx);\n if (v.value === undefined) return { chain, via, error: 'missing-mode', at: current };\n via.push(v.via);\n if (!isAlias(v.value)) return { value: v.value, chain, via };\n current = aliasTarget(v.value);\n }\n}\n\nexport interface ReferenceProblem {\n path: string;\n mode: string;\n kind: 'broken' | 'cycle';\n target: string;\n chain: string[];\n}\n\n/** Mode keys per axis (from the repo layout); the first one is the default. */\nexport type AxisModes = Partial<Record<Axis, string[]>>;\n\n/** Every broken reference and cycle in the set, one entry per token and mode of its tier. */\nexport function findReferenceProblems(index: PathIndex, axes: AxisModes): ReferenceProblem[] {\n const out: ReferenceProblem[] = [];\n const base: ResolveContext = { brand: axes.brand?.[0], theme: axes.theme?.[0], density: axes.density?.[0] };\n for (const t of index.values()) {\n const axis = TIER_AXIS[t.tier];\n const modes = axis ? (axes[axis] ?? Object.keys(t.values)).filter((m) => t.values[m] !== undefined) : [SINGLE_MODE];\n for (const mode of modes) {\n const v = t.values[mode];\n for (const ref of collectRefs(v)) {\n if (!index.has(ref)) out.push({ path: t.path, mode, kind: 'broken', target: ref, chain: [t.path, ref] });\n }\n if (isAlias(v)) {\n const r = resolve(index, t.path, axis ? { ...base, [axis]: mode } : base);\n if (r.error === 'cycle') out.push({ path: t.path, mode, kind: 'cycle', target: r.at ?? '', chain: r.chain });\n }\n }\n }\n return out;\n}\n","// Default Figma variable scopes, inferred from token path and type when the DTCG file does not\n// declare `$extensions[\"com.figma.scopes\"]`. Figma's own default is ALL_SCOPES, which shows every\n// variable in every picker; DS Bridge never creates variables with it.\n\nimport type { Tier } from './types';\n\nconst has = (segments: string[], ...names: string[]) => names.some((n) => segments.includes(n));\n\nexport function defaultScopes(path: string, type: string, tier: Tier): string[] {\n const s = path.split('.');\n switch (type) {\n case 'color':\n // Raw ramps and brand palette roles are referenced by semantic tokens, never applied directly.\n if (tier === 'primitive' || (tier === 'brand' && s[0] === 'palette')) return [];\n if (has(s, 'text')) return ['TEXT_FILL'];\n if (has(s, 'border', 'ring', 'outline')) return ['STROKE_COLOR'];\n if (has(s, 'bg', 'surface', 'background')) return ['FRAME_FILL', 'SHAPE_FILL'];\n if (has(s, 'shadow')) return ['EFFECT_COLOR'];\n return ['FRAME_FILL', 'SHAPE_FILL', 'TEXT_FILL', 'STROKE_COLOR'];\n case 'dimension':\n if (has(s, 'radius')) return ['CORNER_RADIUS'];\n if (has(s, 'border', 'width', 'stroke')) return ['STROKE_FLOAT'];\n if (has(s, 'space', 'spacing', 'gap')) return ['GAP', 'WIDTH_HEIGHT'];\n if (has(s, 'size') && has(s, 'font')) return ['FONT_SIZE'];\n if (has(s, 'letter-spacing')) return ['LETTER_SPACING'];\n return ['WIDTH_HEIGHT', 'GAP'];\n case 'fontWeight':\n return ['FONT_WEIGHT'];\n case 'fontFamily':\n return ['FONT_FAMILY'];\n case 'number':\n if (has(s, 'line-height', 'lineHeight')) return ['LINE_HEIGHT'];\n if (has(s, 'opacity')) return ['OPACITY'];\n return ['WIDTH_HEIGHT', 'GAP'];\n case 'string':\n return ['TEXT_CONTENT'];\n default:\n return [];\n }\n}\n\nexport const sameScopes = (a: string[], b: string[]) => {\n const sa = [...new Set(a)].sort();\n const sb = [...new Set(b)].sort();\n return sa.length === sb.length && sa.every((x, i) => x === sb[i]);\n};\n\n/** Scopes a token effectively has: the declared ones, or the inferred default. */\nexport const effectiveScopes = (t: { path: string; type: string; tier: Tier; scopes: string[] | undefined }) =>\n t.scopes ?? defaultScopes(t.path, t.type, t.tier);\n","// WCAG 2.x contrast for declared foreground/background token pairs.\n\nimport { type PathIndex, type ResolveContext, type StepSource, resolve } from './resolver';\nimport { type Rgba, hexToRgba, parseColor } from './values';\n\nexport type PairKind = 'text' | 'large-text' | 'ui';\n\n/** One entry of contrast.checks.json: foreground and background token paths and the minimum ratio. */\nexport interface ContrastPair {\n foreground: string;\n background: string;\n /** Minimum ratio from contrast.checks.json (4.5 for text, 3 for non-text UI). */\n min: number;\n /** Derived from `min`: 4.5 or more is text, anything lower is a UI component (WCAG 1.4.11). */\n kind: PairKind;\n}\n\n/** contrast.checks.json in the tokens path: the one source of contrast pairs (the token build uses it too). */\nexport const CONTRAST_CHECKS_FILE = 'contrast.checks.json';\n\n/** Minimum ratio for WCAG AA per pair kind (1.4.3 and 1.4.11). */\nexport const AA_MIN: Record<PairKind, number> = { text: 4.5, 'large-text': 3, ui: 3 };\n/** Minimum ratio for WCAG AAA (1.4.6). UI components have no AAA criterion; 4.5 is used as a stretch goal. */\nexport const AAA_MIN: Record<PairKind, number> = { text: 7, 'large-text': 4.5, ui: 4.5 };\n\nconst channel = (c: number) => (c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4);\n\n/** Relative luminance of an opaque sRGB color (channels 0..1, rounded to 8-bit like browsers render). */\nexport function luminance(c: Rgba): number {\n const q = (x: number) => Math.round(Math.min(1, Math.max(0, x)) * 255) / 255;\n return 0.2126 * channel(q(c.r)) + 0.7152 * channel(q(c.g)) + 0.0722 * channel(q(c.b));\n}\n\n/** Composite a possibly translucent foreground over an opaque background. */\nexport function composite(fg: Rgba, bg: Rgba): Rgba {\n const a = fg.a;\n return { r: fg.r * a + bg.r * (1 - a), g: fg.g * a + bg.g * (1 - a), b: fg.b * a + bg.b * (1 - a), a: 1 };\n}\n\nexport function contrastRatio(fg: Rgba | string, bg: Rgba | string): number {\n const f = typeof fg === 'string' ? hexToRgba(fg) : fg;\n const b = typeof bg === 'string' ? hexToRgba(bg) : bg;\n if (!f || !b) throw new Error('Invalid color');\n const opaqueBg = { ...b, a: 1 };\n const l1 = luminance(composite(f, opaqueBg));\n const l2 = luminance(opaqueBg);\n const [hi, lo] = l1 > l2 ? [l1, l2] : [l2, l1];\n return (hi + 0.05) / (lo + 0.05);\n}\n\nexport type ContrastLevel = 'AAA' | 'AA' | 'fail';\n\n/** AAA when it meets the AAA ratio of its kind, AA when it meets `min` (the pair's own minimum), else fail. */\nexport function contrastLevel(ratio: number, kind: PairKind, min = AA_MIN[kind]): ContrastLevel {\n if (ratio < min) return 'fail';\n if (ratio >= AAA_MIN[kind]) return 'AAA';\n return 'AA';\n}\n\n/** One token visited while resolving a pair: its path and whether a brand override supplied the value. */\nexport interface ContrastStep {\n path: string;\n via: StepSource;\n}\n\nexport interface ContrastResult {\n pair: ContrastPair;\n /** Brand mode key; undefined when the repo has no brands. */\n brand: string | undefined;\n /** Theme mode key. */\n theme: string;\n ratio?: number;\n level?: ContrastLevel;\n /** Why the ratio could not be computed (unresolvable alias, not a color). */\n error?: string;\n /** Every token both colors resolve through in this brand x theme (used to find what a change affects). */\n steps: ContrastStep[];\n}\n\n/** Brand x theme combinations a set is checked in, like the token build (density does not change colors). */\nexport interface ContrastScope {\n brands: string[];\n themes: string[];\n density?: string | undefined;\n overrides?: Map<string, unknown> | undefined;\n}\n\nexport function contrastScope(set: { layout: { brands: { mode: string }[]; themes: { mode: string }[]; densities: { mode: string }[] }; overrideIndex: Map<string, unknown> }): ContrastScope {\n return {\n brands: set.layout.brands.map((b) => b.mode),\n themes: set.layout.themes.map((t) => t.mode),\n density: set.layout.densities[0]?.mode,\n overrides: set.overrideIndex,\n };\n}\n\nconst cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n/** \"Ocean dark\", or \"Dark\" when the repo has a single unnamed brand. */\nexport const contextLabel = (r: { brand: string | undefined; theme: string }) => (r.brand ? `${cap(r.brand)} ${r.theme}` : cap(r.theme));\n\n/**\n * The color a browser renders: tokens.css writes the `hex` of a DTCG color when it has one, and\n * components can round differently at the 8-bit boundary, so hex wins (same as the token build).\n */\nexport function renderedColor(value: unknown): Rgba | undefined {\n const c = parseColor(value);\n const hex = value && typeof value === 'object' ? (value as { hex?: unknown }).hex : undefined;\n const fromHex = typeof hex === 'string' ? hexToRgba(hex) : undefined;\n return c && fromHex ? { ...fromHex, a: c.a } : c;\n}\n\n/** Ratios of every pair in every brand x theme. Ratios are rounded to 2 decimals. */\nexport function evaluatePairs(index: PathIndex, pairs: ContrastPair[], scope: ContrastScope): ContrastResult[] {\n const out: ContrastResult[] = [];\n const brands = scope.brands.length ? scope.brands : [undefined];\n for (const brand of brands) {\n for (const theme of scope.themes) {\n const ctx: ResolveContext = { brand, theme, density: scope.density, overrides: scope.overrides };\n for (const pair of pairs) {\n const steps: ContrastStep[] = [];\n const color = (path: string): Rgba | string => {\n const r = resolve(index, path, ctx);\n r.via.forEach((via, i) => steps.push({ path: r.chain[i]!, via }));\n if (r.error) return `${path} cannot be resolved (${r.error === 'broken' ? `missing ${r.at}` : r.error})`;\n return renderedColor(r.value) ?? `${path} is not a color`;\n };\n const fg = color(pair.foreground);\n const bg = color(pair.background);\n if (typeof fg === 'string' || typeof bg === 'string') {\n out.push({ pair, brand, theme, steps, error: typeof fg === 'string' ? fg : (bg as string) });\n continue;\n }\n const ratio = Math.round(contrastRatio(fg, bg) * 100) / 100;\n out.push({ pair, brand, theme, ratio, level: contrastLevel(ratio, pair.kind, pair.min), steps });\n }\n }\n }\n return out;\n}\n\n/** Text pair when the minimum is 4.5:1 or more, UI pair (WCAG 1.4.11) below that. */\nexport const kindForMin = (min: number): PairKind => (min >= AA_MIN.text ? 'text' : 'ui');\n\n/** A pair from its parts; the kind follows the minimum. */\nexport const contrastPair = (foreground: string, background: string, min = AA_MIN.text): ContrastPair => ({ foreground, background, min, kind: kindForMin(min) });\n\n/**\n * Parse contrast checks: `{ \"$description\": \"...\", \"pairs\": [[fg, bg, min], ...] }`. A top-level array and\n * `{ \"fg\", \"bg\", \"min\" }` (or foreground, background, ratio) entries are read too, for other repos' files.\n * Entries that are not a pair of token paths with a positive minimum are skipped.\n */\nexport function parseContrastChecks(text: string | undefined): ContrastPair[] {\n if (!text) return [];\n const data = JSON.parse(text) as { pairs?: unknown } | unknown[];\n const list = Array.isArray(data) ? data : Array.isArray(data.pairs) ? data.pairs : [];\n const out: ContrastPair[] = [];\n for (const p of list) {\n let fg: unknown, bg: unknown, min: unknown;\n if (Array.isArray(p)) [fg, bg, min] = p;\n else if (p && typeof p === 'object') {\n const o = p as Record<string, unknown>;\n fg = o.fg ?? o.foreground;\n bg = o.bg ?? o.background;\n min = o.min ?? o.ratio ?? AA_MIN.text;\n }\n if (typeof fg !== 'string' || typeof bg !== 'string' || typeof min !== 'number' || !(min > 0)) continue;\n out.push(contrastPair(fg, bg, min));\n }\n return out;\n}\n\nexport const pairKey = (r: { pair: ContrastPair; brand: string | undefined; theme: string }) => `${r.brand ?? ''}/${r.theme}:${r.pair.foreground}|${r.pair.background}`;\n","// Three-way diff per token.\n//\n// base = tokens at the commit the Figma file was last pulled from (stored baseSha)\n// figma = tokens read from Figma variables now\n// head = tokens on the main branch now\n//\n// A side \"changed\" a token when it differs from base. Figma-only changes are local edits (they go\n// into the PR). Main-only changes are upstream edits (a pull brings them in; a push keeps them).\n// When both sides changed the same token differently, it is a conflict and the user decides.\n// Without a base (first sync), every difference between Figma and main is a conflict.\n\nimport { effectiveScopes, sameScopes } from './scopes';\nimport type { LogicalToken } from './types';\nimport { valuesEqual } from './values';\n\nexport type ChangeKind = 'added' | 'changed' | 'renamed' | 'removed';\n\nexport interface FieldChange {\n field: 'path' | 'type' | 'value' | 'description' | 'scopes';\n /** Mode key for value changes. */\n mode?: string;\n before: unknown;\n after: unknown;\n}\n\nexport interface SideChange {\n kind: ChangeKind;\n fields: FieldChange[];\n}\n\nexport interface DiffEntry {\n id: string;\n /** Display path: the newest name on the side that changed. */\n path: string;\n base?: LogicalToken | undefined;\n figma?: LogicalToken | undefined;\n head?: LogicalToken | undefined;\n /** Change made in Figma (base -> figma). */\n local?: SideChange | undefined;\n /** Change made on main (base -> head). */\n remote?: SideChange | undefined;\n conflict: boolean;\n}\n\nexport interface ThreeWayResult {\n /** Figma-side changes that main did not touch: candidates for the PR. */\n local: DiffEntry[];\n /** Main-side changes that Figma did not touch: candidates for a pull. */\n remote: DiffEntry[];\n /** Both sides changed the same token differently. */\n conflicts: DiffEntry[];\n unchanged: number;\n}\n\nconst normDesc = (d: string | undefined) => (d ?? '').trim();\n\nexport function fieldChanges(a: LogicalToken, b: LogicalToken): FieldChange[] {\n const out: FieldChange[] = [];\n if (a.path !== b.path) out.push({ field: 'path', before: a.path, after: b.path });\n if (a.type !== b.type) out.push({ field: 'type', before: a.type, after: b.type });\n const modes = [...new Set([...Object.keys(a.values), ...Object.keys(b.values)])];\n for (const mode of modes) {\n if (!valuesEqual(b.type, a.values[mode], b.values[mode])) out.push({ field: 'value', mode, before: a.values[mode], after: b.values[mode] });\n }\n if (normDesc(a.description) !== normDesc(b.description)) out.push({ field: 'description', before: a.description, after: b.description });\n const sa = effectiveScopes(a);\n const sb = effectiveScopes(b);\n if (!sameScopes(sa, sb)) out.push({ field: 'scopes', before: sa, after: sb });\n return out;\n}\n\nexport function sameToken(a: LogicalToken | undefined, b: LogicalToken | undefined): boolean {\n if (!a || !b) return a === b;\n return fieldChanges(a, b).length === 0;\n}\n\nfunction sideChange(from: LogicalToken | undefined, to: LogicalToken | undefined): SideChange | undefined {\n if (!from && !to) return undefined;\n if (!from) return { kind: 'added', fields: [] };\n if (!to) return { kind: 'removed', fields: [] };\n const fields = fieldChanges(from, to);\n if (!fields.length) return undefined;\n return { kind: fields.some((f) => f.field === 'path') ? 'renamed' : 'changed', fields };\n}\n\n/** `base` is undefined when the file was never pulled. Maps are keyed by token id. */\nexport function threeWayDiff(\n base: Map<string, LogicalToken> | undefined,\n figma: Map<string, LogicalToken>,\n head: Map<string, LogicalToken>,\n): ThreeWayResult {\n const ids = new Set<string>([...(base?.keys() ?? []), ...figma.keys(), ...head.keys()]);\n const result: ThreeWayResult = { local: [], remote: [], conflicts: [], unchanged: 0 };\n for (const id of [...ids].sort()) {\n const b = base?.get(id);\n const f = figma.get(id);\n const h = head.get(id);\n const local = sideChange(b, f);\n const remote = sideChange(b, h);\n if ((!local && !remote) || (f && h && sameToken(f, h)) || (!f && !h)) {\n result.unchanged++;\n continue;\n }\n const entry: DiffEntry = { id, path: (f ?? h ?? b)!.path, base: b, figma: f, head: h, local, remote, conflict: false };\n if (local && !remote) {\n entry.path = (f ?? b)!.path;\n result.local.push(entry);\n } else if (remote && !local) {\n entry.path = (h ?? b)!.path;\n result.remote.push(entry);\n } else {\n entry.conflict = true;\n result.conflicts.push(entry);\n }\n }\n const byPath = (a: DiffEntry, b: DiffEntry) => a.path.localeCompare(b.path);\n result.local.sort(byPath);\n result.remote.sort(byPath);\n result.conflicts.sort(byPath);\n return result;\n}\n\nexport const toMap = (tokens: Iterable<LogicalToken>) => new Map([...tokens].map((t) => [t.id, t]));\n\nexport type ConflictChoice = 'figma' | 'main';\n","// Risk tier of a change, following docs/GOVERNANCE.md (\"If a PR spans tiers, the highest tier applies\").\n// The one classifier: the Figma plugin, the docs site editor and reviews, the CLI and the MCP server all\n// call classifyRisk, so a change gets the same tier and semver bump wherever it is proposed.\n//\n// Rules, highest first:\n// Tier 3 (high): any token added, changed (value, type, scopes), renamed or removed, in any tier or in a\n// brand theme override. Renames and removals are breaking (\"major\"); additions and changes are\n// \"minor\". Also any guardrail file: governance.guardrails from bridge.config.json (default: the\n// contrast checks, bridge.config.json, AGENTS.md, CLAUDE.md, docs/GOVERNANCE.md, .stylelintrc.json,\n// anything under .github/). A *.tokens.json file counts as Tier 3 when the token changes inside it\n// are not known.\n// Tier 2 (medium): code component source under the components directory that is not a story, docs or test\n// file, and unknown source files (\"When in doubt about the tier, choose the higher one\").\n// Tier 1 (low): a token whose description is the only thing that changed (\"patch\"), documentation\n// (*.md, docs/**), stories, *.docs.json, tests, changesets.\n\nimport type { AcceptedChange } from './compose';\nimport { type BridgeConfig, CONFIG_FILE, DEFAULT_GOVERNANCE } from './config';\nimport { fieldChanges } from './diff-engine';\n\nexport type RiskTier = 1 | 2 | 3;\nexport type SemverBump = 'patch' | 'minor' | 'major';\nexport type TokenChangeKind = 'added' | 'changed' | 'renamed' | 'removed';\n\nexport interface ChangedFile {\n /** Path relative to the repository root. */\n path: string;\n status?: 'added' | 'modified' | 'removed' | 'renamed' | string;\n}\n\n/** A token change described by kind, for callers that do not hold LogicalTokens (CLI, MCP). */\nexport interface TokenChangeSummary {\n kind: TokenChangeKind;\n path: string;\n /** For \"changed\": true when only the description moved. */\n descriptionOnly?: boolean;\n}\n\nexport interface RiskInput {\n /** Token changes (from a diff or a push). */\n tokenChanges?: (AcceptedChange | TokenChangeSummary)[];\n /** Changed files (from a PR or a commit). */\n files?: ChangedFile[];\n config?: BridgeConfig | undefined;\n}\n\nexport interface RiskResult {\n tier: RiskTier;\n /** PR-template label, for example \"Tier 3: token change, needs design + tech approval\". */\n label: string;\n /** One line per rule that fired, highest tier first. */\n reasons: string[];\n /** Semver bump for the changeset of a token change: undefined when no token changed. */\n bump?: SemverBump | undefined;\n}\n\nexport const RISK_LABELS: Record<RiskTier, string> = {\n 1: 'Tier 1: low risk, one code owner',\n 2: 'Tier 2: medium risk, design review then design + tech approval',\n 3: 'Tier 3: token change, needs design + tech approval',\n};\n\nconst BUMP_RANK: Record<SemverBump, number> = { patch: 0, minor: 1, major: 2 };\nconst LOW = [/\\.md$/, /^docs\\//, /\\.stories\\.tsx?$/, /\\.docs\\.json$/, /\\.test\\.tsx?$/, /^\\.changeset\\//];\n\nconst isSummary = (c: AcceptedChange | TokenChangeSummary): c is TokenChangeSummary => 'kind' in c;\n\n/** Kind and description-only flag of any token change. */\nexport function summarizeTokenChange(c: AcceptedChange | TokenChangeSummary): TokenChangeSummary {\n if (isSummary(c)) return c;\n const path = (c.target ?? c.current)!.path;\n if (!c.target) return { kind: 'removed', path };\n if (!c.current) return { kind: 'added', path };\n if (c.current.path !== c.target.path) return { kind: 'renamed', path };\n const fields = fieldChanges(c.current, c.target);\n return { kind: 'changed', path, descriptionOnly: fields.length > 0 && fields.every((f) => f.field === 'description') };\n}\n\n/** Semver bump of a set of token changes: renames and removals major, other changes minor, descriptions patch. */\nexport function tokenBump(changes: (AcceptedChange | TokenChangeSummary)[]): SemverBump | undefined {\n let bump: SemverBump | undefined;\n for (const c of changes.map(summarizeTokenChange)) {\n const b: SemverBump = c.kind === 'removed' || c.kind === 'renamed' ? 'major' : c.kind === 'changed' && c.descriptionOnly ? 'patch' : 'minor';\n if (!bump || BUMP_RANK[b] > BUMP_RANK[bump]) bump = b;\n }\n return bump;\n}\n\n/** Whether a repo-relative path is a guardrail file under this config (or the defaults). */\nexport function isGuardrail(path: string, config?: BridgeConfig): boolean {\n const list = config ? [...config.governance.guardrails, CONFIG_FILE, ...(config.contrast ? [config.contrast.path] : [])] : DEFAULT_GOVERNANCE.guardrails;\n return list.some((g) => (g.endsWith('/') ? path.startsWith(g) : path === g)) || path.startsWith('.github/') || path.endsWith('/contrast.checks.json') || path === 'contrast.checks.json';\n}\n\nexport function classifyRisk(input: RiskInput): RiskResult {\n const reasons: { tier: RiskTier; text: string }[] = [];\n const tokenChanges = (input.tokenChanges ?? []).map(summarizeTokenChange);\n for (const c of tokenChanges) {\n if (c.kind === 'changed' && c.descriptionOnly) reasons.push({ tier: 1, text: `Token description changed: ${c.path}` });\n else reasons.push({ tier: 3, text: `Token ${c.kind}: ${c.path}` });\n }\n const bump = tokenBump(tokenChanges);\n const componentsDir = input.config?.components?.dir;\n for (const f of input.files ?? []) {\n const p = f.path.replace(/^\\/+/, '');\n if (p.endsWith('.tokens.json')) {\n // Known token changes already decided the tier of token files.\n if (!input.tokenChanges) reasons.push({ tier: 3, text: `Token file ${f.status ?? 'changed'}: ${p}` });\n } else if (isGuardrail(p, input.config)) reasons.push({ tier: 3, text: `Guardrail file changed: ${p}` });\n else if (LOW.some((r) => r.test(p))) reasons.push({ tier: 1, text: `Docs, story or test: ${p}` });\n else if (componentsDir && p.startsWith(`${componentsDir}/`)) reasons.push({ tier: 2, text: `Component source ${f.status ?? 'changed'}: ${p}` });\n else reasons.push({ tier: 2, text: `Source file changed: ${p}` });\n }\n reasons.sort((a, b) => b.tier - a.tier);\n const tier = (reasons[0]?.tier ?? 1) as RiskTier;\n return { tier, label: RISK_LABELS[tier], reasons: reasons.map((r) => r.text), bump };\n}\n","// Branch name, commit message and a reviewer-friendly PR body for a token change (changesets: changeset.ts).\n\nimport type { AcceptedChange } from './compose';\nimport { resolve } from './resolver';\nimport { type TokenSet, contextFor, modesOf } from './token-set';\nimport { type LogicalToken, SINGLE_MODE, TIER_AXIS, TIER_NAMES, isMultiMode, modeDisplayName } from './types';\nimport { RISK_LABELS, classifyRisk } from './risk';\nimport type { ProposalValidation } from './validators';\nimport { formatValue, isAlias, valuesEqual } from './values';\nimport { type ContrastResult, contextLabel, pairKey } from './wcag';\n\n/** Label of the risk tier every token change gets (see risk.ts). */\nexport const RISK_TIER = RISK_LABELS[3];\n\nexport function slugify(text: string, max = 40): string {\n const s = text\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n // Cut at a word boundary so branch names do not end in half a word.\n const cut = s.length <= max ? s : s.slice(0, max + 1).replace(/-[^-]*$/, '');\n return cut.replace(/-+$/g, '') || 'update';\n}\n\nconst pad = (n: number) => String(n).padStart(2, '0');\n\n/** \"tokens/<slug>-<yyyymmdd-hhmm>\" in UTC. */\nexport function branchName(slug: string, date: Date): string {\n const stamp = `${date.getUTCFullYear()}${pad(date.getUTCMonth() + 1)}${pad(date.getUTCDate())}-${pad(date.getUTCHours())}${pad(date.getUTCMinutes())}`;\n return `tokens/${slugify(slug)}-${stamp}`;\n}\n\nexport type RowKind = 'added' | 'changed' | 'renamed' | 'removed';\n\nexport function changeKind(c: AcceptedChange): RowKind {\n if (!c.target) return 'removed';\n if (!c.current) return 'added';\n return c.current.path !== c.target.path ? 'renamed' : 'changed';\n}\n\nexport function defaultTitle(changes: AcceptedChange[]): string {\n const paths = changes.map((c) => (c.target ?? c.current)!.path);\n const first = paths[0] ?? 'tokens';\n const verb = (() => {\n const kinds = new Set(changes.map(changeKind));\n if (kinds.size === 1) return { added: 'Add', changed: 'Update', renamed: 'Rename', removed: 'Remove' }[[...kinds][0]!];\n return 'Update';\n })();\n return paths.length <= 1 ? `${verb} token ${first}` : `${verb} ${paths.length} tokens (${first} and more)`;\n}\n\nconst describe = (set: TokenSet, t: LogicalToken | undefined, mode: string): string => {\n if (!t) return '';\n const v = t.values[mode];\n if (v === undefined) return '';\n if (!isAlias(v)) return formatValue(t.type, v);\n const r = resolve(set.byPath, t.path, contextFor(set, t.tier, mode));\n const resolved = r.value === undefined ? 'unresolved' : formatValue(t.type, r.value);\n return `${formatValue(t.type, v)} (${resolved})`;\n};\n\nconst cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\n/g, ' ') || ' ';\nconst code = (s: string) => (s ? `\\`${s}\\`` : '');\n\nfunction valueText(head: TokenSet, proposed: TokenSet, c: AcceptedChange, mode: string): string {\n const t = c.target ?? c.current!;\n const before = describe(head, c.current, mode);\n const after = describe(proposed, c.target, mode);\n if (c.current && c.target && valuesEqual(t.type, c.current.values[mode], c.target.values[mode]) && before === after) return before ? `${code(before)} (unchanged)` : '';\n return `${before ? code(before) : 'none'} -> ${after ? code(after) : 'removed'}`;\n}\n\n/** One line per mode of the token's tier (\"Light: a -> b\"), or the bare value for single-mode tiers. */\nfunction valuesCell(head: TokenSet, proposed: TokenSet, c: AcceptedChange): string {\n const t = c.target ?? c.current!;\n if (!isMultiMode(t.tier)) return valueText(head, proposed, c, SINGLE_MODE);\n return modesOf(head.layout, t.tier)\n .map((m) => {\n const text = valueText(head, proposed, c, m);\n return text ? `${modeDisplayName(m)}: ${text}` : '';\n })\n .filter(Boolean)\n .join('<br>');\n}\n\n/** Modes whose value differs; undefined means every mode (added, removed, renamed or retyped). */\nexport function changedModes(c: AcceptedChange): Set<string> | undefined {\n if (!c.current || !c.target || c.current.path !== c.target.path || c.current.type !== c.target.type) return undefined;\n const modes = new Set([...Object.keys(c.current.values), ...Object.keys(c.target.values)]);\n return new Set([...modes].filter((m) => !valuesEqual(c.target!.type, c.current!.values[m], c.target!.values[m])));\n}\n\n/**\n * Does this contrast result depend on the changed token? True when either color resolves through\n * the token (directly, or indirectly through aliases: a palette role or a primitive that a semantic\n * token points to) in that brand x theme, using a mode that changed. A semantic token a brand\n * overrides for the theme is not used there, so it does not count.\n */\nfunction dependsOn(r: ContrastResult, path: string, tier: LogicalToken['tier'], modes: Set<string> | undefined): boolean {\n const axis = TIER_AXIS[tier];\n if (modes && modes.size === 0) return false; // description or scopes only\n if (modes && axis) {\n const mode = axis === 'brand' ? r.brand : axis === 'theme' ? r.theme : undefined;\n // Density does not change colors; a brand or theme that did not change is not affected.\n if (mode === undefined || !modes.has(mode)) return false;\n }\n return r.steps.some((s) => s.path === path && s.via === 'token');\n}\n\n/** Pairs affected by a change, with before and after results matched by brand x theme x pair. */\nexport function affectedContrast(c: AcceptedChange, before: ContrastResult[], after: ContrastResult[]): { before?: ContrastResult | undefined; after?: ContrastResult | undefined }[] {\n const modes = changedModes(c);\n const keys = new Set<string>();\n if (c.current) for (const r of before) if (dependsOn(r, c.current.path, c.current.tier, modes)) keys.add(pairKey(r));\n if (c.target) for (const r of after) if (dependsOn(r, c.target.path, c.target.tier, modes)) keys.add(pairKey(r));\n const b = new Map(before.map((r) => [pairKey(r), r]));\n const a = new Map(after.map((r) => [pairKey(r), r]));\n return [...keys].map((k) => ({ before: b.get(k), after: a.get(k) }));\n}\n\n/** Contrast lines shown per row of the Changes table before pointing to the full impact table. */\nexport const CONTRAST_CELL_MAX = 12;\n\nfunction contrastCell(c: AcceptedChange, before: ContrastResult[], after: ContrastResult[]): string {\n const rows = affectedContrast(c, before, after);\n const fmt = (x: ContrastResult | undefined) => (x?.ratio !== undefined ? `${x.ratio}` : 'n/a');\n // Changed ratios first, then the biggest drops, so the cell leads with what a reviewer must look at.\n const delta = (x: (typeof rows)[number]) => (x.after?.ratio ?? 0) - (x.before?.ratio ?? 0);\n rows.sort((x, y) => Number(delta(y) === 0) - Number(delta(x) === 0) || delta(x) - delta(y));\n const parts = rows.slice(0, CONTRAST_CELL_MAX).map((x) => {\n const r = (x.after ?? x.before)!;\n return `${contextLabel(r)}, ${r.pair.foreground} on ${r.pair.background}: ${fmt(x.before)} -> ${fmt(x.after)} ${x.after?.level ?? ''}`.trim();\n });\n if (rows.length > CONTRAST_CELL_MAX) parts.push(`and ${rows.length - CONTRAST_CELL_MAX} more (see Contrast impact)`);\n return parts.join('<br>') || ' ';\n}\n\nexport interface PrInput {\n changes: AcceptedChange[];\n head: TokenSet;\n proposed: TokenSet;\n validation: ProposalValidation;\n baseBranch: string;\n headSha: string;\n baseSha: string | undefined;\n /** Who opened the PR and where the edits were made. */\n origin: PrOrigin;\n title: string;\n notes: string;\n /** Upstream changes kept from main (informational). */\n upstreamPaths: string[];\n /** Conflicts resolved before opening the PR: \"edit\" kept the edited side, \"main\" kept the base branch. */\n resolvedConflicts: { path: string; choice: 'figma' | 'edit' | 'main' }[];\n}\n\n/** Where a token change comes from. The plugin, the CLI and the MCP server each pass their own. */\nexport interface PrOrigin {\n /** Tool that opened the PR, for example \"the DS Bridge Figma plugin\". */\n tool: string;\n /** Where the edits were made, for example \"Figma\". */\n surface: string;\n /** File or session the edits come from, for example the Figma file name. */\n location?: string | undefined;\n /** \"Authored by\" line, for example \"Human designer in Figma, via the DS Bridge plugin (no AI involved in the values)\". */\n authoredBy: string;\n}\n\nexport function composePrBody(input: PrInput): string {\n const { changes, head, proposed, validation } = input;\n const lines: string[] = [];\n lines.push('## What changed and why', '');\n const o = input.origin;\n lines.push(input.notes.trim() || `Token edits made in ${o.surface}${o.location ? ` (\"${o.location}\")` : ''}, exported with ${o.tool}.`);\n lines.push('', `Opened from ${o.tool}. ${o.surface} is the editing surface; this PR is the change. Nothing is merged until it is reviewed.`);\n lines.push('');\n const risk = classifyRisk({ tokenChanges: changes });\n lines.push('## Risk tier', '', `- [x] ${risk.label}`, '');\n lines.push('## Changes', '');\n const header = ['Token', 'Tier', 'Change', 'Value (old -> new)', 'Contrast (before -> after)'];\n lines.push(`| ${header.join(' | ')} |`, `| ${header.map(() => '---').join(' | ')} |`);\n for (const c of changes) {\n const t = (c.target ?? c.current)!;\n const kind = changeKind(c);\n const name = kind === 'renamed' ? `${code(c.current!.path)} -> ${code(c.target!.path)}` : code(t.path);\n const extras: string[] = [];\n if (c.current && c.target && (c.current.description ?? '') !== (c.target.description ?? '')) extras.push('description');\n lines.push(\n `| ${name} | ${TIER_NAMES[t.tier]} | ${kind}${extras.length ? ` (+${extras.join(', ')})` : ''} | ${cell(valuesCell(head, proposed, c))} | ${contrastCell(c, validation.contrastBefore, validation.contrastAfter)} |`,\n );\n }\n lines.push('');\n\n const before = new Map(validation.contrastBefore.map((r) => [pairKey(r), r]));\n const impacted = validation.contrastAfter.filter((r) => before.get(pairKey(r))?.ratio !== r.ratio);\n if (impacted.length) {\n lines.push('### Contrast impact', '', '| Pair | Brand and theme | Before | After | Minimum | WCAG |', '| --- | --- | --- | --- | --- | --- |');\n for (const r of impacted) {\n const b = before.get(pairKey(r));\n lines.push(\n `| ${code(r.pair.foreground)} on ${code(r.pair.background)} | ${contextLabel(r)} | ${b?.ratio ?? 'n/a'} | ${r.ratio ?? 'n/a'} | ${r.pair.min} | ${r.level ?? 'n/a'} |`,\n );\n }\n lines.push('');\n }\n\n if (input.resolvedConflicts.length) {\n lines.push(`### Conflicts resolved in ${o.surface}`, '');\n for (const c of input.resolvedConflicts) lines.push(`- ${code(c.path)}: kept the ${c.choice === 'main' ? input.baseBranch : o.surface} version`);\n lines.push('');\n }\n if (input.upstreamPaths.length) {\n lines.push(`### Kept from ${input.baseBranch}`, '', `${input.upstreamPaths.length} token(s) changed on ${input.baseBranch} since the last pull; this PR leaves them as they are on ${input.baseBranch}.`, '');\n }\n if (validation.warnings.length) {\n lines.push('### Warnings (not introduced by this change)', '');\n for (const w of validation.warnings) lines.push(`- ${w.message}`);\n lines.push('');\n }\n\n lines.push('## Guardrail checklist', '');\n const ok = validation.blocking.length === 0;\n lines.push(`- [${ok ? 'x' : ' '}] Checked by Bridge: tiers alias in order (brand -> primitives, semantic colors -> palette roles, component -> semantic), no raw values where an alias is required`);\n lines.push(`- [${ok ? 'x' : ' '}] Checked by Bridge: no broken references or alias cycles, no \"ALL_SCOPES\" variables`);\n lines.push(`- [${ok ? 'x' : ' '}] Checked by Bridge: every pair in contrast.checks.json meets its minimum in every brand and theme`);\n lines.push('- [ ] CI green: token build, typecheck, Stylelint, Storybook build, changeset present');\n lines.push('- [ ] Design review: Storybook checked in light and dark, both brands, Accessibility panel clean');\n lines.push('- [ ] Tech review: names, semver bump, no consumer breakage');\n lines.push('- [ ] Design owner and tech owner approved (CODEOWNERS)');\n lines.push('');\n lines.push('## Authored by', '', `- [x] ${o.authoredBy}`, '');\n lines.push('<details><summary>Sync details</summary>', '');\n lines.push(`- Base (last pull): ${input.baseSha ? code(input.baseSha.slice(0, 7)) : 'none (first sync)'}`);\n lines.push(`- ${input.baseBranch} at export: ${code(input.headSha.slice(0, 7))}`);\n if (o.location) lines.push(`- ${o.surface}: ${o.location}`);\n lines.push('', '</details>', '');\n return lines.join('\\n');\n}\n\n/** Commit message: \"tokens: <title>\", one line per change, then `footer`. */\nexport function commitMessage(title: string, changes: AcceptedChange[], footer = 'Exported with Bridge.'): string {\n const body = changes.map((c) => `- ${changeKind(c)} ${(c.target ?? c.current)!.path}`).join('\\n');\n return `tokens: ${title.replace(/^tokens:\\s*/i, '')}\\n\\n${body}\\n\\n${footer}`;\n}\n","// Changeset writer for token changes (.changeset/*.md, read by @changesets/cli).\n\nimport type { AcceptedChange } from './compose';\nimport { changeKind } from './pr-composer';\nimport { type SemverBump, tokenBump } from './risk';\n\n/**\n * Semver bump per .changeset/README.md, from the shared risk rules: removals and renames are breaking,\n * other value changes minor, description-only changes patch.\n */\nexport function changesetBump(changes: AcceptedChange[]): SemverBump {\n return tokenBump(changes) ?? 'patch';\n}\n\n/** Text of a changeset file bumping one package. */\nexport function formatChangeset(packageName: string, bump: SemverBump, summary: string, details = ''): string {\n return `---\\n\"${packageName}\": ${bump}\\n---\\n\\n${summary.trim()}\\n${details ? `\\n${details.trim()}\\n` : ''}`;\n}\n\nexport interface ChangesetOptions {\n /** Summary line (usually the PR title). */\n title: string;\n /** Branch name; the file name is derived from it. */\n branch: string;\n /** Package to bump, from bridge.config.json \"changeset.package\". */\n packageName: string;\n /** Appended to the summary, for example \"from Figma via DS Bridge\". */\n source?: string;\n}\n\n/** A changeset file for a token change: `{ path: \".changeset/<name>.md\", content }`. */\nexport function composeChangeset(changes: AcceptedChange[], opts: ChangesetOptions): { path: string; content: string } {\n const bump = changesetBump(changes);\n const name = opts.branch.replace(/^tokens\\//, 'ds-bridge-').replace(/[^a-z0-9-]/gi, '-');\n const list = changes\n .slice(0, 20)\n .map((c) => `- ${changeKind(c)} \\`${(c.target ?? c.current)!.path}\\``)\n .join('\\n');\n const more = changes.length > 20 ? `\\n- and ${changes.length - 20} more` : '';\n const summary = opts.source ? `${opts.title} (${opts.source}).` : `${opts.title}.`;\n return {\n path: `.changeset/${name}.md`,\n content: formatChangeset(opts.packageName, bump, summary, `${list}${more}`),\n };\n}\n","// Token edits (set, add, remove, rename) on a layered set, written back with minimal diffs through the\n// format-preserving codec: untouched lines stay byte for byte, one-line tokens stay one line.\n\nimport { emptyTokenFile, inheritedTypeAt, moveToken, parseTokenFile, readTokenAt, removeToken, serializeTokenFile, upsertToken } from './dtcg-codec';\nimport { type Combo, LayeredTokenSet, aliasOf } from './layered';\nimport { hexToRgba, rgbaToDtcg } from './values';\n\nexport interface TokenEdit {\n op: 'set' | 'add' | 'remove' | 'rename';\n path: string;\n value?: unknown;\n type?: string;\n description?: string;\n newPath?: string;\n /** Token file relative to tokens.root, when the token lives in several files (light and dark). */\n file?: string;\n /** Alternative to `file`: edit the file that wins for this mode, e.g. { theme: \"dark\" }. */\n mode?: Partial<Combo>;\n}\n\nexport interface EditResult {\n /** Every token file after the edits (relative to tokens.root). */\n files: Map<string, string>;\n /** Files whose text changed, sorted. */\n touched: string[];\n notes: string[];\n}\n\n/** Turns friendly input (\"#ff5500\", \"12px\", \"150ms\", \"{palette.x}\") into the repo's DTCG form. */\nexport function coerceValue(input: unknown, type: string | undefined, existing?: unknown): unknown {\n if (typeof input !== 'string') return input;\n const s = input.trim();\n if (aliasOf(s)) return s;\n if (s.startsWith('{') || s.startsWith('[')) {\n try {\n return JSON.parse(s);\n } catch {\n /* not JSON: keep going */\n }\n }\n // A repo that writes plain strings (hex colors, \"12px\") keeps getting plain strings.\n const keepString = typeof existing === 'string' && !aliasOf(existing);\n switch (type) {\n case 'color': {\n const m = /^#([0-9a-f]{6})([0-9a-f]{2})?$/i.exec(s) ?? /^#([0-9a-f]{3})$/i.exec(s);\n if (!m) return s;\n const hex6 = m[1]!.length === 3 ? [...m[1]!].map((c) => c + c).join('') : m[1]!;\n if (keepString) return `#${hex6.toLowerCase()}${m[2] ?? ''}`;\n return rgbaToDtcg(hexToRgba(`#${hex6}${m[2] ?? ''}`)!);\n }\n case 'dimension': {\n const m = /^(-?\\d*\\.?\\d+)\\s*(px|rem)?$/.exec(s);\n if (!m || keepString) return s;\n return { value: Number(m[1]), unit: m[2] ?? 'px' };\n }\n case 'duration': {\n const m = /^(\\d*\\.?\\d+)\\s*(ms|s)?$/.exec(s);\n if (!m || keepString) return s;\n return { value: Number(m[1]), unit: m[2] ?? 'ms' };\n }\n case 'number':\n case 'fontWeight':\n return /^-?\\d*\\.?\\d+$/.test(s) ? Number(s) : s;\n default:\n return s;\n }\n}\n\n/** Applies edits in order; each edit sees the result of the previous ones (add then set in one batch works). */\nexport function applyTokenEdits(base: LayeredTokenSet, edits: TokenEdit[]): EditResult {\n let set = base;\n const files = new Map(base.files);\n const touched = new Set<string>();\n const notes: string[] = [];\n const edit = (f: string, fn: (doc: ReturnType<typeof parseTokenFile>) => boolean) => {\n const doc = files.has(f) ? parseTokenFile(f, files.get(f)!) : emptyTokenFile(f);\n if (!fn(doc)) return;\n const text = serializeTokenFile(doc);\n if (text !== files.get(f)) {\n files.set(f, text);\n touched.add(f);\n }\n };\n const definingFiles = (path: string) => [...new Set(set.defs.filter((d) => d.path === path).map((d) => d.file))];\n const pickFiles = (e: TokenEdit, all: boolean): string[] => {\n const defs = definingFiles(e.path);\n if (e.file) {\n if (!files.has(e.file)) throw new Error(`File \"${e.file}\" is not a token file. Token files: ${set.fileNames.join(', ')}`);\n if (!defs.includes(e.file)) throw new Error(`\"${e.path}\" is not defined in ${e.file}. It is defined in: ${defs.join(', ') || 'no file (use op \"add\")'}.`);\n return [e.file];\n }\n if (e.mode) {\n const combo = set.normalizeCombo(e.mode);\n const v = set.view(combo).get(e.path);\n if (!v) throw new Error(`\"${e.path}\" is not defined for ${JSON.stringify(combo)}.`);\n return [v[v.length - 1]!.file];\n }\n if (!defs.length) throw new Error(`Token \"${e.path}\" does not exist. Use op \"add\" to create it.`);\n if (defs.length > 1 && !all) throw new Error(`\"${e.path}\" is defined in ${defs.length} files (${defs.join(', ')}). Pass \"file\" or \"mode\" (for example { \"theme\": \"dark\" }), or one edit per file.`);\n return defs;\n };\n\n for (const e of edits) {\n if (!e.path || /[{}]/.test(e.path)) throw new Error(`Invalid token path \"${e.path}\". Use dots: color.text.muted.`);\n switch (e.op) {\n case 'set': {\n if (e.value === undefined && e.description === undefined && e.type === undefined) throw new Error(`set ${e.path}: give value, description or type.`);\n for (const f of pickFiles(e, false)) {\n edit(f, (doc) => {\n const cur = readTokenAt(doc, e.path)!;\n const type = e.type ?? cur.type;\n return upsertToken(doc, e.path, {\n type,\n value: e.value === undefined ? cur.value : coerceValue(e.value, type, cur.value),\n description: e.description ?? cur.description,\n });\n });\n }\n break;\n }\n case 'add': {\n let file = e.file;\n if (!file && e.mode) {\n const combo = set.normalizeCombo(e.mode);\n const parent = e.path.split('.').slice(0, -1).join('.');\n const sib = [...set.view(combo).entries()].filter(([p]) => p.startsWith(`${parent}.`)).map(([, d]) => d[d.length - 1]!.file);\n file = sib[sib.length - 1];\n }\n if (!file) {\n // The file that already holds the closest parent group.\n const keys = e.path.split('.');\n for (let d = keys.length - 1; d > 0 && !file; d--) {\n const prefix = `${keys.slice(0, d).join('.')}.`;\n const fs = [...new Set(set.defs.filter((x) => x.path.startsWith(prefix)).map((x) => x.file))];\n if (fs.length === 1) file = fs[0];\n else if (fs.length > 1) throw new Error(`Where should \"${e.path}\" go? Its group exists in ${fs.join(', ')}. Pass \"file\" (one add per file for light and dark).`);\n }\n }\n if (!file) throw new Error(`Cannot infer a file for new token \"${e.path}\". Pass \"file\".`);\n if (!files.has(file)) throw new Error(`File \"${file}\" is not a token file. Token files: ${set.fileNames.join(', ')}`);\n if (set.defs.some((d) => d.path === e.path && d.file === file)) throw new Error(`\"${e.path}\" already exists in ${file}. Use op \"set\".`);\n if (e.value === undefined) throw new Error(`add ${e.path}: value is required.`);\n edit(file, (doc) => {\n const type = e.type ?? inheritedTypeAt(doc, e.path);\n if (!type && !aliasOf(e.value)) throw new Error(`add ${e.path}: pass \"type\" (color, dimension, ...); no parent group sets one.`);\n return upsertToken(doc, e.path, { type, value: coerceValue(e.value, type), description: e.description });\n });\n break;\n }\n case 'remove': {\n for (const f of pickFiles(e, true)) edit(f, (doc) => removeToken(doc, e.path));\n const users = set.referencedBy(e.path).filter((u) => u.path !== e.path);\n if (users.length) notes.push(`${users.length} token(s) alias ${e.path}: ${users.slice(0, 8).map((u) => u.path).join(', ')}. Validation will flag them as broken unless they are edited too.`);\n break;\n }\n case 'rename': {\n const to = e.newPath;\n if (!to || /[{}]/.test(to)) throw new Error(`rename ${e.path}: pass a valid newPath.`);\n if (set.defs.some((d) => d.path === to)) throw new Error(`rename: \"${to}\" already exists.`);\n for (const f of pickFiles(e, true)) edit(f, (doc) => moveToken(doc, e.path, to));\n // Repoint every alias.\n const from = `\"{${e.path}}\"`;\n const next = `\"{${to}}\"`;\n for (const [f, text] of files) {\n if (!text.includes(from)) continue;\n files.set(f, text.split(from).join(next));\n touched.add(f);\n }\n break;\n }\n default:\n throw new Error(`Unknown op \"${(e as TokenEdit).op}\". Use set, add, remove or rename.`);\n }\n set = new LayeredTokenSet(base.config, new Map(files));\n }\n return { files, touched: [...touched].filter((f) => files.get(f) !== base.files.get(f)).sort(), notes };\n}\n","// Contrast, designer-readable diff, downstream impact and the pull request body for changes to a layered\n// token set (the CLI and the MCP server). Risk tier and semver bump come from risk.ts, the same rules\n// the Figma plugin and the docs site use.\n\nimport { type Combo, type LayeredDef, type LayeredTokenSet, comboKey } from './layered';\nimport { RISK_LABELS, type RiskResult, type SemverBump, type TokenChangeSummary, classifyRisk } from './risk';\nimport type { BridgeConfig } from './config';\nimport { rgbaToHex } from './values';\nimport { type ContrastPair, contrastRatio, renderedColor } from './wcag';\n\n// --- contrast ---------------------------------------------------------------------------------------------\n\nexport interface LayeredContrastResult {\n fg: string;\n bg: string;\n min: number;\n /** Mode combination, e.g. \"brand=ocean,theme=dark,density=comfortable\". */\n modes: string;\n ratio: number | null;\n pass: boolean;\n fgValue?: string;\n bgValue?: string;\n note?: string;\n}\n\nexport interface ContrastDelta {\n fg: string;\n bg: string;\n min: number;\n modes: string;\n before: number | null;\n after: number | null;\n passBefore: boolean;\n passAfter: boolean;\n}\n\nexport function checkLayeredPair(set: LayeredTokenSet, pair: ContrastPair, combo: Combo): LayeredContrastResult {\n const base = { fg: pair.foreground, bg: pair.background, min: pair.min, modes: comboKey(combo) };\n const f = set.resolve(pair.foreground, combo);\n const b = set.resolve(pair.background, combo);\n if (f.error || b.error) return { ...base, ratio: null, pass: false, note: f.error ?? b.error! };\n const fc = renderedColor(f.value);\n const bc = renderedColor(b.value);\n if (!fc || !bc) return { ...base, ratio: null, pass: false, note: 'not a color Bridge can measure (needs srgb or hex)' };\n if (bc.a < 1) return { ...base, ratio: null, pass: false, note: 'background is translucent: contrast depends on what is behind it' };\n const ratio = Math.round(contrastRatio(fc, bc) * 100) / 100;\n return { ...base, ratio, pass: ratio >= pair.min, fgValue: rgbaToHex(fc), bgValue: rgbaToHex(bc), ...(fc.a < 1 ? { note: 'foreground alpha composited over background' } : {}) };\n}\n\n/** Every pair in every combination of `modes` (config contrast.modes, else all modes). */\nexport function runLayeredContrast(set: LayeredTokenSet, pairs: ContrastPair[], modes?: string[]): LayeredContrastResult[] {\n const combos = set.combos(modes ?? set.config.contrast?.modes);\n return combos.flatMap((c) => pairs.map((p) => checkLayeredPair(set, p, c)));\n}\n\n/** Pairs whose ratio moved between two runs, plus the ones that fail after. */\nexport function contrastDelta(before: LayeredContrastResult[], after: LayeredContrastResult[]): ContrastDelta[] {\n const key = (r: LayeredContrastResult) => `${r.fg}|${r.bg}|${r.modes}`;\n const prev = new Map(before.map((r) => [key(r), r]));\n return after\n .map((a) => {\n const b = prev.get(key(a));\n return { fg: a.fg, bg: a.bg, min: a.min, modes: a.modes, before: b?.ratio ?? null, after: a.ratio, passBefore: b?.pass ?? true, passAfter: a.pass };\n })\n .filter((d) => d.before !== d.after || !d.passAfter);\n}\n\n// --- diff -------------------------------------------------------------------------------------------------\n\nexport interface LayeredChange {\n kind: 'added' | 'removed' | 'changed' | 'renamed';\n path: string;\n /** Old path, for renames. */\n from?: string;\n file: string;\n tier?: string;\n type?: string;\n fields: ('value' | 'type' | 'description' | 'extensions')[];\n before?: unknown;\n after?: unknown;\n /** Resolved CSS value in the file's own mode (dark file -> dark theme). */\n beforeCss?: string;\n afterCss?: string;\n descriptionBefore?: string;\n descriptionAfter?: string;\n}\n\nexport interface ImpactEntry {\n path: string;\n modes: string[];\n before: string;\n after: string;\n}\n\nconst same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\n\n/** Token changes per file between two sets. A removal plus an addition with the same value in the same file is a rename. */\nexport function diffLayered(before: LayeredTokenSet, after: LayeredTokenSet): LayeredChange[] {\n const key = (d: LayeredDef) => `${d.file}\\u0000${d.path}`;\n const b = new Map(before.defs.map((d) => [key(d), d]));\n const a = new Map(after.defs.map((d) => [key(d), d]));\n const css = (set: LayeredTokenSet, d: LayeredDef) => set.resolve(d.path, set.comboForFile(d.file)).css;\n const tierOf = (set: LayeredTokenSet, f: string) => {\n const t = set.tierOfFile(f);\n return t ? { tier: t } : {};\n };\n const changes: LayeredChange[] = [];\n const removed: LayeredDef[] = [];\n const added: LayeredDef[] = [];\n for (const [k, d] of b) {\n const n = a.get(k);\n if (!n) {\n removed.push(d);\n continue;\n }\n const fields: LayeredChange['fields'] = [];\n if (!same(d.value, n.value)) fields.push('value');\n if (d.type !== n.type) fields.push('type');\n if (d.description !== n.description) fields.push('description');\n if (!same(d.extensions, n.extensions)) fields.push('extensions');\n if (!fields.length) continue;\n changes.push({\n kind: 'changed',\n path: d.path,\n file: d.file,\n ...tierOf(after, d.file),\n ...(n.type ? { type: n.type } : {}),\n fields,\n before: d.value,\n after: n.value,\n beforeCss: css(before, d),\n afterCss: css(after, n),\n ...(d.description !== n.description ? { descriptionBefore: d.description ?? '', descriptionAfter: n.description ?? '' } : {}),\n });\n }\n for (const [k, d] of a) if (!b.has(k)) added.push(d);\n for (const r of [...removed]) {\n const i = added.findIndex((x) => x.file === r.file && same(x.value, r.value) && x.type === r.type);\n if (i < 0) continue;\n const n = added.splice(i, 1)[0]!;\n removed.splice(removed.indexOf(r), 1);\n changes.push({ kind: 'renamed', path: n.path, from: r.path, file: n.file, ...(n.type ? { type: n.type } : {}), fields: [], before: r.value, after: n.value, afterCss: css(after, n), ...tierOf(after, n.file) });\n }\n for (const d of removed) changes.push({ kind: 'removed', path: d.path, file: d.file, ...(d.type ? { type: d.type } : {}), fields: [], before: d.value, beforeCss: css(before, d), ...(d.description ? { descriptionBefore: d.description } : {}), ...tierOf(before, d.file) });\n for (const d of added) changes.push({ kind: 'added', path: d.path, file: d.file, ...(d.type ? { type: d.type } : {}), fields: [], after: d.value, afterCss: css(after, d), ...(d.description ? { descriptionAfter: d.description } : {}), ...tierOf(after, d.file) });\n return changes.sort((x, y) => x.path.localeCompare(y.path) || x.file.localeCompare(y.file));\n}\n\n/** Tokens whose resolved value moved in some mode although they were not edited (they alias an edited token). */\nexport function layeredImpact(before: LayeredTokenSet, after: LayeredTokenSet, direct: LayeredChange[], limit = 60): { total: number; entries: ImpactEntry[] } {\n const skip = new Set(direct.map((c) => c.path));\n const byPath = new Map<string, ImpactEntry>();\n for (const combo of after.combos()) {\n const paths = new Set([...before.view(combo).keys(), ...after.view(combo).keys()]);\n for (const p of paths) {\n if (skip.has(p)) continue;\n const x = before.resolve(p, combo).css;\n const y = after.resolve(p, combo).css;\n if (x === y) continue;\n const e = byPath.get(p);\n if (e) e.modes.push(comboKey(combo));\n else byPath.set(p, { path: p, modes: [comboKey(combo)], before: x, after: y });\n }\n }\n const all = [...byPath.values()].sort((a, b) => a.path.localeCompare(b.path));\n return { total: all.length, entries: all.slice(0, limit) };\n}\n\n// --- tier (shared classifier) -----------------------------------------------------------------------------\n\n/** Summary the shared classifier understands. Extensions-only changes count as a change (they can carry scopes). */\nexport const toChangeSummary = (c: LayeredChange): TokenChangeSummary => ({\n kind: c.kind,\n path: c.path,\n ...(c.kind === 'changed' ? { descriptionOnly: c.fields.length > 0 && c.fields.every((f) => f === 'description') } : {}),\n});\n\nexport interface ChangeTier {\n tier: 1 | 2 | 3;\n bump: SemverBump;\n reasons: string[];\n label: string;\n}\n\n/** classifyRisk over layered changes plus the other files of a change. */\nexport function classifyLayered(changes: LayeredChange[], otherFiles: string[] = [], config?: BridgeConfig): ChangeTier {\n const r: RiskResult = classifyRisk({ tokenChanges: changes.map(toChangeSummary), files: otherFiles.map((path) => ({ path })), config });\n return { tier: r.tier, bump: r.bump ?? 'patch', reasons: r.reasons.length ? r.reasons : ['No token or guardrail change'], label: r.label };\n}\n\n// --- tables and body --------------------------------------------------------------------------------------\n\nconst short = (v: unknown) => {\n if (v === undefined) return '';\n const s = typeof v === 'string' ? v : JSON.stringify(v);\n return s.length > 60 ? `${s.slice(0, 57)}...` : s;\n};\nconst cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\n/g, ' ');\nconst swatch = (css?: string) => (css ? `\\`${cell(css)}\\`` : '');\nconst aliasNote = (v: unknown) => (typeof v === 'string' && v.startsWith('{') ? ` (${cell(short(v))})` : '');\n\nexport function changeTable(changes: LayeredChange[]): string {\n if (!changes.length) return '_No token changes._';\n const rows = changes.map((c) => {\n const what = c.kind === 'renamed' ? `renamed from \\`${c.from}\\`` : c.kind === 'changed' ? c.fields.join(', ') : c.kind;\n const before = c.kind === 'added' || c.kind === 'renamed' ? '' : `${swatch(c.beforeCss)}${aliasNote(c.before)}`;\n const after = c.kind === 'removed' ? '' : `${swatch(c.afterCss)}${aliasNote(c.after)}`;\n return `| \\`${c.path}\\` | ${what} | ${before} | ${after} | ${c.file} |`;\n });\n return ['| Token | Change | Before | After | File |', '| --- | --- | --- | --- | --- |', ...rows].join('\\n');\n}\n\nexport function contrastDeltaTable(deltas: ContrastDelta[], limit = 40): string {\n if (!deltas.length) return '_No contrast pair moved._';\n const rows = deltas.slice(0, limit).map((d) => `| \\`${d.fg}\\` on \\`${d.bg}\\` | ${d.modes} | ${d.before ?? 'n/a'} | ${d.after ?? 'n/a'} | ${d.min} | ${d.passAfter ? 'pass' : '**fail**'} |`);\n const more = deltas.length > limit ? `\\n\\n_${deltas.length - limit} more pair(s) not shown._` : '';\n return ['| Pair | Mode | Before | After | Min | Result |', '| --- | --- | --- | --- | --- | --- |', ...rows].join('\\n') + more;\n}\n\nexport interface ProposalBodyInput {\n summary: string;\n changes: LayeredChange[];\n contrast: ContrastDelta[];\n impact: { total: number; entries: ImpactEntry[] };\n tier: ChangeTier;\n validationErrors: number;\n /** \"Bridge MCP\", \"the bridge CLI\". */\n tool?: string;\n author?: string;\n}\n\nexport function composeProposalBody(args: ProposalBodyInput): string {\n const t = args.tier.tier;\n const box = (n: 1 | 2 | 3) => `- ${n === t ? '[x]' : '[ ]'} ${RISK_LABELS[n]}`;\n const impactList = args.impact.entries.slice(0, 15).map((e) => `- \\`${e.path}\\`: ${swatch(e.before)} -> ${swatch(e.after)} (${e.modes.length} mode${e.modes.length > 1 ? 's' : ''})`);\n return [\n '## What changed and why',\n '',\n args.summary.trim(),\n '',\n `Proposed through ${args.tool ?? 'Bridge MCP'}${args.author ? ` by ${args.author}` : ''}. Agent-authored: a human design owner and tech owner review and merge.`,\n '',\n '## Risk tier',\n '',\n box(1),\n box(2),\n box(3),\n '',\n ...args.tier.reasons.map((r) => `- ${r}`),\n `- Semver bump: \\`${args.tier.bump}\\``,\n '',\n '## Token changes',\n '',\n changeTable(args.changes),\n '',\n '## Contrast before and after',\n '',\n contrastDeltaTable(args.contrast),\n '',\n '## Downstream impact',\n '',\n args.impact.total ? [`${args.impact.total} token(s) resolve to a new value because they alias an edited token.`, '', ...impactList, args.impact.total > 15 ? `- and ${args.impact.total - 15} more` : ''].filter(Boolean).join('\\n') : '_No other token changes value._',\n '',\n '## Checks',\n '',\n `- Token validation: ${args.validationErrors ? `**${args.validationErrors} error(s)**` : 'no errors'} (DTCG schema, aliases, light and dark parity)`,\n `- Contrast gate: ${args.contrast.some((d) => !d.passAfter) ? '**failing pairs, see table**' : 'all pairs pass'}`,\n '',\n '## Authored by',\n '',\n '- [ ] Human',\n '- [x] AI agent (Claude), reviewed by a human before merge',\n '',\n '## Design review checklist',\n '',\n '- [ ] Checked in light and dark themes and in every brand',\n '- [ ] Contrast table reviewed, no pair loosened',\n '- [ ] Changeset bump matches the tier',\n '',\n ].join('\\n');\n}\n","// The branch guard every Bridge write path shares: the GitHub client, the local git writer, the plugin and\n// the MCP server. Agents create new branches and pull requests; they never write to a protected branch.\n\nexport const DEFAULT_PROTECTED_BRANCHES = ['main', 'master'];\n\nexport class ProtectedBranchError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ProtectedBranchError';\n }\n}\n\nexport interface BranchRules {\n protectedBranches?: string[] | undefined;\n /** The branch a proposal targets; writing to it is refused too. */\n base?: string | undefined;\n /** When set, new branches must start with it. */\n branchPrefix?: string | undefined;\n}\n\n/** Throws ProtectedBranchError when `branch` is protected, is the base, or lacks the required prefix. */\nexport function assertSafeBranch(branch: string, rules: BranchRules = {}): void {\n const name = branch.replace(/^refs\\/heads\\//, '').trim();\n const blocked = new Set([...(rules.protectedBranches ?? DEFAULT_PROTECTED_BRANCHES), ...(rules.base ? [rules.base] : [])]);\n if (!name || blocked.has(name)) {\n throw new ProtectedBranchError(`Refusing to write to protected branch \"${name}\". Bridge only creates new branches and pull requests.`);\n }\n if (rules.branchPrefix && !name.startsWith(rules.branchPrefix)) {\n throw new ProtectedBranchError(`Branch \"${name}\" must start with \"${rules.branchPrefix}\".`);\n }\n}\n","// History and rollback for a token set: what changed, when, who changed it and why, and how to undo a\n// change safely. Pure: the commits and file snapshots come from a backend (GitHub REST in\n// history-github.ts, local git in @bridge-ds/core/node), so the same model runs in a browser, the CLI and the\n// MCP server.\n//\n// A revert is not a blind `git revert`. The planner computes the inverse token edits against the CURRENT\n// base branch: a token that changed again after the original change is a conflict, shown with the later\n// change, and kept as it is unless the caller asks to restore the old value anyway. What remains goes\n// through the same minimal-diff edits, validation, contrast gate, risk tier and changeset as any proposal.\n\nimport type { BridgeConfig } from './config';\nimport { type Combo, type LayerIssue, LayeredTokenSet, globToRegExp, validateLayered } from './layered';\nimport { type ChangeTier, type ContrastDelta, type LayeredChange, classifyLayered, composeProposalBody, contrastDelta, diffLayered, layeredImpact, runLayeredContrast } from './layered-review';\nimport { type TokenEdit, applyTokenEdits } from './token-edits';\nimport { formatChangeset } from './changeset';\nimport { slugify } from './pr-composer';\nimport type { SemverBump } from './risk';\nimport type { ContrastPair } from './wcag';\n\n// --- model ------------------------------------------------------------------------------------------------\n\nexport interface HistoryPullRequest {\n number: number;\n title: string;\n url?: string;\n author?: string;\n mergedAt?: string;\n body?: string;\n}\n\n/** A commit that touched the token files, newest first in lists. */\nexport interface HistoryCommit {\n sha: string;\n parents: string[];\n /** ISO date. */\n date: string;\n author: string;\n subject: string;\n body?: string;\n pr?: HistoryPullRequest;\n}\n\nexport interface HistoryChangeset {\n path: string;\n bump?: SemverBump;\n packages: string[];\n summary: string;\n}\n\nexport interface HistoryCounts {\n added: number;\n changed: number;\n removed: number;\n renamed: number;\n total: number;\n}\n\n/** One merged change to the tokens: a pull request, or a commit that landed without one. */\nexport interface HistoryEntry {\n /** `pr-12` for a pull request, the short sha otherwise. */\n id: string;\n /** Commit that landed the change on the base branch. */\n sha: string;\n /** Commit the diff is computed from (first parent). */\n baseSha?: string;\n date: string;\n author: string;\n title: string;\n /** Why: the changeset summary, else the PR description, else the commit body, else the title. */\n why: string;\n pr?: HistoryPullRequest;\n changes: LayeredChange[];\n counts: HistoryCounts;\n tier: 1 | 2 | 3;\n bump: SemverBump;\n breaking: boolean;\n reasons: string[];\n changesets: HistoryChangeset[];\n /** Release the change shipped in, or \"Unreleased\" (set by assignVersions). */\n version?: string;\n /** More than BULK_LIMIT token changes: an import or a restructure, not a reviewable edit. */\n bulk?: boolean;\n /** Fixture data for demos and tests. Never mixed with real history. */\n demo?: boolean;\n}\n\nexport const BULK_LIMIT = 60;\nexport const UNRELEASED = 'Unreleased';\n\nconst SUBJECT_PR = [/^Merge pull request #(\\d+)/, /\\(#(\\d+)\\)\\s*$/];\n\n/** PR number from a merge or squash subject (\"Merge pull request #12 from ...\", \"Fix x (#12)\"). */\nexport function prNumberFromSubject(subject: string): number | undefined {\n for (const re of SUBJECT_PR) {\n const m = re.exec(subject);\n if (m) return Number(m[1]);\n }\n return undefined;\n}\n\n/** Frontmatter bumps and summary of a .changeset/*.md file. */\nexport function parseChangesetText(path: string, text: string): HistoryChangeset | null {\n const m = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?([\\s\\S]*)$/.exec(text);\n if (!m) return null;\n const bumps = [...m[1]!.matchAll(/[\"']?([^\"'\\s:]+)[\"']?\\s*:\\s*(major|minor|patch)/g)].map((x) => ({ pkg: x[1]!, bump: x[2] as SemverBump }));\n const order: SemverBump[] = ['major', 'minor', 'patch'];\n const bump = order.find((b) => bumps.some((x) => x.bump === b));\n const summary = m[2]!.trim().split(/\\r?\\n\\r?\\n/)[0]!.replace(/\\s+/g, ' ').trim();\n return { path, ...(bump ? { bump } : {}), packages: bumps.map((b) => b.pkg), summary };\n}\n\n/** First paragraph of a PR body or commit body, without template headings, checklists or HTML comments. */\nexport function firstParagraph(text: string | undefined): string {\n if (!text) return '';\n const cleaned = text.replace(/<!--[\\s\\S]*?-->/g, '');\n for (const para of cleaned.split(/\\r?\\n\\s*\\r?\\n/)) {\n const lines = para.split(/\\r?\\n/).filter((l) => l.trim() && !/^\\s*#{1,6}\\s/.test(l) && !/^\\s*[-*]\\s*\\[[ xX]\\]/.test(l) && !/^\\s*(Co-Authored-By|Claude-Session|Signed-off-by):/i.test(l));\n const s = lines.join(' ').replace(/\\s+/g, ' ').trim();\n if (s && !/^\\|/.test(s)) return s.length > 400 ? `${s.slice(0, 397)}...` : s;\n }\n return '';\n}\n\nexport function countChanges(changes: LayeredChange[]): HistoryCounts {\n const c: HistoryCounts = { added: 0, changed: 0, removed: 0, renamed: 0, total: changes.length };\n for (const x of changes) c[x.kind]++;\n return c;\n}\n\nconst shortSha = (sha: string) => sha.slice(0, 7);\n\n/** The title of a commit for people: the PR title, else the merged PR's first body line, else the subject. */\nexport function titleOf(commit: HistoryCommit): string {\n if (commit.pr?.title) return commit.pr.title;\n if (/^Merge pull request #\\d+/.test(commit.subject)) {\n const first = (commit.body ?? '').split(/\\r?\\n/).find((l) => l.trim());\n if (first) return first.trim();\n }\n return commit.subject;\n}\n\nexport interface EntryInput {\n config: BridgeConfig;\n commit: HistoryCommit;\n /** Token files (relative to tokens.root) before and after the change. */\n before: Map<string, string>;\n after: Map<string, string>;\n /** Changeset files the change added: { path, text }. */\n changesets?: { path: string; text: string }[];\n demo?: boolean;\n}\n\n/** A history entry from two snapshots, or null when no token changed (formatting, moves of whitespace). */\nexport function buildHistoryEntry(input: EntryInput): HistoryEntry | null {\n const { config, commit } = input;\n const beforeSet = new LayeredTokenSet(config, input.before);\n const afterSet = new LayeredTokenSet(config, input.after);\n const changes = diffLayered(beforeSet, afterSet);\n if (!changes.length) return null;\n const tier = classifyLayered(changes, [], config);\n const changesets = (input.changesets ?? []).map((c) => parseChangesetText(c.path, c.text)).filter((c): c is HistoryChangeset => c !== null);\n const pkg = config.changesets?.package;\n const relevant = changesets.filter((c) => !pkg || !c.packages.length || c.packages.includes(pkg));\n const title = titleOf(commit);\n const why = relevant.map((c) => c.summary).find(Boolean) || firstParagraph(commit.pr?.body) || firstParagraph(commit.body) || title;\n const prNumber = commit.pr?.number ?? prNumberFromSubject(commit.subject);\n const pr = commit.pr ?? (prNumber ? { number: prNumber, title, ...(config.repo ? { url: `https://github.com/${config.repo.owner}/${config.repo.name}/pull/${prNumber}` } : {}) } : undefined);\n const changesetBump = relevant.map((c) => c.bump).find((b) => b === 'major');\n const bump: SemverBump = changesetBump ?? tier.bump;\n return {\n id: pr ? `pr-${pr.number}` : shortSha(commit.sha),\n sha: commit.sha,\n ...(commit.parents[0] ? { baseSha: commit.parents[0] } : {}),\n date: commit.date,\n author: commit.pr?.author ?? commit.author,\n title,\n why,\n ...(pr ? { pr } : {}),\n changes,\n counts: countChanges(changes),\n tier: tier.tier,\n bump,\n breaking: bump === 'major',\n reasons: tier.reasons,\n changesets: relevant,\n ...(changes.length > BULK_LIMIT ? { bulk: true } : {}),\n ...(input.demo ? { demo: true } : {}),\n };\n}\n\n// --- backends ---------------------------------------------------------------------------------------------\n\n/** Where commits and snapshots come from: GitHub REST, local git, or fixtures. */\nexport interface HistoryBackend {\n /** Commits on `ref` that touched `paths` (repo-relative), newest first, with their PR when known. */\n listCommits(opts: { ref: string; paths: string[]; limit: number }): Promise<HistoryCommit[]>;\n /** Token files (relative to tokens.root) at a commit. */\n tokenFiles(sha: string): Promise<Map<string, string>>;\n /** Repo-relative paths of changeset files at a commit (empty when the repo has none). */\n changesetPaths?(sha: string): Promise<string[]>;\n readFile?(sha: string, path: string): Promise<string | null>;\n}\n\nexport interface CollectOptions {\n ref: string;\n /** Most recent commits to inspect (default 40). */\n limit?: number;\n onProgress?: (done: number, total: number) => void;\n}\n\n/**\n * History of the token files on `ref`, newest first. Commits of one pull request fold into one entry when the\n * backend knows the PR (GitHub lists branch commits too); the entry diffs the first parent of the newest\n * commit of the group against that commit, which for a merge or squash commit is the whole PR.\n */\nexport async function collectHistory(config: BridgeConfig, backend: HistoryBackend, opts: CollectOptions): Promise<HistoryEntry[]> {\n const root = config.tokens.root.replace(/\\/$/, '');\n const commits = await backend.listCommits({ ref: opts.ref, paths: [root === '.' ? '' : root].filter(Boolean), limit: opts.limit ?? 40 });\n // Group by PR: keep the newest commit of each PR (the merge or squash commit when it is on the list).\n const seen = new Set<number>();\n const picked: HistoryCommit[] = [];\n for (const c of commits) {\n const n = c.pr?.number;\n if (n !== undefined) {\n if (seen.has(n)) continue;\n seen.add(n);\n }\n picked.push(c);\n }\n const entries: HistoryEntry[] = [];\n let done = 0;\n for (const c of picked) {\n const parent = c.parents[0];\n const [before, after] = await Promise.all([parent ? backend.tokenFiles(parent) : Promise.resolve(new Map<string, string>()), backend.tokenFiles(c.sha)]);\n let changesets: { path: string; text: string }[] = [];\n if (backend.changesetPaths && backend.readFile && config.changesets) {\n const [was, now] = await Promise.all([parent ? backend.changesetPaths(parent) : Promise.resolve([]), backend.changesetPaths(c.sha)]);\n const added = now.filter((p) => !was.includes(p) && p.endsWith('.md') && !/README\\.md$/i.test(p));\n changesets = (await Promise.all(added.map(async (p) => ({ path: p, text: (await backend.readFile!(c.sha, p)) ?? '' })))).filter((x) => x.text);\n }\n const e = buildHistoryEntry({ config, commit: c, before, after, changesets });\n if (e) entries.push(e);\n opts.onProgress?.(++done, picked.length);\n }\n return entries;\n}\n\n// --- versions ---------------------------------------------------------------------------------------------\n\nexport interface HistoryRelease {\n version: string;\n date?: string;\n /** Tag commit, when known. */\n sha?: string;\n /** Commits and PRs the CHANGELOG lists under this version. */\n shas?: string[];\n prs?: number[];\n}\n\n/** Releases from a Changesets CHANGELOG.md: `## 1.2.0` sections and the shas and PR numbers they cite. */\nexport function parseChangelog(text: string): HistoryRelease[] {\n const out: HistoryRelease[] = [];\n const parts = text.split(/^##\\s+/m).slice(1);\n for (const p of parts) {\n const [head, ...rest] = p.split(/\\r?\\n/);\n const version = /v?(\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?)/.exec(head ?? '')?.[1];\n if (!version) continue;\n const body = rest.join('\\n');\n const shas = [...new Set([...body.matchAll(/(?:^|[\\s[`(])([0-9a-f]{7,40})(?=[\\s`\\]):]|$)/gm)].map((m) => m[1]!))];\n const prs = [...new Set([...body.matchAll(/(?:#|\\/pull\\/)(\\d+)/g)].map((m) => Number(m[1])))];\n const date = /(\\d{4}-\\d{2}-\\d{2})/.exec(head ?? '')?.[1];\n out.push({ version, ...(date ? { date } : {}), shas, prs });\n }\n return out;\n}\n\n/** Releases from git tags (`v1.2.0`, `@scope/pkg@1.2.0`); tags of other packages are ignored when `pkg` is given. */\nexport function releasesFromTags(tags: { name: string; sha?: string; date?: string }[], pkg?: string): HistoryRelease[] {\n const out: HistoryRelease[] = [];\n for (const t of tags) {\n const m = /^(?:(@?[^@\\s]+)@)?v?(\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?)$/.exec(t.name);\n if (!m) continue;\n if (pkg && m[1] && m[1] !== pkg) continue;\n out.push({ version: m[2]!, ...(t.sha ? { sha: t.sha } : {}), ...(t.date ? { date: t.date } : {}) });\n }\n return out;\n}\n\n/**\n * Sets `version` on every entry: the release whose CHANGELOG section cites its sha or PR, else the first\n * tagged release dated at or after it, else \"Unreleased\". Returns new entries; the input is not changed.\n */\nexport function assignVersions(entries: HistoryEntry[], releases: HistoryRelease[]): HistoryEntry[] {\n const dated = releases.filter((r) => r.date).sort((a, b) => Date.parse(a.date!) - Date.parse(b.date!));\n return entries.map((e) => {\n const cited = releases.find((r) => r.shas?.some((s) => e.sha.startsWith(s)) || (e.pr && r.prs?.includes(e.pr.number)));\n const byTag = cited ? undefined : dated.find((r) => r.sha === e.sha || Date.parse(r.date!) >= Date.parse(e.date));\n return { ...e, version: (cited ?? byTag)?.version ?? UNRELEASED };\n });\n}\n\nexport interface VersionGroup {\n version: string;\n pending: boolean;\n /** Release date, else the newest change in it. */\n date: string;\n entries: string[];\n prs: number[];\n tokenChanges: number;\n breaking: boolean;\n bump: SemverBump;\n authors: string[];\n}\n\nconst BUMP_RANK: Record<SemverBump, number> = { patch: 0, minor: 1, major: 2 };\n\n/** The timeline of design system versions, newest first (\"Unreleased\" on top). */\nexport function versionTimeline(entries: HistoryEntry[], releases: HistoryRelease[] = []): VersionGroup[] {\n const groups = new Map<string, VersionGroup>();\n for (const e of entries) {\n const v = e.version ?? UNRELEASED;\n let g = groups.get(v);\n if (!g) {\n const rel = releases.find((r) => r.version === v);\n g = { version: v, pending: v === UNRELEASED, date: rel?.date ?? e.date, entries: [], prs: [], tokenChanges: 0, breaking: false, bump: 'patch', authors: [] };\n groups.set(v, g);\n }\n g.entries.push(e.id);\n if (e.pr && !g.prs.includes(e.pr.number)) g.prs.push(e.pr.number);\n g.tokenChanges += e.counts.total;\n g.breaking ||= e.breaking;\n if (BUMP_RANK[e.bump] > BUMP_RANK[g.bump]) g.bump = e.bump;\n if (!g.authors.includes(e.author)) g.authors.push(e.author);\n if (!releases.some((r) => r.version === v && r.date) && Date.parse(e.date) > Date.parse(g.date)) g.date = e.date;\n }\n return [...groups.values()].sort((a, b) => (a.pending ? -1 : b.pending ? 1 : Date.parse(b.date) - Date.parse(a.date)));\n}\n\n// --- filters and per-token history ------------------------------------------------------------------------\n\nexport interface HistoryFilter {\n /** Token path or group prefix: color.text matches color.text.muted. */\n token?: string;\n author?: string;\n tier?: 1 | 2 | 3;\n version?: string;\n breaking?: boolean;\n /** ISO dates, inclusive. */\n since?: string;\n until?: string;\n /** Free text over title, why and PR number. */\n query?: string;\n}\n\nconst matchesToken = (path: string, q: string) => path === q || path.startsWith(`${q.replace(/\\.$/, '')}.`);\n\nexport function filterHistory(entries: HistoryEntry[], f: HistoryFilter = {}): HistoryEntry[] {\n const q = f.query?.trim().toLowerCase();\n return entries.filter(\n (e) =>\n (!f.token || e.changes.some((c) => matchesToken(c.path, f.token!) || (c.from && matchesToken(c.from, f.token!)))) &&\n (!f.author || e.author.toLowerCase() === f.author.toLowerCase()) &&\n (!f.tier || e.tier === f.tier) &&\n (!f.version || (e.version ?? UNRELEASED) === f.version) &&\n (f.breaking === undefined || e.breaking === f.breaking) &&\n (!f.since || Date.parse(e.date) >= Date.parse(f.since)) &&\n (!f.until || Date.parse(e.date) <= Date.parse(f.until) + 86_399_999) &&\n (!q || `${e.title} ${e.why} ${e.pr ? `#${e.pr.number}` : ''} ${e.sha}`.toLowerCase().includes(q)),\n );\n}\n\n/** Mode values a token file stands for, from the layer that matches it: semantic/dark.tokens.json -> { theme: \"dark\" }. */\nexport function fileModes(config: BridgeConfig, file: string): Partial<Combo> {\n for (const layer of config.tokens.layers) {\n const keys: string[] = [];\n const marked = layer.files.replace(/\\{([^}]+)\\}/g, (_, k: string) => {\n keys.push(k);\n return '\\u0001';\n });\n const source = globToRegExp(marked).source.replace(/\\u0001/g, '([^/.]+)');\n const m = new RegExp(source).exec(file);\n if (m) return Object.fromEntries(keys.map((k, i) => [k, m[i + 1]!]));\n }\n return {};\n}\n\n/** \"Dark\", \"Ocean dark\", or \"All modes\". */\nexport function modeLabel(modes: Partial<Combo>): string {\n const v = Object.values(modes).filter(Boolean) as string[];\n if (!v.length) return 'All modes';\n const s = v.join(' ');\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nexport interface TokenHistoryItem {\n entryId: string;\n sha: string;\n date: string;\n author: string;\n title: string;\n why: string;\n pr?: HistoryPullRequest;\n version?: string;\n demo?: boolean;\n kind: LayeredChange['kind'];\n /** Path at the time of the change (a rename shows the old path in `from`). */\n path: string;\n from?: string;\n file: string;\n modes: Partial<Combo>;\n modeLabel: string;\n fields: LayeredChange['fields'];\n before?: unknown;\n after?: unknown;\n beforeCss?: string;\n afterCss?: string;\n descriptionBefore?: string;\n descriptionAfter?: string;\n}\n\n/** Every change of one token, newest first, following renames back to older names. */\nexport function tokenHistory(entries: HistoryEntry[], path: string, config?: BridgeConfig): TokenHistoryItem[] {\n const names = new Set([path]);\n const out: TokenHistoryItem[] = [];\n const sorted = [...entries].sort((a, b) => Date.parse(b.date) - Date.parse(a.date));\n for (const e of sorted) {\n const hits = e.changes.filter((c) => names.has(c.path));\n for (const c of hits) {\n const modes = config ? fileModes(config, c.file) : {};\n out.push({\n entryId: e.id,\n sha: e.sha,\n date: e.date,\n author: e.author,\n title: e.title,\n why: e.why,\n ...(e.pr ? { pr: e.pr } : {}),\n ...(e.version ? { version: e.version } : {}),\n ...(e.demo ? { demo: true } : {}),\n kind: c.kind,\n path: c.path,\n ...(c.from ? { from: c.from } : {}),\n file: c.file,\n modes,\n modeLabel: modeLabel(modes),\n fields: c.fields,\n ...(c.before !== undefined ? { before: c.before } : {}),\n ...(c.after !== undefined ? { after: c.after } : {}),\n ...(c.beforeCss !== undefined ? { beforeCss: c.beforeCss } : {}),\n ...(c.afterCss !== undefined ? { afterCss: c.afterCss } : {}),\n ...(c.descriptionBefore !== undefined ? { descriptionBefore: c.descriptionBefore } : {}),\n ...(c.descriptionAfter !== undefined ? { descriptionAfter: c.descriptionAfter } : {}),\n });\n }\n for (const c of hits) if (c.kind === 'renamed' && c.from) names.add(c.from);\n }\n return out;\n}\n\n// --- planning: revert and restore -------------------------------------------------------------------------\n\nexport type ConflictReason = 'changed-later' | 'removed-later' | 'recreated-later' | 'renamed-later' | 'still-referenced';\nexport type RevertResolution = 'keep-current' | 'use-before';\n\nexport interface LaterChange {\n id: string;\n title: string;\n date: string;\n author: string;\n pr?: number;\n}\n\nexport interface RevertConflict {\n /** `path@file`, the key `resolutions` uses. */\n key: string;\n path: string;\n file: string;\n kind: LayeredChange['kind'];\n reason: ConflictReason;\n message: string;\n original: { before?: unknown; after?: unknown; beforeCss?: string; afterCss?: string };\n current?: { value: unknown; css: string };\n later: LaterChange[];\n resolution: RevertResolution;\n}\n\nexport interface PlannedEdit {\n key: string;\n path: string;\n file: string;\n /** Plain words: \"Set color.text.muted back to {palette.neutral.600} (Light)\". */\n summary: string;\n edit: TokenEdit;\n}\n\nexport interface ChangePlan {\n kind: 'revert' | 'restore';\n /** ready: can be proposed. blocked: it would add validation errors or break a contrast pair. nothing-to-do: no edit left. */\n status: 'ready' | 'blocked' | 'nothing-to-do';\n why?: string;\n title: string;\n /** Pull request title. */\n prTitle: string;\n summary: string;\n source?: { id: string; sha: string; title: string; pr?: HistoryPullRequest; date: string; author: string };\n planned: PlannedEdit[];\n edits: TokenEdit[];\n conflicts: RevertConflict[];\n /** Changes already undone on the base branch. */\n skipped: { key: string; path: string; file: string; reason: string }[];\n /** Token changes the plan makes against the current base (what reviewers see). */\n changes: LayeredChange[];\n contrast: ContrastDelta[];\n newFailures: ContrastDelta[];\n newErrors: LayerIssue[];\n tier: ChangeTier;\n /** Repo-relative files to commit: token files plus the changeset. */\n files: { path: string; content: string }[];\n changeset?: { path: string; content: string };\n branch: string;\n commitMessage: string;\n prBody: string;\n notes: string[];\n}\n\nexport interface PlanCommon {\n /** The token set on the base branch now. */\n current: LayeredTokenSet;\n /** Contrast pairs for the before/after table; empty skips the gate. */\n pairs?: ContrastPair[];\n /** \"Bridge docs\", \"Bridge MCP\", \"the bridge CLI\". */\n tool?: string;\n author?: string;\n}\n\nexport interface RevertInput extends PlanCommon {\n entry: HistoryEntry;\n /** Entries after `entry` (any order): they explain conflicts. */\n later?: HistoryEntry[];\n /** Per conflict key: keep the current value (default) or put the value from before the change back. */\n resolutions?: Record<string, RevertResolution>;\n}\n\nexport interface RestoreInput extends PlanCommon {\n path: string;\n /** Token file relative to tokens.root; needed when the token lives in several files. */\n file?: string;\n /** Raw DTCG value (or a friendly form: \"#ff5500\", \"{palette.x}\"). */\n value: unknown;\n /** Where the value comes from, for the title and the PR body: \"1.2.0\", \"#12\", a date. */\n label?: string;\n /** The history item the value comes from, linked in the PR body. */\n item?: TokenHistoryItem;\n}\n\nconst same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b);\nconst keyOf = (path: string, file: string) => `${path}@${file}`;\nconst show = (v: unknown) => (typeof v === 'string' ? v : JSON.stringify(v));\n\nfunction defIn(set: LayeredTokenSet, path: string, file: string) {\n return set.defs.find((d) => d.path === path && d.file === file);\n}\n\n/** Whether two token files resolve together in some mode combination (an alias in one can reach the other). */\nfunction sharesCombo(set: LayeredTokenSet, a: string, b: string): boolean {\n return a === b || set.combos().some((c) => {\n const files = set.layerFiles(c).files;\n return files.includes(a) && files.includes(b);\n });\n}\n\nfunction laterTouching(later: HistoryEntry[], path: string, file: string, from?: string): LaterChange[] {\n return later\n .filter((e) => e.changes.some((c) => c.file === file && (c.path === path || c.from === path || (from !== undefined && (c.path === from || c.from === from)))))\n .sort((a, b) => Date.parse(a.date) - Date.parse(b.date))\n .map((e) => ({ id: e.id, title: e.title, date: e.date, author: e.author, ...(e.pr ? { pr: e.pr.number } : {}) }));\n}\n\n/** Inverse edits of a history entry against the current set, with the conflicts it meets. */\nexport function planRevert(input: RevertInput): ChangePlan {\n const { current, entry } = input;\n const later = (input.later ?? []).filter((e) => e.id !== entry.id && Date.parse(e.date) >= Date.parse(entry.date));\n const res = input.resolutions ?? {};\n const planned: PlannedEdit[] = [];\n const conflicts: RevertConflict[] = [];\n const skipped: ChangePlan['skipped'] = [];\n const config = current.config;\n const css = (path: string, file: string) => current.resolve(path, current.comboForFile(file)).css;\n\n for (const c of entry.changes) {\n const key = keyOf(c.path, c.file);\n const label = modeLabel(fileModes(config, c.file));\n const original = { ...(c.before !== undefined ? { before: c.before } : {}), ...(c.after !== undefined ? { after: c.after } : {}), ...(c.beforeCss ? { beforeCss: c.beforeCss } : {}), ...(c.afterCss ? { afterCss: c.afterCss } : {}) };\n const conflict = (reason: ConflictReason, message: string, cur?: { value: unknown; css: string }, editIfForced?: TokenEdit, summary?: string) => {\n const resolution = res[key] ?? 'keep-current';\n conflicts.push({ key, path: c.path, file: c.file, kind: c.kind, reason, message, original, ...(cur ? { current: cur } : {}), later: laterTouching(later, c.path, c.file, c.from), resolution });\n if (resolution === 'use-before' && editIfForced) planned.push({ key, path: c.path, file: c.file, summary: summary ?? `${editIfForced.op} ${c.path}`, edit: editIfForced });\n };\n const now = defIn(current, c.path, c.file);\n switch (c.kind) {\n case 'changed': {\n if (!now) {\n conflict('removed-later', `${c.path} was removed from ${c.file} after this change. Restoring it is a new token decision, not a revert.`, undefined, { op: 'add', path: c.path, file: c.file, value: c.before, ...(c.type ? { type: c.type } : {}), ...(c.descriptionBefore ? { description: c.descriptionBefore } : {}) }, `Add ${c.path} back with ${show(c.before)} (${label})`);\n break;\n }\n const valueField = c.fields.includes('value');\n const descField = c.fields.includes('description');\n const cur = { value: now.value, css: css(c.path, c.file) };\n const valueAt = (v: unknown) => same(now.value, v);\n const descNow = now.description ?? '';\n if (!valueField && !descField) {\n skipped.push({ key, path: c.path, file: c.file, reason: 'Only the type or extensions changed: edit those by hand.' });\n break;\n }\n if ((!valueField || valueAt(c.before)) && (!descField || descNow === (c.descriptionBefore ?? ''))) {\n skipped.push({ key, path: c.path, file: c.file, reason: 'Already back to the value from before this change.' });\n break;\n }\n const valueMoved = valueField && !valueAt(c.after) && !valueAt(c.before);\n const descMoved = descField && descNow !== (c.descriptionAfter ?? '') && descNow !== (c.descriptionBefore ?? '');\n const edit: TokenEdit = {\n op: 'set',\n path: c.path,\n file: c.file,\n ...(valueField ? { value: c.before } : {}),\n ...(descField ? { description: c.descriptionBefore ?? '' } : {}),\n };\n const summary = valueField ? `Set ${c.path} back to ${show(c.before)} (${label})` : `Put the old description of ${c.path} back (${label})`;\n if (valueMoved || descMoved) {\n conflict('changed-later', `${c.path} changed again after this change: it is now ${cur.css || show(cur.value)}, not ${c.afterCss || show(c.after)}.`, cur, edit, summary);\n break;\n }\n planned.push({ key, path: c.path, file: c.file, summary, edit });\n break;\n }\n case 'added': {\n if (!now) {\n skipped.push({ key, path: c.path, file: c.file, reason: 'Already removed.' });\n break;\n }\n const users = current.referencedBy(c.path).filter((u) => u.path !== c.path && sharesCombo(current, u.file, c.file));\n const edit: TokenEdit = { op: 'remove', path: c.path, file: c.file };\n const summary = `Remove ${c.path} (${label})`;\n if (!same(now.value, c.after)) {\n conflict('changed-later', `${c.path} changed after it was added: it is now ${css(c.path, c.file) || show(now.value)}.`, { value: now.value, css: css(c.path, c.file) }, edit, summary);\n break;\n }\n if (users.length) {\n conflict('still-referenced', `${users.length} token(s) alias ${c.path} now (${users.slice(0, 4).map((u) => u.path).join(', ')}${users.length > 4 ? ', ...' : ''}). Removing it would break them.`, { value: now.value, css: css(c.path, c.file) }, edit, summary);\n break;\n }\n planned.push({ key, path: c.path, file: c.file, summary, edit });\n break;\n }\n case 'removed': {\n const edit: TokenEdit = { op: 'add', path: c.path, file: c.file, value: c.before, ...(c.type ? { type: c.type } : {}), ...(c.descriptionBefore ? { description: c.descriptionBefore } : {}) };\n const summary = `Add ${c.path} back with ${show(c.before)} (${label})`;\n if (now) {\n if (same(now.value, c.before)) skipped.push({ key, path: c.path, file: c.file, reason: 'Already back.' });\n else conflict('recreated-later', `${c.path} was added again later with another value (${css(c.path, c.file) || show(now.value)}).`, { value: now.value, css: css(c.path, c.file) });\n break;\n }\n planned.push({ key, path: c.path, file: c.file, summary, edit });\n break;\n }\n case 'renamed': {\n const from = c.from!;\n const back = defIn(current, from, c.file);\n if (back && !now) {\n skipped.push({ key, path: c.path, file: c.file, reason: `Already named ${from}.` });\n break;\n }\n if (!now) {\n conflict('renamed-later', `${c.path} no longer exists in ${c.file}: it was renamed or removed again later.`);\n break;\n }\n if (back) {\n conflict('recreated-later', `${from} exists again in ${c.file}, so ${c.path} cannot take its old name back.`, { value: back.value, css: css(from, c.file) });\n break;\n }\n // A rename moves every file that defines the token, so one edit covers light and dark.\n if (planned.some((p) => p.edit.op === 'rename' && p.path === c.path)) {\n skipped.push({ key, path: c.path, file: c.file, reason: 'Covered by the rename above.' });\n break;\n }\n planned.push({ key, path: c.path, file: c.file, summary: `Rename ${c.path} back to ${from} and repoint its aliases`, edit: { op: 'rename', path: c.path, newPath: from } });\n break;\n }\n }\n }\n\n const prLink = entry.pr ? (entry.pr.url ? `[#${entry.pr.number}](${entry.pr.url})` : `#${entry.pr.number}`) : `commit ${entry.sha.slice(0, 7)}`;\n const title = `Revert: ${entry.title}`;\n const lines = [\n `Reverts ${prLink} (\"${entry.title}\"), merged ${entry.date.slice(0, 10)} by ${entry.author}.`,\n '',\n `Original reason: ${entry.why}`,\n '',\n 'Bridge computed the inverse token edits against the current base branch, not a blind git revert: tokens that changed again since are listed as conflicts and kept unless a reviewer chose to restore them.',\n ];\n if (conflicts.length) {\n lines.push('', '### Conflicts', '', '| Token | File | Why | Decision |', '| --- | --- | --- | --- |');\n for (const k of conflicts) lines.push(`| \\`${k.path}\\` | ${k.file} | ${k.message.replace(/\\|/g, '\\\\|')}${k.later.length ? ` Later: ${k.later.map((l) => (l.pr ? `#${l.pr}` : l.id)).join(', ')}.` : ''} | ${k.resolution === 'use-before' ? 'restore the old value' : 'keep current'} |`);\n }\n if (skipped.length) lines.push('', `${skipped.length} change(s) were already undone on the base branch and are left alone.`);\n return finishPlan({ ...input, kind: 'revert', title, prTitle: title, summary: lines.join('\\n'), planned, conflicts, skipped, source: entry });\n}\n\n/** One token back to an earlier value, in one file (one mode). */\nexport function planRestore(input: RestoreInput): ChangePlan {\n const { current, path } = input;\n const files = [...new Set(current.defs.filter((d) => d.path === path).map((d) => d.file))];\n if (!files.length) throw new Error(`Token \"${path}\" does not exist on the base branch. Restoring a removed token is a revert of the change that removed it.`);\n const file = input.file ?? (files.length === 1 ? files[0]! : undefined);\n if (!file) throw new Error(`\"${path}\" is defined in ${files.join(', ')}. Pass the file (the mode) to restore.`);\n if (!files.includes(file)) throw new Error(`\"${path}\" is not defined in ${file}. It is defined in: ${files.join(', ')}.`);\n const label = modeLabel(fileModes(current.config, file));\n const from = input.label ? ` from ${input.label}` : '';\n const planned: PlannedEdit[] = [{ key: keyOf(path, file), path, file, summary: `Set ${path} to ${show(input.value)} (${label})`, edit: { op: 'set', path, file, value: input.value } }];\n const title = `Restore ${path} (${label})${from}`;\n const item = input.item;\n const summary = [\n `Restores \\`${path}\\` in ${label} to ${show(input.value)}${from}.`,\n ...(item ? ['', `That value came from ${item.pr ? (item.pr.url ? `[#${item.pr.number}](${item.pr.url})` : `#${item.pr.number}`) : `commit ${item.sha.slice(0, 7)}`} (\"${item.title}\"), ${item.date.slice(0, 10)}, by ${item.author}.`] : []),\n ].join('\\n');\n return finishPlan({ ...input, kind: 'restore', title, prTitle: title, summary, planned, conflicts: [], skipped: [] });\n}\n\nconst issueKey = (i: LayerIssue) => `${i.code}|${i.path ?? ''}|${i.file ?? ''}|${i.message}`;\n\ninterface FinishInput extends PlanCommon {\n kind: 'revert' | 'restore';\n title: string;\n prTitle: string;\n summary: string;\n planned: PlannedEdit[];\n conflicts: RevertConflict[];\n skipped: ChangePlan['skipped'];\n source?: HistoryEntry;\n}\n\nfunction finishPlan(p: FinishInput): ChangePlan {\n const { current } = p;\n const config = current.config;\n const edits = p.planned.map((x) => x.edit);\n const notes: string[] = [];\n const empty: ChangeTier = classifyLayered([], [], config);\n const base = {\n kind: p.kind,\n title: p.title,\n prTitle: p.prTitle,\n summary: p.summary,\n ...(p.source ? { source: { id: p.source.id, sha: p.source.sha, title: p.source.title, ...(p.source.pr ? { pr: p.source.pr } : {}), date: p.source.date, author: p.source.author } } : {}),\n planned: p.planned,\n edits,\n conflicts: p.conflicts,\n skipped: p.skipped,\n branch: `${config.governance.branchPrefix}${slugify(p.title, 48) || p.kind}`,\n };\n const nothing = (why: string): ChangePlan => ({ ...base, status: 'nothing-to-do', why, changes: [], contrast: [], newFailures: [], newErrors: [], tier: empty, files: [], commitMessage: '', prBody: '', notes });\n if (!edits.length) return nothing(p.conflicts.length ? 'Every change conflicts with a later one. Choose \"restore the old value\" on a conflict to include it.' : 'Nothing left to undo: the base branch already has the old values.');\n let result;\n try {\n result = applyTokenEdits(current, edits);\n } catch (e) {\n return { ...nothing((e as Error).message), status: 'blocked' };\n }\n notes.push(...result.notes);\n const after = new LayeredTokenSet(config, result.files);\n const changes = diffLayered(current, after);\n if (!changes.length) return nothing('The edits leave every token as it is now.');\n const prev = new Set(validateLayered(current).map(issueKey));\n const newErrors = validateLayered(after).filter((i) => i.level === 'error' && !prev.has(issueKey(i)));\n const pairs = p.pairs ?? [];\n const modes = config.contrast?.modes;\n const contrast = pairs.length ? contrastDelta(runLayeredContrast(current, pairs, modes), runLayeredContrast(after, pairs, modes)) : [];\n const newFailures = contrast.filter((d) => d.passBefore && !d.passAfter);\n const tier = classifyLayered(changes, [], config);\n const impact = layeredImpact(current, after, changes);\n const prBody = composeProposalBody({ summary: p.summary, changes, contrast, impact, tier, validationErrors: newErrors.length, tool: p.tool ?? 'Bridge', ...(p.author ? { author: p.author } : {}) });\n const changeset = config.changesets ? { path: `${config.changesets.dir.replace(/\\/$/, '')}/bridge-${slugify(p.title, 48) || p.kind}.md`, content: formatChangeset(config.changesets.package, tier.bump, p.title.replace(/\\.?$/, '.')) } : undefined;\n const files = [...result.touched.map((f) => ({ path: current.repoPath(f), content: result.files.get(f)! })), ...(changeset ? [changeset] : [])];\n const commitMessage = `${p.kind === 'revert' ? 'revert(tokens)' : 'fix(tokens)'}: ${p.title.replace(/^Revert: /, '')}\\n\\n${p.source?.pr ? `Reverts #${p.source.pr.number}. ` : ''}Tier ${tier.tier}. Planned with ${p.tool ?? 'Bridge'}.`;\n const blocked = newErrors.length || newFailures.length;\n return {\n ...base,\n status: blocked ? 'blocked' : 'ready',\n ...(blocked ? { why: [newErrors.length ? `${newErrors.length} new validation error(s)` : '', newFailures.length ? `${newFailures.length} contrast pair(s) would fail` : ''].filter(Boolean).join(' and ') } : {}),\n changes,\n contrast,\n newFailures,\n newErrors,\n tier,\n files,\n ...(changeset ? { changeset } : {}),\n commitMessage,\n prBody,\n notes,\n };\n}\n\n/** A patch-like JSON of a plan, for people without a GitHub token: apply it by hand or hand it to an agent. */\nexport function planToJson(plan: ChangePlan): Record<string, unknown> {\n return {\n bridge: 'change-plan',\n kind: plan.kind,\n status: plan.status,\n title: plan.prTitle,\n branch: plan.branch,\n tier: plan.tier.tier,\n bump: plan.tier.bump,\n edits: plan.edits,\n conflicts: plan.conflicts.map((c) => ({ key: c.key, reason: c.reason, message: c.message, resolution: c.resolution })),\n files: plan.files,\n commitMessage: plan.commitMessage,\n prBody: plan.prBody,\n };\n}\n\n// --- report -----------------------------------------------------------------------------------------------\n\nexport interface HistoryReport {\n source: 'github' | 'git' | 'demo';\n /** `owner/name@main`, a local path and ref, or \"demo\". */\n label: string;\n ref: string;\n entries: HistoryEntry[];\n releases: HistoryRelease[];\n timeline: VersionGroup[];\n /** Version in the changesets package's package.json on the ref. */\n currentVersion?: string;\n /** More commits exist than were read (raise the limit to go further back). */\n truncated: boolean;\n /** True when every entry is fixture data. The docs site shows it only behind the demo toggle. */\n demo?: boolean;\n}\n\n/** Where the changesets package may keep CHANGELOG.md and package.json: the tokens root and its parents. */\nexport function packageDirCandidates(config: BridgeConfig): string[] {\n const parts = config.tokens.root.replace(/\\/$/, '').split('/').filter((p) => p && p !== '.');\n const out: string[] = [];\n for (let i = parts.length; i >= 0; i--) out.push(parts.slice(0, i).join('/'));\n return out;\n}\n\n/** Releases from a CHANGELOG and tags, dated by the tags when the CHANGELOG has no dates. */\nexport function mergeReleases(changelog: HistoryRelease[], tags: HistoryRelease[]): HistoryRelease[] {\n const byVersion = new Map<string, HistoryRelease>();\n for (const r of [...changelog, ...tags]) {\n const prev = byVersion.get(r.version);\n byVersion.set(r.version, prev ? { ...r, ...prev, ...(prev.date ? {} : r.date ? { date: r.date } : {}), ...(prev.sha ? {} : r.sha ? { sha: r.sha } : {}) } : r);\n }\n return [...byVersion.values()];\n}\n\nexport function buildReport(args: Omit<HistoryReport, 'timeline' | 'entries'> & { entries: HistoryEntry[] }): HistoryReport {\n const entries = assignVersions(args.entries, args.releases).sort((a, b) => Date.parse(b.date) - Date.parse(a.date));\n return { ...args, entries, timeline: versionTimeline(entries, args.releases) };\n}\n","// Component specs: a declarative description of a coded component, derived from its TSX props and CSS module, that a\n// design tool can rebuild (the DS Bridge Figma plugin pulls them as component sets bound to variables).\n//\n// Generated, never hand-maintained: `npm run specs` reads packages/react/src/components and writes\n// packages/react/component-specs.json (generator in @bridge-ds/core/node, component-specs.ts). A test fails when the\n// committed file is out of date. Only token paths are recorded: component CSS has no literal values.\n//\n// Pure types and helpers: safe in the plugin sandbox and the browser.\n\n/** Format version of component-specs.json. */\nexport const COMPONENT_SPECS_VERSION = 1;\n\n/** Where the specs live when bridge.config.json does not say (`components.specs`). */\nexport const DEFAULT_COMPONENT_SPECS_FILE = 'packages/react/component-specs.json';\n\n/**\n * A Figma-side property a CSS declaration maps to.\n * Frames: fill (background-color), stroke and stroke weights (border), cornerRadius (border-radius), paddings, itemSpacing\n * (gap), sizes. Text: textFill (color), font family, size, weight, line height, letter spacing.\n */\nexport type SpecField =\n | 'fill'\n | 'stroke'\n | 'strokeWeight'\n | 'strokeTopWeight'\n | 'strokeRightWeight'\n | 'strokeBottomWeight'\n | 'strokeLeftWeight'\n | 'cornerRadius'\n | 'paddingTop'\n | 'paddingRight'\n | 'paddingBottom'\n | 'paddingLeft'\n | 'itemSpacing'\n | 'width'\n | 'height'\n | 'minWidth'\n | 'minHeight'\n | 'textFill'\n | 'fontFamily'\n | 'fontSize'\n | 'fontWeight'\n | 'lineHeight'\n | 'letterSpacing';\n\nexport const SPEC_FIELDS: readonly SpecField[] = [\n 'fill',\n 'stroke',\n 'strokeWeight',\n 'strokeTopWeight',\n 'strokeRightWeight',\n 'strokeBottomWeight',\n 'strokeLeftWeight',\n 'cornerRadius',\n 'paddingTop',\n 'paddingRight',\n 'paddingBottom',\n 'paddingLeft',\n 'itemSpacing',\n 'width',\n 'height',\n 'minWidth',\n 'minHeight',\n 'textFill',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'lineHeight',\n 'letterSpacing',\n];\n\n/** Fields whose token must be a color. */\nexport const COLOR_FIELDS: ReadonlySet<SpecField> = new Set(['fill', 'stroke', 'textFill']);\n\n/**\n * A token path (\"button.primary.bg\"), a literal zero (`padding: 0`), null: no paint (`transparent`), or a calc() of token\n * paths (\"calc(space.2 + space.0-5)\", operators + - * / and px numbers): resolved to a number, set but not bound.\n */\nexport type SpecValue = string | 0 | null;\n\nexport interface SpecLayout {\n direction: 'HORIZONTAL' | 'VERTICAL';\n /** justify-content. */\n primary: 'MIN' | 'CENTER' | 'MAX' | 'SPACE_BETWEEN';\n /** align-items. STRETCH: children fill the cross axis. */\n counter: 'MIN' | 'CENTER' | 'MAX' | 'STRETCH';\n}\n\nexport interface SpecPart {\n /** Stable id inside the component (\"root\", \"label\", \"icon-start\"). Figma layers keep it in plugin data. */\n id: string;\n /** Layer name in Figma. */\n name: string;\n kind: 'frame' | 'text' | 'icon';\n /** Parent part id; undefined for the root (the variant itself). */\n parent?: string | undefined;\n /** CSS module class the part is styled by (\"Button.module.css .label\"), for people reading the spec. */\n source?: string | undefined;\n layout?: SpecLayout | undefined;\n /** Text parts: the TEXT component property that holds the characters. */\n text?: string | undefined;\n /** Optional parts (an icon prop): the BOOLEAN component property that shows them. */\n visible?: string | undefined;\n /** Frames with `overflow: hidden` or `clip`: clip their content in Figma. */\n clip?: boolean | undefined;\n /** Root only: block-level in code (display block, flex or grid, or width 100%), so it fills its container. Figma draws it at a fixed width. */\n fill?: boolean | undefined;\n /**\n * A swappable part: drawn as an instance of a generated component (\"Icon/Plus\", \"Slot/Media\") and swapped through an\n * INSTANCE_SWAP property. Icon parts swap between every icon of `icons`; content slots between `options`.\n */\n swap?: SpecSwap | undefined;\n}\n\nexport interface SpecSwap {\n /** INSTANCE_SWAP property name (\"Icon\", \"Icon start\", \"Body\"). */\n property: string;\n /** Component the property defaults to (the default variant's): \"Icon/Pencil\", \"Slot/Card body text\". */\n default: string;\n /** Preferred values. Undefined for icon parts: every icon of the file. */\n options?: string[] | undefined;\n /** Code prop it stands for (\"icon\", \"iconStart\"); undefined for a compound part's content. */\n prop?: string | undefined;\n}\n\n/** A Lucide icon the specs use, drawn as a component \"Icon/<name>\" on the Icons page. */\nexport interface SpecIcon {\n /** Name as code imports it from lucide-react (\"Trash2\"), the first one referenced. */\n name: string;\n /** Lucide icon id (file name in lucide-react): \"trash\". */\n lucide: string;\n /** Other names of the same icon referenced by the components or the common set (\"AlertTriangle\"). */\n aliases?: string[] | undefined;\n /** Normalized SVG markup, 24x24 viewBox, stroke=\"currentColor\". */\n svg: string;\n}\n\n/** Tokens of the icon components (Icon/<name>) themselves; instances in components use their variant's tokens. */\nexport interface SpecIconStyle {\n /** Size token of the master frame. */\n size: string;\n /** Stroke color token. */\n color: string;\n /** Stroke width token. */\n stroke: string;\n}\n\n/** A generated content component a slot swaps to (\"Slot/Card body text\", \"Slot/Media\"), on the Slots page. */\nexport interface SpecSlot {\n name: string;\n kind: 'text' | 'media';\n /** Fields of the slot's own layer: text fields for a text slot, fill and width for media. */\n values: Partial<Record<SpecField, SpecValue>>;\n /** Text slots: the TEXT property and its default. */\n text?: { property: string; default: string } | undefined;\n /** Media: width / height ratio, and the centered icon with its fields. */\n aspect?: [number, number] | undefined;\n icon?: string | undefined;\n iconValues?: Partial<Record<SpecField, SpecValue>> | undefined;\n}\n\n/** A variant axis from a string-literal union prop (variant, size, tone) or the State axis. */\nexport interface SpecAxis {\n /** Figma property name (\"Variant\", \"Size\", \"State\"). */\n name: string;\n /** Code prop it comes from; undefined for State. */\n prop?: string | undefined;\n values: string[];\n default: string;\n}\n\nexport interface SpecProperty {\n name: string;\n type: 'TEXT' | 'BOOLEAN';\n default: string | boolean;\n /** Code prop it stands for (\"children\", \"iconStart\"). */\n prop?: string | undefined;\n}\n\nexport interface SpecVariant {\n /** Axis name -> value, in axis order. */\n props: Record<string, string>;\n /** Part id -> Figma field -> value. */\n values: Record<string, Partial<Record<SpecField, SpecValue>>>;\n /** Swappable part id -> the component this variant shows by default (\"Icon/Plus\", \"Slot/Media\"). */\n slots?: Record<string, string> | undefined;\n}\n\n/** A declaration, prop or part that has no Figma equivalent in this version, with the reason. */\nexport interface SpecUnmapped {\n part: string;\n property: string;\n value: string;\n reason: string;\n}\n\nexport interface ComponentSpec {\n name: string;\n /** FNV-1a of everything else in the spec: unchanged hash, nothing to rebuild. */\n hash: string;\n /** Files it was read from, repo-relative. */\n source: string[];\n axes: SpecAxis[];\n properties: SpecProperty[];\n parts: SpecPart[];\n variants: SpecVariant[];\n unmapped: SpecUnmapped[];\n}\n\nexport interface ComponentSpecsFile {\n version: number;\n /** Human note at the top of the file. */\n generated: string;\n components: ComponentSpec[];\n /** Icons the components use (slot defaults, docs and stories) plus a common set, sorted by name. */\n icons?: SpecIcon[] | undefined;\n iconStyle?: SpecIconStyle | undefined;\n /** Content components slots swap to. */\n slots?: SpecSlot[] | undefined;\n}\n\n/** Figma component name of an icon: \"Icon/Plus\". */\nexport const iconComponentName = (name: string) => `Icon/${name}`;\n\n/** FNV-1a, 32 bits, 8 hex digits. */\nexport function specHash(text: string): string {\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return (h >>> 0).toString(16).padStart(8, '0');\n}\n\n/** Hash of a spec without its own hash field. */\nexport function hashSpec(spec: Omit<ComponentSpec, 'hash'> | ComponentSpec): string {\n const { hash: _ignored, ...rest } = spec as ComponentSpec;\n return specHash(JSON.stringify(rest));\n}\n\n/** Figma variant name for a variant's props: \"Variant=primary, Size=md, State=Default\" (axis order). */\nexport const variantName = (props: Record<string, string>) =>\n Object.entries(props)\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n\n/** Variant key independent of axis order (same as the plugin's signature keys): sorted \"Size=md, Variant=primary\". */\nexport const variantKeyOf = (props: Record<string, string>) =>\n Object.keys(props)\n .sort()\n .map((k) => `${k}=${props[k]}`)\n .join(', ') || 'Default';\n\n/** Parses component-specs.json; throws with a readable message when it is not a specs file of a known version. */\nexport function parseComponentSpecs(text: string): ComponentSpecsFile {\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch {\n throw new Error('component-specs.json is not valid JSON.');\n }\n const f = data as ComponentSpecsFile;\n if (!f || typeof f !== 'object' || !Array.isArray(f.components)) throw new Error('component-specs.json has no \"components\" list.');\n if (f.version !== COMPONENT_SPECS_VERSION) throw new Error(`component-specs.json is version ${String(f.version)}; this tool reads version ${COMPONENT_SPECS_VERSION}.`);\n return f;\n}\n\n/** CSS custom property of a token path, with the repo convention (`cssVar` in bridge.config.json): \"--\" + path joined by \"-\". */\nexport const tokenCssVar = (path: string, prefix = '--', separator = '-') => `${prefix}${path.split('.').join(separator)}`;\n"],"names":["isObj","norm","ordered","body","pad","list","rank","BUMP_RANK","cell","same","changesetBump","commitMessage"],"mappings":"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"}