@bridge-ds/core 0.8.0 → 0.9.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.
- package/dist/audit/index.d.ts +1 -0
- package/dist/audit/index.js +269 -23
- package/dist/audit/index.js.map +1 -1
- package/dist/audit/missing-pieces.d.ts +43 -0
- package/dist/component-spec-BzfBkYRD.js +1122 -0
- package/dist/component-spec-BzfBkYRD.js.map +1 -0
- package/dist/github-client.d.ts +9 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1685 -1432
- package/dist/index.js.map +1 -1
- package/dist/node/index.js +3 -3
- package/dist/{component-spec-SKuywZqr.js → pr-composer-D2SZm7cg.js} +822 -1444
- package/dist/pr-composer-D2SZm7cg.js.map +1 -0
- package/dist/prod-branch-D5Tl87Wf.js +266 -0
- package/dist/prod-branch-D5Tl87Wf.js.map +1 -0
- package/dist/prod-branch-github.d.ts +139 -0
- package/dist/prod-branch.d.ts +257 -0
- package/dist/{report-iPSnsjYi.js → report-DY_peRy4.js} +24 -24
- package/dist/{report-iPSnsjYi.js.map → report-DY_peRy4.js.map} +1 -1
- package/dist/token-proposal.d.ts +72 -0
- package/package.json +1 -1
- package/dist/component-spec-SKuywZqr.js.map +0 -1
- package/dist/layered-BnbmToGs.js +0 -500
- package/dist/layered-BnbmToGs.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-spec-BzfBkYRD.js","sources":["../src/changeset.ts","../src/token-edits.ts","../src/layered-review.ts","../src/governance.ts","../src/history.ts","../src/component-spec.ts"],"sourcesContent":["// 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, and textDecoration (a\n * keyword, \"UNDERLINE\" or \"STRIKETHROUGH\", not a token).\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 | 'counterAxisSpacing'\n | 'width'\n | 'height'\n | 'minWidth'\n | 'minHeight'\n | 'opacity'\n | 'textFill'\n | 'fontFamily'\n | 'fontSize'\n | 'fontWeight'\n | 'lineHeight'\n | 'letterSpacing'\n | 'textDecoration';\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 'counterAxisSpacing',\n 'width',\n 'height',\n 'minWidth',\n 'minHeight',\n 'opacity',\n 'textFill',\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'lineHeight',\n 'letterSpacing',\n 'textDecoration',\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 number (`padding: 0`, a unitless `stroke-width: 3` or `opacity: 0.5`),\n * null: no paint (`transparent`), or a calc() of token paths (\"calc(space.2 + space.0-5)\", operators + - * / and px\n * numbers): resolved to a number, set but not bound.\n */\nexport type SpecValue = string | number | 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 /** `flex-direction: row-reverse | column-reverse`: children are drawn in reverse order. */\n reverse?: boolean | undefined;\n /** `flex-wrap: wrap` on a row: items wrap to new lines (Figma auto layout wrap). */\n wrap?: boolean | undefined;\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 /** vector: an inline SVG drawn from the variant's `vectors` markup (a spinner arc, a progress ring). */\n kind: 'frame' | 'text' | 'icon' | 'vector';\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 /** Text parts with no TEXT property (content written in code, like a group's option labels): the characters drawn. */\n characters?: string | undefined;\n /**\n * Positioned over its parent instead of flowing in its auto layout (an avatar photo over its initials): `position:\n * absolute` with `inset: 0`, or `width` and `height` 100%. Drawn as an absolute child that fills its parent.\n */\n cover?: boolean | undefined;\n /**\n * `position: absolute` with token offsets (a dialog's close button): out of the auto layout, pinned to the parent's\n * edges by these offsets (top, right, bottom, left).\n */\n pin?: { top?: SpecValue; right?: SpecValue; bottom?: SpecValue; left?: SpecValue } | undefined;\n /** `width: 100%` or `height: 100%` in a parent of that size: Fill container on that axis. */\n stretch?: { width?: boolean; height?: boolean } | undefined;\n /** A value indicator (a progress fill): this share of its parent's width, from the component's value. */\n fraction?: number | undefined;\n /**\n * A thumb placed at the component's value (a slider's): out of the auto layout, its center at this share of its\n * parent's width, centered on the parent's height.\n */\n at?: number | undefined;\n /** `flex: 1` in code: takes the free space along its parent's auto layout direction (Figma \"Fill container\"). */\n grow?: 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 /** Icon parts whose icon is written in code (a checkbox's check mark): an instance of this icon, with no property. */\n icon?: string | 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 /** Parts this variant does not show (`display: none`, `opacity: 0` or `scale(0)` in this state): hidden layers. */\n hidden?: string[] | undefined;\n /** Parts whose auto layout differs from the part's own in this variant (a switch thumb at the end when on). */\n layout?: Record<string, SpecLayout> | undefined;\n /** Vector parts: the SVG this variant draws and the stroke token of each shape, in order. */\n vectors?: Record<string, SpecVector> | undefined;\n /** Absolute parts placed differently in this variant (offsets from the parent's edges, like SpecPart.pin). */\n pins?: Record<string, NonNullable<SpecPart['pin']>> | undefined;\n}\n\n/** An inline SVG part: markup with literal geometry (strokes painted #000000) and the token bound to each shape's stroke. */\nexport interface SpecVector {\n svg: string;\n strokes: SpecValue[];\n}\n\n/**\n * A prototype trigger, Figma's names. ON_HOVER \"While hovering\" and ON_PRESS \"While pressing\" go back when the pointer\n * leaves or lets go; ON_CLICK \"On click\" stays. A set with a Checked axis uses MOUSE_ENTER / MOUSE_LEAVE for hover, so a\n * click that changes Checked is not undone when the pointer leaves.\n */\nexport type SpecTrigger = 'ON_HOVER' | 'ON_PRESS' | 'ON_CLICK' | 'MOUSE_ENTER' | 'MOUSE_LEAVE';\n\n/** Designer names of the triggers, as Figma's prototype panel shows them. */\nexport const TRIGGER_LABELS: Record<SpecTrigger, string> = {\n ON_HOVER: 'While hovering',\n ON_PRESS: 'While pressing',\n ON_CLICK: 'On click',\n MOUSE_ENTER: 'Mouse enter',\n MOUSE_LEAVE: 'Mouse leave',\n};\n\n/** An easing Figma can play: linear, or a cubic bezier with the exact points of the code's curve. */\nexport interface SpecEasing {\n type: 'LINEAR' | 'CUSTOM_CUBIC_BEZIER';\n /** CUSTOM_CUBIC_BEZIER: x1, y1, x2, y2. */\n bezier?: [number, number, number, number] | undefined;\n}\n\n/** The code's CSS transition for one change, resolved from the motion tokens. Played with Smart animate. */\nexport interface SpecTransition {\n /** Milliseconds. */\n duration: number;\n /** Token behind the duration (\"motion.duration.instant\"), when it is one. */\n durationToken?: string | undefined;\n easing: SpecEasing;\n /** Token behind the easing (\"motion.easing.standard\"), when it is one. */\n easingToken?: string | undefined;\n /** CSS properties the code animates in this change (\"background-color\"). */\n properties: string[];\n /** Why Figma plays it slightly differently from the code (one speed for parts that move at several), when it does. */\n approximated?: string | undefined;\n}\n\n/**\n * A prototype interaction between variants of the set, read from the CSS: on `trigger`, every variant whose `axis` is\n * `from` changes to the variant with `to` instead (other axes kept). `variants` narrows it to those variant keys\n * (variantKeyOf) when it does not apply to all of them. `transition` null: the code changes it instantly.\n */\nexport interface SpecInteraction {\n trigger: SpecTrigger;\n axis: string;\n from: string;\n to: string;\n variants?: string[] | undefined;\n transition: SpecTransition | null;\n}\n\n/** Motion the code has that a Figma prototype cannot play (a looping spinner, keyboard focus, a popup opening). */\nexport interface SpecMotionNote {\n /** What moves, in plain words (\"Looping animation spin, 700 ms\"). */\n what: string;\n /** Why Figma does not play it. */\n reason: string;\n /** A keyframe animation: the token behind its duration (\"motion.duration.spin\"), when it is one. */\n durationToken?: string | undefined;\n /** Opening and closing: the code's transition when it opens (enter) and when it closes (exit), when it has one. */\n enter?: SpecTransition | undefined;\n exit?: SpecTransition | 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 /** Component folder the set comes from, when it is not the set's name (Radio comes from RadioGroup). */\n component?: string | undefined;\n /** Props pinned for this set (`{ variant: 'circular' }` for Progress/Circular, a set per layer tree). */\n fixed?: Record<string, string> | undefined;\n /** A popup drawn open (`popup`), or the component without its popup (`without-popup`). */\n view?: 'popup' | 'without-popup' | undefined;\n /**\n * Drafted with Claude, not generated: the generator cannot read this component, so its spec was written by hand from\n * the code (packages/react/component-spec-overrides/<Name>.json, `\"source\": \"drafted\"`) and validated like a generated\n * one. Shown in the plugin as \"Drafted, check it\". `stale`: the code it was drafted from changed since.\n */\n drafted?: { reason: string; stale?: boolean | undefined } | undefined;\n /**\n * The code example the set's content comes from (the docs preview or a component sandbox example): the element, its\n * props and children, so the fidelity check renders the same thing. Not in the hash: it does not change the drawing.\n */\n example?: SpecExample | undefined;\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 /** Prototype interactions between the variants (hover, press, click to check), with the code's motion. */\n interactions?: SpecInteraction[] | undefined;\n /** Motion of the code a Figma prototype cannot play. */\n motion?: SpecMotionNote[] | undefined;\n}\n\n/** An element of a code example: component export name, literal props, children (texts or elements). */\nexport interface SpecExample {\n c: string;\n p?: Record<string, unknown> | undefined;\n children?: (string | SpecExample)[] | undefined;\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 * Every component of the design system and whether it is in Figma: generated (its sets are in `components`),\n * unsupported (with the generator's reason) or layout (no visual of its own: a layout helper, use auto layout).\n * Undefined in files written before coverage was recorded.\n */\n coverage?: SpecCoverage[] | undefined;\n}\n\nexport type CoverageStatus = 'generated' | 'drafted' | 'unsupported' | 'layout';\n\nexport interface SpecCoverage {\n /** Component folder name (\"RadioGroup\"). */\n name: string;\n status: CoverageStatus;\n /** Plain reason, for unsupported, drafted and layout components (\"opens a popup\", \"uses CSS grid\"). */\n reason?: string | undefined;\n /** Sets generated from it, when they are not just its own name (\"RadioGroup\", \"Radio\"). */\n sets?: string[] | undefined;\n}\n\n/**\n * Coverage counts from a specs file: visual components (generated, drafted with Claude, unsupported), in Figma\n * (generated + drafted), and layout helpers.\n */\nexport function coverageSummary(file: Pick<ComponentSpecsFile, 'coverage' | 'components'>): { generated: number; drafted: number; inFigma: number; visual: number; layout: number; total: number; missing: SpecCoverage[] } {\n const list = file.coverage ?? file.components.map((c) => ({ name: c.name, status: 'generated' as const }));\n const generated = list.filter((c) => c.status === 'generated').length;\n const drafted = list.filter((c) => c.status === 'drafted').length;\n const layout = list.filter((c) => c.status === 'layout').length;\n return { generated, drafted, inFigma: generated + drafted, visual: list.length - layout, layout, total: list.length, missing: list.filter((c) => c.status === 'unsupported') };\n}\n\nconst LAYOUT_DIRECTIONS = new Set(['HORIZONTAL', 'VERTICAL']);\nconst PRIMARY = new Set(['MIN', 'CENTER', 'MAX', 'SPACE_BETWEEN']);\nconst COUNTER = new Set(['MIN', 'CENTER', 'MAX', 'STRETCH']);\nconst PART_KINDS = new Set(['frame', 'text', 'icon', 'vector']);\n\n/**\n * Checks a component spec against the format (the schema every set follows, generated or drafted): axes and their\n * variants (one per combination, no extra), properties, parts (one root, known parents in order, text and visibility\n * properties that exist), each value's field and type, and, given `tokenTypes` (token path -> $type), that every token\n * path exists and has a type the field takes. Returns the problems in plain language, none when the spec is valid.\n */\nexport function validateComponentSpec(spec: Omit<ComponentSpec, 'hash'> & { hash?: string }, tokenTypes?: Map<string, string>): string[] {\n const out: string[] = [];\n const at = (where: string, why: string) => out.push(`${spec.name ?? 'spec'}: ${where}: ${why}`);\n if (typeof spec.name !== 'string' || !spec.name) return ['the spec has no name'];\n if (!Array.isArray(spec.axes) || !Array.isArray(spec.properties) || !Array.isArray(spec.parts) || !Array.isArray(spec.variants) || !Array.isArray(spec.unmapped)) return [`${spec.name}: axes, properties, parts, variants and unmapped must be lists`];\n const axisNames = new Set<string>();\n for (const a of spec.axes) {\n if (!a.name || axisNames.has(a.name)) at('axes', `\"${a.name}\" is missing or repeated`);\n axisNames.add(a.name);\n if (!Array.isArray(a.values) || !a.values.length) at(`axis ${a.name}`, 'has no values');\n else if (!a.values.includes(a.default)) at(`axis ${a.name}`, `default \"${a.default}\" is not one of its values`);\n }\n const props = new Map<string, SpecProperty>();\n for (const p of spec.properties) {\n if (props.has(p.name)) at('properties', `\"${p.name}\" is repeated`);\n props.set(p.name, p);\n if (p.type !== 'TEXT' && p.type !== 'BOOLEAN') at(`property ${p.name}`, `type ${String(p.type)} is not TEXT or BOOLEAN`);\n else if (typeof p.default !== (p.type === 'TEXT' ? 'string' : 'boolean')) at(`property ${p.name}`, `default must be a ${p.type === 'TEXT' ? 'text' : 'true or false'}`);\n }\n const parts = new Map<string, SpecPart>();\n for (const part of spec.parts) {\n if (!part.id || parts.has(part.id)) at('parts', `id \"${part.id}\" is missing or repeated`);\n if (!PART_KINDS.has(part.kind)) at(`part ${part.id}`, `kind ${String(part.kind)} is not frame, text, icon or vector`);\n if (part.parent === undefined) {\n if ([...parts.values()].some((x) => x.parent === undefined)) at(`part ${part.id}`, 'a second root (every other part needs a parent)');\n } else if (!parts.has(part.parent)) at(`part ${part.id}`, `parent \"${part.parent}\" is not a part listed before it`);\n else if (parts.get(part.parent)!.kind !== 'frame') at(`part ${part.id}`, `parent \"${part.parent}\" is not a frame`);\n if (part.layout && (!LAYOUT_DIRECTIONS.has(part.layout.direction) || !PRIMARY.has(part.layout.primary) || !COUNTER.has(part.layout.counter))) at(`part ${part.id}`, 'layout is not a valid auto layout');\n if (part.text !== undefined && props.get(part.text)?.type !== 'TEXT') at(`part ${part.id}`, `text property \"${part.text}\" does not exist`);\n if (part.visible !== undefined && props.get(part.visible)?.type !== 'BOOLEAN') at(`part ${part.id}`, `visibility property \"${part.visible}\" does not exist`);\n if (part.kind === 'text' && part.text === undefined && part.characters === undefined && !part.swap) at(`part ${part.id}`, 'a text part needs a TEXT property or its characters');\n parts.set(part.id, part);\n }\n if (!spec.parts.length || spec.parts[0]!.parent !== undefined) at('parts', 'the first part must be the root');\n const expected = spec.axes.reduce((n, a) => n * (a.values?.length || 1), 1);\n if (spec.variants.length !== expected) at('variants', `${spec.variants.length} variants for ${expected} combinations of the axes`);\n const seen = new Set<string>();\n for (const v of spec.variants) {\n const key = variantKeyOf(v.props ?? {});\n const where = `variant ${key}`;\n if (seen.has(key)) at(where, 'is repeated');\n seen.add(key);\n for (const a of spec.axes) if (!a.values?.includes(v.props?.[a.name] ?? '')) at(where, `${a.name} is not one of its values`);\n for (const k of Object.keys(v.props ?? {})) if (!axisNames.has(k)) at(where, `${k} is not an axis`);\n for (const [id, fields] of Object.entries(v.values ?? {})) {\n const part = parts.get(id);\n if (!part) {\n at(where, `values for \"${id}\", which is not a part`);\n continue;\n }\n for (const [field, value] of Object.entries(fields ?? {}) as [SpecField, SpecValue][]) {\n if (!SPEC_FIELDS.includes(field)) at(`${where}, ${id}`, `${field} is not a field`);\n else if (value === null) {\n if (!COLOR_FIELDS.has(field)) at(`${where}, ${id}`, `${field} cannot be empty (only colors can be none)`);\n } else if (typeof value === 'number') {\n if (COLOR_FIELDS.has(field)) at(`${where}, ${id}`, `${field} cannot be a number`);\n } else if (typeof value !== 'string') at(`${where}, ${id}`, `${field} must be a token path, a number or none`);\n else if (field === 'textDecoration') {\n if (!/^(UNDERLINE|STRIKETHROUGH|NONE)$/.test(value)) at(`${where}, ${id}`, `${value} is not a text decoration`);\n } else if (tokenTypes) {\n for (const path of value.startsWith('calc(') ? (value.match(/[A-Za-z][\\w.-]*/g) ?? []).filter((x) => x !== 'calc' && !/^\\d|^px$/.test(x)) : [value]) {\n const type = tokenTypes.get(path);\n if (!type) at(`${where}, ${id}`, `${path} is not a token`);\n else if (!value.startsWith('calc(') && !FIELD_TOKEN_TYPES(field).includes(type)) at(`${where}, ${id}`, `${path} is a ${type} token, ${field} needs ${FIELD_TOKEN_TYPES(field).join(' or ')}`);\n }\n }\n }\n }\n for (const id of v.hidden ?? []) if (!parts.has(id)) at(where, `hides \"${id}\", which is not a part`);\n for (const id of Object.keys(v.layout ?? {})) if (!parts.has(id)) at(where, `lays out \"${id}\", which is not a part`);\n for (const [id, vec] of Object.entries(v.vectors ?? {})) if (parts.get(id)?.kind !== 'vector' || !/^<svg[\\s>]/.test(vec.svg)) at(where, `vector \"${id}\" is not a vector part with an SVG`);\n for (const id of Object.keys(v.slots ?? {})) if (!parts.has(id)) at(where, `shows a component in \"${id}\", which is not a part`);\n }\n for (const [i, x] of (spec.interactions ?? []).entries()) {\n const where = `interaction ${i + 1}`;\n const axis = spec.axes.find((a) => a.name === x.axis);\n if (!(x.trigger in TRIGGER_LABELS)) at(where, `trigger ${String(x.trigger)} is not one Figma has`);\n if (!axis) at(where, `${x.axis} is not an axis`);\n else if (!axis.values.includes(x.from) || !axis.values.includes(x.to) || x.from === x.to) at(where, `${x.from} to ${x.to} are not two values of ${x.axis}`);\n for (const k of x.variants ?? []) if (!seen.has(k)) at(where, `variant ${k} does not exist`);\n const t = x.transition;\n if (t && (!(t.duration > 0) || (t.easing.type === 'CUSTOM_CUBIC_BEZIER' && (t.easing.bezier?.length !== 4 || t.easing.bezier.some((n) => typeof n !== 'number'))))) at(where, 'the transition needs a duration and a valid easing');\n }\n return out;\n}\n\n/** Token types a field takes (a color for fills, a dimension or number for sizes). */\nfunction FIELD_TOKEN_TYPES(field: SpecField): string[] {\n if (COLOR_FIELDS.has(field)) return ['color'];\n if (field === 'fontFamily') return ['fontFamily'];\n if (field === 'fontWeight') return ['fontWeight', 'number'];\n if (field === 'opacity') return ['number'];\n return ['dimension', 'number'];\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 (and without its code example, which does not change the drawing). */\nexport function hashSpec(spec: Omit<ComponentSpec, 'hash'> | ComponentSpec): string {\n const { hash: _ignored, example: _example, ...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/** What a set's description says about reduced motion: tokens set every duration to 0 under prefers-reduced-motion. */\nexport const REDUCED_MOTION_NOTE = 'In code, reduced motion turns this off.';\n\n/** One prototype reaction: on `trigger`, the variant `fromKey` changes to `toKey`, with the code's transition. */\nexport interface MotionReaction {\n trigger: SpecTrigger;\n /** Figma's name for the trigger (\"While hovering\"). */\n label: string;\n from: Record<string, string>;\n to: Record<string, string>;\n /** variantKeyOf(from) and variantKeyOf(to). */\n fromKey: string;\n toKey: string;\n transition: SpecTransition | null;\n}\n\n/** A component set's motion and interactions, read from its spec: for Figma prototypes, docs and reviews. */\nexport interface ComponentMotion {\n name: string;\n /** Every reaction between variants, one per variant it starts from. */\n reactions: MotionReaction[];\n /** The interactions as the spec lists them (one per trigger and change), with the number of variants each covers. */\n triggers: (SpecInteraction & { label: string; count: number })[];\n /** Motion tokens the transitions use (\"motion.duration.instant\", \"motion.easing.standard\"), sorted. */\n tokens: string[];\n /** CSS properties that animate (\"background-color\"), sorted. */\n properties: string[];\n /** Where Figma plays the motion differently from the code. */\n approximations: string[];\n /** Motion of the code a Figma prototype cannot play. */\n cannotPlay: SpecMotionNote[];\n /** Opening and closing (a popup, a panel): the code's enter and exit transitions, when it has them. */\n opening: { enter: SpecTransition | null; exit: SpecTransition | null } | undefined;\n /** REDUCED_MOTION_NOTE when the component animates in code, else undefined. */\n reducedMotion: string | undefined;\n}\n\n/**\n * The motion of a component set from its spec: every reaction between its variants (trigger, from and to variants, the\n * transition with duration and easing resolved from the motion tokens), the tokens and properties involved, what Figma\n * approximates or cannot play, and the reduced motion note. Pure: works in the plugin, the browser and Node.\n */\nexport function componentMotion(spec: Pick<ComponentSpec, 'name' | 'variants' | 'interactions' | 'motion'>): ComponentMotion {\n const keys = new Set(spec.variants.map((v) => variantKeyOf(v.props)));\n const reactions: MotionReaction[] = [];\n const triggers: ComponentMotion['triggers'] = [];\n for (const x of spec.interactions ?? []) {\n const only = x.variants ? new Set(x.variants) : undefined;\n let count = 0;\n for (const v of spec.variants) {\n if (v.props[x.axis] !== x.from) continue;\n const fromKey = variantKeyOf(v.props);\n if (only && !only.has(fromKey)) continue;\n const to = { ...v.props, [x.axis]: x.to };\n const toKey = variantKeyOf(to);\n if (!keys.has(toKey)) continue;\n reactions.push({ trigger: x.trigger, label: TRIGGER_LABELS[x.trigger], from: { ...v.props }, to, fromKey, toKey, transition: x.transition });\n count++;\n }\n triggers.push({ ...x, label: TRIGGER_LABELS[x.trigger], count });\n }\n const transitions = (spec.interactions ?? []).map((x) => x.transition).filter((t): t is SpecTransition => !!t);\n const cannotPlay = [...(spec.motion ?? [])];\n // Opening and closing is not a prototype interaction, but its transitions use motion tokens too (a dialog's enter).\n const openNote = cannotPlay.find((n) => n.enter || n.exit);\n const opening = openNote ? { enter: openNote.enter ?? null, exit: openNote.exit ?? null } : undefined;\n const openTransitions = opening ? [opening.enter, opening.exit].filter((t): t is SpecTransition => !!t) : [];\n const tokens = [\n ...new Set([...transitions, ...openTransitions].flatMap((t) => [t.durationToken, t.easingToken]).concat(cannotPlay.map((n) => n.durationToken)).filter((t): t is string => !!t)),\n ].sort();\n const properties = [...new Set(transitions.flatMap((t) => t.properties))].sort();\n const approximations = [...new Set(transitions.map((t) => t.approximated).filter((t): t is string => !!t))];\n const animates = transitions.length > 0 || openTransitions.length > 0 || cannotPlay.some((n) => /animation/i.test(n.what));\n return { name: spec.name, reactions, triggers, tokens, properties, approximations, cannotPlay, opening, reducedMotion: animates ? REDUCED_MOTION_NOTE : undefined };\n}\n\n/**\n * Sets whose interactions use a motion token, directly or through an alias: `chainOf(path)` gives the tokens a path\n * resolves through (resolve(...).chain), so a change to a primitive (\"duration.75\") finds the sets using\n * \"motion.duration.instant\". Without it, only direct uses count. Sorted set names.\n */\nexport function componentsUsingMotionToken(specs: Pick<ComponentSpecsFile, 'components'>, tokenPath: string, chainOf?: (path: string) => string[]): string[] {\n const out = new Set<string>();\n for (const c of specs.components) {\n for (const t of componentMotion(c).tokens) {\n if (t === tokenPath || (chainOf?.(t) ?? []).includes(tokenPath)) out.add(c.name);\n }\n }\n return [...out].sort();\n}\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\n/** How a component stands in Figma, in Studio's words (the \"In Figma\" column): a short word and, for the ones not in Figma, the reason as a tooltip. Undefined: no data. */\nexport function figmaCell(entry: SpecCoverage | undefined): { label: string; title?: string } | undefined {\n if (!entry) return undefined;\n if (entry.status === 'generated') return { label: 'Yes' };\n if (entry.status === 'drafted') return { label: 'Drafted', title: 'Drafted with Claude where the code cannot be read on its own: in Figma, check it against the code.' };\n if (entry.status === 'layout') return { label: 'Auto layout', title: 'A layout helper: nothing to draw, use auto layout in Figma.' };\n return { label: 'Not yet', ...(entry.reason ? { title: `Not supported yet: ${entry.reason}` } : {}) };\n}\n"],"names":["same","changesetBump"],"mappings":"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"}
|
package/dist/github-client.d.ts
CHANGED
|
@@ -508,6 +508,15 @@ export declare class GitHubClient {
|
|
|
508
508
|
}>;
|
|
509
509
|
/** GitHub's "Update branch": merges the base into the pull request, only when its head is still `expectedHeadSha`. */
|
|
510
510
|
updatePullRequestBranch(n: number, expectedHeadSha: string): Promise<void>;
|
|
511
|
+
/**
|
|
512
|
+
* Merges the branch `head` into the branch `base` (GitHub's merges API): a merge commit on `base`, or nothing when
|
|
513
|
+
* `base` already has every commit of `head`. A conflict throws a GitHubError with status 409. Refuses protected
|
|
514
|
+
* branches and, with a branch prefix, a `base` without it.
|
|
515
|
+
*/
|
|
516
|
+
mergeIntoBranch(base: string, head: string, message: string): Promise<{
|
|
517
|
+
status: 'merged' | 'up-to-date';
|
|
518
|
+
sha: string | null;
|
|
519
|
+
}>;
|
|
511
520
|
/** Posts a comment on an issue or pull request and returns its id and link. */
|
|
512
521
|
createIssueComment(n: number, body: string): Promise<{
|
|
513
522
|
id: number;
|
package/dist/index.d.ts
CHANGED