@bridge-ds/core 0.15.0 → 0.17.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/bridge.config.schema.json +5 -0
- package/dist/audit/index.js +3 -3
- package/dist/config.d.ts +5 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +412 -341
- package/dist/index.js.map +1 -1
- package/dist/node/index.js +3 -3
- package/dist/{prod-branch-BjXFIz74.js → prod-branch-DenQkr_e.js} +158 -143
- package/dist/prod-branch-DenQkr_e.js.map +1 -0
- package/dist/repo-model.d.ts +35 -1
- package/dist/{repo-source-CNZLq_xK.js → repo-source-B4jNZhyC.js} +676 -534
- package/dist/repo-source-B4jNZhyC.js.map +1 -0
- package/dist/{report-DCPfvvoq.js → report-DVEmUr0p.js} +2 -2
- package/dist/{report-DCPfvvoq.js.map → report-DVEmUr0p.js.map} +1 -1
- package/dist/review-gate.d.ts +17 -6
- package/dist/rights.d.ts +19 -0
- package/dist/snapshot.d.ts +5 -0
- package/dist/suggestions-github.d.ts +52 -4
- package/dist/suggestions.d.ts +25 -1
- package/dist/titles.d.ts +9 -0
- package/package.json +1 -1
- package/dist/prod-branch-BjXFIz74.js.map +0 -1
- package/dist/repo-source-CNZLq_xK.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"repo-source-CNZLq_xK.js","sources":["../src/changeset.ts","../src/token-edits.ts","../src/layered-review.ts","../src/governance.ts","../src/github-client.ts","../src/history.ts","../src/docs-draft.ts","../src/change-drafts.ts","../src/explorations.ts","../src/requests.ts","../src/requests-github.ts","../src/component-spec.ts","../src/review-gate.ts","../src/jira.ts","../src/suggestion-review.ts","../src/figma-push.ts","../src/suggestions.ts","../src/suggestions-github.ts","../src/docs-proposal.ts","../src/suggestion-apply.ts","../src/repo-source.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","// Minimal GitHub REST client over fetch. The token is passed in; nothing is read from the\n// environment. Talks to api.github.com (the Figma plugin manifest allows nothing else) and, for\n// token-less reads of public repos, raw.githubusercontent.com, which has no hourly API limit.\n// Bulk reads go through the git trees and blobs endpoints; single files can use the contents API.\n//\n// Writes refuse protected branches (main, master and whatever the caller adds) whatever the caller\n// asks: the client is the last guard between an agent and the default branch.\n\nimport { type BridgeConfig, CONFIG_FILE, ConfigError, DEFAULT_TOKEN_PATHS, loadConfig } from './config';\nimport { assertSafeBranch, DEFAULT_PROTECTED_BRANCHES, ProtectedBranchError } from './governance';\nimport type { ClassicProtection, Ruleset, RulesetPayload } from './protection';\n\n/**\n * What an auth failure means for the token:\n * - \"rejected\": GitHub refused the token itself (401). It was revoked, regenerated or has expired; every call\n * with it will fail until it is replaced.\n * - \"missing-permission\": the token works but lacks a permission this call needs (403 \"Resource not accessible\n * by personal access token\", or a permission GitHub names in X-Accepted-GitHub-Permissions).\n * Undefined for everything else, including rate limits and a missing token.\n */\nexport type GitHubAuthState = 'rejected' | 'missing-permission';\n\n/** Fine-grained token permission names, as GitHub spells them (issues, pull_requests, contents...). */\nexport type GitHubPermission = string;\n\nexport interface GitHubErrorInfo {\n auth?: GitHubAuthState | undefined;\n /** The permission the call needed, when GitHub or the endpoint tells (only with auth \"missing-permission\"). */\n permission?: GitHubPermission | undefined;\n}\n\nexport class GitHubError extends Error {\n /** Set when the failure is about the token: rejected (401) or missing a permission (403). */\n readonly auth: GitHubAuthState | undefined;\n /** With auth \"missing-permission\": the permission the call needed, when known. */\n readonly permission: GitHubPermission | undefined;\n\n constructor(\n readonly status: number,\n message: string,\n readonly detail?: string,\n info: GitHubErrorInfo = {},\n ) {\n super(message);\n this.name = 'GitHubError';\n this.auth = info.auth;\n this.permission = info.permission;\n }\n}\n\n/** True when `err` says GitHub refused the token itself (revoked, regenerated or expired). */\nexport const isTokenRejected = (err: unknown): boolean => err instanceof GitHubError && err.auth === 'rejected';\n\n/** True when `err` says the token works but lacks a permission for that call. */\nexport const isMissingPermission = (err: unknown): boolean => err instanceof GitHubError && err.auth === 'missing-permission';\n\nconst PERMISSION_LABELS: Record<string, string> = {\n issues: 'Issues',\n pull_requests: 'Pull requests',\n contents: 'Contents',\n checks: 'Checks',\n statuses: 'Commit statuses',\n metadata: 'Metadata',\n actions: 'Actions',\n deployments: 'Deployments',\n workflows: 'Workflows',\n administration: 'Administration',\n};\n\n/** \"pull_requests\" -> \"Pull requests\", as GitHub labels it on the token page. */\nexport function permissionLabel(permission: GitHubPermission): string {\n return PERMISSION_LABELS[permission] ?? permission.replace(/_/g, ' ').replace(/^./, (c) => c.toUpperCase());\n}\n\n/** Where a fine-grained token's permissions are edited. */\nexport const TOKEN_SETTINGS_URL = 'https://github.com/settings/personal-access-tokens';\n\n/** The one sentence for a token GitHub no longer accepts. */\nexport const TOKEN_REJECTED_MESSAGE = 'Your GitHub token stopped working. It was revoked, regenerated or has expired: replace it with a new one.';\n\n/**\n * \"This token cannot create issues. Add Issues: Read and write on GitHub.\" `action` is a verb phrase\n * (\"create issues\"); without it the sentence names only the permission.\n */\nexport function missingPermissionMessage(permission: GitHubPermission | undefined, action?: string): string {\n const what = action ? `This token cannot ${action}.` : 'This token is missing a permission for this.';\n if (!permission) return `${what} Check its repository permissions on GitHub (Contents and Pull requests need Read and write).`;\n return `${what} Add ${permissionLabel(permission)}: Read and write on GitHub.`;\n}\n\n/**\n * The permission a refused call needed. GitHub names it in X-Accepted-GitHub-Permissions (\"issues=write\",\n * alternatives split by \";\"); otherwise the endpoint says it (/issues, /pulls, /contents, /git...).\n */\nexport function requiredPermission(path: string, acceptedHeader?: string | null): GitHubPermission | undefined {\n if (acceptedHeader) {\n const first = acceptedHeader.split(';')[0]!.split(',').map((p) => p.trim().split('=')[0]!.trim()).filter((p) => p && p !== 'metadata');\n if (first.length) return first[0];\n }\n const p = path.replace(/[?#].*$/, '');\n if (/\\/repos\\/[^/]+\\/[^/]+\\/(issues|labels|milestones)(\\/|$)/.test(p)) return 'issues';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/pulls(\\/|$)/.test(p)) return 'pull_requests';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/(rulesets(\\/|$)|branches\\/.+\\/protection$)/.test(p)) return 'administration';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/(contents|git|commits|branches|merges)(\\/|$)/.test(p)) return 'contents';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/(check-runs|check-suites)(\\/|$)/.test(p)) return 'checks';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/statuses(\\/|$)/.test(p)) return 'statuses';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/deployments(\\/|$)/.test(p)) return 'deployments';\n if (/\\/repos\\/[^/]+\\/[^/]+\\/actions(\\/|$)/.test(p)) return 'actions';\n return undefined;\n}\n\nconst PERMISSION_DENIED = /not accessible by (personal access token|integration)|must have (admin|push|write) (rights|access)|write access to repository not granted|permission to .* denied/i;\n\n/**\n * Classifies a GitHub error response for the token. 401 with a token sent = rejected. 403 (not a rate limit,\n * not archived) where GitHub names a permission or says the resource is not accessible = missing permission.\n */\nexport function classifyAuth(\n status: number,\n detail: string,\n opts: { path?: string; acceptedPermissions?: string | null; withToken?: boolean } = {},\n): GitHubErrorInfo {\n if (status === 401 && opts.withToken !== false) return { auth: 'rejected' };\n if (status !== 403 || /rate limit|archived/i.test(detail)) return {};\n if (opts.acceptedPermissions || PERMISSION_DENIED.test(detail)) {\n return { auth: 'missing-permission', permission: requiredPermission(opts.path ?? '', opts.acceptedPermissions) };\n }\n return {};\n}\n\nexport interface RepoInfo {\n fullName: string;\n defaultBranch: string;\n private: boolean;\n permissions: { admin?: boolean; maintain?: boolean; push?: boolean; triage?: boolean; pull?: boolean } | undefined;\n}\n\nexport interface TreeEntry {\n path: string;\n type: 'blob' | 'tree' | 'commit';\n sha: string;\n mode: string;\n /** Bytes, for blobs (GitHub sends it in tree listings). */\n size?: number | undefined;\n}\n\nexport interface CompareResult {\n status: string;\n aheadBy: number;\n behindBy: number;\n files: { filename: string; status: string }[];\n}\n\nexport interface PullRequest {\n number: number;\n url: string;\n title: string;\n draft: boolean;\n headRef: string;\n}\n\nexport interface Review {\n id: number;\n user: string | undefined;\n state: string;\n body: string;\n submittedAt?: string | undefined;\n}\n\nexport interface PullRequestSummary {\n number: number;\n title: string;\n /** \"open\", \"closed\" or \"merged\". */\n state: string;\n draft: boolean;\n author: string;\n headRef: string;\n headSha: string;\n baseRef: string;\n labels: string[];\n url: string;\n updatedAt: string;\n /** Description, when the list endpoint returns it (component change requests read \"Closes #n\" from it). */\n body?: string | undefined;\n}\n\nexport interface ClientOptions {\n /** API base, for GitHub Enterprise or tests. */\n apiUrl?: string;\n /** Raw file host used for token-less reads. */\n rawUrl?: string;\n /** Branches no write may target. Default main and master; the repo's default branch belongs here too. */\n protectedBranches?: string[];\n /** When set, branches this client creates must start with it (agents use \"bridge/\"). */\n branchPrefix?: string;\n /**\n * How a person adds a token where this client runs, for the rate-limit message without one (\"set GITHUB_TOKEN in\n * the MCP server config\"). Default: \"add a GitHub token\".\n */\n tokenHint?: string;\n /**\n * Where conditional GET responses are kept (ETag + body). Default: one in-memory store shared by every client in\n * this process or page, keyed by the token's fingerprint, so two accounts never share an entry. `false` turns\n * conditional requests off. A 304 answer does not count against GitHub's primary rate limit.\n */\n etags?: EtagStore | false;\n /**\n * Who the cached responses belong to, when a stable name is known (the signed-in login). Default: a fingerprint of\n * the token, which changes when the token is refreshed.\n */\n etagScope?: string;\n /**\n * When GitHub's hourly limit is used up and a cached response exists for that request, return it instead of\n * throwing. Off by default: the caller then knows the data may be stale only from `rateLimit`.\n */\n serveStaleOnRateLimit?: boolean;\n}\n\n/** One cached conditional response: what GitHub sent with this ETag. */\nexport interface EtagEntry {\n etag: string;\n body: unknown;\n /** When it was stored or last confirmed by a 304 (ms since epoch). */\n at: number;\n}\n\n/** Storage for conditional requests. Keys never contain the token. */\nexport interface EtagStore {\n get(key: string): EtagEntry | undefined;\n set(key: string, entry: EtagEntry): void;\n /** Forgets every entry (sign-out). */\n clear(): void;\n}\n\n/** An in-memory ETag store that keeps the `max` most recently used entries. */\nexport function memoryEtagStore(max = 500): EtagStore {\n const map = new Map<string, EtagEntry>();\n return {\n get(key) {\n const e = map.get(key);\n if (e) {\n map.delete(key);\n map.set(key, e);\n }\n return e;\n },\n set(key, entry) {\n map.delete(key);\n map.set(key, entry);\n while (map.size > max) map.delete(map.keys().next().value!);\n },\n clear: () => map.clear(),\n };\n}\n\n/** The subset of the Web Storage API (localStorage, sessionStorage) an ETag store needs. */\nexport interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n key(index: number): string | null;\n readonly length: number;\n}\n\n/**\n * An ETag store over Web Storage, so conditional requests survive a page load. Every access is guarded: private\n * windows, quota errors and blocked storage turn into cache misses, never into failures. Entries live under\n * `prefix` (default \"bridge.gh.etag:\"); `clear()` removes only those. Bodies of private repositories land here\n * too, so a sign-out must call `clear()`.\n */\nexport function webStorageEtagStore(storage: StorageLike, opts: { prefix?: string; maxEntryBytes?: number } = {}): EtagStore {\n const prefix = opts.prefix ?? 'bridge.gh.etag:';\n const maxBytes = opts.maxEntryBytes ?? 512_000;\n return {\n get(key) {\n try {\n const raw = storage.getItem(prefix + key);\n if (!raw) return undefined;\n const e = JSON.parse(raw) as EtagEntry;\n return typeof e?.etag === 'string' ? e : undefined;\n } catch {\n return undefined;\n }\n },\n set(key, entry) {\n try {\n const raw = JSON.stringify(entry);\n if (raw.length > maxBytes) return;\n storage.setItem(prefix + key, raw);\n } catch {\n // Quota or blocked storage: the next request is simply unconditional.\n }\n },\n clear() {\n try {\n const keys: string[] = [];\n for (let i = 0; i < storage.length; i++) {\n const k = storage.key(i);\n if (k?.startsWith(prefix)) keys.push(k);\n }\n for (const k of keys) storage.removeItem(k);\n } catch {\n // Nothing to clear when storage is unavailable.\n }\n },\n };\n}\n\nconst sharedEtags = memoryEtagStore();\n\n/** Clears the default in-memory ETag store every client shares (sign-out, account switch). */\nexport function clearSharedEtags(): void {\n sharedEtags.clear();\n}\n\n/** A short, non-reversible name for a token, used in cache keys instead of the token itself (two FNV-1a passes). */\nexport function tokenFingerprint(token: string): string {\n if (!token) return 'anon';\n let a = 0x811c9dc5;\n let b = 0x01000193 ^ token.length;\n for (let i = 0; i < token.length; i++) {\n const c = token.charCodeAt(i);\n a = Math.imul(a ^ c, 0x01000193) >>> 0;\n b = Math.imul(b ^ c ^ (i & 0xff), 0x5bd1e995) >>> 0;\n }\n return a.toString(16).padStart(8, '0') + b.toString(16).padStart(8, '0');\n}\n\n/** GitHub's rate-limit headers from the last API response. */\nexport interface RateLimitInfo {\n limit: number | undefined;\n remaining: number | undefined;\n resetsAt: Date | undefined;\n /** \"core\", \"search\", \"graphql\"... */\n resource: string | undefined;\n}\n\n/** What the conditional request cache did, for tests and diagnostics. */\nexport interface EtagStats {\n /** Requests sent with If-None-Match. */\n conditional: number;\n /** 304 answers served from the cache (free for the primary rate limit). */\n notModified: number;\n /** Cached bodies returned because the hourly limit was used up (serveStaleOnRateLimit). */\n stale: number;\n}\n\n/** An installation of a GitHub App the signed-in user can reach (GET /user/installations). */\nexport interface Installation {\n id: number;\n account: { login: string; type: string } | null;\n /** \"all\" repositories of the account, or \"selected\" ones. */\n repositorySelection: 'all' | 'selected' | string;\n appSlug: string | undefined;\n}\n\n/** One repository of an installation (GET /user/installations/{id}/repositories). */\nexport interface InstallationRepo {\n owner: string;\n name: string;\n fullName: string;\n private: boolean;\n}\n\n/** One installation of the GitHub App, as GET /user/installations lists it (raw or mapped). */\nexport interface InstallationLike {\n id: number;\n account?: { login?: string } | null;\n repository_selection?: 'all' | 'selected' | string;\n repositorySelection?: 'all' | 'selected' | string;\n}\n\n/**\n * Whether the signed-in account reaches a repository of `owner` through the app: 'yes' when an installation on the\n * owner covers all its repositories, 'check' (with its id) when it covers selected ones (list them to know), 'no'\n * when there is none. Same contract as the site's `installationFor` (lib/github-signin.ts).\n */\nexport function installationFor(list: InstallationLike[], owner: string): { reach: 'yes'; id: number } | { reach: 'check'; id: number } | { reach: 'no' } {\n const inst = list.find((i) => i.account?.login?.toLowerCase() === owner.toLowerCase());\n if (!inst) return { reach: 'no' };\n const selection = inst.repositorySelection ?? inst.repository_selection;\n return selection === 'all' ? { reach: 'yes', id: inst.id } : { reach: 'check', id: inst.id };\n}\n\n/** Pages read at most by the paged listings (100 items each). */\nconst MAX_PAGES = 10;\n\n/**\n * The sentence for GitHub's exhausted hourly limit. With a token, the token's own limit is used up: wait. Without one,\n * the shared limit for anonymous reads is (60 an hour per address): say how to get a higher one.\n */\nexport function rateLimitMessage(x: { withToken: boolean; resetsAt?: Date; tokenHint?: string }): string {\n const when = x.resetsAt ? ` It resets at ${x.resetsAt.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}.` : '';\n if (x.withToken) return `GitHub's hourly request limit for this token is used up.${when} Try again after that.`;\n const hint = x.tokenHint ?? 'add a GitHub token';\n return `GitHub's hourly limit for requests without a token (60 an hour) is used up.${when} To keep going now, ${hint}: a token gets 5,000 requests an hour.`;\n}\n\n/** A file in a new commit: text content, or null to delete it. */\nexport interface CommitFile {\n path: string;\n content: string | null;\n}\n\nexport interface CheckRun {\n id: number;\n name: string;\n status: string;\n conclusion: string | null;\n url: string | undefined;\n /** Slug of the GitHub App that reported it (\"github-actions\", \"vercel\"), when GitHub says. */\n app?: string | undefined;\n}\n\nexport interface CommitSummary {\n sha: string;\n parents: string[];\n /** ISO date the commit landed (committer date). */\n date: string;\n /** GitHub login when known, else the git author name. */\n author: string;\n message: string;\n}\n\nexport interface PullRequestFile {\n filename: string;\n status: string;\n additions: number;\n deletions: number;\n}\n\nexport type FetchLike = (url: string, init?: { method?: string; headers?: Record<string, string>; body?: string }) => Promise<{\n ok: boolean;\n status: number;\n headers?: { get(name: string): string | null };\n json(): Promise<unknown>;\n text(): Promise<string>;\n}>;\n\nexport interface RetryPolicy {\n /** Attempts for idempotent calls (GET, and content-addressed blob/tree/commit creation). */\n attempts: number;\n /** First backoff in ms; doubles each retry. */\n baseDelayMs: number;\n sleep: (ms: number) => Promise<void>;\n}\n\nconst DEFAULT_RETRY: RetryPolicy = { attempts: 3, baseDelayMs: 600, sleep: (ms) => new Promise((r) => setTimeout(r, ms)) };\n\n/** Transient failures worth retrying: network errors, 5xx, and secondary rate limits. */\n/** Errors for an exhausted hourly limit: waiting seconds will not help, so they are never retried. */\nconst hourlyLimitErrors = new WeakSet<GitHubError>();\n\nconst isTransient = (status: number, detail: string) => status === 0 || status >= 500 || status === 429 || (status === 403 && /secondary rate limit/i.test(detail));\n\nconst API = 'https://api.github.com';\nconst ACCEPT_JSON = 'application/vnd.github+json';\n/** Contents and blobs APIs: the file's bytes as the body, no base64 and no 1 MB JSON limit. */\nconst ACCEPT_RAW = 'application/vnd.github.raw';\n\ninterface RequestOptions {\n /** Accept header (default the JSON media type). */\n accept?: string;\n /** Read the body as text instead of JSON. */\n text?: boolean;\n /** False: never conditional and never cached (immutable resources the caller caches by sha). */\n etag?: boolean;\n}\nconst RAW = 'https://raw.githubusercontent.com';\n\n/** \"owner/name\", a github.com URL or an SSH remote. */\nexport function parseRepo(repo: string): { owner: string; name: string } {\n const m = /^\\s*(?:https?:\\/\\/github\\.com\\/|git@github\\.com:)?([A-Za-z0-9-]+)\\/([A-Za-z0-9._-]+?)(?:\\.git)?\\/?\\s*$/.exec(repo);\n if (!m) throw new Error(`\"${repo}\" is not a repository. Use the form owner/name.`);\n return { owner: m[1]!, name: m[2]! };\n}\n\nexport function utf8ToBase64(text: string): string {\n const bytes = new TextEncoder().encode(text);\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n return btoa(bin);\n}\n\nexport function base64ToUtf8(b64: string): string {\n const bin = atob(b64.replace(/\\s/g, ''));\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return new TextDecoder('utf-8').decode(bytes);\n}\n\n/** A deep copy, so a caller that edits a response never edits the cached one. */\nconst copy = <T>(value: T): T => (value === null || typeof value !== 'object' ? value : typeof structuredClone === 'function' ? structuredClone(value) : (JSON.parse(JSON.stringify(value)) as T));\n\nconst encodeRef = (ref: string) => ref.split('/').map(encodeURIComponent).join('/');\n\nexport class GitHubClient {\n readonly owner: string;\n readonly name: string;\n private readonly blobCache = new Map<string, string>();\n private readonly api: string;\n private readonly protectedBranches: string[];\n private readonly etags: EtagStore | undefined;\n private readonly etagScope: string;\n private rate: RateLimitInfo | undefined;\n /** What the conditional request cache did for this client. */\n readonly etagStats: EtagStats = { conditional: 0, notModified: 0, stale: 0 };\n\n constructor(\n repo: string,\n private readonly token: string,\n private readonly fetchImpl: FetchLike = (url, init) => fetch(url, init),\n private readonly retry: RetryPolicy = DEFAULT_RETRY,\n private readonly options: ClientOptions = {},\n ) {\n const r = parseRepo(repo);\n this.owner = r.owner;\n this.name = r.name;\n this.api = (options.apiUrl ?? API).replace(/\\/$/, '');\n this.protectedBranches = options.protectedBranches ?? DEFAULT_PROTECTED_BRANCHES;\n this.etags = options.etags === false ? undefined : (options.etags ?? sharedEtags);\n this.etagScope = options.etagScope ?? tokenFingerprint(token);\n }\n\n /** GitHub's rate-limit headers from the last API response, or undefined before any response carried them. */\n get rateLimit(): RateLimitInfo | undefined {\n return this.rate;\n }\n\n /** \"owner/name\". */\n get fullName() {\n return `${this.owner}/${this.name}`;\n }\n\n /** Whether a token was given (without one, every write is refused before any request). */\n get canWrite() {\n return Boolean(this.token);\n }\n\n /** Throws unless `branch` may be written: not protected, not the base, and with the agent prefix when set. */\n assertWritableBranch(branch: string, base?: string): void {\n try {\n assertSafeBranch(branch, { protectedBranches: this.protectedBranches, base, branchPrefix: this.options.branchPrefix });\n } catch (err) {\n if (err instanceof ProtectedBranchError) throw new GitHubError(403, err.message, 'protected-branch');\n throw err;\n }\n }\n\n private assertToken(what: string): void {\n if (!this.token) throw new GitHubError(401, `${what} needs a GitHub token (contents and pull requests, read and write, on this repository only). Without one Bridge is read-only.`, 'no-token');\n }\n\n private get repoPath() {\n return `/repos/${this.owner}/${this.name}`;\n }\n\n private async request<T>(method: string, path: string, body?: unknown, retryable = method === 'GET', opts: RequestOptions = {}): Promise<T> {\n const attempts = retryable ? Math.max(1, this.retry.attempts) : 1;\n for (let attempt = 1; ; attempt++) {\n try {\n return await this.once<T>(method, path, body, opts);\n } catch (err) {\n const e = err as GitHubError;\n if (attempt >= attempts || !(e instanceof GitHubError) || hourlyLimitErrors.has(e) || !isTransient(e.status, e.detail ?? '')) throw err;\n await this.retry.sleep(this.retry.baseDelayMs * 2 ** (attempt - 1));\n }\n }\n }\n\n private noteRateLimit(headers: { get(name: string): string | null } | undefined): void {\n const remaining = headers?.get('x-ratelimit-remaining');\n if (remaining == null) return;\n const limit = headers?.get('x-ratelimit-limit');\n const reset = headers?.get('x-ratelimit-reset');\n this.rate = {\n limit: limit != null ? Number(limit) : undefined,\n remaining: Number(remaining),\n resetsAt: reset ? new Date(Number(reset) * 1000) : undefined,\n resource: headers?.get('x-ratelimit-resource') ?? undefined,\n };\n }\n\n private async once<T>(method: string, path: string, body?: unknown, opts: RequestOptions = {}): Promise<T> {\n const accept = opts.accept ?? ACCEPT_JSON;\n const headers: Record<string, string> = {\n Accept: accept,\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n if (this.token) headers.Authorization = `Bearer ${this.token}`;\n if (body !== undefined) headers['Content-Type'] = 'application/json';\n // Conditional GET: the key names the account (fingerprint or scope), the media type and the URL, never the token.\n // If-None-Match is sent only with a token: GitHub does not count a 304 against the primary limit only when the\n // request is authorized. Anonymous responses are still kept, for serveStaleOnRateLimit.\n const key = method === 'GET' && this.etags && opts.etag !== false ? `${this.etagScope} ${accept} ${this.api}${path}` : undefined;\n const cached = key ? this.etags!.get(key) : undefined;\n if (cached && this.token) {\n headers['If-None-Match'] = cached.etag;\n this.etagStats.conditional++;\n }\n let res: Awaited<ReturnType<FetchLike>>;\n try {\n res = await this.fetchImpl(`${this.api}${path}`, { method, headers, ...(body !== undefined ? { body: JSON.stringify(body) } : {}) });\n } catch (err) {\n // A fetch that answers for GitHub with its own GitHubError (the Studio waiting for an app's OK) keeps it.\n if (err instanceof GitHubError) throw err;\n throw new GitHubError(0, 'Could not reach GitHub. Check your connection, then try again.', (err as Error).message);\n }\n this.noteRateLimit(res.headers);\n if (res.status === 304 && cached && key && this.token) {\n this.etagStats.notModified++;\n this.etags!.set(key, { ...cached, at: Date.now() });\n return copy(cached.body) as T;\n }\n if (res.status === 204) return undefined as T;\n if (!res.ok) {\n let detail = '';\n try {\n const data = (await res.json()) as { message?: string; errors?: ({ message?: string } | string)[] };\n detail = [data.message, ...(data.errors ?? []).map((e) => (typeof e === 'string' ? e : e.message))].filter(Boolean).join(' ');\n } catch {\n detail = '';\n }\n const remaining = res.headers?.get('x-ratelimit-remaining');\n const reset = res.headers?.get('x-ratelimit-reset');\n if ((res.status === 403 || res.status === 429) && remaining === '0') {\n if (cached && this.options.serveStaleOnRateLimit) {\n this.etagStats.stale++;\n return copy(cached.body) as T;\n }\n const resetsAt = reset ? new Date(Number(reset) * 1000) : undefined;\n const limited = new GitHubError(429, rateLimitMessage({ withToken: Boolean(this.token), resetsAt, tokenHint: this.options.tokenHint }), detail);\n hourlyLimitErrors.add(limited);\n throw limited;\n }\n const info = classifyAuth(res.status, detail, {\n path,\n acceptedPermissions: res.headers?.get('x-accepted-github-permissions'),\n withToken: Boolean(this.token),\n });\n throw new GitHubError(res.status, friendlyMessage(res.status, detail, info), detail, info);\n }\n const data = opts.text ? await res.text() : await res.json();\n const etag = key ? res.headers?.get('etag') : null;\n if (key && etag) this.etags!.set(key, { etag, body: copy(data), at: Date.now() });\n return data as T;\n }\n\n /**\n * Every item of a paged listing (`per_page=100`), at most 10 pages. `pick` takes the items out of one page (the\n * installation endpoints wrap them in an object with `total_count`).\n */\n private async paged<R, I>(path: string, pick: (page: R) => { items: I[]; total?: number | undefined }): Promise<I[]> {\n const out: I[] = [];\n const sep = path.includes('?') ? '&' : '?';\n for (let page = 1; page <= MAX_PAGES; page++) {\n const { items, total } = pick(await this.request<R>('GET', `${path}${sep}per_page=100&page=${page}`));\n out.push(...items);\n if (items.length < 100 || (total !== undefined && out.length >= total)) break;\n }\n return out;\n }\n\n async getRepo(): Promise<RepoInfo> {\n const r = await this.request<{ full_name: string; default_branch: string; private: boolean; permissions?: RepoInfo['permissions'] }>(\n 'GET',\n this.repoPath,\n );\n return { fullName: r.full_name, defaultBranch: r.default_branch, private: r.private, permissions: r.permissions };\n }\n\n /** Commit sha a branch points to, or undefined when the branch does not exist. */\n async getBranchSha(branch: string): Promise<string | undefined> {\n try {\n const r = await this.request<{ object: { sha: string } }>('GET', `${this.repoPath}/git/ref/heads/${encodeRef(branch)}`);\n return r.object.sha;\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return undefined;\n throw err;\n }\n }\n\n async getCommitTree(commitSha: string): Promise<string> {\n const r = await this.request<{ tree: { sha: string } }>('GET', `${this.repoPath}/git/commits/${commitSha}`);\n return r.tree.sha;\n }\n\n async getTree(treeSha: string, recursive = true): Promise<{ entries: TreeEntry[]; truncated: boolean }> {\n const r = await this.request<{ tree: TreeEntry[]; truncated: boolean }>(\n 'GET',\n `${this.repoPath}/git/trees/${treeSha}${recursive ? '?recursive=1' : ''}`,\n );\n return { entries: r.tree, truncated: r.truncated };\n }\n\n async getBlobText(sha: string): Promise<string> {\n const cached = this.blobCache.get(sha);\n if (cached !== undefined) return cached;\n const r = await this.request<{ content: string; encoding: string }>('GET', `${this.repoPath}/git/blobs/${sha}`);\n const text = r.encoding === 'base64' ? base64ToUtf8(r.content) : r.content;\n this.blobCache.set(sha, text);\n return text;\n }\n\n async compare(base: string, head: string): Promise<CompareResult> {\n const r = await this.request<{ status: string; ahead_by: number; behind_by: number; files?: { filename: string; status: string }[] }>(\n 'GET',\n `${this.repoPath}/compare/${base}...${head}`,\n );\n return { status: r.status, aheadBy: r.ahead_by, behindBy: r.behind_by, files: (r.files ?? []).map((f) => ({ filename: f.filename, status: f.status })) };\n }\n\n // --- History (read only) ----------------------------------------------------------------------\n\n /** Commits on a ref, newest first, optionally only those touching `path` (a file or directory). */\n async listCommits(opts: { sha?: string; path?: string; perPage?: number; page?: number } = {}): Promise<CommitSummary[]> {\n const q = new URLSearchParams();\n if (opts.sha) q.set('sha', opts.sha);\n if (opts.path) q.set('path', opts.path);\n q.set('per_page', String(Math.min(100, opts.perPage ?? 30)));\n if (opts.page) q.set('page', String(opts.page));\n const r = await this.request<Record<string, any>[]>('GET', `${this.repoPath}/commits?${q}`);\n return r.map(toCommitSummary);\n }\n\n /** One commit: message, author, date and parents. */\n async getCommitInfo(sha: string): Promise<CommitSummary> {\n return toCommitSummary(await this.request<Record<string, any>>('GET', `${this.repoPath}/commits/${encodeRef(sha)}`));\n }\n\n /** Pull requests a commit belongs to (merged ones first): how a commit on main finds its PR. */\n async listPullRequestsForCommit(sha: string): Promise<(PullRequestSummary & { body: string; mergedAt?: string; mergeCommitSha?: string })[]> {\n const r = await this.request<Record<string, any>[]>('GET', `${this.repoPath}/commits/${encodeRef(sha)}/pulls`);\n return r\n .map((p) => ({ ...toSummary(p), body: p.body ?? '', ...(p.merged_at ? { mergedAt: p.merged_at as string } : {}), ...(p.merge_commit_sha ? { mergeCommitSha: p.merge_commit_sha as string } : {}) }))\n .sort((a, b) => Number(Boolean(b.mergedAt)) - Number(Boolean(a.mergedAt)));\n }\n\n /** Tags with the commit they point to, newest first as GitHub lists them. */\n async listTags(perPage = 30): Promise<{ name: string; sha: string }[]> {\n const r = await this.request<{ name: string; commit: { sha: string } }[]>('GET', `${this.repoPath}/tags?per_page=${Math.min(100, perPage)}`);\n return r.map((t) => ({ name: t.name, sha: t.commit.sha }));\n }\n\n async createBlob(content: string): Promise<string> {\n // Blobs, trees and commits are content-addressed: retrying a create is harmless.\n const r = await this.request<{ sha: string }>('POST', `${this.repoPath}/git/blobs`, { content, encoding: 'utf-8' }, true);\n return r.sha;\n }\n\n /** A tree on top of `baseTree`. Each file gives a blob `sha`, inline `content`, or `sha: null` to delete. */\n async createTree(baseTree: string, files: ({ path: string; sha: string | null } | { path: string; content: string })[]): Promise<string> {\n const r = await this.request<{ sha: string }>('POST', `${this.repoPath}/git/trees`, {\n base_tree: baseTree,\n tree: files.map((f) => ({ path: f.path, mode: '100644', type: 'blob', ...('content' in f ? { content: f.content } : { sha: f.sha }) })),\n }, true);\n return r.sha;\n }\n\n async createCommit(message: string, tree: string, parents: string[]): Promise<string> {\n const r = await this.request<{ sha: string }>('POST', `${this.repoPath}/git/commits`, { message, tree, parents }, true);\n return r.sha;\n }\n\n /** Create a new branch. Refuses protected branches; GitHub refuses existing ones, so nothing is overwritten. */\n async createBranch(branch: string, sha: string): Promise<void> {\n this.assertWritableBranch(branch);\n await this.request('POST', `${this.repoPath}/git/refs`, { ref: `refs/heads/${branch}`, sha });\n }\n\n /** Fast-forward a branch. Never forces: a concurrent push makes this fail instead of losing work. */\n async updateBranch(branch: string, sha: string): Promise<void> {\n this.assertWritableBranch(branch);\n await this.request('PATCH', `${this.repoPath}/git/refs/heads/${encodeRef(branch)}`, { sha, force: false });\n }\n\n /**\n * One commit with `files` on top of `base`, on the new branch `branch`. The branch is created, never\n * moved, so an existing branch is never overwritten. Refuses protected branches and the base itself.\n */\n async commitToNewBranch(input: { base: string; branch: string; message: string; files: CommitFile[] }): Promise<{ sha: string; branch: string }> {\n this.assertToken('Creating a branch');\n this.assertWritableBranch(input.branch, input.base);\n const baseSha = await this.getBranchSha(input.base);\n if (!baseSha) throw new GitHubError(404, `Base branch \"${input.base}\" not found.`);\n const baseTree = await this.getCommitTree(baseSha);\n const tree = await this.createTree(baseTree, input.files.map((f) => (f.content === null ? { path: f.path, sha: null } : { path: f.path, content: f.content })));\n const sha = await this.createCommit(input.message, tree, [baseSha]);\n await this.createBranch(input.branch, sha);\n return { sha, branch: input.branch };\n }\n\n /** The same client (token, fetch, retry, protected branches) with another required branch prefix (`explore/`). */\n withBranchPrefix(branchPrefix: string | undefined): GitHubClient {\n return new GitHubClient(this.fullName, this.token, this.fetchImpl, this.retry, { ...this.options, protectedBranches: this.protectedBranches, branchPrefix });\n }\n\n /**\n * One commit with `files` on top of an existing branch, fast-forwarded (never forced). Refuses protected\n * branches and, with a branch prefix, branches without it: explorations take token edits this way.\n */\n async commitToBranch(input: { branch: string; message: string; files: CommitFile[] }): Promise<{ sha: string; branch: string }> {\n this.assertToken('Committing to a branch');\n this.assertWritableBranch(input.branch);\n const head = await this.getBranchSha(input.branch);\n if (!head) throw new GitHubError(404, `Branch \"${input.branch}\" not found. Start it first.`);\n const baseTree = await this.getCommitTree(head);\n const tree = await this.createTree(baseTree, input.files.map((f) => (f.content === null ? { path: f.path, sha: null } : { path: f.path, content: f.content })));\n const sha = await this.createCommit(input.message, tree, [head]);\n await this.updateBranch(input.branch, sha);\n return { sha, branch: input.branch };\n }\n\n /**\n * Marks a draft pull request ready for review. REST cannot unset `draft`, so this is the GraphQL mutation\n * markPullRequestReadyForReview, with the same token (pull requests: write).\n */\n async markReadyForReview(n: number): Promise<void> {\n this.assertToken('Marking a pull request ready for review');\n const pr = await this.request<{ node_id?: string; draft?: boolean }>('GET', `${this.repoPath}/pulls/${n}`);\n if (pr.draft === false) return;\n if (!pr.node_id) throw new GitHubError(422, `Pull request #${n} has no node id: mark it ready for review on GitHub.`);\n const r = await this.request<{ data?: unknown; errors?: { message?: string }[] }>('POST', '/graphql', {\n query: 'mutation($id: ID!) { markPullRequestReadyForReview(input: { pullRequestId: $id }) { pullRequest { number isDraft } } }',\n variables: { id: pr.node_id },\n });\n if (r?.errors?.length) {\n const detail = r.errors.map((e) => e.message).filter(Boolean).join(' ');\n throw new GitHubError(422, `GitHub refused to mark #${n} ready for review${detail ? `: ${detail}` : '.'} Use \"Ready for review\" on GitHub instead.`, detail);\n }\n }\n\n /**\n * Turns an open pull request back into a draft: the GraphQL mutation convertPullRequestToDraft (REST cannot set\n * `draft` either), same token. No-op when it is already a draft.\n */\n async convertToDraft(n: number): Promise<void> {\n this.assertToken('Turning a pull request back into a draft');\n const pr = await this.request<{ node_id?: string; draft?: boolean; state?: string }>('GET', `${this.repoPath}/pulls/${n}`);\n if (pr.draft === true) return;\n if (pr.state && pr.state !== 'open') throw new GitHubError(422, `Pull request #${n} is ${pr.state}: only an open one can go back to draft.`);\n if (!pr.node_id) throw new GitHubError(422, `Pull request #${n} has no node id: convert it to draft on GitHub.`);\n const r = await this.request<{ data?: unknown; errors?: { message?: string }[] }>('POST', '/graphql', {\n query: 'mutation($id: ID!) { convertPullRequestToDraft(input: { pullRequestId: $id }) { pullRequest { number isDraft } } }',\n variables: { id: pr.node_id },\n });\n if (r?.errors?.length) {\n const detail = r.errors.map((e) => e.message).filter(Boolean).join(' ');\n throw new GitHubError(422, `GitHub refused to turn #${n} back into a draft${detail ? `: ${detail}` : '.'} Use \"Convert to draft\" on GitHub instead.`, detail);\n }\n }\n\n async createPullRequest(input: { title: string; head: string; base: string; body: string; draft: boolean }): Promise<PullRequest> {\n this.assertWritableBranch(input.head, input.base);\n const r = await this.request<{ number: number; html_url: string; title: string; draft?: boolean; head: { ref: string } }>(\n 'POST',\n `${this.repoPath}/pulls`,\n input,\n );\n return { number: r.number, url: r.html_url, title: r.title, draft: !!r.draft, headRef: r.head.ref };\n }\n\n async findOpenPullRequest(branch: string): Promise<PullRequest | undefined> {\n const r = await this.request<{ number: number; html_url: string; title: string; draft?: boolean; head: { ref: string } }[]>(\n 'GET',\n `${this.repoPath}/pulls?state=open&head=${encodeURIComponent(`${this.owner}:${branch}`)}`,\n );\n const pr = r[0];\n return pr ? { number: pr.number, url: pr.html_url, title: pr.title, draft: !!pr.draft, headRef: pr.head.ref } : undefined;\n }\n\n /** Best effort: labels need the repo to allow it; failure is not fatal. */\n async addLabels(issueNumber: number, labels: string[]): Promise<boolean> {\n try {\n await this.request('POST', `${this.repoPath}/issues/${issueNumber}/labels`, { labels });\n return true;\n } catch {\n return false;\n }\n }\n\n async addComment(issueNumber: number, body: string): Promise<void> {\n await this.request('POST', `${this.repoPath}/issues/${issueNumber}/comments`, { body });\n }\n\n /**\n * Comments on an issue or pull request, oldest first (first 100: the sticky preview comment is posted early).\n * `authorAssociation` is GitHub's OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, NONE... (suggestion approvals read it).\n */\n async listIssueComments(issueNumber: number): Promise<{ id: number; body: string; author: string; updatedAt: string; createdAt: string; authorAssociation: string }[]> {\n const r = await this.request<{ id: number; body?: string | null; user?: { login: string } | null; updated_at: string; created_at?: string; author_association?: string }[]>(\n 'GET',\n `${this.repoPath}/issues/${issueNumber}/comments?per_page=100`,\n );\n return r.map((c) => ({ id: c.id, body: c.body ?? '', author: c.user?.login ?? 'unknown', updatedAt: c.updated_at, createdAt: c.created_at ?? c.updated_at, authorAssociation: c.author_association ?? 'NONE' }));\n }\n\n // --- Issues (component change requests) ---------------------------------------------------\n\n async createIssue(input: { title: string; body: string; labels?: string[]; assignees?: string[] }): Promise<IssueSummary> {\n const r = await this.request<RawIssue>('POST', `${this.repoPath}/issues`, {\n title: input.title,\n body: input.body,\n ...(input.labels?.length ? { labels: input.labels } : {}),\n ...(input.assignees?.length ? { assignees: input.assignees } : {}),\n });\n return toIssue(r);\n }\n\n /** Issues (not pull requests) with a label, newest first. */\n async listIssues(opts: { label?: string; state?: 'open' | 'closed' | 'all'; perPage?: number } = {}): Promise<IssueSummary[]> {\n const q = new URLSearchParams({ state: opts.state ?? 'all', per_page: String(opts.perPage ?? 50), sort: 'created', direction: 'desc' });\n if (opts.label) q.set('labels', opts.label);\n const r = await this.request<RawIssue[]>('GET', `${this.repoPath}/issues?${q}`);\n return r.filter((i) => !i.pull_request).map(toIssue);\n }\n\n async getIssue(n: number): Promise<IssueSummary> {\n return toIssue(await this.request<RawIssue>('GET', `${this.repoPath}/issues/${n}`));\n }\n\n /** Edits an issue: its body, or closes it with a reason (\"not_planned\" for a declined request). */\n async updateIssue(n: number, patch: { body?: string; state?: 'open' | 'closed'; state_reason?: 'completed' | 'not_planned' | 'reopened' }): Promise<IssueSummary> {\n this.assertToken('Editing an issue');\n return toIssue(await this.request<RawIssue>('PATCH', `${this.repoPath}/issues/${n}`, patch));\n }\n\n /** Adds people to an issue's assignees (GitHub ignores logins that cannot be assigned: the result says who is). */\n async addAssignees(n: number, logins: string[]): Promise<string[]> {\n this.assertToken('Assigning an issue');\n const r = await this.request<{ assignees?: { login: string }[] | null }>('POST', `${this.repoPath}/issues/${n}/assignees`, { assignees: logins });\n return (r.assignees ?? []).map((a) => a.login);\n }\n\n /** People with at least `permission` on the repository (reading the list needs push access). First 100. */\n async listCollaborators(permission: 'pull' | 'triage' | 'push' | 'maintain' | 'admin' = 'push'): Promise<{ login: string; avatarUrl: string }[]> {\n const r = await this.request<{ login: string; avatar_url?: string }[]>('GET', `${this.repoPath}/collaborators?permission=${permission}&per_page=100`);\n return r.map((c) => ({ login: c.login, avatarUrl: c.avatar_url ?? '' }));\n }\n\n /** Whether a token is sent with each request (TeamReader). */\n get hasToken(): boolean {\n return Boolean(this.token);\n }\n\n /** Every page of a list endpoint (per_page 100), up to `maxPages`. */\n private async paginate<T>(path: string, maxPages = 20): Promise<T[]> {\n const out: T[] = [];\n const sep = path.includes('?') ? '&' : '?';\n for (let page = 1; page <= maxPages; page++) {\n const r = await this.request<T[]>('GET', `${path}${sep}per_page=100&page=${page}`);\n out.push(...r);\n if (r.length < 100) break;\n }\n return out;\n }\n\n /** Every member login of an organization team (needs read:org, or Members: Read on a fine-grained token). */\n async listTeamMembers(org: string, slug: string): Promise<string[]> {\n const r = await this.paginate<{ login: string }>(`/orgs/${encodeURIComponent(org)}/teams/${encodeURIComponent(slug)}/members`);\n return r.map((m) => m.login);\n }\n\n /** A user's membership of a team: \"active\", \"pending\", or null when GitHub says they are not a member (404). */\n async getTeamMembership(org: string, slug: string, login: string): Promise<'active' | 'pending' | null> {\n try {\n const r = await this.request<{ state: string }>('GET', `/orgs/${encodeURIComponent(org)}/teams/${encodeURIComponent(slug)}/memberships/${encodeURIComponent(login)}`);\n return r.state === 'active' ? 'active' : 'pending';\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return null;\n throw err;\n }\n }\n\n /** \"User\" or \"Organization\" for a login, null when GitHub does not know it. */\n async getAccountType(login: string): Promise<'User' | 'Organization' | null> {\n try {\n const r = await this.request<{ type?: string }>('GET', `/users/${encodeURIComponent(login)}`);\n return r.type === 'Organization' ? 'Organization' : r.type === 'User' ? 'User' : null;\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return null;\n throw err;\n }\n }\n\n /** The organization's teams this token can see. */\n async listOrgTeams(org: string): Promise<{ slug: string; name: string }[]> {\n const r = await this.paginate<{ slug: string; name: string }>(`/orgs/${encodeURIComponent(org)}/teams`);\n return r.map((t) => ({ slug: t.slug, name: t.name }));\n }\n\n /** Create or update a binary file (base64 content) on a branch, e.g. a Figma export attached to a request. */\n async putBase64File(input: { path: string; base64: string; branch: string; message: string }): Promise<string> {\n this.assertWritableBranch(input.branch);\n const r = await this.request<{ commit: { sha: string } }>('PUT', `${this.repoPath}/contents/${encodeRef(input.path)}`, {\n message: input.message,\n content: input.base64,\n branch: input.branch,\n });\n return r.commit.sha;\n }\n\n // --- Contents API: single files -----------------------------------------------------------\n\n /** Text of one file at a ref (branch, tag or sha), or undefined when it does not exist. */\n async getFileText(path: string, ref?: string): Promise<string | undefined> {\n try {\n const q = ref ? `?ref=${encodeURIComponent(ref)}` : '';\n const r = await this.request<{ content?: string; encoding?: string; sha: string; type: string }>('GET', `${this.repoPath}/contents/${encodeRef(path)}${q}`);\n if (r.type !== 'file') return undefined;\n if (r.encoding === 'base64' && r.content !== undefined) return base64ToUtf8(r.content);\n return r.content;\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return undefined;\n throw err;\n }\n }\n\n /**\n * Text and blob sha of one file at a ref, or undefined when it does not exist. The sha is what an update or a\n * delete must send back (optimistic concurrency: GitHub answers 409 when the file changed since).\n */\n async getFile(path: string, ref?: string): Promise<{ text: string; sha: string } | undefined> {\n try {\n const q = ref ? `?ref=${encodeURIComponent(ref)}` : '';\n const r = await this.request<{ content?: string; encoding?: string; sha: string; type: string }>('GET', `${this.repoPath}/contents/${encodeRef(path)}${q}`);\n if (r.type !== 'file') return undefined;\n const text = r.encoding === 'base64' && r.content !== undefined ? base64ToUtf8(r.content) : (r.content ?? '');\n return { text, sha: r.sha };\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return undefined;\n throw err;\n }\n }\n\n /**\n * Base64 content of a binary file at a ref (an image), or undefined when it does not exist or is too large for the\n * contents API to inline (over 1 MB).\n */\n async getFileBase64(path: string, ref?: string): Promise<{ base64: string; size: number } | undefined> {\n try {\n const q = ref ? `?ref=${encodeURIComponent(ref)}` : '';\n const r = await this.request<{ content?: string; encoding?: string; size?: number; type: string }>('GET', `${this.repoPath}/contents/${encodeRef(path)}${q}`);\n if (r.type !== 'file' || r.encoding !== 'base64' || !r.content) return undefined;\n return { base64: r.content.replace(/\\s+/g, ''), size: r.size ?? 0 };\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return undefined;\n throw err;\n }\n }\n\n /** Entries of one folder at a ref (contents API), or an empty list when the folder does not exist. */\n async listDirectory(path: string, ref?: string): Promise<{ name: string; path: string; type: string; sha: string; size: number }[]> {\n try {\n const q = ref ? `?ref=${encodeURIComponent(ref)}` : '';\n const r = await this.request<unknown>('GET', `${this.repoPath}/contents/${encodeRef(path)}${q}`);\n if (!Array.isArray(r)) return [];\n return (r as { name: string; path: string; type: string; sha: string; size?: number }[]).map((e) => ({ name: e.name, path: e.path, type: e.type, sha: e.sha, size: e.size ?? 0 }));\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return [];\n throw err;\n }\n }\n\n /** Deletes one file on a branch in its own commit (contents API). `sha` is the file's blob sha. */\n async deleteFile(input: { path: string; branch: string; message: string; sha: string }): Promise<string> {\n this.assertToken('Deleting a file');\n this.assertWritableBranch(input.branch);\n const r = await this.request<{ commit: { sha: string } }>('DELETE', `${this.repoPath}/contents/${encodeRef(input.path)}`, {\n message: input.message,\n branch: input.branch,\n sha: input.sha,\n });\n return r.commit.sha;\n }\n\n /** Create or update one file on a branch in its own commit (contents API). Returns the commit sha. */\n async putFile(input: { path: string; content: string; branch: string; message: string; sha?: string | undefined }): Promise<string> {\n this.assertWritableBranch(input.branch);\n const r = await this.request<{ commit: { sha: string } }>('PUT', `${this.repoPath}/contents/${encodeRef(input.path)}`, {\n message: input.message,\n content: utf8ToBase64(input.content),\n branch: input.branch,\n ...(input.sha ? { sha: input.sha } : {}),\n });\n return r.commit.sha;\n }\n\n /**\n * Text of a file at a ref, or undefined. Without a token, public repos are read from the raw host (no\n * hourly API limit); with one, through the contents API (private repos work).\n */\n async readFile(path: string, ref: string): Promise<string | undefined> {\n if (this.token) return this.getFileText(path, ref);\n return this.readRawFile(path, ref);\n }\n\n /**\n * Text of a file from the raw host (raw.githubusercontent.com), sent without any header so the browser makes a\n * simple CORS request (no preflight) and nothing counts against the API limit. Works for public repositories only:\n * a private file answers 404 there, like a missing one. Undefined on 404.\n */\n async readRawFile(path: string, ref: string): Promise<string | undefined> {\n const url = `${(this.options.rawUrl ?? RAW).replace(/\\/$/, '')}/${this.owner}/${this.name}/${encodeRef(ref)}/${encodeRef(path)}`;\n let res: Awaited<ReturnType<FetchLike>>;\n try {\n res = await this.fetchImpl(url, {});\n } catch (err) {\n throw new GitHubError(0, 'Could not reach GitHub. Check your connection, then try again.', (err as Error).message);\n }\n if (res.status === 404) return undefined;\n if (!res.ok) throw new GitHubError(res.status, friendlyMessage(res.status, ''), `raw ${path}@${ref}`);\n return res.text();\n }\n\n /**\n * Text of a file at a ref through the contents API with the raw media type: the way to read a private file (the raw\n * host cannot take the token without a preflight). Counts against the API limit; conditional when cached.\n * Undefined when the file does not exist.\n */\n async getRawText(path: string, ref: string): Promise<string | undefined> {\n try {\n return await this.request<string>('GET', `${this.repoPath}/contents/${encodeRef(path)}?ref=${encodeURIComponent(ref)}`, undefined, true, { accept: ACCEPT_RAW, text: true });\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return undefined;\n throw err;\n }\n }\n\n /**\n * Text of a blob by its sha through the git blobs API with the raw media type: how a signed-in reader loads a file\n * listed by a tree (the raw host refuses any request that carries a token). A blob sha names its content, so the\n * answer is cached for the client's life and never revalidated. Undefined on 404.\n */\n async getBlobRaw(sha: string): Promise<string | undefined> {\n const cached = this.blobCache.get(sha);\n if (cached !== undefined) return cached;\n try {\n const text = await this.request<string>('GET', `${this.repoPath}/git/blobs/${encodeURIComponent(sha)}`, undefined, true, { accept: ACCEPT_RAW, text: true, etag: false });\n this.blobCache.set(sha, text);\n return text;\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return undefined;\n throw err;\n }\n }\n\n // --- GitHub App installations (user-to-server tokens) ---------------------------------------\n\n /**\n * Installations of the signing-in GitHub App that the signed-in user can reach (GET /user/installations, every\n * page). Needs a user-to-server token of that same App: a personal or OAuth token is refused (403), and each App\n * sees only its own installations. GitHub lists only installations on accounts and repositories the user has\n * explicit permission on: a public repository where the user is not a collaborator is never listed, installed or\n * not. (GET /repos/{o}/{r}/installation would say, but it needs the App's private key, which Bridge never holds.)\n */\n async listUserInstallations(): Promise<Installation[]> {\n this.assertToken('Reading where Bridge is installed');\n type Raw = { id: number; account?: { login?: string; type?: string } | null; repository_selection?: string; app_slug?: string };\n const list = await this.paged<{ total_count?: number; installations?: Raw[] }, Raw>('/user/installations', (p) => ({ items: p.installations ?? [], total: p.total_count }));\n return list.map((i) => ({\n id: i.id,\n account: i.account?.login ? { login: i.account.login, type: i.account.type ?? 'User' } : null,\n repositorySelection: i.repository_selection ?? 'selected',\n appSlug: i.app_slug,\n }));\n }\n\n /** Repositories of one installation the signed-in user can reach (GET /user/installations/{id}/repositories, every page). */\n async listInstallationRepos(installationId: number): Promise<InstallationRepo[]> {\n this.assertToken('Reading where Bridge is installed');\n type Raw = { name: string; full_name: string; private?: boolean; owner?: { login?: string } };\n const list = await this.paged<{ total_count?: number; repositories?: Raw[] }, Raw>(`/user/installations/${encodeURIComponent(String(installationId))}/repositories`, (p) => ({\n items: p.repositories ?? [],\n total: p.total_count,\n }));\n return list.map((r) => ({ owner: r.owner?.login ?? r.full_name.split('/')[0]!, name: r.name, fullName: r.full_name, private: Boolean(r.private) }));\n }\n\n /**\n * The App installation that gives the signed-in user this repository (this client's by default): its id, or null\n * when the App is not installed there or the user cannot reach it. One call when the installation covers all of\n * the owner's repositories, two (paged) when it covers selected ones.\n */\n async findInstallation(owner: string = this.owner, repo: string = this.name): Promise<{ id: number; selection: 'all' | 'selected' } | null> {\n const found = installationFor(await this.listUserInstallations(), owner);\n if (found.reach === 'no') return null;\n if (found.reach === 'yes') return { id: found.id, selection: 'all' };\n const repos = await this.listInstallationRepos(found.id);\n const hit = repos.some((r) => r.owner.toLowerCase() === owner.toLowerCase() && r.name.toLowerCase() === repo.toLowerCase());\n return hit ? { id: found.id, selection: 'selected' } : null;\n }\n\n /** The repository's default branch. */\n async getDefaultBranch(): Promise<string> {\n return (await this.getRepo()).defaultBranch;\n }\n\n /** Every file path at a ref (branch, tag or sha), one API call. */\n async listFiles(ref: string): Promise<string[]> {\n const r = await this.request<{ tree: { path: string; type: string }[]; truncated: boolean }>('GET', `${this.repoPath}/git/trees/${encodeRef(ref)}?recursive=1`);\n if (r.truncated) throw new GitHubError(413, 'The repository tree is too large to read in one request.');\n return r.tree.filter((e) => e.type === 'blob').map((e) => e.path);\n }\n\n // --- Pull requests, reviews, checks ---------------------------------------------------------\n\n async listPullRequests(state: 'open' | 'closed' | 'all' = 'open'): Promise<PullRequestSummary[]> {\n const r = await this.request<Record<string, any>[]>('GET', `${this.repoPath}/pulls?state=${state}&per_page=50&sort=updated&direction=desc`);\n return r.map(toSummary);\n }\n\n /** Commit statuses and check runs of a commit, folded into one state. */\n async getChecks(sha: string): Promise<{ state: 'success' | 'failure' | 'pending' | 'none'; checks: { name: string; status: string; conclusion: string | null }[] }> {\n const [combined, runs] = await Promise.all([\n this.request<{ statuses: { context: string; state: string }[] }>('GET', `${this.repoPath}/commits/${encodeRef(sha)}/status`).catch(() => ({ statuses: [] })),\n this.listCheckRuns(sha).catch(() => [] as CheckRun[]),\n ]);\n const checks = [\n ...runs.map((c) => ({ name: c.name, status: c.status, conclusion: c.conclusion })),\n ...combined.statuses.map((s) => ({ name: s.context, status: s.state === 'pending' ? 'in_progress' : 'completed', conclusion: s.state === 'pending' ? null : s.state })),\n ];\n const failing = checks.some((c) => c.conclusion && !['success', 'neutral', 'skipped'].includes(c.conclusion));\n const pending = checks.some((c) => c.status !== 'completed');\n return { state: !checks.length ? 'none' : failing ? 'failure' : pending ? 'pending' : 'success', checks };\n }\n\n /** Commit statuses of a commit, newest first (Vercel reports each project as \"Vercel – <project>\"). */\n async listCommitStatuses(sha: string): Promise<{ context: string; state: string; target_url: string | null; description: string | null }[]> {\n const r = await this.request<{ context: string; state: string; target_url?: string | null; description?: string | null }[]>('GET', `${this.repoPath}/commits/${encodeRef(sha)}/statuses?per_page=100`);\n return r.map((s) => ({ context: s.context, state: s.state, target_url: s.target_url ?? null, description: s.description ?? null }));\n }\n\n /**\n * GitHub deployments of a commit with their latest status (environment \"Preview – <project>\", environment_url the\n * preview). Latest per environment only, so it costs one read plus one per environment.\n */\n async listDeployments(sha: string): Promise<{ id: number; environment: string; state: string | null; environmentUrl: string | null }[]> {\n const list = await this.request<{ id: number; environment: string; created_at?: string }[]>('GET', `${this.repoPath}/deployments?sha=${encodeURIComponent(sha)}&per_page=30`);\n const latest = new Map<string, { id: number; environment: string }>();\n for (const d of list) if (!latest.has(d.environment)) latest.set(d.environment, d);\n return Promise.all(\n [...latest.values()].map(async (d) => {\n const st = await this.request<{ state: string; environment_url?: string | null; target_url?: string | null }[]>('GET', `${this.repoPath}/deployments/${d.id}/statuses?per_page=1`).catch(() => []);\n const s = st[0];\n return { id: d.id, environment: d.environment, state: s?.state ?? null, environmentUrl: s?.environment_url || null };\n }),\n );\n }\n\n async getPullRequest(n: number): Promise<PullRequest & PullRequestSummary & { body: string; mergeable: boolean | null; requestedReviewers: string[] }> {\n const r = await this.request<Record<string, any>>('GET', `${this.repoPath}/pulls/${n}`);\n return { ...toSummary(r), body: r.body ?? '', mergeable: r.mergeable ?? null, requestedReviewers: ((r.requested_reviewers ?? []) as { login: string }[]).map((x) => x.login) };\n }\n\n async listPullRequestFiles(n: number): Promise<PullRequestFile[]> {\n const r = await this.request<{ filename: string; status: string; additions: number; deletions: number }[]>('GET', `${this.repoPath}/pulls/${n}/files?per_page=100`);\n return r.map((f) => ({ filename: f.filename, status: f.status, additions: f.additions, deletions: f.deletions }));\n }\n\n async updatePullRequest(n: number, patch: { title?: string; body?: string; state?: 'open' | 'closed' }): Promise<void> {\n await this.request('PATCH', `${this.repoPath}/pulls/${n}`, patch);\n }\n\n async listReviews(n: number): Promise<Review[]> {\n const r = await this.request<{ id: number; user?: { login: string }; state: string; body: string | null; submitted_at?: string }[]>('GET', `${this.repoPath}/pulls/${n}/reviews`);\n return r.map((x) => ({ id: x.id, user: x.user?.login, state: x.state, body: x.body ?? '', ...(x.submitted_at ? { submittedAt: x.submitted_at } : {}) }));\n }\n\n /** Submit a review. `COMMENT` works for any collaborator; approving your own PR is refused by GitHub. */\n async createReview(n: number, input: { event: 'COMMENT' | 'APPROVE' | 'REQUEST_CHANGES'; body: string }): Promise<Review> {\n this.assertToken('Reviewing a pull request');\n const r = await this.request<{ id: number; user?: { login: string }; state: string; body: string | null }>('POST', `${this.repoPath}/pulls/${n}/reviews`, input);\n return { id: r.id, user: r.user?.login, state: r.state, body: r.body ?? '' };\n }\n\n async listCheckRuns(ref: string): Promise<CheckRun[]> {\n const r = await this.request<{ check_runs: { id: number; name: string; status: string; conclusion: string | null; html_url?: string; app?: { slug?: string } | null }[] }>(\n 'GET',\n `${this.repoPath}/commits/${encodeRef(ref)}/check-runs`,\n );\n return r.check_runs.map((c) => ({ id: c.id, name: c.name, status: c.status, conclusion: c.conclusion, url: c.html_url, ...(c.app?.slug ? { app: c.app.slug } : {}) }));\n }\n\n /** Rulesets that apply to the repository, without their rules (GET /rulesets; read access is enough). */\n async listRulesets(): Promise<Ruleset[]> {\n const r = await this.request<(Ruleset & { _links?: { html?: { href?: string } } })[]>('GET', `${this.repoPath}/rulesets?includes_parents=true&per_page=100`);\n return r.map(withRulesetUrl);\n }\n\n /** One ruleset with its rules. */\n async getRuleset(id: number): Promise<Ruleset> {\n return withRulesetUrl(await this.request<Ruleset>('GET', `${this.repoPath}/rulesets/${id}`));\n }\n\n /** Creates a repository ruleset. Needs admin on the repo (fine-grained token: Administration read and write). */\n async createRuleset(payload: RulesetPayload): Promise<Ruleset> {\n this.assertToken('Protecting the library');\n return withRulesetUrl(await this.request<Ruleset>('POST', `${this.repoPath}/rulesets`, payload));\n }\n\n /** Replaces a repository ruleset (same permissions as createRuleset). */\n async updateRuleset(id: number, payload: RulesetPayload): Promise<Ruleset> {\n this.assertToken('Protecting the library');\n return withRulesetUrl(await this.request<Ruleset>('PUT', `${this.repoPath}/rulesets/${id}`, payload));\n }\n\n /**\n * Classic branch protection of `branch`: the settings, null when the branch has none (404), undefined when this\n * token cannot read them (403: the endpoint needs admin). On a 403 the public branch summary still tells\n * whether the branch is protected at all: `protected: false` means there is nothing to read, so null.\n */\n async getBranchProtection(branch: string): Promise<ClassicProtection | null | undefined> {\n try {\n return await this.request<ClassicProtection>('GET', `${this.repoPath}/branches/${encodeRef(branch)}/protection`);\n } catch (err) {\n if (!(err instanceof GitHubError)) throw err;\n if (err.status === 404) return null;\n if (err.status === 403 || err.status === 401) {\n const b = await this.request<{ protected?: boolean }>('GET', `${this.repoPath}/branches/${encodeRef(branch)}`).catch(() => undefined);\n return b?.protected === false ? null : undefined;\n }\n throw err;\n }\n }\n\n /** Create a check run (needs a GitHub App token; personal tokens are refused by GitHub). */\n async createCheckRun(input: {\n name: string;\n headSha: string;\n status?: 'queued' | 'in_progress' | 'completed';\n conclusion?: 'success' | 'failure' | 'neutral' | 'cancelled' | 'skipped' | 'timed_out' | 'action_required';\n output?: { title: string; summary: string; text?: string };\n }): Promise<CheckRun> {\n const r = await this.request<{ id: number; name: string; status: string; conclusion: string | null; html_url?: string }>('POST', `${this.repoPath}/check-runs`, {\n name: input.name,\n head_sha: input.headSha,\n ...(input.status ? { status: input.status } : {}),\n ...(input.conclusion ? { conclusion: input.conclusion } : {}),\n ...(input.output ? { output: input.output } : {}),\n });\n return { id: r.id, name: r.name, status: r.status, conclusion: r.conclusion, url: r.html_url };\n }\n\n async removeLabel(issueNumber: number, label: string): Promise<void> {\n await this.request('DELETE', `${this.repoPath}/issues/${issueNumber}/labels/${encodeURIComponent(label)}`);\n }\n\n // --- branch actions shared by Studio, the MCP server and the CLI (branch-actions.ts) ---\n\n /** The account the token belongs to (GET /user). Needs a token. */\n async getViewer(): Promise<{ login: string }> {\n this.assertToken('Reading who you are on GitHub');\n const r = await this.request<{ login: string }>('GET', '/user');\n return { login: r.login };\n }\n\n /** The repository's merge settings and the viewer's permissions (unknown settings count as allowed). */\n async getMergeSettings(): Promise<{ allow_squash_merge?: boolean; allow_merge_commit?: boolean; allow_rebase_merge?: boolean; permissions?: { admin?: boolean; maintain?: boolean; push?: boolean } }> {\n return this.request('GET', this.repoPath);\n }\n\n /**\n * Merges a pull request, only at `sha` (GitHub refuses when the branch moved meanwhile). The repository's branch\n * rules still apply: GitHub refuses a merge they block, whatever Bridge says.\n */\n async mergePullRequest(n: number, input: { method: 'squash' | 'merge' | 'rebase'; sha: string; commitMessage?: string | undefined }): Promise<{ sha: string; merged: boolean }> {\n this.assertToken('Merging a branch');\n const r = await this.request<{ sha: string; merged: boolean }>('PUT', `${this.repoPath}/pulls/${n}/merge`, {\n merge_method: input.method,\n sha: input.sha,\n ...(input.commitMessage !== undefined && input.method !== 'rebase' ? { commit_message: input.commitMessage } : {}),\n });\n return { sha: r?.sha ?? '', merged: r?.merged ?? true };\n }\n\n /** GitHub's \"Update branch\": merges the base into the pull request, only when its head is still `expectedHeadSha`. */\n async updatePullRequestBranch(n: number, expectedHeadSha: string): Promise<void> {\n this.assertToken('Updating a branch from main');\n await this.request('PUT', `${this.repoPath}/pulls/${n}/update-branch`, { expected_head_sha: expectedHeadSha });\n }\n\n /**\n * Merges the branch `head` into the branch `base` (GitHub's merges API): a merge commit on `base`, or nothing when\n * `base` already has every commit of `head`. A conflict throws a GitHubError with status 409. Refuses protected\n * branches and, with a branch prefix, a `base` without it.\n */\n async mergeIntoBranch(base: string, head: string, message: string): Promise<{ status: 'merged' | 'up-to-date'; sha: string | null }> {\n this.assertToken('Merging a branch into another');\n this.assertWritableBranch(base);\n const r = await this.request<{ sha?: string } | undefined>('POST', `${this.repoPath}/merges`, { base, head, commit_message: message });\n return r?.sha ? { status: 'merged', sha: r.sha } : { status: 'up-to-date', sha: null };\n }\n\n /** Posts a comment on an issue or pull request and returns its id and link. */\n async createIssueComment(n: number, body: string): Promise<{ id: number; url: string }> {\n this.assertToken('Commenting');\n const r = await this.request<{ id: number; html_url: string }>('POST', `${this.repoPath}/issues/${n}/comments`, { body });\n return { id: r.id, url: r.html_url };\n }\n\n /** Replaces the text of a comment. */\n async updateIssueComment(id: number, body: string): Promise<void> {\n this.assertToken('Editing a comment');\n await this.request('PATCH', `${this.repoPath}/issues/comments/${id}`, { body });\n }\n\n /** Submits a review on a given commit (the head the reviewer saw); the body may be empty for an approval. */\n async submitReview(n: number, input: { event: 'COMMENT' | 'APPROVE' | 'REQUEST_CHANGES'; body?: string | undefined; commitId?: string | undefined }): Promise<Review> {\n this.assertToken('Reviewing a branch');\n const r = await this.request<{ id: number; user?: { login: string }; state: string; body: string | null }>('POST', `${this.repoPath}/pulls/${n}/reviews`, {\n event: input.event,\n ...(input.body ? { body: input.body } : {}),\n ...(input.commitId ? { commit_id: input.commitId } : {}),\n });\n return { id: r.id, user: r.user?.login, state: r.state, body: r.body ?? '' };\n }\n\n /** Line comments of a pull request (review threads), oldest first. */\n async listReviewComments(n: number): Promise<{ id: number; body: string; author: string; path: string; line: number | null; inReplyTo: number | null; url: string; createdAt: string }[]> {\n const r = await this.request<{ id: number; body?: string | null; user?: { login: string } | null; path: string; line?: number | null; in_reply_to_id?: number; html_url: string; created_at: string }[]>(\n 'GET',\n `${this.repoPath}/pulls/${n}/comments?per_page=100`,\n );\n return r.map((c) => ({ id: c.id, body: c.body ?? '', author: c.user?.login ?? 'unknown', path: c.path, line: c.line ?? null, inReplyTo: c.in_reply_to_id ?? null, url: c.html_url, createdAt: c.created_at }));\n }\n\n /** Asks these people to review a pull request. */\n async requestReviewers(n: number, logins: string[]): Promise<void> {\n this.assertToken('Asking for a review');\n await this.request('POST', `${this.repoPath}/pulls/${n}/requested_reviewers`, { reviewers: logins });\n }\n\n /** Takes these people off the requested reviewers. */\n async removeRequestedReviewers(n: number, logins: string[]): Promise<void> {\n this.assertToken('Changing the requested reviewers');\n await this.request('DELETE', `${this.repoPath}/pulls/${n}/requested_reviewers`, { reviewers: logins });\n }\n\n /** Replies in the thread of a line comment. */\n async replyToReviewComment(n: number, commentId: number, body: string): Promise<{ id: number; url: string }> {\n this.assertToken('Replying to a comment');\n const r = await this.request<{ id: number; html_url: string }>('POST', `${this.repoPath}/pulls/${n}/comments/${commentId}/replies`, { body });\n return { id: r.id, url: r.html_url };\n }\n\n /**\n * What `head` adds on top of `base`, with what library sync needs: the shared start (merge base), the base\n * commit and its tree, how far behind, and the files with their previous names.\n */\n async compareDetailed(base: string, head: string): Promise<{\n behindBy: number;\n aheadBy: number;\n mergeBase: string | null;\n baseSha: string | null;\n baseTree: string | null;\n files: { filename: string; status: string; previous_filename?: string | undefined }[];\n }> {\n const r = await this.request<{\n ahead_by: number;\n behind_by: number;\n merge_base_commit?: { sha?: string };\n base_commit?: { sha?: string; commit?: { tree?: { sha?: string } } };\n files?: { filename: string; status: string; previous_filename?: string }[];\n }>('GET', `${this.repoPath}/compare/${encodeRef(base)}...${encodeRef(head)}`);\n return {\n behindBy: r.behind_by,\n aheadBy: r.ahead_by,\n mergeBase: r.merge_base_commit?.sha ?? null,\n baseSha: r.base_commit?.sha ?? null,\n baseTree: r.base_commit?.commit?.tree?.sha ?? null,\n files: (r.files ?? []).map((f) => ({ filename: f.filename, status: f.status, ...(f.previous_filename ? { previous_filename: f.previous_filename } : {}) })),\n };\n }\n\n /** A tree on top of `baseTree` from entries with their own file mode (blob sha, inline content, or sha null to delete). */\n async createTreeEntries(baseTree: string, entries: ({ path: string; mode: string; sha: string | null } | { path: string; mode: string; content: string })[]): Promise<string> {\n const r = await this.request<{ sha: string }>('POST', `${this.repoPath}/git/trees`, { base_tree: baseTree, tree: entries.map((e) => ({ ...e, type: 'blob' })) }, true);\n return r.sha;\n }\n}\n\nfunction toCommitSummary(c: Record<string, any>): CommitSummary {\n return {\n sha: c.sha,\n parents: (c.parents ?? []).map((p: { sha: string }) => p.sha),\n date: c.commit?.committer?.date ?? c.commit?.author?.date ?? '',\n author: c.author?.login ?? c.commit?.author?.name ?? 'unknown',\n message: c.commit?.message ?? '',\n };\n}\n\nfunction toSummary(r: Record<string, any>): PullRequestSummary & PullRequest {\n return {\n number: r.number,\n title: r.title,\n state: r.merged_at || r.merged ? 'merged' : r.state,\n draft: Boolean(r.draft),\n author: r.user?.login ?? 'unknown',\n headRef: r.head?.ref,\n headSha: r.head?.sha,\n baseRef: r.base?.ref,\n labels: (r.labels ?? []).map((l: { name: string }) => l.name),\n url: r.html_url,\n updatedAt: r.updated_at,\n ...(typeof r.body === 'string' ? { body: r.body } : {}),\n };\n}\n\nexport function friendlyMessage(status: number, detail: string, info: GitHubErrorInfo = {}): string {\n if (info.auth === 'rejected') return TOKEN_REJECTED_MESSAGE;\n if (info.auth === 'missing-permission') return missingPermissionMessage(info.permission);\n switch (status) {\n case 401:\n return 'GitHub rejected the token. It may be expired or mistyped: create a new one and save it in Settings.';\n case 403:\n if (/rate limit/i.test(detail)) return 'GitHub is limiting requests right now. Wait a minute, then try again.';\n if (/archived/i.test(detail)) return 'This repository is archived and read-only.';\n return 'The token does not have permission for this. It needs \"Contents: read and write\" and \"Pull requests: read and write\" on this repository.';\n case 404:\n return 'Repository, branch or file not found, or the token cannot see this repository.';\n case 409:\n return 'GitHub reported a conflict (the branch moved while saving). Scan again, then retry.';\n case 429:\n return 'GitHub is limiting requests right now. Wait a minute, then try again.';\n case 422:\n return `GitHub refused the request${detail ? `: ${detail}` : '.'}`;\n default:\n return `GitHub error ${status}${detail ? `: ${detail}` : ''}`;\n }\n}\n\nexport interface RepoFiles {\n commitSha: string;\n treeSha: string;\n /** Token files relative to the tokens root. */\n files: Record<string, string>;\n /** Contents of the contrast checks file (tokens.contrastChecks in the config), when present. */\n contrastChecks: string | undefined;\n /** bridge.config.json at the repository root, parsed; undefined when the repo has none. */\n config: BridgeConfig | undefined;\n /** bridge.config.json as written, for minimal-diff edits (a new brand); undefined when the repo has none. */\n configText?: string | undefined;\n /** Tokens root actually used (from the config when present, else the fallback). */\n tokensPath: string;\n /** Problems reading the config (it is then ignored and the fallback is used). */\n warnings: string[];\n}\n\n/**\n * Read every *.tokens.json under the tokens root, plus the contrast checks file, at a commit.\n * The tokens root and the checks file come from bridge.config.json at the repository root when it\n * exists; otherwise from `fallbackTokensPath` and the default layout.\n */\nexport async function loadRepoFiles(client: GitHubClient, commitSha: string, fallbackTokensPath: string): Promise<RepoFiles> {\n const treeSha = await client.getCommitTree(commitSha);\n const { entries, truncated } = await client.getTree(treeSha, true);\n if (truncated) throw new Error('The repository tree is too large to read in one request.');\n const warnings: string[] = [];\n let config: BridgeConfig | undefined;\n let configText: string | undefined;\n const configEntry = entries.find((e) => e.type === 'blob' && e.path === CONFIG_FILE);\n if (configEntry) {\n try {\n configText = await client.getBlobText(configEntry.sha);\n config = loadConfig(configText);\n } catch (err) {\n warnings.push(err instanceof ConfigError ? `${err.message}. Using ${fallbackTokensPath} instead.` : `${CONFIG_FILE} could not be read.`);\n }\n }\n const tokensPath = (config?.tokens.root ?? fallbackTokensPath).replace(/^\\/+|\\/+$/g, '');\n const checksFile = config?.tokens.contrastChecks ?? DEFAULT_TOKEN_PATHS.contrastChecks;\n const prefix = tokensPath + '/';\n const wanted = entries.filter(\n (e) => e.type === 'blob' && e.path.startsWith(prefix) && (e.path.endsWith('.tokens.json') || e.path === prefix + checksFile),\n );\n if (!wanted.some((e) => e.path.endsWith('.tokens.json'))) throw new Error(`No *.tokens.json files found under ${tokensPath} at ${commitSha.slice(0, 7)}.`);\n const files: Record<string, string> = {};\n let contrastChecks: string | undefined;\n // Small concurrency limit: friendly to rate limits, still quick for a handful of files.\n const queue = [...wanted];\n const worker = async () => {\n for (let e = queue.shift(); e; e = queue.shift()) {\n const text = await client.getBlobText(e.sha);\n const rel = e.path.slice(prefix.length);\n if (rel === checksFile) contrastChecks = text;\n else files[rel] = text;\n }\n };\n await Promise.all([worker(), worker(), worker(), worker()]);\n return { commitSha, treeSha, files, contrastChecks, config, ...(config ? { configText } : {}), tokensPath, warnings };\n}\n\n/** Lifts the ruleset's GitHub page (`_links.html.href`) to `html_url`. */\nfunction withRulesetUrl(r: Ruleset): Ruleset {\n const href = r._links?.html?.href;\n return href && !r.html_url ? { ...r, html_url: href } : r;\n}\n\nexport interface IssueSummary {\n number: number;\n title: string;\n body: string;\n url: string;\n state: 'open' | 'closed';\n stateReason: string | null;\n labels: string[];\n author: string;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface RawIssue {\n number: number;\n title: string;\n body: string | null;\n html_url: string;\n state: 'open' | 'closed';\n state_reason?: string | null;\n labels: (string | { name?: string })[];\n user?: { login?: string } | null;\n created_at: string;\n updated_at: string;\n pull_request?: unknown;\n}\n\nfunction toIssue(r: RawIssue): IssueSummary {\n return {\n number: r.number,\n title: r.title,\n body: r.body ?? '',\n url: r.html_url,\n state: r.state,\n stateReason: r.state_reason ?? null,\n labels: r.labels.map((l) => (typeof l === 'string' ? l : (l.name ?? ''))).filter(Boolean),\n author: r.user?.login ?? '',\n createdAt: r.created_at,\n updatedAt: r.updated_at,\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 docs drafts: the deterministic part of a component's documentation, computed from its code, and the\n// review state of prose an AI drafted. Shared by the Bridge docs editor, the MCP server (bridge_draft_docs), the\n// CLI (bridge docs draft) and the docs-draft GitHub Action, so a draft looks the same wherever it starts.\n//\n// What code can tell (deterministic, never invented): the props table from the TypeScript props, the tokens the\n// stylesheet reads, the anatomy from the CSS module classes, the contrast pairs those tokens take part in, and a\n// changelog line. What only a person (or an AI, then a person) can write: summary, when to use, do and don't,\n// accessibility and content guidelines. Prose an AI wrote carries \"draftedBy\": \"claude\" and \"needsReview\": true\n// until a reviewer accepts it.\n\nimport { type JsonEntry, type JsonNode, fromPlain, getEntry, parseJson, plainEqual, serializeJson, toPlain } from './json-ast';\n\nexport type DocsExampleNode = string | { c: string; p?: Record<string, unknown>; children?: DocsExampleNode[] };\n\nexport interface DocsGuidance {\n title: string;\n text: string;\n example?: DocsExampleNode;\n}\n\n/** The shape of <Name>.docs.json (same keys as Button.docs.json). */\nexport interface ComponentDocsJson {\n summary: string;\n category?: string;\n status?: 'stable' | 'beta' | 'deprecated';\n preview?: DocsExampleNode;\n whenToUse: string[];\n whenNotToUse: string[];\n dos: DocsGuidance[];\n donts: DocsGuidance[];\n accessibility: string[];\n contentGuidelines?: string[];\n anatomy?: Record<string, string>;\n /** Who wrote the prose when it was not a person in the editor. Only \"claude\" today. */\n draftedBy?: string;\n /**\n * The prose sections Claude drafted that wait for review, when a draft covered only some of them (in-place drafting\n * on the Library page, the docs-draft Action). Missing means the whole file. Accepting removes it.\n */\n draftedSections?: ProseKey[];\n /** True while drafted prose waits for a reviewer. Accepting sets it to false. */\n needsReview?: boolean;\n}\n\n/** Keys of docs.json in the order Button.docs.json lists them. The editor and the drafts follow this order. */\nexport const DOCS_KEYS = ['summary', 'preview', 'whenToUse', 'whenNotToUse', 'dos', 'donts', 'accessibility', 'contentGuidelines', 'anatomy'] as const;\nexport type DocsKey = (typeof DOCS_KEYS)[number];\n\n/** Prose keys: the ones code cannot fill. */\nexport const PROSE_KEYS = ['summary', 'whenToUse', 'whenNotToUse', 'dos', 'donts', 'accessibility', 'contentGuidelines'] as const;\nexport type ProseKey = (typeof PROSE_KEYS)[number];\n\nexport interface DocsPropInput {\n name: string;\n type: string;\n required: boolean;\n defaultValue?: string | undefined;\n description?: string | undefined;\n}\n\nexport interface DocsContrastInput {\n foreground: string;\n background: string;\n /** Lowest ratio over every brand and theme. */\n ratio: number;\n min: number;\n}\n\nexport interface DocsPrefillInput {\n /** PascalCase component name. */\n name: string;\n /** JSDoc of the component export, when there is one. */\n description?: string | undefined;\n props: DocsPropInput[];\n /** Native element whose attributes the component also accepts (button, span). */\n inherits?: string | undefined;\n /** CSS custom properties the stylesheet reads that are tokens, e.g. --color-text-default. */\n tokens: string[];\n /** Tokens it reads through another component's stylesheet, by that component (IconButton reads Button's). */\n inheritedTokens?: Record<string, string[]>;\n /** Class names of the CSS module, in source order. */\n cssClasses: string[];\n /** Contrast pairs from the contrast checks that involve the tokens it reads. */\n contrast?: DocsContrastInput[];\n /** The docs.json it has today, if any: existing prose is kept, only gaps are listed. */\n existing?: Partial<ComponentDocsJson> | null;\n /** What changed, when the pre-fill runs for a proposed change (\"token color.text.muted changed\"). */\n change?: string;\n}\n\nexport interface DocsPrefill {\n component: string;\n /** Markdown table: prop, type, default, description. Empty string when the component has no props. */\n propsTable: string;\n tokens: string[];\n inheritedTokens: Record<string, string[]>;\n /** Class name -> readable label, keeping labels a writer already set. */\n anatomy: Record<string, string>;\n contrastNotes: string[];\n changelogLine: string;\n /** Prose keys with no content yet. */\n missing: ProseKey[];\n /** docs.json with the deterministic parts filled and the existing prose kept. Empty prose stays empty. */\n draft: ComponentDocsJson;\n}\n\nconst ACRONYMS = new Set(['sm', 'md', 'lg', 'xl', 'xs']);\n\n/** Readable label for a CSS module class: iconOnly -> \"Icon only\", is-open -> \"Is open\", sm -> \"Size sm\". */\nexport function anatomyLabel(className: string): string {\n if (ACRONYMS.has(className)) return `Size ${className}`;\n const words = className\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[-_]+/g, ' ')\n .trim()\n .toLowerCase();\n if (!words) return className;\n if (words === 'root') return 'Container';\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/** Class names of a CSS module, in source order, without duplicates and without keyframes. */\nexport function cssModuleClasses(css: string): string[] {\n const clean = css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '').replace(/@keyframes\\s+[\\w-]+\\s*\\{(?:[^{}]*\\{[^{}]*\\})*[^{}]*\\}/g, '');\n const out: string[] = [];\n for (const m of clean.matchAll(/\\.(-?[_a-zA-Z][\\w-]*)/g)) {\n // Skip decimals inside values (0.5) and file names: a class follows a selector boundary.\n const before = clean[m.index! - 1] ?? ' ';\n if (/[\\w)]/.test(before)) continue;\n if (!out.includes(m[1]!)) out.push(m[1]!);\n }\n return out;\n}\n\nconst cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\n/g, ' ');\n\nexport function propsTable(name: string, props: DocsPropInput[], inherits?: string): string {\n if (!props.length) return inherits ? `${name} has no props of its own. It accepts every native <${inherits}> attribute.` : '';\n const rows = props.map((p) => `| \\`${p.name}\\`${p.required ? ' (required)' : ''} | \\`${cell(p.type)}\\` | ${p.defaultValue ? `\\`${cell(p.defaultValue)}\\`` : ''} | ${cell(p.description ?? '')} |`);\n const tail = inherits ? `\\n\\nAlso accepts every native <${inherits}> attribute.` : '';\n return ['| Prop | Type | Default | Description |', '| --- | --- | --- | --- |', ...rows].join('\\n') + tail;\n}\n\nconst isEmpty = (v: unknown) => v === undefined || v === null || (typeof v === 'string' && !v.trim()) || (Array.isArray(v) && v.length === 0);\n\n/** Prose keys with no content in a docs.json (missing or empty). */\nexport function missingProse(d: Partial<ComponentDocsJson> | null | undefined): ProseKey[] {\n return PROSE_KEYS.filter((k) => isEmpty(d?.[k]));\n}\n\n/** The deterministic pre-fill of a component's docs. Same input, same output: nothing is invented. */\nexport function prefillDocs(input: DocsPrefillInput): DocsPrefill {\n const existing = input.existing ?? null;\n const anatomy: Record<string, string> = {};\n for (const c of input.cssClasses) anatomy[c] = existing?.anatomy?.[c] ?? anatomyLabel(c);\n const contrastNotes = (input.contrast ?? [])\n .slice()\n .sort((a, b) => a.ratio - b.ratio)\n .map((p) => `${p.foreground} on ${p.background}: ${p.ratio.toFixed(2)}:1 at worst over every brand and theme, needs ${p.min}:1 (${p.ratio >= p.min ? 'passes' : 'fails'}).`);\n const missing = missingProse(existing);\n const changelogLine = input.change\n ? `${input.name}: ${input.change.replace(/\\.$/, '')}.`\n : missing.length === PROSE_KEYS.length\n ? `${input.name}: usage guidance added.`\n : `${input.name}: usage guidance updated.`;\n const draft: ComponentDocsJson = {\n summary: existing?.summary ?? input.description ?? '',\n ...(existing?.category ? { category: existing.category } : {}),\n ...(existing?.status ? { status: existing.status } : {}),\n ...(existing?.preview ? { preview: existing.preview } : {}),\n whenToUse: existing?.whenToUse ?? [],\n whenNotToUse: existing?.whenNotToUse ?? [],\n dos: existing?.dos ?? [],\n donts: existing?.donts ?? [],\n accessibility: existing?.accessibility ?? [],\n contentGuidelines: existing?.contentGuidelines ?? [],\n anatomy,\n ...(existing?.draftedBy ? { draftedBy: existing.draftedBy } : {}),\n ...(existing?.draftedSections?.length ? { draftedSections: existing.draftedSections } : {}),\n ...(existing?.needsReview !== undefined ? { needsReview: existing.needsReview } : {}),\n };\n return {\n component: input.name,\n propsTable: propsTable(input.name, input.props, input.inherits),\n tokens: [...new Set(input.tokens)].sort(),\n inheritedTokens: input.inheritedTokens ?? {},\n anatomy,\n contrastNotes,\n changelogLine,\n missing,\n draft,\n };\n}\n\nexport interface DocsConventions {\n /** AGENTS.md (or the part about docs.json). */\n agents?: string;\n /** The voice section of the design language. */\n voice?: string;\n /** A finished docs.json to copy the structure and tone from (Button.docs.json). */\n example?: string;\n /** The component source, so the prose stays true to the code. */\n source?: string;\n /** The component's CSS module: its states and parts, so the prose stays true to the look. */\n styles?: string;\n}\n\n/** What docsPrompt asks for. Without `keys`, the missing prose as a full docs.json (the docs-draft Action, bridge_draft_docs). */\nexport interface DocsPromptOptions {\n /** Only these sections, answered as an object holding only them. */\n keys?: readonly ProseKey[];\n /** Rewrite the sections even when they hold text. */\n rewrite?: boolean;\n /**\n * Written sections older than the component code, to check (among `keys`): Claude returns one only when something\n * in it is no longer true for the code, keeping the writer's wording elsewhere; an accurate one is left out.\n */\n check?: readonly ProseKey[];\n}\n\nconst SECTION_SHAPE: Record<ProseKey, string> = {\n summary: '\"summary\": \"one or two sentences\"',\n whenToUse: '\"whenToUse\": [\"...\"]',\n whenNotToUse: '\"whenNotToUse\": [\"...\"]',\n dos: '\"dos\": [{ \"title\": \"...\", \"text\": \"...\" }]',\n donts: '\"donts\": [{ \"title\": \"...\", \"text\": \"...\" }]',\n accessibility: '\"accessibility\": [\"...\"]',\n contentGuidelines: '\"contentGuidelines\": [\"...\"]',\n};\n\n/** The JSON shape of these sections, for a prompt: {\"summary\": \"...\", \"dos\": [{ \"title\", \"text\" }]}. */\nexport const docsSectionShapes = (keys: readonly ProseKey[]): string => `{ ${keys.map((k) => SECTION_SHAPE[k]).join(', ')} }`;\n\n/**\n * The prompt a model gets to write the prose of a docs.json: the pre-fill as facts, the conventions, and strict\n * rules (no invention, JSON only). Used by the GitHub Action and returned by bridge_draft_docs for the user's own\n * Claude.\n */\nexport function docsPrompt(prefill: DocsPrefill, conventions: DocsConventions = {}, options: DocsPromptOptions = {}): string {\n const facts = [\n `Component: ${prefill.component}`,\n prefill.propsTable ? `Props (parsed from TypeScript):\\n${prefill.propsTable}` : 'Props: none of its own.',\n `Tokens its stylesheet reads: ${prefill.tokens.join(', ') || 'none'}`,\n ...Object.entries(prefill.inheritedTokens).map(([from, list]) => `Tokens it reads through ${from}'s stylesheet: ${list.length}`),\n `Anatomy (CSS module classes): ${Object.entries(prefill.anatomy)\n .map(([k, v]) => `${k} = ${v}`)\n .join('; ') || 'none'}`,\n prefill.contrastNotes.length ? `Contrast checks:\\n- ${prefill.contrastNotes.join('\\n- ')}` : '',\n `Changelog line: ${prefill.changelogLine}`,\n ].filter(Boolean);\n const block = (title: string, text?: string) => (text?.trim() ? `<${title}>\\n${text.trim()}\\n</${title}>` : '');\n const keys = options.keys;\n const check = keys ? (options.check ?? []).filter((k) => keys.includes(k)) : [];\n const write = keys ? keys.filter((k) => !check.includes(k)) : [];\n const task = keys\n ? [\n ...(write.length ? [`${options.rewrite ? 'Rewrite' : 'Write'} these sections of ${prefill.component}.docs.json for the Bridge design system: ${write.join(', ')}.`] : []),\n ...(check.length\n ? [\n `Check these written sections of ${prefill.component}.docs.json against the current code: ${check.join(', ')}. The code changed after they were written.`,\n 'Return a checked section ONLY when something in it is no longer true for the code (a wrong or removed prop, a removed state or variant, changed behavior). Then return the whole section with only the untrue parts fixed, keeping the writer\\'s wording everywhere else.',\n 'Leave a checked section out of the answer when it is still accurate: a missing key means unchanged. Never return a checked section just to improve its style.',\n ]\n : []),\n ...(options.rewrite ? ['Rewrite each one from the facts and the source: keep what is true in the current text, drop what the code does not support.'] : []),\n ]\n : [`Write the missing prose of ${prefill.component}.docs.json for the Bridge design system.`];\n const shape = keys\n ? [\n `- ${check.length ? 'Return' : 'Write'} only these keys: ${keys.join(', ')}${check.length ? ` (the checked ones, ${check.join(', ')}, only when they need a fix)` : ''}. Never return anatomy, preview or any other key: code decides them.`,\n `- Answer with one JSON object holding only those keys, nothing else: ${docsSectionShapes(keys)}.`,\n ]\n : [\n `- Fill only these keys: ${prefill.missing.join(', ') || 'none (everything is written: improve nothing, return the draft as is)'}. Keep every other key exactly as given.`,\n '- Answer with the full docs.json as one JSON object, nothing else.',\n ];\n return [\n ...task,\n '',\n 'Rules:',\n '- Ground every sentence in the facts and the source below. Never invent props, variants, keyboard behavior or tokens that are not there.',\n '- Bridge voice: sentence case, plain words, verbs first, no em dashes, no marketing words.',\n '- Keep the keys and shapes of the example docs.json. dos and donts are { \"title\", \"text\" } objects; add an \"example\" only with components and props that exist.',\n ...shape,\n '',\n 'Facts computed from the code:',\n facts.join('\\n\\n'),\n '',\n `Current draft:\\n${JSON.stringify(prefill.draft, null, 2)}`,\n '',\n block('source', conventions.source),\n block('styles', conventions.styles),\n block('agents-md', conventions.agents),\n block('voice', conventions.voice),\n block('example-docs-json', conventions.example),\n ]\n .filter((x, i, all) => x !== '' || all[i - 1] !== '')\n .join('\\n');\n}\n\n/**\n * Marks prose as drafted by Claude and waiting for review. With `sections`, only those sections were drafted: they\n * join the ones already waiting (draftedSections, in the PROSE_KEYS order). Without, the whole file was.\n */\nexport function markClaudeDraft<T extends Partial<ComponentDocsJson>>(d: T, sections?: readonly ProseKey[]): T {\n if (!sections) {\n const { draftedSections: _all, ...rest } = d;\n return { ...rest, draftedBy: 'claude', needsReview: true } as T;\n }\n const waiting = d.needsReview === true ? (d.draftedSections ?? (d.draftedBy ? [...PROSE_KEYS] : [])) : [];\n const union = PROSE_KEYS.filter((k) => waiting.includes(k) || sections.includes(k));\n return { ...d, draftedBy: 'claude', needsReview: true, draftedSections: union };\n}\n\n/** Prose sections that wait for review: draftedSections, every prose key for a whole-file draft, none once accepted. */\nexport function sectionsNeedingReview(d: Partial<ComponentDocsJson> | null | undefined): ProseKey[] {\n if (!d || d.needsReview !== true) return [];\n return d.draftedSections ? PROSE_KEYS.filter((k) => d.draftedSections!.includes(k)) : [...PROSE_KEYS];\n}\n\n/** True when the docs hold AI-drafted prose nobody has reviewed yet. */\nexport const needsDocsReview = (d: Partial<ComponentDocsJson> | null | undefined): boolean => Boolean(d && d.needsReview === true);\n\n/** A reviewer accepts drafted prose: needsReview goes false, draftedBy stays as the record of who wrote it. */\nexport function acceptDocsDraft(d: ComponentDocsJson): ComponentDocsJson {\n const { draftedSections: _done, ...rest } = d;\n return { ...rest, needsReview: false };\n}\n\n/** docs.json text the way the repo writes it: two spaces, keys in the Button.docs.json order, trailing newline. */\nexport function formatDocsJson(d: Partial<ComponentDocsJson>): string {\n const order = ['summary', 'category', 'status', ...DOCS_KEYS.filter((k) => k !== 'summary'), 'draftedBy', 'draftedSections', 'needsReview'];\n const out: Record<string, unknown> = {};\n for (const k of order) if ((d as Record<string, unknown>)[k] !== undefined) out[k] = (d as Record<string, unknown>)[k];\n for (const [k, v] of Object.entries(d)) if (!(k in out) && v !== undefined) out[k] = v;\n return `${JSON.stringify(out, null, 2)}\\n`;\n}\n\n/** Keeps untouched nodes as they were written; rebuilds only what changed, in the shape of what it replaces. */\nfunction patchNode(old: JsonNode, next: unknown): JsonNode {\n if (plainEqual(toPlain(old), next)) return old;\n if (old.kind === 'object' && next && typeof next === 'object' && !Array.isArray(next)) {\n const n = next as Record<string, unknown>;\n const kept = old.entries.filter((e) => n[e.key] !== undefined).map((e): JsonEntry => ({ key: e.key, value: patchNode(e.value, n[e.key]) }));\n const added = Object.keys(n)\n .filter((k) => n[k] !== undefined && !getEntry(old, k))\n .map((k): JsonEntry => ({ key: k, value: fromPlain(n[k], undefined, old.inline) }));\n return { kind: 'object', inline: old.inline, entries: [...kept, ...added] };\n }\n if (old.kind === 'array' && Array.isArray(next)) {\n return { kind: 'array', inline: old.inline, items: next.map((v, i) => (old.items[i] ? patchNode(old.items[i]!, v) : fromPlain(v, old.items[0], old.inline))) };\n }\n return fromPlain(next, old);\n}\n\n/**\n * docs.json text for edited docs, written as a minimal diff of the file it replaces: untouched sections stay byte for\n * byte (a hand-formatted file keeps its inline preview nodes), new keys go at the end in the repo order. Without an\n * original (or with one that is not valid JSON) it falls back to formatDocsJson.\n */\nexport function patchDocsJson(original: string | null | undefined, next: Partial<ComponentDocsJson>): string {\n const plain = JSON.parse(formatDocsJson(next)) as unknown;\n if (!original) return formatDocsJson(next);\n try {\n const doc = parseJson(original);\n if (doc.root.kind !== 'object') return formatDocsJson(next);\n return serializeJson({ ...doc, root: patchNode(doc.root, plain) });\n } catch {\n return formatDocsJson(next);\n }\n}\n\n/** Accepts the drafted prose inside a docs.json text: only the review lines change. Throws on invalid JSON. */\nexport function acceptDocsText(text: string): string {\n return patchDocsJson(text, acceptDocsDraft(JSON.parse(text) as ComponentDocsJson));\n}\n\n/** Tier and bump of a docs-only change: Tier 1 under the shared classifier, and a patch. */\nexport const DOCS_CHANGE_BUMP = 'patch' as const;\n","// Change drafts: the words a designer would otherwise type by hand when sending a change for review. Deterministic and\n// offline: computed only from what the diff detected, so they never invent a reason or a number. Shared by the Figma\n// plugin (request form, Push description) and any tool that sends requests or pull requests from detected changes.\n//\n// Voice (docs/DESIGN-LANGUAGE.md section 10): sentence case, starts with a verb, no em dash, digits for numbers.\n// A request title never repeats the component: the issue title already starts with it (\"Badge: add a danger tone\").\n\nimport type { DiffEntry } from './diff-engine';\nimport type { RequestChange, RequestKind } from './requests';\nimport { modeDisplayName } from './types';\nimport { formatValue } from './values';\n\nexport interface DraftText {\n /** One line, sentence case, no trailing period. Empty when nothing was detected. */\n title: string;\n /** 1 or 2 sentences. Empty when nothing was detected. */\n summary: string;\n}\n\n/** Removes em dashes (U+2014), the punctuation the Bridge voice never uses: \" a [em dash] b \" becomes \"a, b\". */\nexport function cleanDraftText(text: string): string {\n return text\n .replace(/\\s*\\u2014\\s*/g, ', ')\n .replace(/,\\s*,/g, ',')\n .replace(/^,\\s*/, '')\n .replace(/[ \\t]+/g, ' ')\n .trim();\n}\n\nconst values = (s: string | undefined) => (s ?? '').split(', ').map((x) => x.trim()).filter(Boolean);\nconst article = (word: string) => (/^[aeiou]/i.test(word) ? 'an' : 'a');\nconst andList = (xs: string[]) => (xs.length <= 1 ? (xs[0] ?? '') : `${xs.slice(0, -1).join(', ')} and ${xs[xs.length - 1]}`);\nconst plural = (n: number, word: string, many = `${word}s`) => `${n} ${n === 1 ? word : many}`;\nconst capital = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\nconst lower = (s: string) => s.charAt(0).toLowerCase() + s.slice(1);\n\n/** \"boolean, default false\" -> { type: \"boolean\", def: \"false\" }. */\nfunction propShape(s: string | undefined): { type: string; def: string } | undefined {\n if (!s) return undefined;\n const m = /^(.*?), default (.*)$/.exec(s);\n return m ? { type: m[1]!, def: m[2]! } : { type: s, def: '' };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Structure changes: a layer added, removed or moved in a variant. The scan writes them as rows\n// `New layer \"Icon\" (Size=sm, Variant=primary)` with the kind and the place as values:\n// added `instance Icon/Pencil, after \"Label\"`, removed the same as `before`, moved `after \"A\"` -> `before \"B\"`.\n\nconst VARIANT_FIRST = ['variant', 'tone', 'intent', 'appearance', 'kind', 'type', 'style'];\n\n/** \"Size=sm, State=Default, Variant=primary\" -> \"primary sm\": the values a designer says, default states left out. */\nexport function shortVariant(key: string): string {\n const pairs = key.split(', ').map((p) => {\n const at = p.indexOf('=');\n return at < 0 ? { k: '', v: p.trim() } : { k: p.slice(0, at).trim(), v: p.slice(at + 1).trim() };\n });\n const kept = pairs.filter((p) => p.v && !/^default$/i.test(p.v));\n if (!kept.length) return key;\n const rank = (k: string) => {\n const i = VARIANT_FIRST.indexOf(k.toLowerCase());\n return i < 0 ? VARIANT_FIRST.length : i;\n };\n return kept\n .map((p, i) => ({ ...p, i }))\n .sort((a, b) => rank(a.k) - rank(b.k) || a.i - b.i)\n .map((p) => p.v)\n .join(' ');\n}\n\n/** \"Size=sm, Variant=primary; Size=md, Variant=primary\" -> \"primary sm and primary md\"; empty -> \"every variant\". */\nexport const shortVariants = (list: string | undefined) => (list ? andList(list.split('; ').map(shortVariant)) : 'every variant');\n\nexport interface StructureRow {\n op: 'added' | 'removed' | 'moved';\n name: string;\n /** \"in primary sm\" or \"in every variant\". */\n where: string;\n /** Layer type in words (\"instance\", \"text\", \"frame\"), when known. */\n type?: string | undefined;\n /** Main component of an instance (\"Icon/Pencil\"). */\n main?: string | undefined;\n /** Where it sits now (added, moved) or sat (removed): `after \"Label\"`, `before \"Label\"`, `alone`. */\n at?: string | undefined;\n /** Moved: where it sat before. */\n from?: string | undefined;\n}\n\n/** A structure row read back, or undefined when the field is not one. */\nexport function parseStructureChange(c: RequestChange): StructureRow | undefined {\n const m = /^(New|Removed|Moved) layer \"(.*)\"(?: \\((.*)\\))?$/.exec(c.field);\n if (!m) return undefined;\n const op = m[1] === 'New' ? 'added' : m[1] === 'Removed' ? 'removed' : 'moved';\n const where = `in ${shortVariants(m[3])}`;\n if (op === 'moved') return { op, name: m[2]!, where, at: c.after, from: c.before };\n const shape = (op === 'added' ? c.after : c.before) ?? '';\n const sm = /^(\\S+)(?: (.*?))?, ((?:after|before) \".*\"|alone)$/.exec(shape);\n return { op, name: m[2]!, where, ...(sm ? { type: sm[1], ...(sm[2] ? { main: sm[2] } : {}), at: sm[3] } : {}) };\n}\n\nfunction structurePhrase(r: StructureRow): string {\n const type = r.type ? `${r.type} ` : '';\n const main = r.main ? ` (${r.main})` : '';\n const at = r.at && r.at !== 'alone' ? ` ${r.at}` : '';\n if (r.op === 'added') return `New ${type}layer \"${r.name}\"${main}${at} ${r.where}`;\n if (r.op === 'removed') return `Removed ${type}layer \"${r.name}\"${main}${at} ${r.where}`;\n return `Moved layer \"${r.name}\" ${r.at ?? ''}${r.from ? ` (was ${r.from})` : ''} ${r.where}`.replace(/\\s+/g, ' ');\n}\n\nconst bare = (at: string | undefined) => (at ?? '').replace(/\"/g, '');\n\n/** Title and summary for the first change of a detected component change. */\nfunction firstChange(component: string, kind: RequestKind, c: RequestChange | undefined, all: RequestChange[]): DraftText {\n switch (kind) {\n case 'new-component': {\n const axes = all.filter((x) => x.field.startsWith('Variant '));\n const props = all.filter((x) => x.field.startsWith('Prop '));\n const parts = [axes.length ? plural(axes.length, 'variant axis', 'variant axes') : '', props.length ? plural(props.length, 'prop') : ''].filter(Boolean);\n return {\n title: `Add the ${component} component`,\n summary: `${component} is not in code yet.${parts.length ? ` The Figma component has ${andList(parts)}.` : ''}`,\n };\n }\n case 'new-variant': {\n if (!c) return { title: `Update the ${component} variants`, summary: `The variants of ${component} changed in Figma.` };\n const axis = c.field.replace(/^Variant /, '');\n const before = values(c.before);\n const after = values(c.after);\n const added = after.filter((x) => !before.includes(x));\n const removed = before.filter((x) => !after.includes(x));\n const word = axis.toLowerCase();\n if (!before.length) return { title: `Add a ${axis} variant axis`, summary: `${component} gets a new variant axis, ${axis}, with ${after.length === 1 ? 'the value' : 'the values'} ${andList(after)}.` };\n if (!after.length) return { title: `Remove the ${axis} variant axis`, summary: `${component} no longer has the ${axis} variant axis (${andList(before)}).` };\n if (added.length === 1 && !removed.length) return { title: `Add ${article(added[0]!)} ${added[0]} ${word}`, summary: `${component} gets a new ${axis} value, ${added[0]}.` };\n if (added.length && !removed.length) return { title: `Add ${andList(added)} to ${axis}`, summary: `${component} gets ${plural(added.length, `new ${axis} value`)}: ${andList(added)}.` };\n if (removed.length === 1 && !added.length) return { title: `Remove the ${removed[0]} ${word}`, summary: `${component} no longer has the ${axis} value ${removed[0]}.` };\n if (removed.length && !added.length) return { title: `Remove ${andList(removed)} from ${axis}`, summary: `${component} no longer has the ${axis} values ${andList(removed)}.` };\n return { title: `Change the ${axis} values`, summary: `${axis} on ${component} goes from ${andList(before)} to ${andList(after)}.` };\n }\n case 'prop-change': {\n if (!c) return { title: `Change a ${component} prop`, summary: `A prop of ${component} changed in Figma.` };\n const name = c.field.replace(/^Prop /, '');\n const b = propShape(c.before);\n const a = propShape(c.after);\n if (!b && a) return { title: `Add the ${name} prop`, summary: `${component} gets a new ${a.type} prop, ${name}${a.def ? `, default ${a.def}` : ''}.` };\n if (b && !a) return { title: `Remove the ${name} prop`, summary: `${component} no longer has the ${name} prop.` };\n if (b && a && b.type === a.type && b.def !== a.def) return { title: `Change the ${name} default to ${a.def || 'empty'}`, summary: `The default of ${name} on ${component} goes from ${b.def || 'empty'} to ${a.def || 'empty'}.` };\n return { title: `Change the ${name} prop`, summary: `${name} on ${component} goes from ${c.before ?? 'none'} to ${c.after ?? 'none'}.` };\n }\n case 'token-binding': {\n if (!c) return { title: 'Use another token', summary: `A part of ${component} uses another token in Figma.` };\n const m = /^(.*?)(?: \\((.*)\\))?$/.exec(c.field)!;\n const part = lower(m[1]!);\n const where = m[2] ? ` in ${m[2]}` : '';\n const after = c.after && c.after !== 'none' ? c.after : '';\n const before = c.before && c.before !== 'none' ? c.before : '';\n if (!after) return { title: `Unbind the ${part}`, summary: `The ${part} of ${component}${where} no longer uses ${before || 'a token'}.` };\n return {\n title: `Use ${after} for the ${part}`,\n summary: `The ${part} of ${component}${where} ${before ? `moves from ${before} to ${after}` : `now uses ${after}`}.`,\n };\n }\n case 'structure': {\n const r = c ? parseStructureChange(c) : undefined;\n if (!r) return { title: 'Change the layers to match Figma', summary: `The layers of ${component} changed in Figma.` };\n if (r.op === 'added') {\n const at = r.at && r.at !== 'alone' ? ` ${bare(r.at)}` : '';\n return { title: `Add a layer${at}`, summary: `${component} gets ${article(r.type ?? 'layer')} ${r.type ?? 'layer'}${r.type ? ' layer' : ''}, ${r.name}${r.main ? ` (${r.main})` : ''}${at} ${r.where}.` };\n }\n if (r.op === 'removed') return { title: `Remove the ${r.name} layer`, summary: `${component} no longer has the ${r.name} layer ${r.where}.` };\n return { title: `Move the ${r.name} layer`, summary: `The ${r.name} layer of ${component} moves ${bare(r.at) || 'elsewhere'}${r.from ? ` (it was ${bare(r.from)})` : ''} ${r.where}.` };\n }\n case 'visual':\n return {\n title: 'Update the look to match Figma',\n summary: `${component} looks different in Figma${c?.field.startsWith('Look of ') && c.field !== 'Look of every variant' ? ` in ${c.field.slice(8)}` : ''}, and no variable edit explains it.`,\n };\n default:\n return { title: '', summary: '' };\n }\n}\n\n/**\n * The deterministic title and summary of a component change request, from the changes a scan detected. Manual\n * requests with no detected change (a bug, an idea) get empty text: there is nothing factual to say yet.\n */\nexport function draftRequestText(component: string, kind: RequestKind, changes: RequestChange[]): DraftText {\n const name = component.trim() || 'the component';\n if (!changes.length && kind !== 'new-component') return { title: '', summary: '' };\n const d = firstChange(name, kind, changes[0], changes);\n const rest = kind === 'new-component' ? 0 : changes.length - 1;\n const summary = rest > 0 ? `${d.summary} ${capital(plural(rest, 'other change'))} ${rest === 1 ? 'is' : 'are'} listed below.` : d.summary;\n return { title: cleanDraftText(d.title), summary: cleanDraftText(summary) };\n}\n\n// ---------------------------------------------------------------------------------------------\n// Change lines: one sentence per detected component change, the main line of its row in the plugin and the first line\n// of its request. Claude rewrites it from the before and after images; this is the deterministic default.\n\n/** A change line is one sentence of at most this many characters, with no trailing period. */\nexport const DRAFT_LINE_MAX = 120;\n\n/** Shortens to `max` characters at a word boundary, without a trailing period. */\nfunction clipText(text: string, max: number): string {\n const t = text.replace(/\\s+/g, ' ').trim().replace(/\\.$/, '');\n if (t.length <= max) return t;\n const cut = t.slice(0, max + 1);\n const at = cut.lastIndexOf(' ');\n return (at > max * 0.5 ? cut.slice(0, at) : t.slice(0, max)).replace(/[\\s,;:(]+$/, '');\n}\n\n/** A change line kept to the contract: one line, no em dash, at most 120 characters, no trailing period. */\nexport function sanitizeDraftLine(raw: unknown): string {\n if (typeof raw !== 'string') return '';\n return capital(clipText(cleanDraftText(raw.replace(/[\\r\\n]+/g, ' ')), DRAFT_LINE_MAX));\n}\n\n/** One change row as a short phrase a developer reads (\"Fill uses color.x instead of color.y in Size=sm\"). */\nfunction changePhrase(c: RequestChange): string {\n let m: RegExpExecArray | null;\n if ((m = /^Variant (.+)$/.exec(c.field))) {\n const axis = m[1]!;\n const before = values(c.before);\n const after = values(c.after);\n if (!before.length) return `New ${axis} variant axis: ${after.join(', ')}`;\n if (!after.length) return `${axis} variant axis removed (${before.join(', ')})`;\n const added = after.filter((x) => !before.includes(x));\n const removed = before.filter((x) => !after.includes(x));\n const parts = [added.length ? `${andList(added)} added to ${axis}` : '', removed.length ? `${andList(removed)} removed from ${axis}` : ''].filter(Boolean);\n return parts.join('; ') || `${axis} values reordered: ${after.join(', ')}`;\n }\n if ((m = /^Prop (.+)$/.exec(c.field))) {\n const name = m[1]!;\n const b = propShape(c.before);\n const a = propShape(c.after);\n if (!b && a) return `New ${a.type} prop ${name}${a.def ? `, default ${a.def}` : ''}`;\n if (b && !a) return `${name} prop removed`;\n if (b && a && b.type === a.type) return `${name} default goes from ${b.def || 'empty'} to ${a.def || 'empty'}`;\n return `${name} prop goes from ${c.before ?? 'none'} to ${c.after ?? 'none'}`;\n }\n if ((m = /^Swapped instance(?: \\((.*)\\))?$/.exec(c.field))) return `Shows ${c.after ?? 'another instance'} instead of ${c.before ?? 'the coded one'} ${m[1] ? `in ${m[1]}` : 'in every variant'}`;\n if ((m = /^Look of (.+)$/.exec(c.field))) return `Looks different in ${m[1]}; no variable explains it`;\n const layer = parseStructureChange(c);\n if (layer) return structurePhrase(layer);\n // A token binding: \"Fill\" or \"Fill (Size=sm, Tone=primary)\".\n m = /^(.*?)(?: \\((.*)\\))?$/.exec(c.field)!;\n const where = m[2] ? ` in ${m[2]}` : '';\n const before = c.before && c.before !== 'none' ? c.before : '';\n const after = c.after && c.after !== 'none' ? c.after : '';\n if (!after) return `${m[1]} no longer uses ${before || 'a token'}${where}`;\n if (!before) return `${m[1]} now uses ${after}${where}`;\n return `${m[1]} uses ${after} instead of ${before}${where}`;\n}\n\n/**\n * The deterministic change line of a detected component change: what changed, in one sentence, from the diff only.\n * The first change is spelled out, the others counted (\"and 2 more\"). Empty when nothing was detected.\n */\nexport function draftChangeLine(kind: RequestKind, changes: RequestChange[]): string {\n if (kind === 'new-component') {\n const axes = changes.filter((x) => x.field.startsWith('Variant ')).length;\n const props = changes.filter((x) => x.field.startsWith('Prop ')).length;\n const parts = [axes ? plural(axes, 'variant axis', 'variant axes') : '', props ? plural(props, 'prop') : ''].filter(Boolean);\n return `New component${parts.length ? ` with ${andList(parts)}` : ''}, not in code yet`;\n }\n if (!changes.length) return '';\n const first = changePhrase(changes[0]!);\n const rest = changes.length - 1;\n const tail = rest ? ` (and ${rest} more)` : '';\n return capital(clipText(cleanDraftText(first), DRAFT_LINE_MAX - tail.length)) + tail;\n}\n\n// ---------------------------------------------------------------------------------------------\n// Push description (variables pull request and the requests sent with it)\n\nconst tokenOf = (e: DiffEntry) => e.figma ?? e.head ?? e.base;\nconst pathOf = (e: DiffEntry) => tokenOf(e)?.path ?? e.path;\n\n/** One line per variable edit for a change table: the token, its value before, its value in Figma. */\nexport function pushChangeRows(entries: DiffEntry[]): RequestChange[] {\n return entries.map((e) => {\n const before = e.head ?? e.base;\n const after = e.figma;\n const show = (t: typeof before) => {\n if (!t) return undefined;\n const modes = Object.keys(t.values);\n if (modes.length <= 1) return formatValue(t.type, t.values[modes[0] ?? '']);\n return modes.map((m) => `${modeDisplayName(m)} ${formatValue(t.type, t.values[m])}`).join('; ');\n };\n const renamed = e.local?.kind === 'renamed' && before && after && before.path !== after.path;\n return { field: renamed ? `${before.path} -> ${after.path}` : pathOf(e), before: show(before), after: show(after) };\n });\n}\n\n/** \"a, b and c\", or \"7 tokens, including a and b\" when the list is long. */\nfunction names(paths: string[]): string {\n if (paths.length <= 3) return andList(paths);\n return `${paths.length} tokens, including ${andList(paths.slice(0, 2))}`;\n}\n\n/** Modes a changed token's value moved in (\"Light and Dark\"), for a single changed token. */\nfunction valueModes(e: DiffEntry): string[] {\n return (e.local?.fields ?? []).filter((f) => f.field === 'value' && f.mode && f.mode !== 'value').map((f) => modeDisplayName(f.mode!));\n}\n\nexport interface PushDraftComponent {\n component: string;\n kind: RequestKind;\n}\n\n/**\n * The deterministic Push description: what the checked variable edits do and which components get a request.\n * 1 or 2 sentences, never a reason (only the designer knows why). Empty when nothing is checked.\n */\nexport function draftPushDescription(entries: DiffEntry[], components: PushDraftComponent[] = []): string {\n const by: Record<'changed' | 'added' | 'renamed' | 'removed', DiffEntry[]> = { changed: [], added: [], renamed: [], removed: [] };\n for (const e of entries) by[e.local?.kind ?? 'changed'].push(e);\n const clauses: string[] = [];\n if (by.changed.length) {\n const only = by.changed.length === 1 ? by.changed[0]! : undefined;\n const fields = new Set((only?.local?.fields ?? []).map((f) => f.field));\n const modes = only ? valueModes(only) : [];\n if (only && fields.size === 1 && fields.has('description')) clauses.push(`updates the description of ${pathOf(only)}`);\n else if (only && modes.length) clauses.push(`changes ${pathOf(only)} in ${andList(modes)}`);\n else clauses.push(`changes ${names(by.changed.map(pathOf))}`);\n }\n if (by.added.length) clauses.push(`adds ${names(by.added.map(pathOf))}`);\n if (by.renamed.length) {\n const r = by.renamed[0]!;\n const from = (r.head ?? r.base)?.path;\n clauses.push(by.renamed.length === 1 && from && from !== pathOf(r) ? `renames ${from} to ${pathOf(r)}` : `renames ${names(by.renamed.map(pathOf))}`);\n }\n if (by.removed.length) clauses.push(`removes ${names(by.removed.map(pathOf))}`);\n const sentences: string[] = [];\n if (clauses.length) sentences.push(`${capital(andList(clauses))}.`);\n const fresh = components.filter((c) => c.kind === 'new-component').map((c) => c.component);\n const changed = [...new Set(components.filter((c) => c.kind !== 'new-component').map((c) => c.component))];\n const comp: string[] = [];\n if (changed.length) comp.push(`${changed.length === 1 ? 'a change' : 'changes'} to ${andList(changed)}`);\n if (fresh.length) comp.push(`the new ${andList(fresh)} component${fresh.length === 1 ? '' : 's'}`);\n if (comp.length) sentences.push(`Requests ${andList(comp)}.`);\n return cleanDraftText(sentences.join(' '));\n}\n","// Explorations: try experimental variables and components in a real product staging branch without touching main.\n// An exploration is a branch named `explore/<slug>` with an open DRAFT pull request labeled `exploration`. It holds\n// token edits and component work (requests filed with `exploration: explore/<slug>` are implemented there). Every\n// exploration gets the per-branch previews (bridge.config.json previews.apps) and a snapshot of the packages a product\n// staging branch installs (.github/workflows/preview-packages.yml). It is never merged as is: when the idea is\n// validated it is promoted to a normal pull request for review, otherwise it is closed. The CI check \"Exploration not\n// merged as is\" fails while the label is on, so an exploration cannot be merged by accident.\n//\n// Pure: branch naming, the draft pull request body, status and the promotion plan. Shared by Studio, the MCP server\n// and the CLI, so an exploration reads the same everywhere. GitHub calls live in explorations-github.ts.\n\nimport type { BridgeConfig } from './config';\nimport { slugify } from './pr-composer';\nimport { previewLinks, readPreviewComment, type PreviewApps } from './previews';\nimport { classifyRisk, type ChangedFile, type RiskTier } from './risk';\n\n/** Every exploration pull request carries this label while it is an exploration. */\nexport const EXPLORATION_LABEL = 'exploration';\n/** Exploration branches start with it. */\nexport const EXPLORATION_PREFIX = 'explore/';\n/** Where the note that starts an exploration branch lives. Promotion removes it, so main never gets it. */\nexport const EXPLORATION_NOTES_DIR = '.bridge/explorations';\n/** What Studio shows instead of a risk tier while the pull request is an exploration. */\nexport const EXPLORATION_TIER_LABEL = 'Exploration (not mergeable)';\n/** Name of the CI job that fails while the label is on. */\nexport const EXPLORATION_CHECK = 'Exploration not merged as is';\n\nexport type ExplorationUseCase = 'user-test' | 'stakeholder-demo' | 'ab-idea' | 'terminal' | 'other';\nexport type ExplorationStatus = 'active' | 'promoted' | 'closed';\n/** Where an exploration was started: Bridge Studio, the Figma plugin, the CLI or the MCP server (an AI agent). */\nexport type ExplorationSource = 'studio' | 'figma' | 'cli' | 'mcp';\n\nexport const EXPLORATION_USE_CASES: { value: ExplorationUseCase; label: string; hint: string }[] = [\n { value: 'user-test', label: 'Prototype for a user test', hint: 'A coded prototype on a product staging branch, with the real components and tokens.' },\n { value: 'stakeholder-demo', label: 'Stakeholder demo', hint: 'Show an idea on real screens before anyone commits to it.' },\n { value: 'ab-idea', label: 'A/B idea', hint: 'Ship a variant to a staging or experiment branch and compare it with what is live.' },\n { value: 'terminal', label: 'Exploring with Claude Code', hint: 'A designer works from the terminal with Claude and the Bridge MCP server on this branch, never on main.' },\n { value: 'other', label: 'Other', hint: 'Anything else worth trying before it becomes a change.' },\n];\n\nexport const EXPLORATION_STATUS_LABEL: Record<ExplorationStatus, string> = { active: 'Running', promoted: 'Promoted to review', closed: 'Closed' };\n\nexport interface Exploration {\n /** Display name, sentence case: \"Denser data tables\". */\n name: string;\n /** What the team wants to learn, in one or two sentences. */\n purpose: string;\n /** Branch slug: `explore/<slug>`. Derived from the name when missing. */\n slug?: string | undefined;\n useCase?: ExplorationUseCase | undefined;\n /** What is experimental, one line each: \"color.action.primary.bg\", \"Button: pill radius\". */\n experimental?: string[] | undefined;\n /** GitHub login of who started it, when known. */\n author?: string | undefined;\n /** ISO date it started. */\n startedAt?: string | undefined;\n /** Where it was started, so Studio says \"You\" only for what the viewer started there. */\n source?: ExplorationSource | undefined;\n /** The AI agent that started it (\"claude\"), when one did: the GitHub account alone cannot tell. */\n agent?: string | undefined;\n /** A Jira ticket key (\"DS-42\"), first in the pull request title so Jira's GitHub integration links it. */\n jira?: string | undefined;\n}\n\nconst MARK = 'bridge-exploration';\nconst SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/** \"Denser data tables!\" -> \"denser-data-tables\". Up to 40 characters, cut at a word boundary. Empty when nothing is left. */\nexport function explorationSlug(name: string): string {\n const s = name.trim().replace(/^explore\\//i, '');\n if (!/[a-z0-9]/i.test(s)) return '';\n return slugify(s, 40);\n}\n\n/** `explore/<slug>` for a name, a slug or a branch name. */\nexport function explorationBranch(nameOrBranch: string): string {\n return `${EXPLORATION_PREFIX}${explorationSlug(nameOrBranch)}`;\n}\n\n/** True for `explore/<valid-slug>`. */\nexport function isExplorationBranch(ref: string | null | undefined): boolean {\n const r = (ref ?? '').replace(/^refs\\/heads\\//, '');\n return r.startsWith(EXPLORATION_PREFIX) && SLUG_RE.test(r.slice(EXPLORATION_PREFIX.length));\n}\n\n/** The slug of an exploration branch, or null. */\nexport function explorationSlugFromBranch(ref: string): string | null {\n return isExplorationBranch(ref) ? ref.replace(/^refs\\/heads\\//, '').slice(EXPLORATION_PREFIX.length) : null;\n}\n\n/** Path of the note that starts an exploration branch. */\nexport const explorationNotePath = (slug: string) => `${EXPLORATION_NOTES_DIR}/${slug}.md`;\n\n/** Problems with a new exploration, as sentences that say how to fix them. Empty when it can start. */\nexport function explorationProblems(e: Pick<Exploration, 'name' | 'purpose'> & { slug?: string | undefined }): string[] {\n const out: string[] = [];\n const name = e.name.trim();\n const slug = e.slug?.trim() || explorationSlug(name);\n if (!name) out.push('Name the exploration, for example \"Denser data tables\".');\n else if (name.length > 60) out.push('Keep the name under 60 characters: it becomes the branch name.');\n else if (slug.length < 2 || !SLUG_RE.test(slug)) out.push('Use letters or digits in the name: it becomes the branch explore/<name>.');\n if (!e.purpose.trim()) out.push('Say what you want to learn, in one sentence.');\n return out;\n}\n\nconst useCaseLabel = (u: ExplorationUseCase | undefined) => EXPLORATION_USE_CASES.find((x) => x.value === u)?.label;\n\n/** The note committed as the first commit of the branch (`.bridge/explorations/<slug>.md`). */\nexport function explorationNote(e: Exploration): string {\n const slug = e.slug || explorationSlug(e.name);\n const uc = useCaseLabel(e.useCase);\n return [\n `# Exploration: ${e.name.trim()}`,\n '',\n e.purpose.trim(),\n '',\n `- Branch: \\`${EXPLORATION_PREFIX}${slug}\\``,\n ...(uc ? [`- Use case: ${uc}`] : []),\n ...(e.startedAt ? [`- Started: ${e.startedAt.slice(0, 10)}${e.author ? ` by @${e.author}` : ''}`] : []),\n '',\n 'This file marks the branch as an exploration. It is never merged as is: promoting the pull request to review removes it.',\n '',\n ].join('\\n');\n}\n\nexport interface ExplorationPrContext {\n owner: string;\n repo: string;\n /** Unknown before the pull request exists: the install section then says where the command will appear. */\n pr?: number | undefined;\n packages: string[];\n apps: PreviewApps;\n /** Requests implemented on this exploration. */\n requests?: { number: number; title: string }[] | undefined;\n}\n\n/** Draft pull request title: \"Exploration: denser data tables\". */\nexport function explorationPrTitle(e: Pick<Exploration, 'name'>): string {\n const n = e.name.trim().replace(/\\.$/, '');\n return `Exploration: ${n.charAt(0).toLowerCase()}${n.slice(1)}`;\n}\n\n/**\n * The draft pull request body: purpose, what is experimental, how a product staging branch installs it, the\n * previews, and how to promote or close it. Markdown for people plus one hidden JSON block for tools.\n */\nexport function explorationPrBody(e: Exploration, ctx: ExplorationPrContext): string {\n const slug = e.slug || explorationSlug(e.name);\n const branch = `${EXPLORATION_PREFIX}${slug}`;\n const uc = useCaseLabel(e.useCase);\n const experimental = (e.experimental ?? []).map((x) => x.trim()).filter(Boolean);\n const lines = [\n `## Exploration: ${e.name.trim()}`,\n '',\n `> Not mergeable as is. This draft pull request is a sandbox on \\`${branch}\\`: promote it to a normal review when the idea is validated, or close it.`,\n '',\n `**Purpose.** ${e.purpose.trim()}`,\n ...(uc ? ['', `**Use case.** ${uc}`] : []),\n '',\n '### What is experimental',\n '',\n ...(experimental.length ? experimental.map((x) => `- ${x}`) : ['- Token edits and component work committed to this branch. Nothing here reaches main or production.']),\n ...(ctx.requests?.length ? ['', 'Requests implemented here:', ...ctx.requests.map((r) => `- #${r.number} ${r.title}`)] : []),\n '',\n '### Try it in a product staging branch',\n '',\n ];\n // No guessed command here: pkg.pr.new may not be set up. The sticky comment has the one the workflow published.\n lines.push(\n 'In the product repo, on a branch that deploys to staging (production keeps the released version), install the snapshot with the command in the \"Try this exploration in your product\" comment below. It appears a few minutes after each push and always matches the latest commit.',\n );\n lines.push('', '### Previews', '');\n const links = previewLinks(ctx.apps, { branch, ...(ctx.pr ? { pr: ctx.pr } : {}) });\n if (links.length) lines.push('| App | Preview |', '| --- | --- |', ...links.map((l) => `| ${l.label} | ${l.url} |`));\n else lines.push('Preview deploys are not set up: add `previews.apps` to `bridge.config.json` (docs/PREVIEWS.md).');\n lines.push(\n '',\n '### When it is done',\n '',\n `- **Promote:** in Bridge Studio (Changes, Explorations, Promote to review) or \\`bridge explore promote ${slug}\\`. Bridge marks the pull request ready for review, removes the \\`${EXPLORATION_LABEL}\\` label and the exploration note, and adds the tier labels. Then it goes through the usual review.`,\n '- **Close:** close this pull request. The branch stays for reference; the preview prerelease is removed.',\n '',\n `<!-- ${MARK} ${JSON.stringify({ name: e.name.trim(), purpose: e.purpose.trim(), slug, ...(e.useCase ? { useCase: e.useCase } : {}), ...(experimental.length ? { experimental } : {}), ...(e.author ? { author: e.author } : {}), ...(e.startedAt ? { startedAt: e.startedAt } : {}), ...(e.source ? { source: e.source } : {}), ...(e.agent ? { agent: e.agent } : {}) }).replace(/-->/g, '--\\\\u003e')} -->`,\n );\n return lines.join('\\n');\n}\n\n/** The exploration inside a pull request body, or undefined when it has no valid Bridge block. */\nexport function parseExplorationBody(body: string | null | undefined): Exploration | undefined {\n if (!body) return undefined;\n const m = new RegExp(`<!-- ${MARK} (\\\\{[\\\\s\\\\S]*?\\\\}) -->`).exec(body);\n if (!m) return undefined;\n try {\n const e = JSON.parse(m[1]!) as Exploration;\n return e && typeof e.name === 'string' && typeof e.purpose === 'string' ? e : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport interface ExplorationPullLike {\n state: string;\n merged?: boolean | undefined;\n merged_at?: string | null | undefined;\n labels: (string | { name?: string })[];\n headRef?: string | undefined;\n body?: string | null | undefined;\n}\n\nconst labelNames = (labels: ExplorationPullLike['labels']) => labels.map((l) => (typeof l === 'string' ? l : (l.name ?? '')));\n\n/** True for a pull request that is or was an exploration: an `explore/*` branch, the label, or the Bridge block. */\nexport function isExplorationPull(p: ExplorationPullLike): boolean {\n return isExplorationBranch(p.headRef) || labelNames(p.labels).includes(EXPLORATION_LABEL) || Boolean(parseExplorationBody(p.body));\n}\n\n/**\n * Where an exploration stands: closed without merging = closed; open with the `exploration` label = active\n * (running); otherwise promoted (the label was removed, so it is a normal pull request now, open or merged).\n */\nexport function explorationStatus(p: ExplorationPullLike): ExplorationStatus {\n const merged = Boolean(p.merged || p.merged_at || p.state === 'merged');\n if (p.state !== 'open' && !merged) return 'closed';\n if (p.state === 'open' && labelNames(p.labels).includes(EXPLORATION_LABEL)) return 'active';\n return 'promoted';\n}\n\n/** True while the label is on: the pull request must not merge (the CI check fails, Studio blocks the merge). */\nexport const isActiveExploration = (labels: ExplorationPullLike['labels']) => labelNames(labels).includes(EXPLORATION_LABEL);\n\nexport interface PromotionPlan {\n tier: RiskTier;\n reasons: string[];\n /** Labels to remove (the exploration label). */\n removeLabels: string[];\n /** Tier labels from the shared classifier. */\n addLabels: string[];\n /** Files to delete on the branch before review: the exploration note. */\n removeFiles: string[];\n /** The pull request body for review. */\n body: string;\n /** Title without the \"Exploration:\" prefix. */\n title: string;\n markReady: true;\n}\n\n/**\n * What promoting an exploration does: the tier from the files it changes (the shared classifier, the exploration\n * note left out since promotion deletes it), tier labels, the exploration label removed, a review body that keeps\n * the purpose and closes the requests implemented on it, and the draft marked ready for review.\n */\nexport function promotionPlan(input: {\n title: string;\n body: string | null | undefined;\n labels: ExplorationPullLike['labels'];\n files: ChangedFile[];\n config?: BridgeConfig | undefined;\n /** Request issues implemented on this exploration: the review body closes them. */\n requests?: number[] | undefined;\n date?: Date | undefined;\n}): PromotionPlan {\n const exploration = parseExplorationBody(input.body);\n // A Jira key first in the title (\"DS-42 Exploration: pill buttons\") stays first after promotion.\n const jira = /^([A-Z][A-Z0-9_]*-\\d+)\\s+/.exec(input.title)?.[1] ?? null;\n const title = jira ? input.title.slice(jira.length).trim() : input.title;\n const removeFiles = input.files.filter((f) => f.path.startsWith(`${EXPLORATION_NOTES_DIR}/`) && f.status !== 'removed').map((f) => f.path);\n const files = input.files.filter((f) => !f.path.startsWith(`${EXPLORATION_NOTES_DIR}/`));\n const risk = classifyRisk({ files, ...(input.config ? { config: input.config } : {}) });\n const tokens = files.some((f) => f.path.endsWith('.tokens.json'));\n const addLabels = [`tier: ${risk.tier}`, ...(risk.tier === 3 && tokens ? ['tokens'] : [])];\n const date = (input.date ?? new Date()).toISOString().slice(0, 10);\n const existing = new Set(input.body ? [...input.body.matchAll(/\\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#(\\d+)/gi)].map((m) => Number(m[1])) : []);\n const closes = [...new Set(input.requests ?? [])].filter((n) => !existing.has(n));\n const kept = (input.body ?? '')\n // The sandbox warning and the promote/close instructions no longer apply.\n .replace(/^> Not mergeable as is\\..*$\\n?\\n?/m, '')\n .replace(/### When it is done[\\s\\S]*?(?=<!-- |$)/, '')\n .replace(/^## Exploration: /m, '## ')\n .trim();\n const body = [\n `**Promoted from an exploration on ${date}.** Review it like any change: the tier below comes from the files it touches.`,\n '',\n kept || `## ${title.replace(/^Exploration:\\s*/i, '')}`,\n '',\n `**Risk tier:** ${risk.tier}.`,\n ...risk.reasons.slice(0, 8).map((r) => `- ${r}`),\n ...(closes.length ? ['', ...closes.map((n) => `Closes #${n}`)] : []),\n ].join('\\n');\n const t = title.replace(/^Exploration:\\s*/i, '').trim() || exploration?.name || title;\n return {\n tier: risk.tier,\n reasons: risk.reasons,\n removeLabels: [EXPLORATION_LABEL],\n addLabels,\n removeFiles,\n body,\n title: `${jira ? `${jira} ` : ''}${t.charAt(0).toUpperCase()}${t.slice(1)}`,\n markReady: true,\n };\n}\n\n/** Where the test build of an exploration stands, from its sticky preview comment and the branch head. */\nexport type ExplorationTryIt =\n | { state: 'ready'; command: string; source: 'pkg.pr.new' | 'release' | 'other'; sha7: string | null }\n | { state: 'building' }\n | { state: 'failed' };\n\n/**\n * The install command a product staging branch can trust, read from the `<!-- bridge-branch-preview -->` comment,\n * never guessed: no comment yet, or a comment about an older commit than the head, means the snapshot is still\n * building; a comment without a command means the publish failed.\n */\nexport function explorationTryIt(input: { comment?: string | null | undefined; headSha?: string | null | undefined }): ExplorationTryIt {\n const c = readPreviewComment(input.comment);\n if (!c) return { state: 'building' };\n if (input.headSha && c.sha7 && !input.headSha.startsWith(c.sha7)) return { state: 'building' };\n if (!c.command || c.source === 'none') return { state: 'failed' };\n return { state: 'ready', command: c.command, source: c.source, sha7: c.sha7 };\n}\n\n/**\n * The message a designer sends a developer: what the exploration is, the install command for a product staging\n * branch, the previews and the pull request. Plain text, one paragraph, ready to paste in a chat.\n */\nexport function explorationShareMessage(input: { name: string; branch: string; url: string; command?: string | null | undefined; previews?: { label: string; url: string }[] | undefined }): string {\n const name = input.name.trim().replace(/\"/g, \"'\");\n const head = input.command\n ? `Exploration \"${name}\" (${input.branch}): try it in a staging branch of your product with: ${input.command}.`\n : `Exploration \"${name}\" (${input.branch}): its test build is being prepared, the install command for a staging branch of your product will be on the pull request in a few minutes.`;\n const previews = (input.previews ?? []).map((p) => `${p.label} ${p.url}`);\n return [head, previews.length ? `Previews: ${previews.join(', ')}.` : '', `Pull request: ${input.url}.`].filter(Boolean).join(' ');\n}\n\n/**\n * The rules Claude follows on an exploration branch (request briefs, docs drafts, token edits with a target branch):\n * work there, never on main, and never open a pull request to main: the exploration's draft pull request is the place.\n */\nexport function explorationRules(branch: string): string[] {\n return [\n `- Work on the existing branch ${branch} (git fetch origin && git switch ${branch}). Commit there.`,\n `- Do not open a pull request to main and do not create another branch: the draft pull request of ${branch} is the place. It is promoted to review only when the idea is validated.`,\n '- Do not mark the pull request ready for review and do not remove the exploration label: promoting is a person\\'s decision.',\n ];\n}\n","// Component change requests: a designer asks for a new component or a change to a coded one (variant, prop, structure,\n// visual, token binding, bug) from Figma or Studio. Variable edits never become requests: they are pull requests\n// people approve (tokens are data). Components need code, so they become requests. Code stays the source of truth, so a request never rewrites React: it lands as\n// a GitHub issue that people (or Claude, through the MCP server or the CLI) implement in a pull request that closes it.\n// Shared by the Figma plugin, Studio, the MCP server, the CLI and the Jira Action, so a request reads the same\n// everywhere. The issue body is plain Markdown for people plus one hidden JSON block for tools.\n\nimport { EXPLORATION_LABEL, explorationRules } from './explorations';\n\nexport type RequestKind = 'new-component' | 'new-variant' | 'prop-change' | 'structure' | 'visual' | 'token-binding' | 'bug' | 'other';\nexport type RequestSource = 'figma' | 'studio' | 'cli' | 'mcp';\nexport type RequestStatus = 'requested' | 'in-progress' | 'done' | 'declined';\n\nexport const REQUEST_KINDS: { value: RequestKind; label: string; hint: string }[] = [\n { value: 'new-component', label: 'New component', hint: 'A component the design system does not have yet.' },\n { value: 'new-variant', label: 'New variant', hint: 'A size, tone or state the component does not have yet.' },\n { value: 'prop-change', label: 'Option change (prop)', hint: 'Add, rename or change an option (a prop in code) or its default.' },\n { value: 'structure', label: 'Structure change', hint: 'A part was added, removed or moved.' },\n { value: 'visual', label: 'Visual change', hint: 'Spacing, radius, layout or icon placement.' },\n { value: 'token-binding', label: 'Token change', hint: 'The component should paint with another token.' },\n { value: 'bug', label: 'Bug', hint: 'It looks or behaves differently from the guidance.' },\n { value: 'other', label: 'Other', hint: 'Anything else.' },\n];\n\n/** Every request issue carries this label; tools list requests by it. */\nexport const REQUEST_LABEL = 'component-change';\n\nexport interface RequestChange {\n /** What changes: a prop, a variant axis, a token, a part (\"radius\", \"size\", \"color.action.primary.bg\"). */\n field: string;\n before?: string | undefined;\n after?: string | undefined;\n}\n\nexport interface ComponentChangeRequest {\n /** Component name as exported (\"Button\"), or the proposed name of a new component. */\n component: string;\n kind: RequestKind;\n /** One line, sentence case: \"Add a danger ghost variant\". */\n title: string;\n /** What and why, in the requester's words. */\n summary: string;\n /**\n * What changed for developers in one sentence (\"Icon added after the label in primary sm: Pencil, 16px\"): written\n * by Claude from the before and after images, or drafted from the detected changes. Optional.\n */\n line?: string | undefined;\n changes: RequestChange[];\n /** Where the design lives, when it comes from Figma. */\n figma?: { fileKey?: string | undefined; nodeId?: string | undefined; nodeName?: string | undefined; url?: string | undefined } | undefined;\n /** Image URLs (Figma exports committed to the requests branch, or links). */\n images?: string[] | undefined;\n source: RequestSource;\n /** GitHub login, when known. */\n requestedBy?: string | undefined;\n /**\n * Exploration branch (`explore/<slug>`) to implement it on instead of a pull request to main. The issue gets the\n * `exploration` label and the brief says to work on that branch (docs/EXPLORATIONS.md).\n */\n exploration?: string | undefined;\n}\n\nexport interface RequestIssue {\n title: string;\n body: string;\n labels: string[];\n assignees: string[];\n}\n\nconst MARK = 'bridge-request';\nconst kindLabel = (k: RequestKind) => REQUEST_KINDS.find((x) => x.value === k)?.label ?? 'Other';\nconst kindSlug = (k: RequestKind) => `request: ${k}`;\n\n/** Issue title: \"Button: add a danger ghost variant\". */\nexport function requestIssueTitle(r: Pick<ComponentChangeRequest, 'component' | 'title'>): string {\n const t = r.title.trim().replace(/\\.$/, '');\n return `${r.component}: ${t.charAt(0).toLowerCase()}${t.slice(1)}`;\n}\n\n/** The GitHub issue for a request: readable Markdown, the labels tools filter on, and a hidden JSON block. */\nexport function composeRequestIssue(r: ComponentChangeRequest, opts: { labels?: string[]; assignees?: string[]; componentUrl?: string } = {}): RequestIssue {\n const rows = r.changes.length\n ? ['| What | Now | Requested |', '| --- | --- | --- |', ...r.changes.map((c) => `| ${cell(c.field)} | ${cell(c.before ?? '')} | ${cell(c.after ?? '')} |`)]\n : [];\n const figma = r.figma?.url ? `[${r.figma.nodeName ?? 'Open in Figma'}](${r.figma.url})` : r.figma?.nodeName ? r.figma.nodeName : '';\n const body = [\n r.kind === 'new-component' ? `## New component request: ${r.component}` : `## ${kindLabel(r.kind)} request for ${r.component}`,\n '',\n r.summary.trim(),\n '',\n ...(r.line?.trim() ? [`**What changes:** ${r.line.trim()}`, ''] : []),\n ...(rows.length ? [...rows, ''] : []),\n ...(r.images?.length ? [...r.images.map((u, i) => ``), ''] : []),\n ...(figma ? [`**Design:** ${figma}`, ''] : []),\n ...(opts.componentUrl ? [`**Component:** ${opts.componentUrl}`, ''] : []),\n ...(r.exploration ? [`**Exploration:** \\`${r.exploration}\\`. Implement it on that branch, not in a pull request to main: it ships to product staging as a snapshot and is promoted to review only when the idea is validated.`, ''] : []),\n '## How to implement',\n '',\n r.exploration\n ? `Commit the change to \\`${r.exploration}\\` (its draft pull request is the place). With Claude: \\`bridge request implement <number>\\` (CLI) or the \\`bridge_get_request\\` MCP tool. Promoting the exploration closes this request when it merges.`\n : `Code is the source of truth: change the component in a pull request that says \\`Closes #<this issue>\\`, so this request closes when it merges. With Claude: \\`bridge request implement <number>\\` (CLI) or the \\`bridge_get_request\\` MCP tool.`,\n '',\n `<sub>Requested from ${sourceLabel(r.source)}${r.requestedBy ? ` by @${r.requestedBy}` : ''} with Bridge.</sub>`,\n '',\n `<!-- ${MARK} ${JSON.stringify(r)} -->`,\n ].join('\\n');\n const labels = [...new Set([REQUEST_LABEL, kindSlug(r.kind), `source: ${r.source}`, ...(r.exploration ? [EXPLORATION_LABEL] : []), ...(opts.labels ?? [])])];\n return { title: requestIssueTitle(r), body, labels, assignees: opts.assignees ?? [] };\n}\n\n/** The request inside an issue body, or undefined when the body has no valid Bridge block. */\nexport function parseRequestIssue(body: string | null | undefined): ComponentChangeRequest | undefined {\n if (!body) return undefined;\n const m = new RegExp(`<!-- ${MARK} (\\\\{[\\\\s\\\\S]*?\\\\}) -->`).exec(body);\n if (!m) return undefined;\n try {\n const r = JSON.parse(m[1]!) as ComponentChangeRequest;\n return r && typeof r.component === 'string' && typeof r.title === 'string' ? { ...r, changes: Array.isArray(r.changes) ? r.changes : [] } : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The issue body with the request linked to an exploration branch: the hidden block gets `exploration` (what the\n * Explorations view, the MCP server and the CLI read) and the readable part says where to implement it. The rest of the\n * body stays as people wrote it. Undefined when the body has no Bridge block (nothing to link).\n */\nexport function withRequestExploration(body: string | null | undefined, branch: string): string | undefined {\n const r = parseRequestIssue(body);\n if (!r || !body) return undefined;\n const block = new RegExp(`<!-- ${MARK} \\\\{[\\\\s\\\\S]*?\\\\} -->`);\n let out = body.replace(block, () => `<!-- ${MARK} ${JSON.stringify({ ...r, exploration: branch })} -->`);\n const line = `**Exploration:** \\`${branch}\\`. Implement it on that branch, not in a pull request to main: it ships to product staging as a snapshot and is promoted to review only when the idea is validated.`;\n if (/^\\*\\*Exploration:\\*\\* .*$/m.test(out)) out = out.replace(/^\\*\\*Exploration:\\*\\* .*$/m, () => line);\n else if (out.includes('\\n## How to implement')) out = out.replace('\\n## How to implement', () => `\\n${line}\\n\\n## How to implement`);\n else out = out.replace(block, (m) => `${line}\\n\\n${m}`);\n return out;\n}\n\n/** Problems with a decline reason, as sentences that say how to fix them. */\nexport function declineReasonProblems(reason: string): string[] {\n const r = reason.trim();\n if (!r) return ['Say why, in one or two sentences: the requester reads it.'];\n if (r.length < 10) return ['Say a bit more, so the requester knows why: at least 10 characters.'];\n return [];\n}\n\n/** The comment posted on a declined request: who declined it and why, in the decliner's words. */\nexport function declineComment(reason: string, by?: string | null): string {\n const quote = reason\n .trim()\n .split('\\n')\n .map((l) => `> ${l}`.trimEnd())\n .join('\\n');\n return [`Declined${by ? ` by @${by.replace(/^@/, '')}` : ''} in Bridge Studio.`, '', quote, '', '<sub>Closed as not planned. Reopen the issue if things change.</sub>'].join('\\n');\n}\n\n/**\n * Where a request stands: open with no linked pull request = requested; open with an open linked pull request =\n * in progress; closed as completed or by a merged pull request = done; closed otherwise = declined.\n */\nexport function requestStatus(issue: { state: 'open' | 'closed'; stateReason?: string | null | undefined; linkedPrs?: { state: 'open' | 'closed'; merged?: boolean }[] }): RequestStatus {\n const prs = issue.linkedPrs ?? [];\n if (issue.state === 'open') return prs.some((p) => p.state === 'open') ? 'in-progress' : 'requested';\n if (prs.some((p) => p.merged) || issue.stateReason === 'completed') return 'done';\n return 'declined';\n}\n\nexport const REQUEST_STATUS_LABEL: Record<RequestStatus, string> = { requested: 'Requested', 'in-progress': 'In progress', done: 'Done', declined: 'Declined' };\n\n/** Issue numbers a pull request body closes (\"Closes #42\", \"fixes #7\", \"resolves #3\"). */\nexport function closingIssueNumbers(body: string | null | undefined): number[] {\n const out = new Set<number>();\n for (const m of (body ?? '').matchAll(/\\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\\s+#(\\d+)/gi)) out.add(Number(m[1]));\n return [...out];\n}\n\n/** Path of a Figma image attached to a request, on the requests branch. */\nexport const REQUESTS_BRANCH = 'bridge-requests';\nexport function requestImagePath(component: string, date: Date): string {\n const slug = component.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') || 'component';\n return `.bridge/requests/${slug}-${date.toISOString().replace(/[-:]/g, '').replace(/\\..*$/, '')}.png`;\n}\n\n/**\n * The brief Claude gets to implement a request (CLI `bridge request implement`, MCP `bridge_get_request`): the request,\n * the component's files, the repo rules, and how to open the pull request so it closes the issue.\n */\nexport function requestBrief(r: ComponentChangeRequest, ctx: { issue: number; issueUrl?: string; files?: string[]; agentsFile?: string; exploration?: string | undefined }): string {\n const exploration = ctx.exploration ?? r.exploration;\n return [\n `Implement Bridge component change request #${ctx.issue}${ctx.issueUrl ? ` (${ctx.issueUrl})` : ''}.`,\n '',\n `Component: ${r.component}`,\n `Kind: ${kindLabel(r.kind)}`,\n `Request: ${r.title}`,\n ...(r.line?.trim() ? [`What changes: ${r.line.trim()}`] : []),\n '',\n r.summary.trim(),\n '',\n ...(r.changes.length ? ['Changes asked:', ...r.changes.map((c) => `- ${c.field}: ${c.before ?? '(none)'} -> ${c.after ?? '(removed)'}`), ''] : []),\n ...(r.figma?.url ? [`Design: ${r.figma.url}`, ''] : []),\n ...(r.images?.length ? ['Images:', ...r.images.map((u) => `- ${u}`), ''] : []),\n ...(ctx.files?.length ? ['Files of this component:', ...ctx.files.map((f) => `- ${f}`), ''] : []),\n 'Rules:',\n `- Follow ${ctx.agentsFile ?? 'AGENTS.md'}: tokens only in component CSS, Base UI for behavior, states, tests, story, docs.json, changeset.`,\n '- A new component, prop or variant is Tier 2: open the pull request as a draft (new component: follow the new component checklist). A token add or rename is Tier 3: describe it, do not invent values.',\n ...(exploration\n ? [`- This request is part of the exploration ${exploration}.`, ...explorationRules(exploration), `- Reference the request in the commit message (\"Refs #${ctx.issue}\"). Promoting the exploration closes it.`]\n : [`- Work on a branch named agent/request-${ctx.issue}. The pull request body must contain \"Closes #${ctx.issue}\".`]),\n '- If the request is unclear or conflicts with the guidance, comment on the issue instead of guessing.',\n ].join('\\n');\n}\n\nconst cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\n/g, ' ');\nconst sourceLabel = (s: RequestSource) => (s === 'figma' ? 'Figma' : s === 'studio' ? 'Bridge Studio' : s === 'cli' ? 'the CLI' : 'Claude (MCP)');\n\n// ---------------------------------------------------------------------------------------------\n// Integrations (bridge.config.json \"integrations\"): where requests go besides the GitHub issue.\n\nexport interface JiraIntegration {\n /** Jira site, e.g. \"https://acme.atlassian.net\". The token lives in the repo secrets, never in config. */\n baseUrl: string;\n /** Project key, e.g. \"DS\". */\n project: string;\n /** Issue type, default \"Task\". */\n issueType?: string | undefined;\n labels?: string[] | undefined;\n}\n\nexport interface IntegrationsConfig {\n requests?: { labels?: string[] | undefined; assignees?: string[] | undefined } | undefined;\n /** Mirror each request to Jira through the bridge-jira GitHub Action. */\n jira?: JiraIntegration | undefined;\n}\n\n/** Problems in an integrations block, as sentences that say how to fix them. Empty when valid. */\nexport function validateIntegrations(i: IntegrationsConfig | undefined): string[] {\n const out: string[] = [];\n if (!i?.jira) return out;\n if (!/^https:\\/\\/[^/]+/.test(i.jira.baseUrl ?? '')) out.push('Jira site must start with https://, for example https://acme.atlassian.net.');\n if (!/^[A-Z][A-Z0-9_]{1,9}$/.test(i.jira.project ?? '')) out.push('Jira project key is 2 to 10 capital letters or digits, like DS.');\n return out;\n}\n\n/** The Jira issue fields the Action sends for a request (Jira Cloud REST v3, Atlassian document format). */\nexport function jiraIssueFields(r: ComponentChangeRequest, jira: JiraIntegration, issueUrl: string): Record<string, unknown> {\n const text = (t: string) => ({ type: 'text', text: t });\n const para = (...c: unknown[]) => ({ type: 'paragraph', content: c });\n return {\n project: { key: jira.project },\n issuetype: { name: jira.issueType ?? 'Task' },\n summary: requestIssueTitle(r),\n labels: [...new Set(['bridge', REQUEST_LABEL, ...(jira.labels ?? [])])].map((l) => l.replace(/\\s+/g, '-')),\n description: {\n type: 'doc',\n version: 1,\n content: [\n para(text(r.summary.trim() || r.title)),\n ...(r.line?.trim() ? [para(text(r.line.trim()))] : []),\n ...r.changes.map((c) => para(text(`${c.field}: ${c.before ?? '(none)'} -> ${c.after ?? '(removed)'}`))),\n para({ type: 'text', text: 'GitHub request', marks: [{ type: 'link', attrs: { href: issueUrl } }] }),\n ],\n },\n };\n}\n","// Deciding on a component change request on GitHub: link it to an exploration, assign someone, or decline it. The\n// same calls for Studio (the viewer's own token), the MCP server and the CLI. Pure rules live in requests.ts.\nimport { EXPLORATION_LABEL, isExplorationBranch } from './explorations';\nimport { GitHubClient, GitHubError } from './github-client';\nimport { declineComment, declineReasonProblems, withRequestExploration } from './requests';\n\nexport interface RequestExplorationLink {\n number: number;\n branch: string;\n /** Who is now on it, when someone was assigned in the same step. */\n assignees: string[];\n /** Sentences about the parts that did not go through (label refused): the link itself holds. */\n warnings: string[];\n}\n\n/**\n * Links a request to an exploration branch, the way `bridge request create --exploration` files one: the hidden block\n * gets `exploration`, the issue gets the `exploration` label, and whoever starts the exploration is assigned, so the\n * request reads \"in progress\" everywhere. Implementing it then happens on that branch (`request implement --branch`).\n */\nexport async function linkRequestToExplorationOnGitHub(gh: GitHubClient, n: number, branch: string, opts: { assignee?: string | null } = {}): Promise<RequestExplorationLink> {\n if (!isExplorationBranch(branch)) throw new GitHubError(422, `\"${branch}\" is not an exploration branch. Exploration branches are named explore/<name>.`);\n const issue = await gh.getIssue(n);\n const body = withRequestExploration(issue.body, branch);\n if (!body) throw new GitHubError(422, `#${n} has no Bridge request block, so it cannot be linked. Add \"exploration: ${branch}\" to it on GitHub.`);\n await gh.updateIssue(n, { body });\n const warnings: string[] = [];\n if (!(await gh.addLabels(n, [EXPLORATION_LABEL]))) warnings.push(`The ${EXPLORATION_LABEL} label could not be added to #${n}.`);\n let assignees: string[] = [];\n if (opts.assignee) {\n try {\n assignees = await gh.addAssignees(n, [opts.assignee.replace(/^@/, '')]);\n } catch {\n warnings.push(`@${opts.assignee.replace(/^@/, '')} could not be assigned to #${n}.`);\n }\n }\n return { number: n, branch, assignees, warnings };\n}\n\n/** Assigns someone to a request. Throws when GitHub does not keep the assignee (no access to the repository). */\nexport async function assignRequestOnGitHub(gh: GitHubClient, n: number, login: string): Promise<string[]> {\n const who = login.trim().replace(/^@/, '');\n if (!who) throw new GitHubError(422, 'Pick who should work on it.');\n const assignees = await gh.addAssignees(n, [who]);\n if (!assignees.some((a) => a.toLowerCase() === who.toLowerCase())) throw new GitHubError(422, `GitHub did not assign @${who}: they need access to this repository.`);\n return assignees;\n}\n\n/** Declines a request: the reason as a comment the requester is notified of, then the issue closed as not planned. */\nexport async function declineRequestOnGitHub(gh: GitHubClient, n: number, reason: string, by?: string | null): Promise<void> {\n const problems = declineReasonProblems(reason);\n if (problems.length) throw new GitHubError(422, problems.join(' '));\n await gh.addComment(n, declineComment(reason, by));\n await gh.updateIssue(n, { state: 'closed', state_reason: 'not_planned' });\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","// Review and merge rules shared by Bridge Studio, the MCP server and the CLI: one implementation of who may merge\n// a branch, what blocks it, the owner override and its audit comment, the review queue and the status of a branch.\n// Pure functions over GitHub REST shapes, no fetch, no DOM. Same rules as docs/GOVERNANCE.md: the highest tier wins,\n// Tier 2 and 3 need a design and a tech approval, nothing merges while tests fail. Who may ship comes from\n// `governance.rights` (rights.ts). Moved from the docs site (apps/docs-site/src/lib/review-rules.ts re-exports it).\nimport type { OverridePolicy } from './config';\nimport { isActiveExploration } from './explorations';\nimport { canShip, soloApprover, unreadableShipTeams, whoCanShipSentence, type ShipPolicy } from './rights';\nimport { classifyRisk, type RiskTier } from './risk';\n\nexport interface LabelLike {\n name: string;\n}\n\n/** Tier from labels (`tier-3`, `tier: 3`, `risk:3`), the PR template checkbox (`- [x] Tier 3`) or a `Risk tier: 3` line. Highest wins. */\nexport function parseTier(labels: LabelLike[], body: string | null | undefined): RiskTier | null {\n const found: number[] = [];\n for (const l of labels) {\n const m = l.name.match(/^(?:risk[\\s:-]*)?tier[\\s:_-]*([123])\\b/i) ?? l.name.match(/^risk[\\s:_-]*([123])$/i);\n if (m) found.push(Number(m[1]));\n }\n for (const m of (body ?? '').matchAll(/-\\s*\\[[xX]\\]\\s*\\**\\s*Tier\\s*([123])\\b/g)) found.push(Number(m[1]));\n // \"**Risk tier:** 3, high\" or \"Risk tier: Tier 2\"\n for (const m of (body ?? '').matchAll(/risk tier\\W{0,6}(?:tier\\s*)?([123])\\b/gi)) found.push(Number(m[1]));\n return found.length ? (Math.max(...found) as RiskTier) : null;\n}\n\n/** What GitHub returns about a pull request's lifecycle. `merged_at` is set once merged; `state` is then \"closed\". */\nexport interface PullStateLike {\n state?: string;\n draft?: boolean;\n merged?: boolean;\n merged_at?: string | null;\n}\n\nexport type PullState = 'merged' | 'closed' | 'draft' | 'open';\n\n/** Merged wins over closed (GitHub reports merged pull requests as closed), closed over draft, draft over open. */\nexport function pullState(p: PullStateLike): PullState {\n if (p.merged_at || p.merged) return 'merged';\n if (p.state && p.state !== 'open') return 'closed';\n if (p.draft) return 'draft';\n return 'open';\n}\n\n/** Label and pill tone of each state, for list and detail views. */\nexport const PULL_STATE_PILL: Record<PullState, { label: string; cls: string }> = {\n merged: { label: 'Merged', cls: '' },\n closed: { label: 'Closed', cls: '' },\n draft: { label: 'Draft', cls: '' },\n open: { label: 'Open', cls: '' },\n};\n\n/** Pull requests still waiting for review (open or draft): merged and closed ones never count as open reviews. */\nexport function openPulls<P extends PullStateLike>(pulls: P[]): P[] {\n return pulls.filter((p) => {\n const s = pullState(p);\n return s === 'open' || s === 'draft';\n });\n}\n\nexport interface CiRunLike {\n name: string;\n status: 'queued' | 'in_progress' | 'completed' | string;\n conclusion: string | null;\n html_url?: string;\n}\n\nexport interface CiStatusLike {\n context: string;\n state: 'success' | 'failure' | 'error' | 'pending' | string;\n target_url?: string | null;\n}\n\nexport type CiState = 'pass' | 'fail' | 'pending' | 'none';\n\nexport interface CiSummary {\n state: CiState;\n total: number;\n passed: number;\n failed: { name: string; url?: string }[];\n pending: { name: string; url?: string }[];\n}\n\nconst OK = new Set(['success', 'neutral', 'skipped']);\n\n/** Combines check runs and commit statuses into one verdict. Any failure wins over pending. */\nexport function summarizeCi(runs: CiRunLike[], statuses: CiStatusLike[] = []): CiSummary {\n const failed: CiSummary['failed'] = [];\n const pending: CiSummary['pending'] = [];\n let passed = 0;\n for (const r of runs) {\n if (r.status !== 'completed') pending.push({ name: r.name, url: r.html_url });\n else if (r.conclusion && OK.has(r.conclusion)) passed++;\n else failed.push({ name: r.name, url: r.html_url });\n }\n // Statuses repeat per context; the first one is the latest.\n const seen = new Set<string>();\n for (const s of statuses) {\n if (seen.has(s.context)) continue;\n seen.add(s.context);\n if (s.state === 'success') passed++;\n else if (s.state === 'pending') pending.push({ name: s.context, url: s.target_url ?? undefined });\n else failed.push({ name: s.context, url: s.target_url ?? undefined });\n }\n const total = passed + failed.length + pending.length;\n const state: CiState = total === 0 ? 'none' : failed.length ? 'fail' : pending.length ? 'pending' : 'pass';\n return { state, total, passed, failed, pending };\n}\n\nexport interface ReviewLike {\n user: { login: string } | null;\n state: 'APPROVED' | 'CHANGES_REQUESTED' | 'COMMENTED' | 'DISMISSED' | 'PENDING' | string;\n submitted_at?: string | null;\n}\n\nexport interface ApprovalSummary {\n approvers: string[];\n changesRequested: string[];\n design: boolean;\n tech: boolean;\n}\n\nexport interface ApprovalRules {\n /**\n * `governance.soloOwnerCanApproveBoth`: when the owners resolve to one person holding both roles, that person's\n * approval counts for design and tech. Default false. The author still never approves their own change.\n */\n soloOwnerCanApproveBoth?: boolean | undefined;\n}\n\n/** Latest decisive review per person (comments do not reset an approval), then owner coverage. */\nexport function summarizeApprovals(reviews: ReviewLike[], owners: { design: string[]; tech: string[] }, author?: string, rules: ApprovalRules = {}): ApprovalSummary {\n const latest = new Map<string, string>();\n const sorted = [...reviews].sort((a, b) => String(a.submitted_at ?? '').localeCompare(String(b.submitted_at ?? '')));\n for (const r of sorted) {\n const login = r.user?.login;\n if (!login || login === author) continue;\n if (r.state === 'APPROVED' || r.state === 'CHANGES_REQUESTED' || r.state === 'DISMISSED') latest.set(login, r.state);\n }\n const approvers = [...latest].filter(([, s]) => s === 'APPROVED').map(([l]) => l);\n const changesRequested = [...latest].filter(([, s]) => s === 'CHANGES_REQUESTED').map(([l]) => l);\n const lower = (xs: string[]) => xs.map((x) => x.toLowerCase().replace(/^@/, ''));\n const d = lower(owners.design);\n const t = lower(owners.tech);\n const a = lower(approvers);\n let design: boolean;\n let tech: boolean;\n if (d.length || t.length) {\n design = d.length ? a.some((x) => d.includes(x)) : a.length > 0;\n // One person holding both roles cannot cover both approvals alone, unless the team opted in and that person is\n // the only owner (governance.soloOwnerCanApproveBoth).\n const solo = rules.soloOwnerCanApproveBoth ? soloApprover(owners) : null;\n const soloBoth = (x: string) => a.length === 1 && d.includes(x) && x !== solo;\n tech = t.length ? a.some((x) => t.includes(x) && !soloBoth(x)) : a.length > 1;\n } else {\n // No owners configured: two distinct approvers stand in for design and tech.\n design = a.length >= 1;\n tech = a.length >= 2;\n }\n return { approvers, changesRequested, design, tech };\n}\n\nexport type MissingApproval = 'design approval' | 'tech approval' | 'approval';\n\nexport interface MergeGate {\n allowed: boolean;\n reasons: string[];\n /** True when the only failing reasons are missing approvals and the viewer is in `governance.override.allowed`. */\n overridable: boolean;\n /** Approvals still missing, in the words the override comment uses. */\n missing: MissingApproval[];\n /** Whether the viewer holds the right to ship (true when no rule singles anyone out or the viewer is unknown). */\n canShip: boolean;\n}\n\nconst normLogin = (x: string) => x.trim().toLowerCase().replace(/^@/, '');\n\n/** Whether `login` may use the owner override. Case-insensitive, a leading @ is ignored. */\nexport function canOverride(login: string | null | undefined, policy: OverridePolicy | null | undefined): boolean {\n if (!login || !policy?.allowed.length) return false;\n return policy.allowed.map(normLogin).includes(normLogin(login));\n}\n\n/**\n * Whether the Merge button is enabled, and why not. Mirrors docs/GOVERNANCE.md.\n * The owner override only ever covers missing approvals: CI failing or running, changes requested, a draft,\n * a closed pull request or a merge conflict always block, for everyone.\n */\nexport function mergeGate(input: {\n tier: RiskTier | null;\n ci: CiSummary;\n approvals: ApprovalSummary;\n draft: boolean;\n mergeable?: boolean | null;\n state: string;\n merged_at?: string | null;\n /** Login of the connected viewer (GitHub /user). */\n viewer?: string | null;\n override?: OverridePolicy | null;\n /** A running exploration (label `exploration`): never merged as is, whatever else is green. */\n exploration?: boolean;\n /** Who may ship (shipPolicy from governance.rights). null or absent: anyone with write access. */\n ship?: ShipPolicy | null;\n}): MergeGate {\n const blocking: string[] = [];\n const missing: MissingApproval[] = [];\n const approvalReasons: string[] = [];\n const lifecycle = pullState(input);\n if (lifecycle === 'merged') blocking.push('This branch is already merged.');\n else if (lifecycle === 'closed') blocking.push('This branch is closed.');\n if (input.exploration && lifecycle !== 'merged' && lifecycle !== 'closed') blocking.push('It is an exploration: promote it to review first.');\n if (input.draft) blocking.push('It is a draft. Mark it ready for review on GitHub first.');\n if (input.ci.state === 'fail') blocking.push(`Tests fail: ${input.ci.failed.map((f) => f.name).join(', ')}.`);\n if (input.ci.state === 'pending') blocking.push('Tests are still running.');\n if (input.approvals.changesRequested.length) blocking.push(`Changes requested by @${input.approvals.changesRequested.join(', @')}.`);\n const tier = input.tier ?? 3;\n // docs/GOVERNANCE.md: Tier 2 (new component, variant or prop) and Tier 3 need a design and a tech owner approval.\n if (tier >= 2) {\n if (!input.approvals.design) {\n approvalReasons.push('It needs a design owner approval.');\n missing.push('design approval');\n }\n if (!input.approvals.tech) {\n approvalReasons.push('It needs a tech owner approval.');\n missing.push('tech approval');\n }\n } else if (!input.approvals.approvers.length) {\n approvalReasons.push('It needs one approval.');\n missing.push('approval');\n }\n const conflict = input.mergeable === false ? [CONFLICT_REASON] : [];\n // Only a known viewer is checked: without a login the Merge button asks to connect first anyway.\n const shipper = !input.viewer || canShip(input.viewer, input.ship);\n // A team holding the right that GitHub would not show: say why and how to fix it, never treat it as empty.\n const ship = !shipper && lifecycle !== 'merged' && lifecycle !== 'closed' ? [whoCanShipSentence(input.ship!), ...unreadableShipTeams(input.ship).map((t) => (t.status === 'unreadable' ? t.message : ''))] : [];\n // Order: state, draft, CI, changes requested, approvals, who ships, conflict.\n const reasons = [...blocking, ...approvalReasons, ...ship, ...conflict];\n const allowed = reasons.length === 0;\n // The override skips approvals only: it never lets someone ship who does not hold the right.\n const overridable = !allowed && blocking.length + conflict.length + ship.length === 0 && missing.length > 0 && canOverride(input.viewer, input.override);\n return { allowed, reasons, overridable, missing, canShip: shipper };\n}\n\n/** The gate reason of a conflict, in the words a designer reads. Detected by identity, never by regex. */\nexport const CONFLICT_REASON = 'It conflicts with main: resolve it with Update from main on the branch.';\n\nexport const OVERRIDE_HEADING = '**Bridge owner override**';\n\n/** Problem with an override reason, or null when it is accepted. */\nexport function overrideReasonProblem(reason: string, policy: OverridePolicy): string | null {\n if (!policy.requireReason) return null;\n const n = reason.trim().length;\n if (n === 0) return `Write why this merges without the missing approvals, in at least ${policy.minReasonLength} characters.`;\n if (n < policy.minReasonLength) return `Write at least ${policy.minReasonLength} characters (${n} so far), so the history says why.`;\n return null;\n}\n\n/**\n * The audit comment posted on the pull request before an override merge. Stable format: History and the PR\n * timeline find it by its first line, `**Bridge owner override**`, and read it back with parseOverrideComment.\n */\nexport function overrideComment(login: string, reason: string, missing: MissingApproval[]): string {\n const why = reason.trim().replace(/\\s+/g, ' ').replace(/[.\\s]+$/, '');\n return `${OVERRIDE_HEADING}\\n\\nOwner override by @${normLogin(login)}: ${why || 'no reason given'}. Missing: ${missing.join(', ')}. Merged from Bridge.`;\n}\n\n/** The comment body after GitHub refused the merge, so the audit trail does not claim a merge that never happened. */\nexport function overrideRefusedComment(body: string, message: string): string {\n return body.replace(/ Merged from Bridge\\.$/, ` Merge refused by GitHub: ${message.trim().replace(/[.\\s]+$/, '')}. Not merged.`);\n}\n\nexport interface OverrideRecord {\n login: string;\n reason: string;\n missing: string[];\n merged: boolean;\n}\n\n/** Reads an override comment back; null for any other comment. */\nexport function parseOverrideComment(body: string | null | undefined): OverrideRecord | null {\n const text = (body ?? '').trim();\n if (!text.startsWith(OVERRIDE_HEADING)) return null;\n const m = text.match(/Owner override by @([\\w-]+): ([\\s\\S]*?)\\. Missing: ([^.]*)\\. (Merged from Bridge\\.|Merge refused by GitHub)/);\n if (!m) return null;\n return { login: m[1]!, reason: m[2]!, missing: m[3]!.split(/,\\s*/).filter(Boolean), merged: m[4]!.startsWith('Merged') };\n}\n\nexport type MergeMethod = 'squash' | 'merge' | 'rebase';\n\n/** Merge methods the repo allows, squash first. Unknown settings (no push access) count as allowed. */\nexport function allowedMergeMethods(repo: { allow_squash_merge?: boolean; allow_merge_commit?: boolean; allow_rebase_merge?: boolean } | null | undefined): MergeMethod[] {\n const out: MergeMethod[] = [];\n if (repo?.allow_squash_merge !== false) out.push('squash');\n if (repo?.allow_merge_commit !== false) out.push('merge');\n if (repo?.allow_rebase_merge !== false) out.push('rebase');\n return out;\n}\n\n/** Whether the viewer can write to the repo, from `permissions` on GET /repos/{owner}/{repo} with their token. */\nexport function hasWriteAccess(perms: { admin?: boolean; maintain?: boolean; push?: boolean } | null | undefined): boolean {\n return Boolean(perms && (perms.admin || perms.maintain || perms.push));\n}\n\nexport type ReviewStatusKind =\n | 'merged'\n | 'closed'\n | 'draft'\n | 'ci-failing'\n | 'changes-requested'\n | 'ci-running'\n | 'needs-design'\n | 'needs-tech'\n | 'needs-approval'\n | 'conflict'\n | 'checking'\n | 'ready'\n | 'unknown';\n\n/**\n * Sort order for a \"needs you\" list, most urgent first: what blocks the merge, then what waits for an approval,\n * then what is ready, then running checks and unknown ones, drafts and finished ones last. Lower comes first.\n */\nexport const REVIEW_STATUS_ORDER: Record<ReviewStatusKind, number> = {\n 'ci-failing': 0,\n conflict: 1,\n 'changes-requested': 2,\n 'needs-design': 3,\n 'needs-tech': 4,\n 'needs-approval': 5,\n ready: 6,\n 'ci-running': 7,\n checking: 8,\n unknown: 9,\n draft: 10,\n merged: 11,\n closed: 12,\n};\n\n/**\n * One status chip for a pull request, from real data. Same rules and order as the pull request header\n * (lib/changes needFromDetail): lifecycle, draft, CI failing, changes requested, merge conflict, CI running, then\n * missing approvals (Tier 3 by default), then ready. `mergeable` null means GitHub has not computed it yet: the chip\n * reads \"Checking\" instead of an approval or \"Ready to ship\", so a list never says something the detail contradicts.\n * Undefined means it was not read: no conflict known. `ready` is returned only when mergeGate allows the merge.\n * Unknown CI or reviews (null, still loading or failed) never read as ready.\n */\nexport function reviewStatusKind(input: {\n state?: string;\n draft?: boolean;\n merged_at?: string | null;\n ci: CiSummary | null;\n approvals: ApprovalSummary | null;\n tier: RiskTier | null;\n mergeable?: boolean | null;\n}): ReviewStatusKind {\n const out = (kind: ReviewStatusKind): ReviewStatusKind => kind;\n const lifecycle = pullState(input);\n if (lifecycle === 'merged') return out('merged');\n if (lifecycle === 'closed') return out('closed');\n if (lifecycle === 'draft') return out('draft');\n if (input.ci?.state === 'fail') return out('ci-failing');\n if (input.approvals?.changesRequested.length) return out('changes-requested');\n if (input.mergeable === false) return out('conflict');\n if (input.ci?.state === 'pending') return out('ci-running');\n if (!input.ci || !input.approvals) return out('unknown');\n if (input.mergeable === null) return out('checking');\n const tier = input.tier ?? 3;\n if (tier >= 2) {\n if (!input.approvals.design) return out('needs-design');\n if (!input.approvals.tech) return out('needs-tech');\n } else if (!input.approvals.approvers.length) return out('needs-approval');\n const gate = mergeGate({ tier: input.tier, ci: input.ci, approvals: input.approvals, draft: Boolean(input.draft), mergeable: input.mergeable, state: input.state ?? 'open', merged_at: input.merged_at });\n return gate.allowed ? out('ready') : out('unknown');\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// The review queue: which open pull requests wait for a review. Left out: running explorations (tried, never merged\n// as is) and GitHub automation (the changesets release pull request, anything github-actions[bot] opened).\n\nexport interface QueuePull extends PullStateLike {\n state: string;\n labels?: ({ name?: string } | string)[];\n head: { ref: string };\n user?: { login: string; type?: string } | null;\n}\n\nconst BOTS = new Set(['github-actions[bot]', 'app/github-actions', 'changeset-bot[bot]']);\n\n/** The changesets release pull request (\"Version packages\"), on a changeset-release/* branch. */\nexport const isReleasePull = (p: Pick<QueuePull, 'head'>) => p.head.ref.startsWith('changeset-release/');\n\n/** Opened by GitHub automation, not by a person: the release pull request or anything github-actions[bot] opened. */\nexport function isAutomationPull(p: Pick<QueuePull, 'head' | 'user'>): boolean {\n return isReleasePull(p) || BOTS.has((p.user?.login ?? '').toLowerCase());\n}\n\n/** A running exploration: open and labeled exploration. */\nconst runningExploration = (p: Pick<QueuePull, 'state' | 'labels'>) => p.state === 'open' && isActiveExploration((p.labels ?? []) as never);\n\n/** The open pull requests that wait for a review, in the order given. Every count in the Studio comes from here. */\nexport function reviewQueue<P extends QueuePull>(pulls: P[]): P[] {\n return openPulls(pulls).filter((p) => !isAutomationPull(p) && !runningExploration(p));\n}\n\n/** The open release pull request, if the changesets action opened one. */\nexport function releasePull<P extends QueuePull>(pulls: P[]): P | null {\n return openPulls(pulls).find((p) => isReleasePull(p)) ?? null;\n}\n\n/**\n * The approval a change needs, the same rule everywhere: the tier the author set (label, PR template checkbox or\n * \"Risk tier\" line) or the one the shared classifier computes from the changed files, highest wins. Without files\n * (not read yet) only a label counts, and a missing label stays unknown.\n */\nexport function effectiveTier(labels: LabelLike[], body: string | null | undefined, files: { filename: string; status?: string }[] | null): RiskTier | null {\n const labelled = parseTier(labels, body);\n if (!files) return labelled;\n const computed = classifyRisk({ files: files.map((f) => ({ path: f.filename, status: f.status })) }).tier;\n return Math.max(labelled ?? 0, computed) as RiskTier;\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Reopen\n\nexport type ReopenEligibility =\n /** The branch is still there: the change can be reopened as it was. */\n | { kind: 'reopen' }\n /** The branch is gone: nothing to reopen, but its token edits can start a new change. */\n | { kind: 'gone' }\n /** Not closed, or not the viewer's to reopen, or not known yet. */\n | { kind: 'none' };\n\nconst norm = (x: string) => x.trim().toLowerCase().replace(/^@/, '');\n\n/**\n * Whether the viewer can reopen a closed change: only a change closed without shipping, only its author or an owner\n * (governance.owners, both roles), and only someone GitHub lets write (write access, or the author). `branch` is what\n * GitHub said about the head branch: there, removed, or not read.\n */\nexport function reopenEligibility(x: {\n state: PullState;\n viewer: string | null;\n author: string;\n owners: string[];\n canWrite: boolean;\n branch: 'exists' | 'gone' | 'unknown';\n}): ReopenEligibility {\n if (x.state !== 'closed' || !x.viewer) return { kind: 'none' };\n const isAuthor = norm(x.viewer) === norm(x.author);\n const isOwner = x.owners.some((o) => norm(o) === norm(x.viewer!));\n if (!isAuthor && !isOwner) return { kind: 'none' };\n if (!x.canWrite && !isAuthor) return { kind: 'none' };\n if (x.branch === 'exists') return { kind: 'reopen' };\n if (x.branch === 'gone') return { kind: 'gone' };\n return { kind: 'none' };\n}\n\n\n// ---------------------------------------------------------------------------------------------------------------\n// Who still approves, and who else to ask (\"Ask someone else to review\" in the review queue)\n\nexport type ApprovalRole = 'design' | 'tech' | 'approval';\n\nconst NO_CI: CiSummary = { state: 'pass', total: 0, passed: 0, failed: [], pending: [] };\nconst ROLE_OF_MISSING: Record<MissingApproval, ApprovalRole> = { 'design approval': 'design', 'tech approval': 'tech', approval: 'approval' };\n\n/** The approvals a tier needs, as mergeGate counts them (Tier 2 and 3: design and tech; Tier 1: one approval). */\nexport function requiredApprovals(tier: RiskTier | null): ApprovalRole[] {\n return mergeGate({ tier, ci: NO_CI, approvals: { approvers: [], changesRequested: [], design: false, tech: false }, draft: false, state: 'open' }).missing.map((m) => ROLE_OF_MISSING[m]);\n}\n\n/** The approvals still missing on a branch, from its tier and the reviews read (empty when either is unknown). */\nexport function pendingApprovals(tier: RiskTier | null | undefined, approvals: ApprovalSummary | null | undefined): ApprovalRole[] {\n if (tier == null || !approvals) return [];\n return mergeGate({ tier, ci: NO_CI, approvals, draft: false, state: 'open' }).missing.map((m) => ROLE_OF_MISSING[m]);\n}\n\nconst uniqLogins = (xs: string[]) => xs.filter((x, i) => xs.findIndex((y) => normLogin(y) === normLogin(x)) === i);\n\n/**\n * Who can still give an approval: the owners listed for the role (both lists for a plain approval) minus the author\n * and anyone who already approved. `open`: the config lists nobody for the role, so any reviewer but the author counts.\n */\nexport function eligibleReviewers(role: ApprovalRole, p: { owners: { design: string[]; tech: string[] }; author: string; approvers?: string[] | undefined }): { open: boolean; logins: string[]; listed: string[] } {\n const raw = role === 'design' ? p.owners.design : role === 'tech' ? p.owners.tech : uniqLogins([...p.owners.design, ...p.owners.tech]);\n const listed = raw.map((x) => x.replace(/^@/, ''));\n const approvers = (p.approvers ?? []).map(normLogin);\n const logins = listed.filter((l) => normLogin(l) !== normLogin(p.author) && !approvers.includes(normLogin(l)));\n return { open: listed.length === 0, logins, listed };\n}\n\n/**\n * \"Ask someone else to review\": the other people who can give the missing approvals, never the viewer or the author.\n * Empty when nobody else can (the caller says to review it or to add a reviewer in Settings).\n */\nexport function reviewersToAsk(x: { tier: RiskTier | null; approvals: ApprovalSummary; owners: { design: string[]; tech: string[] }; author: string; viewer: string | null | undefined }): string[] {\n const roles = pendingApprovals(x.tier, x.approvals);\n const all = roles.flatMap((r) => eligibleReviewers(r, { owners: x.owners, author: x.author, approvers: x.approvals.approvers }).logins);\n return uniqLogins(all).filter((l) => normLogin(l) !== normLogin(x.viewer ?? '') && normLogin(l) !== normLogin(x.author));\n}\n","// Jira ticket keys: an optional \"DS-42\" given when a branch is created (Bridge Studio, the MCP server, the CLI).\n// Jira's GitHub integration links a pull request whose title (or branch name) starts with the key, so the key goes\n// first in both.\n\nconst JIRA_KEY = /^[A-Z][A-Z0-9_]{0,9}-[1-9]\\d{0,6}$/;\n\n/**\n * The Jira key given when a branch is created, normalised (\"ds-42 \" is \"DS-42\"), or null when empty. Throws a\n * sentence that says how to fix it when the text is not a key.\n */\nexport function parseJiraKey(input: string | null | undefined): string | null {\n const t = (input ?? '').trim().toUpperCase();\n if (!t) return null;\n if (!JIRA_KEY.test(t)) throw new Error('Write the Jira ticket as its key, like DS-42, or leave it empty.');\n return t;\n}\n\n/** Whether a text is a Jira key, without throwing (for live field validation). */\nexport const isJiraKey = (input: string) => JIRA_KEY.test(input.trim().toUpperCase());\n\nconst LEADING_KEY = /^\\[?([A-Z][A-Z0-9_]{0,9}-[1-9]\\d{0,6})\\]?[:\\s]\\s*/;\n\n/** The Jira key a title starts with (\"DS-42 tokens: darker primary\" gives \"DS-42\"), else null. */\nexport function jiraKeyOf(title: string): string | null {\n return LEADING_KEY.exec(title.trim())?.[1] ?? null;\n}\n\n/** The title without its leading Jira key. */\nexport const withoutJiraKey = (title: string) => title.trim().replace(LEADING_KEY, '');\n\n/** The pull request title with the key first: \"DS-42 tokens: darker primary\". Idempotent; no key, no change. */\nexport function titleWithJiraKey(title: string, key: string | null): string {\n if (!key) return title;\n return `${key} ${withoutJiraKey(title)}`;\n}\n\n/** The branch name with the key first in its last part: \"tokens/DS-42-darker-primary-20261019-1200\". */\nexport function branchWithJiraKey(branch: string, key: string | null): string {\n if (!key || branch.includes(key)) return branch;\n const i = branch.lastIndexOf('/');\n return i < 0 ? `${key}-${branch}` : `${branch.slice(0, i + 1)}${key}-${branch.slice(i + 1)}`;\n}\n","// Reviews on a suggestion. Issues have no native reviews, so a review is a comment with a hidden record\n// (`<!-- bridge-suggestion-review {...} -->`) plus a sentence people read. The truth is the comment author, which GitHub\n// authenticates, checked against the owners in the config read from the default branch (never from the payload), and\n// the payload sha the reviewer saw: an approval of an older payload no longer counts, like a stale pull request review.\n// Pure; posting lives in suggestions-github.ts.\n\nimport type { Owners } from './config';\nimport { pendingApprovals, summarizeApprovals, type ApprovalRole, type ApprovalSummary, type ReviewLike } from './review-gate';\nimport { approverLists, type Rights } from './rights';\nimport type { RiskTier } from './risk';\nimport type { TeamStates } from './teams';\n\nexport const SUGGESTION_REVIEW_MARK = 'bridge-suggestion-review';\nexport const SUGGESTION_APPLIED_MARK = 'bridge-suggestion-applied';\n\nexport type SuggestionReviewEvent = 'approve' | 'request-changes' | 'comment';\n\nexport interface SuggestionReviewRecord {\n event: SuggestionReviewEvent;\n /** The role the reviewer approved for. Informative: what counts is the author against the owner lists. */\n role?: ApprovalRole | undefined;\n /** sha256 of the payload the reviewer saw (suggestionPayloadSha). */\n payloadSha: string;\n /** ISO date. */\n at: string;\n}\n\nconst EVENTS: readonly SuggestionReviewEvent[] = ['approve', 'request-changes', 'comment'];\nconst ROLE_TEXT: Record<ApprovalRole, string> = { design: 'for design', tech: 'for tech', approval: '' };\n\n/** The comment a review posts: a sentence, the reviewer's message quoted, and the hidden record. */\nexport function composeSuggestionReviewComment(r: SuggestionReviewRecord & { by?: string | null | undefined; message?: string | undefined }): string {\n const who = r.by ? ` by @${r.by.replace(/^@/, '')}` : '';\n const role = r.role ? ROLE_TEXT[r.role] : '';\n const head =\n r.event === 'approve'\n ? `Approved${role ? ` ${role}` : ''}${who} in Bridge.`\n : r.event === 'request-changes'\n ? `Changes requested${who} in Bridge.`\n : `Comment${who} in Bridge.`;\n const quote = r.message?.trim()\n ? r.message\n .trim()\n .split('\\n')\n .map((l) => `> ${l}`.trimEnd())\n .join('\\n')\n : '';\n const record: SuggestionReviewRecord = { event: r.event, ...(r.role ? { role: r.role } : {}), payloadSha: r.payloadSha, at: r.at };\n return [head, ...(quote ? ['', quote] : []), '', `<sub>Applies to version \\`${r.payloadSha.slice(0, 7)}\\` of this suggestion.</sub>`, '', `<!-- ${SUGGESTION_REVIEW_MARK} ${JSON.stringify(record)} -->`].join('\\n');\n}\n\n/** The review record in a comment, or null when the comment is not a Bridge review. */\nexport function parseSuggestionReviewComment(body: string | null | undefined): SuggestionReviewRecord | null {\n const m = new RegExp(`<!-- ${SUGGESTION_REVIEW_MARK} (\\\\{[^\\\\n]*?\\\\}) -->`).exec(body ?? '');\n if (!m) return null;\n try {\n const r = JSON.parse(m[1]!) as Partial<SuggestionReviewRecord>;\n if (!r || !(EVENTS as readonly unknown[]).includes(r.event) || typeof r.payloadSha !== 'string' || !/^[0-9a-f]{64}$/.test(r.payloadSha)) return null;\n return {\n event: r.event as SuggestionReviewEvent,\n ...(r.role === 'design' || r.role === 'tech' || r.role === 'approval' ? { role: r.role } : {}),\n payloadSha: r.payloadSha,\n at: typeof r.at === 'string' ? r.at : '',\n };\n } catch {\n return null;\n }\n}\n\n/** A developer applied the suggestion: where, and on which payload. */\nexport interface SuggestionAppliedRecord {\n by?: string | undefined;\n branch?: string | undefined;\n commit?: string | undefined;\n pr?: number | undefined;\n payloadSha: string;\n at: string;\n /** Applied without the approvals (`--force-unapproved`). */\n forced?: boolean | undefined;\n}\n\n/** The comment recording that a suggestion is being applied (a branch or a pull request exists). */\nexport function composeSuggestionAppliedComment(r: SuggestionAppliedRecord): string {\n const where = r.pr ? `in pull request #${r.pr}` : r.branch ? `on \\`${r.branch}\\`` : r.commit ? `in commit ${r.commit.slice(0, 7)}` : 'locally';\n const record = Object.fromEntries(Object.entries(r).filter(([, v]) => v !== undefined));\n return [\n `Being applied ${where}${r.by ? ` by @${r.by.replace(/^@/, '')}` : ''}.${r.forced ? ' Applied before every approval was in.' : ''}`,\n '',\n `<!-- ${SUGGESTION_APPLIED_MARK} ${JSON.stringify(record)} -->`,\n ].join('\\n');\n}\n\nexport function parseSuggestionAppliedComment(body: string | null | undefined): SuggestionAppliedRecord | null {\n const m = new RegExp(`<!-- ${SUGGESTION_APPLIED_MARK} (\\\\{[^\\\\n]*?\\\\}) -->`).exec(body ?? '');\n if (!m) return null;\n try {\n const r = JSON.parse(m[1]!) as Partial<SuggestionAppliedRecord>;\n return r && typeof r.payloadSha === 'string' ? ({ ...r, payloadSha: r.payloadSha, at: typeof r.at === 'string' ? r.at : '' } as SuggestionAppliedRecord) : null;\n } catch {\n return null;\n }\n}\n\n/** A comment as read from GitHub (listIssueComments), oldest first. */\nexport interface SuggestionCommentLike {\n author: string;\n body: string;\n createdAt?: string | undefined;\n /** GitHub's author_association: OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, NONE... */\n authorAssociation?: string | undefined;\n}\n\nexport interface SuggestionGovernance {\n owners: Owners;\n rights?: Rights | null | undefined;\n /** Team members once read (teams.ts). Undefined: owner entries are used as listed. */\n teams?: TeamStates | null | undefined;\n /** `governance.soloOwnerCanApproveBoth`: the only owner's approval covers design and tech (review-gate summarizeApprovals). */\n soloOwnerCanApproveBoth?: boolean | undefined;\n}\n\nexport interface SuggestionApprovals extends ApprovalSummary {\n /** People whose latest review is on an older payload: it no longer counts. */\n stale: string[];\n /** People whose review does not count because they are not owners (or not collaborators when no owner is set). */\n ignored: string[];\n}\n\nconst norm = (l: string) => l.trim().replace(/^@/, '').toLowerCase();\nconst COLLABORATOR = ['OWNER', 'MEMBER', 'COLLABORATOR'];\n\n/**\n * Approvals on a suggestion, as summarizeApprovals counts them on a pull request, from the review comments: only\n * comments by people in the approver lists (governance owners and rights) count; with no owner configured at all, only\n * repository owners, members and collaborators (GitHub's author association). Only reviews of the current payload\n * sha count; the suggestion's author never approves their own suggestion. With `soloOwnerCanApproveBoth` and one\n * owner holding both roles, that owner's approval covers design and tech.\n */\nexport function summarizeSuggestionApprovals(comments: readonly SuggestionCommentLike[], gov: SuggestionGovernance, opts: { payloadSha: string; author?: string | null | undefined }): SuggestionApprovals {\n const lists = approverLists(gov.owners, gov.rights ?? null, gov.teams);\n const owners = new Set([...lists.design, ...lists.tech].map(norm));\n const anyOwner = owners.size > 0;\n const reviews: ReviewLike[] = [];\n const latestOld = new Map<string, SuggestionReviewEvent>();\n const ignored = new Set<string>();\n const ordered = comments.map((c, i) => ({ c, i })).sort((a, b) => String(a.c.createdAt ?? '').localeCompare(String(b.c.createdAt ?? '')) || a.i - b.i);\n ordered.forEach(({ c }, i) => {\n const r = parseSuggestionReviewComment(c.body);\n if (!r || r.event === 'comment' || !c.author) return;\n const login = norm(c.author);\n if (opts.author && login === norm(opts.author)) return;\n const counts = anyOwner ? owners.has(login) : COLLABORATOR.includes((c.authorAssociation ?? '').toUpperCase());\n if (!counts) {\n ignored.add(c.author);\n return;\n }\n const at = String(i).padStart(6, '0');\n if (r.payloadSha !== opts.payloadSha) {\n latestOld.set(c.author, r.event);\n // An older review is dismissed: it neither approves nor blocks the current payload.\n reviews.push({ user: { login: c.author }, state: 'DISMISSED', submitted_at: at });\n return;\n }\n latestOld.delete(c.author);\n reviews.push({ user: { login: c.author }, state: r.event === 'approve' ? 'APPROVED' : 'CHANGES_REQUESTED', submitted_at: at });\n });\n const summary = summarizeApprovals(reviews, lists, opts.author ?? undefined, { soloOwnerCanApproveBoth: gov.soloOwnerCanApproveBoth });\n const stale = [...latestOld.keys()].filter((l) => !summary.approvers.includes(l) && !summary.changesRequested.includes(l));\n return { ...summary, stale, ignored: [...ignored].filter((l) => !summary.approvers.includes(l)) };\n}\n\n/** The review state for the status machine: changes requested beats approved; approved when no approval is missing. */\nexport function suggestionReviewState(tier: RiskTier, approvals: ApprovalSummary): 'needs-review' | 'changes-requested' | 'approved' {\n if (approvals.changesRequested.length) return 'changes-requested';\n return pendingApprovals(tier, approvals).length ? 'needs-review' : 'approved';\n}\n","// Components pushed from Figma: a component a designer changed in Figma comes back to the coded library as a library\n// branch, routed by what Bridge can write with certainty:\n// - exact, no AI: the only change is a token swap (a padding, a radius, a colour now bound to another variable) on a\n// property code paints through a component token used nowhere else. It becomes a token change: that component token\n// now points to the new variable, checked for contrast and reviewed like any token change.\n// - drafted by Claude AI, reviewed by a person: a new variant, a new property, layers added or moved, a new component,\n// or a token swap code cannot express with a token alone. The structured diff (variant matrix, properties, bound\n// variables, layers, screenshot) goes on a library branch as a spec; Claude writes the code there through the MCP\n// server. Until it has, the branch says so: it carries the spec as a request, labelled \"waiting for Claude\".\n// - manual: what the scan cannot read with confidence (a detached layer, a raw value, a variable code does not have).\n// Each one is listed with what to do. Never dropped silently, never sent.\n// Once a library branch ships, a pull rebuilds the Figma component from the reviewed code, so Figma never diverges.\n//\n// Pure and browser safe: the Figma plugin, the MCP server and the CLI share these rules. The GitHub writes are in\n// figma-push-github.ts.\n\nimport { shortVariants } from './change-drafts';\nimport { variantKeyOf, type ComponentSpecsFile } from './component-spec';\nimport { slugify } from './pr-composer';\nimport { REQUEST_KINDS, requestIssueTitle, type RequestChange, type RequestKind, type RequestSource } from './requests';\nimport type { TokenEdit } from './token-edits';\nimport type { ContrastPair } from './wcag';\n\n/** Where a component change goes: a token change (exact), a library branch Claude drafts, or nowhere yet (manual). */\nexport type PushRoute = 'token-change' | 'claude-draft' | 'manual';\n\n/** A token swap seen in Figma: in these variants, one property moved from one variable to another (token paths). */\nexport interface Rebind {\n /** Property family, as the scan names it: fill, stroke, radius, padding, gap, size, typography... */\n kind: string;\n /** Variant names (\"Size=md, Tone=primary\") where it moved. */\n variants: string[];\n /** Every variant of the component moved the same way. */\n allVariants: boolean;\n before: string[];\n after: string[];\n}\n\n/** An edit the scan cannot read with confidence, and what the designer does about it. */\nexport interface PushIssue {\n what: string;\n todo: string;\n}\n\n/**\n * A component change from Figma, structured: what the designer sees in the Push tab, and what the library branch\n * carries as its spec (the JSON Claude reads to write the code).\n */\nexport interface ComponentPushDiff {\n v: 1;\n /** Coded name (\"Button\"), or the proposed name of a new component (\"DatePicker\"). */\n component: string;\n /** Name of the set in Figma (\"Forms / Date picker\"). */\n figmaName: string;\n /** The component has a folder in code. */\n coded: boolean;\n kind: RequestKind;\n /** One line, sentence case: \"Add a lg size\". */\n title: string;\n summary: string;\n /** What changes, in one sentence. */\n line?: string | undefined;\n /** The rows of the change, as the Push tab lists them. */\n changes: RequestChange[];\n /** Token swaps, for the exact route. */\n rebinds: Rebind[];\n /** Something only code can carry: a variant, a property, layers, a swapped instance, a new component. */\n needsCode: boolean;\n /** Edits the scan cannot read with confidence: listed with what to do, never sent. */\n unknown: PushIssue[];\n figma?:\n | {\n fileKey?: string | undefined;\n nodeId?: string | undefined;\n nodeName?: string | undefined;\n url?: string | undefined;\n /** A node that shows the design before the change, when the file keeps one (optional). */\n before?: { nodeId: string; nodeName?: string | undefined; url?: string | undefined } | undefined;\n }\n | undefined;\n /** The component as Figma has it now: variant axes, properties, bound variables (token paths) per variant. */\n variantAxes: Record<string, string[]>;\n properties: { name: string; type: string; default: string }[];\n bindings: Record<string, Record<string, string[]>>;\n /** Layers of each variant, in order, as words (\"instance Icon/Pencil, \\\"Icon\\\"\"). */\n anatomy: Record<string, string[]>;\n /** What code gave Figma at the last pull, when known. */\n before?: { variantAxes: Record<string, string[]>; properties: { name: string; type: string; default: string }[] } | undefined;\n /** Screenshot URLs (Figma exports on the requests branch). */\n images?: string[] | undefined;\n source: RequestSource;\n requestedBy?: string | undefined;\n}\n\n/** What the plan needs to know about tokens, from wherever the caller reads them (the plugin, the MCP server). */\nexport interface PushTokenContext {\n /** Tier of a token path (\"component\", \"semantic\"...), undefined when the library has no such token. */\n tierOf(path: string): string | undefined;\n /**\n * Where else this token paints: variants of the same component outside the swap (\"Size=sm, Variant=primary\"), and\n * other components (\"IconButton\"). Empty lists: nowhere else.\n */\n usedElsewhere(path: string, rebind: Rebind): { variants: string[]; components: string[] };\n}\n\nexport interface ComponentPushPlan {\n route: PushRoute;\n /** One sentence in designer words: what happens when it is sent. */\n said: string;\n /** Exact token edits: the whole change (token-change), or the part Claude makes too (claude-draft). */\n edits: TokenEdit[];\n /** Why a token swap needs Claude rather than a token change, one sentence each. */\n reasons: string[];\n /** Listed with what to do, never sent. */\n issues: PushIssue[];\n /** Other components an exact token change also repaints (they share the component token): said, for review. */\n alsoChanges: string[];\n}\n\nconst where = (r: Rebind) => (r.allVariants ? 'every variant' : shortVariants(r.variants.join('; ')));\nconst cap = (s: string) => (s ? s.charAt(0).toUpperCase() + s.slice(1) : s);\n\n/**\n * How a component change from Figma goes back to the library. A token swap is exact when the property was painted by a\n * component token (one variable before, one after), that token paints nothing else, and the new variable is a token\n * the library has: the token then points to the new variable. Anything else that needs code is drafted by Claude AI;\n * what cannot be read with confidence is listed with what to do.\n */\nexport function planComponentPush(d: ComponentPushDiff, ctx: PushTokenContext): ComponentPushPlan {\n const issues = [...d.unknown];\n const reasons: string[] = [];\n const edits = new Map<string, TokenEdit>();\n const also = new Set<string>();\n for (const r of d.rebinds) {\n const label = `${cap(r.kind)} in ${where(r)}`;\n if (!r.after.length) {\n issues.push({ what: `${label} is no longer bound to a variable: it uses a raw value.`, todo: 'Bind it to a variable, or create the variable and push it with the variables, then push again.' });\n continue;\n }\n const missing = r.after.filter((p) => !ctx.tierOf(p));\n if (missing.length) {\n issues.push({ what: `${label} uses ${missing.join(', ')}, a variable the library does not have yet.`, todo: 'Push the variable first (Variables, above), then push this component again.' });\n continue;\n }\n if (!r.before.length) {\n reasons.push(`${label} is bound to ${r.after.join(', ')} where code paints nothing: Claude AI adds it to the CSS.`);\n continue;\n }\n if (r.before.length !== 1 || r.after.length !== 1) {\n reasons.push(`${label} moved from ${r.before.join(', ')} to ${r.after.join(', ')}: several variables on one property, so Claude AI writes the CSS.`);\n continue;\n }\n const [from, to] = [r.before[0]!, r.after[0]!];\n if (ctx.tierOf(from) !== 'component') {\n reasons.push(`Code paints ${r.kind} with ${from} directly, not through a ${d.component} token: Claude AI changes the CSS to ${to}.`);\n continue;\n }\n // Other variants of this component still paint with it: the designer changed only some, so a new token is needed.\n // Other components that share it (IconButton uses button tokens) change with it: said, the review decides.\n const elsewhere = ctx.usedElsewhere(from, r);\n if (elsewhere.variants.length) {\n const v = elsewhere.variants;\n const list = v.length > 3 ? `${shortVariants(v.slice(0, 3).join('; ')).replace(/ and /, ', ')} and ${v.length - 3} more` : shortVariants(v.join('; '));\n reasons.push(`${from} also paints ${list}: pointing it to ${to} would change them too, so Claude AI adds a token for ${where(r)}.`);\n continue;\n }\n for (const c of elsewhere.components) also.add(c);\n const prev = edits.get(from);\n if (prev && prev.value !== `{${to}}`) {\n reasons.push(`${from} moved to two different variables (${String(prev.value).slice(1, -1)} and ${to}): Claude AI splits it.`);\n edits.delete(from);\n continue;\n }\n edits.set(from, { op: 'set', path: from, value: `{${to}}` });\n }\n const list = [...edits.values()];\n if (d.needsCode || reasons.length) {\n return {\n route: 'claude-draft',\n said: `Claude AI drafts the code from what you changed, then a person reviews it.${list.length ? ` ${list.length === 1 ? 'Its token swap goes' : 'Its token swaps go'} with it.` : ''}`,\n edits: list,\n reasons,\n issues,\n alsoChanges: [...also],\n };\n }\n if (list.length) {\n const n = list.length;\n const others = [...also];\n const names = others.length > 3 ? [...others.slice(0, 3), `${others.length - 3} more`] : others;\n const alsoLine = names.length ? ` It also repaints ${names.length > 1 ? `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}` : names[0]}: they use the same token${n === 1 ? '' : 's'}.` : '';\n return { route: 'token-change', said: `Exact, no AI: ${n === 1 ? `${list[0]!.path} points` : `${n} ${d.component} tokens point`} to the new variable${n === 1 ? '' : 's'}, checked for contrast and reviewed like any token change.${alsoLine}`, edits: list, reasons, issues, alsoChanges: others };\n }\n return { route: 'manual', said: issues.length ? 'Fix it in Figma first: nothing is sent until Bridge can read it.' : 'Nothing to send.', edits: [], reasons, issues, alsoChanges: [] };\n}\n\n/**\n * Where else a token paints, from component-specs.json (what code gives each component): the variants of `component`\n * outside the swap, and the other components. For tools that read the code, not a Figma file (the MCP server, the CLI).\n */\nexport function specsUsage(specs: Pick<ComponentSpecsFile, 'components'>, component: string): PushTokenContext['usedElsewhere'] {\n const own = specs.components.find((x) => x.name === component) ?? specs.components.find((x) => x.component === component);\n return (path, r) => {\n const variants: string[] = [];\n const components: string[] = [];\n for (const c of specs.components) {\n for (const v of c.variants) {\n if (!Object.values(v.values).some((fields) => Object.values(fields ?? {}).includes(path))) continue;\n const key = variantKeyOf(v.props);\n if (c === own) {\n if (!r.variants.includes(key)) variants.push(key);\n } else if (!components.includes(c.name)) components.push(c.name);\n }\n }\n return { variants, components };\n };\n}\n\n/**\n * The contrast gate for component token swaps. contrast.checks.json lists semantic pairs (action text on action bg);\n * a component token that aliases one side of a pair is checked in its place, against the component token that aliases\n * the other side (button.primary.text on button.primary.bg), else against that other side itself. So pointing\n * button.primary.bg to a pale variable fails the same way the semantic pair would.\n */\nexport function componentContrastPairs(edits: readonly Pick<TokenEdit, 'path'>[], pairs: readonly ContrastPair[], tokens: { aliasOf(path: string): string | undefined; paths: readonly string[] }): ContrastPair[] {\n const out = new Map<string, ContrastPair>();\n for (const e of edits) {\n const target = tokens.aliasOf(e.path);\n if (!target) continue;\n const group = e.path.split('.')[0]!;\n // The component token in the same component that paints the other side, when there is one.\n const sibling = (other: string) => tokens.paths.find((p) => p !== e.path && p.split('.')[0] === group && tokens.aliasOf(p) === other) ?? other;\n for (const p of pairs) {\n if (p.foreground === target) out.set(`${e.path}|${sibling(p.background)}`, { ...p, foreground: e.path, background: sibling(p.background) });\n if (p.background === target) out.set(`${sibling(p.foreground)}|${e.path}`, { ...p, foreground: sibling(p.foreground), background: e.path });\n }\n }\n return [...out.values()];\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// The library branch: origin mark, spec file, brief and body\n\n/** Every library branch opened from a Figma component carries this label. */\nexport const FROM_FIGMA_LABEL = 'from-figma';\n/** A Claude draft branch that carries the spec only: no code yet. */\nexport const WAITING_FOR_CLAUDE_LABEL = 'waiting-for-claude';\n/** A Claude draft branch once Claude wrote the code: a person reviews it. */\nexport const DRAFTED_BY_CLAUDE_LABEL = 'drafted-by-claude';\n/** Where a Claude draft branch keeps the spec it was opened with. */\nexport const FIGMA_SPEC_DIR = '.bridge/figma';\n\nconst ORIGIN_MARK = 'bridge-from-figma';\n\nexport type FigmaOriginStatus = 'spec' | 'drafted';\n\n/** What the library branch remembers about where it came from: the Figma component and how it was routed. */\nexport interface FigmaOrigin {\n component: string;\n figmaName: string;\n route: Exclude<PushRoute, 'manual'>;\n kind: RequestKind;\n nodeId?: string | undefined;\n fileKey?: string | undefined;\n url?: string | undefined;\n /** Claude draft branches: the spec file, and whether Claude wrote the code yet. */\n spec?: string | undefined;\n status?: FigmaOriginStatus | undefined;\n requestedBy?: string | undefined;\n}\n\nconst hidden = (data: unknown) => `<!-- ${ORIGIN_MARK} ${JSON.stringify(data).replace(/-->/g, '--\\\\u003e')} -->`;\n\nexport function parseFigmaOrigin(body: string | null | undefined): FigmaOrigin | undefined {\n if (!body) return undefined;\n const m = new RegExp(`<!-- ${ORIGIN_MARK} (\\\\{[\\\\s\\\\S]*?\\\\}) -->`).exec(body);\n if (!m) return undefined;\n try {\n const o = JSON.parse(m[1]!) as FigmaOrigin;\n return typeof o.component === 'string' && (o.route === 'token-change' || o.route === 'claude-draft') ? o : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The \"From Figma\" lines people read on GitHub, then the hidden block tools read. */\nexport function figmaOriginSection(o: FigmaOrigin): string {\n const design = o.url ? `[${o.figmaName}](${o.url})` : `\"${o.figmaName}\"`;\n const who = o.requestedBy ? ` by @${o.requestedBy}` : '';\n const status =\n o.route === 'token-change'\n ? 'Exact token change, no AI: Bridge read the token swap from the Figma component.'\n : o.status === 'drafted'\n ? '**Drafted by Claude AI** from the Figma spec. A person reviews it before it ships.'\n : `**Waiting for Claude AI:** this branch carries the spec only, as a request. Claude writes the code here (\\`bridge_get_figma_change\\`, or \\`bridge figma show <number>\\`), then it is labelled ${DRAFTED_BY_CLAUDE_LABEL}.`;\n return [`**From Figma:** ${design}${who}. Once it ships, a pull in the DS Bridge plugin rebuilds the component from this code.`, '', status, '', hidden(o)].join('\\n');\n}\n\n/** The body with the \"From Figma\" section first (replacing an earlier one). */\nexport function withFigmaOrigin(body: string | null | undefined, o: FigmaOrigin): string {\n let b = (body ?? '').trim();\n const at = b.indexOf('**From Figma:**');\n const mark = b.indexOf(`<!-- ${ORIGIN_MARK} `);\n if (at >= 0 && mark > at) {\n const end = b.indexOf('-->', mark);\n b = `${b.slice(0, at)}${b.slice(end + 3)}`.trim();\n }\n return `${figmaOriginSection(o)}${b ? `\\n\\n${b}` : ''}`;\n}\n\nexport const figmaSpecSlug = (d: Pick<ComponentPushDiff, 'component' | 'title'>) => slugify(`${d.component} ${d.title}`, 48) || 'component-change';\n\n/** The spec file of a Claude draft branch. */\nexport const figmaSpecPath = (d: Pick<ComponentPushDiff, 'component' | 'title'>) => `${FIGMA_SPEC_DIR}/${figmaSpecSlug(d)}.json`;\n\nconst kindLabel = (k: RequestKind) => REQUEST_KINDS.find((x) => x.value === k)?.label ?? 'Change';\n\n/** The structured diff as the spec file stores it (stable key order, two-space JSON). */\nexport function formatFigmaSpec(d: ComponentPushDiff, plan: Pick<ComponentPushPlan, 'edits' | 'reasons' | 'issues'>): string {\n return `${JSON.stringify({ ...d, tokenEdits: plan.edits, reasons: plan.reasons, unknown: plan.issues }, null, 2)}\\n`;\n}\n\n/** Reads a spec file back; undefined when it is not one. */\nexport function parseFigmaSpec(text: string | null | undefined): (ComponentPushDiff & { tokenEdits?: TokenEdit[]; reasons?: string[] }) | undefined {\n if (!text) return undefined;\n try {\n const s = JSON.parse(text) as ComponentPushDiff & { tokenEdits?: TokenEdit[]; reasons?: string[] };\n return s && s.v === 1 && typeof s.component === 'string' && Array.isArray(s.changes) ? s : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * What Claude gets to draft the code on the branch (MCP `bridge_get_figma_change`, CLI `bridge figma show`): the change,\n * the spec, the exact token swaps to make too, the rules, and how to say it is drafted.\n */\nexport function figmaDraftBrief(\n d: ComponentPushDiff & { tokenEdits?: TokenEdit[] | undefined; reasons?: string[] | undefined },\n ctx: { pr: number; branch: string; specPath: string; componentsDir?: string | undefined; agentsFile?: string | undefined } | { suggestion: true; specPath: string; componentsDir?: string | undefined; agentsFile?: string | undefined },\n): string {\n const dir = `${(ctx.componentsDir ?? 'packages/react/src/components').replace(/\\/+$/, '')}/${d.component}`;\n // A suggestion has no branch yet: the developer starts one by applying it, and the pull request closes the issue.\n const suggested = 'suggestion' in ctx;\n const variants = Object.entries(d.variantAxes).map(([axis, values]) => `${axis}: ${values.join(', ')}`);\n const props = d.properties.filter((p) => p.type !== 'VARIANT').map((p) => `${p.name} (${p.type.toLowerCase().replace('_', ' ')}, default ${p.default || 'empty'})`);\n return [\n suggested\n ? 'Draft the code for a component change made in Figma, sent as a Bridge suggestion (this issue).'\n : `Draft the code for a component change made in Figma, on the library branch ${ctx.branch} (draft pull request #${ctx.pr}).`,\n '',\n d.coded ? `Component: ${d.component} (${dir})` : `New component: ${d.component} (create ${dir})`,\n `Kind: ${kindLabel(d.kind)}`,\n `Change: ${d.title}`,\n ...(d.line?.trim() ? [`What changes: ${d.line.trim()}`] : []),\n '',\n d.summary.trim(),\n '',\n ...(d.changes.length ? ['Changes in Figma:', ...d.changes.map((c) => `- ${c.field}: ${c.before ?? '(none)'} -> ${c.after ?? '(removed)'}`), ''] : []),\n ...(variants.length ? ['Variant matrix in Figma:', ...variants.map((v) => `- ${v}`), ''] : []),\n ...(props.length ? ['Properties in Figma:', ...props.map((p) => `- ${p}`), ''] : []),\n ...(d.tokenEdits?.length ? ['Token swaps to make too (exact, with bridge_propose_token_change on this branch or by hand in the token files):', ...d.tokenEdits.map((e) => `- ${e.path} -> ${String(e.value)}`), ''] : []),\n ...(d.reasons?.length ? ['Why this needs code:', ...d.reasons.map((r) => `- ${r}`), ''] : []),\n `Spec: ${ctx.specPath} ${suggested ? 'in the suggestion' : 'on the branch'} has the bound variables of every variant (token paths), the layers of every variant and what code gave Figma before.`,\n ...(d.figma?.url ? [`Design: ${d.figma.url}`] : []),\n ...(suggested && d.figma?.fileKey && d.figma.nodeId\n ? [`Read the design straight from Figma: Figma MCP get_design_context { fileKey: \"${d.figma.fileKey}\", nodeId: \"${d.figma.nodeId}\" }${d.figma.before?.nodeId ? ` (before: node ${d.figma.before.nodeId})` : ''}, or the REST API GET https://api.figma.com/v1/files/${d.figma.fileKey}/nodes?ids=${encodeURIComponent(d.figma.nodeId)}.`]\n : []),\n ...(d.images?.length ? ['Screenshot:', ...d.images.map((u) => `- ${u}`)] : []),\n '',\n 'Steps:',\n 'suggestion' in ctx ? '1. Apply the suggestion on a new branch: bridge apply <this issue number> (it writes the spec file), or start a branch from the default branch.' : `1. git fetch origin && git checkout ${ctx.branch}`,\n `2. Write the change in ${dir}: the TSX on Base UI, the CSS module with tokens only (the bound variables of the spec, as token paths), the stories (examples), docs.json and a changeset. Follow ${ctx.agentsFile ?? 'AGENTS.md'}.`,\n '3. Run npm run specs so component-specs.json matches the code, then npm test.',\n 'suggestion' in ctx\n ? '4. Commit, push and open a pull request that says \"Closes #<this issue number>\", so the suggestion closes when it ships. A person reviews it.'\n : `4. Commit and push to ${ctx.branch}, then call bridge_mark_figma_change_drafted { pr: ${ctx.pr} } (CLI: bridge figma drafted ${ctx.pr}). The branch is then labelled ${DRAFTED_BY_CLAUDE_LABEL} and a person reviews it.`,\n '',\n 'Rules:',\n '- Never invent a token or a value: use the variables the spec lists. A value the library lacks is a token change, said in the pull request.',\n '- Keep every existing variant and prop unchanged unless the spec changes it.',\n `- If the spec is unclear, comment on the ${suggested ? 'suggestion' : 'pull request'} instead of guessing.`,\n ].join('\\n');\n}\n\n/** The pull request body of a Claude draft branch: the origin, the change, the rows and the spec. */\nexport function figmaDraftBody(d: ComponentPushDiff, plan: Pick<ComponentPushPlan, 'edits' | 'reasons' | 'issues'>, o: FigmaOrigin): string {\n const cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\n/g, ' ');\n const rows = d.changes.length ? ['| What | Code now | In Figma |', '| --- | --- | --- |', ...d.changes.map((c) => `| ${cell(c.field)} | ${cell(c.before ?? '')} | ${cell(c.after ?? '')} |`), ''] : [];\n return withFigmaOrigin(\n [\n `## ${d.coded ? `${kindLabel(d.kind)} for ${d.component}` : `New component: ${d.component}`}`,\n '',\n d.summary.trim(),\n '',\n ...(d.line?.trim() ? [`**What changes:** ${d.line.trim()}`, ''] : []),\n ...rows,\n ...(d.images?.length ? [...d.images.map((u, i) => ``), ''] : []),\n ...(plan.edits.length ? ['**Token swaps to make too:**', ...plan.edits.map((e) => `- \\`${e.path}\\` -> \\`${String(e.value)}\\``), ''] : []),\n ...(plan.reasons.length ? ['**Why this needs code:**', ...plan.reasons.map((r) => `- ${r}`), ''] : []),\n ...(plan.issues.length ? ['**Left in Figma (the designer fixes these first):**', ...plan.issues.map((i) => `- ${i.what} ${i.todo}`), ''] : []),\n `**Spec:** \\`${o.spec ?? figmaSpecPath(d)}\\` (variant matrix, properties, bound variables and layers of every variant).`,\n ].join('\\n'),\n o,\n );\n}\n\n/** The title of a library branch opened from Figma: \"Button: add a lg size\". */\nexport const figmaBranchTitle = (d: Pick<ComponentPushDiff, 'component' | 'title'>) => requestIssueTitle(d);\n\n// ---------------------------------------------------------------------------------------------------------------\n// Where a library branch from Figma stands\n\nexport type FigmaPushStatusKey = 'waiting-for-claude' | 'drafted' | 'in-review' | 'shipped' | 'closed';\n\nexport interface FigmaPushStatus {\n key: FigmaPushStatusKey;\n /** \"Waiting for Claude AI\", \"Shipped\". */\n label: string;\n /** One sentence for the designer. */\n sentence: string;\n /** The Figma component should be rebuilt from code (the branch shipped or was closed). */\n rebuild: boolean;\n}\n\n/** Where a library branch opened from Figma stands, from its state and labels. */\nexport function figmaPushStatus(x: { state: string; draft?: boolean | undefined; labels?: readonly string[] | undefined; route?: PushRoute | undefined }): FigmaPushStatus {\n const labels = x.labels ?? [];\n if (x.state === 'merged') return { key: 'shipped', label: 'Shipped', sentence: 'It shipped. Pull to rebuild the component from the reviewed code.', rebuild: true };\n if (x.state !== 'open') return { key: 'closed', label: 'Closed', sentence: 'The library closed it without shipping. Pull to bring the component back to the code.', rebuild: true };\n if (labels.includes(WAITING_FOR_CLAUDE_LABEL)) return { key: 'waiting-for-claude', label: 'Waiting for Claude AI', sentence: 'The spec is on the library branch. Claude AI writes the code there, then a person reviews it.', rebuild: false };\n if (labels.includes(DRAFTED_BY_CLAUDE_LABEL)) return { key: 'drafted', label: 'Drafted by Claude AI', sentence: 'Claude AI drafted the code. A person reviews it before it ships.', rebuild: false };\n return { key: 'in-review', label: 'In review', sentence: x.route === 'token-change' ? 'Owners review the token change.' : 'Owners review it.', rebuild: false };\n}\n","// Suggestions: a change Bridge files as a GitHub issue instead of a branch, so a design system owner can work with\n// read access to the code. Owners approve it on the issue (suggestion-review.ts) and a developer applies it with their\n// own access (`bridge apply <n>`). It follows the request conventions (requests.ts): a readable Markdown body, labels\n// tools filter on, status from the issue state and the pull requests that close it. The difference is an exact,\n// machine-applicable payload: a versioned JSON block (schema \"bridge.suggestion/1\") in a collapsed section at the end\n// of the body, with the sha256 of its canonical form in a marker, so an edit by hand is detected. Token changes are\n// stored as edits (paths and values, re-applied on the current tokens), other files as whole contents with the git\n// blob sha before and after. Large file contents move to continuation comments (\"parts\") to fit GitHub's limit.\n// Pure: no I/O, runs in a browser, a plugin sandbox or Node. GitHub calls live in suggestions-github.ts.\n\nimport { CONFIG_FILE, tokensPath, type BridgeConfig } from './config';\nimport { EXPLORATION_LABEL } from './explorations';\nimport { FROM_FIGMA_LABEL } from './figma-push';\nimport type { LayeredChange } from './layered-review';\nimport { NEEDED_BY_LABEL, type NeededBy } from './prod-branch';\nimport type { RequestSource } from './requests';\nimport type { TokenEdit } from './token-edits';\n\nexport const SUGGESTION_SCHEMA = 'bridge.suggestion/1';\n/** Every suggestion issue carries this label; tools list suggestions by it. */\nexport const SUGGESTION_LABEL = 'bridge-suggestion';\n\nexport type SuggestionKind = 'token-change' | 'docs' | 'component-spec' | 'brand' | 'revert' | 'config';\nexport const SUGGESTION_KINDS: readonly SuggestionKind[] = ['token-change', 'docs', 'component-spec', 'brand', 'revert', 'config'];\n\n/** The states a suggestion label records, exactly one at a time while the issue is open. */\nexport type SuggestionState = 'needs-review' | 'changes-requested' | 'approved' | 'applying';\n/** Where a suggestion stands (suggestionStatus). */\nexport type SuggestionStatus = SuggestionState | 'applied' | 'declined' | 'outdated';\n\nexport const SUGGESTION_STATE_LABELS: Record<SuggestionState, string> = {\n 'needs-review': 'suggestion: needs review',\n 'changes-requested': 'suggestion: changes requested',\n approved: 'suggestion: approved',\n applying: 'suggestion: applying',\n};\n\nexport const SUGGESTION_STATUS_LABEL: Record<SuggestionStatus, string> = {\n 'needs-review': 'Needs review',\n 'changes-requested': 'Changes requested',\n approved: 'Approved, ready to apply',\n applying: 'Being applied',\n applied: 'Applied',\n declined: 'Declined',\n outdated: 'Outdated',\n};\n\n/** A whole-file result: the git blob sha at `base` (null: a new file), after (null: deleted), and the new content. */\nexport interface SuggestionFile {\n path: string;\n beforeSha: string | null;\n afterSha: string | null;\n /** The new text; null for a deleted file. Absent from the body when it moved to a continuation comment (`part`). */\n content?: string | null | undefined;\n /** Continuation comment (1-based) where the content starts. Transport only: not part of the payload sha. */\n part?: number | undefined;\n}\n\nexport interface SuggestionContrastCheck {\n pair: string;\n mode?: string | undefined;\n before: number;\n after: number;\n min: number;\n pass: boolean;\n}\n\nexport type SuggestionTokenChange = Pick<LayeredChange, 'kind' | 'path' | 'from' | 'file' | 'before' | 'after' | 'beforeCss' | 'afterCss'>;\n\n/**\n * A Figma node a suggestion is about: what Claude Code (Figma MCP get_design_context) or the Figma REST API reads the\n * design from, so a suggestion needs no hosted image. `state`: the design before the change or as it is now (after).\n */\nexport interface SuggestionFigmaNode {\n nodeId: string;\n url?: string | undefined;\n name?: string | undefined;\n state?: 'before' | 'after' | undefined;\n}\n\n/** The Figma design URL of a node: what a person opens and what the Figma MCP server reads. */\nexport const figmaNodeUrl = (fileKey: string, nodeId: string) => `https://www.figma.com/design/${fileKey}/?node-id=${encodeURIComponent(nodeId.replace(/:/g, '-'))}`;\n\nexport interface SuggestionPayloadV1 {\n schema: typeof SUGGESTION_SCHEMA;\n kind: SuggestionKind;\n title: string;\n summary: string;\n source: RequestSource;\n /** GitHub login. */\n suggestedBy?: string | undefined;\n /** ISO date. */\n createdAt: string;\n /** Default branch and the commit the plan was computed on. */\n base: { ref: string; sha: string };\n tier: { tier: 1 | 2 | 3; bump: 'patch' | 'minor' | 'major' };\n /** Semantic token ops, applied with applyTokenEdits on the current token set, never as a text patch. */\n tokens?: { edits: TokenEdit[]; changes: SuggestionTokenChange[] } | undefined;\n /** docs.json edits: the component and the cleaned docs object. */\n docs?: { component: string; path: string; after: unknown }[] | undefined;\n /** Figma component push spec, for Claude or a developer to implement. */\n componentSpec?: { component: string; specPath: string; spec: unknown; brief: string } | undefined;\n /** Whole-file results for everything else (changeset, brand files, revert, config). */\n files?: SuggestionFile[] | undefined;\n checks: {\n newErrors: number;\n contrast: SuggestionContrastCheck[];\n /** The planner's `blocked` sentence at creation; a suggestion is never created when it is set. */\n blocked: string | null;\n impact: number;\n };\n links?:\n | {\n neededBy?: NeededBy | undefined;\n figma?:\n | {\n fileKey?: string | undefined;\n nodeId?: string | undefined;\n url?: string | undefined;\n /** Figma nodes of the change (optional, added in 0.x: older payloads omit it). Claude reads them from Figma. */\n nodes?: SuggestionFigmaNode[] | undefined;\n }\n | undefined;\n /** explore/<slug> */\n exploration?: string | undefined;\n /** A previous suggestion this one replaces. */\n supersedes?: number | undefined;\n }\n | undefined;\n previews?: { label: string; url: string }[] | undefined;\n}\n\n/** GitHub caps an issue body and a comment at 65,536 characters. The budgets below keep every write under it. */\nexport const SUGGESTION_LIMITS = {\n body: 65_536,\n /** The readable part of the body (tables are cut with \"and N more\"). */\n human: 12_000,\n /** The JSON block in the body. */\n inline: 48_000,\n /** The JSON block of one continuation comment. */\n part: 60_000,\n /** Continuation comments at most (about 480 KB of file contents). */\n maxParts: 8,\n} as const;\n\nexport type SuggestionErrorCode = 'too-large' | 'invalid';\n\nexport class SuggestionError extends Error {\n constructor(\n readonly code: SuggestionErrorCode,\n message: string,\n ) {\n super(message);\n this.name = 'SuggestionError';\n }\n}\n\nexport const SUGGESTION_TOO_LARGE = 'Too large for a suggestion: split it, or ask a developer to open it directly.';\n\n// ---------------------------------------------------------------------------------------------------------------\n// Hashes: sha256 for the payload, git blob sha1 for files. Pure TypeScript so it runs where crypto.subtle does not\n// (Figma plugin sandbox) and stays synchronous.\n\nconst utf8 = (text: string): Uint8Array => new TextEncoder().encode(text);\nconst hex = (words: number[]) => words.map((w) => (w >>> 0).toString(16).padStart(8, '0')).join('');\n\nfunction padded(bytes: Uint8Array): DataView {\n const len = bytes.length;\n const total = Math.ceil((len + 9) / 64) * 64;\n const buf = new Uint8Array(total);\n buf.set(bytes);\n buf[len] = 0x80;\n const view = new DataView(buf.buffer);\n view.setUint32(total - 8, Math.floor(len / 0x20000000), false);\n view.setUint32(total - 4, (len * 8) >>> 0, false);\n return view;\n}\n\nconst K256 = [\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n];\n\n/** sha256 of a string's UTF-8 bytes, as 64 hex characters. */\nexport function sha256Hex(text: string): string {\n const view = padded(utf8(text));\n const h = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19];\n const w = new Array<number>(64);\n const rotr = (x: number, n: number) => (x >>> n) | (x << (32 - n));\n for (let off = 0; off < view.byteLength; off += 64) {\n for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4, false);\n for (let i = 16; i < 64; i++) {\n const a = w[i - 15]!;\n const b = w[i - 2]!;\n const s0 = rotr(a, 7) ^ rotr(a, 18) ^ (a >>> 3);\n const s1 = rotr(b, 17) ^ rotr(b, 19) ^ (b >>> 10);\n w[i] = (w[i - 16]! + s0 + w[i - 7]! + s1) | 0;\n }\n let [a, b, c, d, e, f, g, hh] = h as [number, number, number, number, number, number, number, number];\n for (let i = 0; i < 64; i++) {\n const t1 = (hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ (~e & g)) + K256[i]! + w[i]!) | 0;\n const t2 = ((rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) | 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n h[0] = (h[0]! + a) | 0;\n h[1] = (h[1]! + b) | 0;\n h[2] = (h[2]! + c) | 0;\n h[3] = (h[3]! + d) | 0;\n h[4] = (h[4]! + e) | 0;\n h[5] = (h[5]! + f) | 0;\n h[6] = (h[6]! + g) | 0;\n h[7] = (h[7]! + hh) | 0;\n }\n return hex(h);\n}\n\nfunction sha1Bytes(bytes: Uint8Array): string {\n const view = padded(bytes);\n const h = [0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0];\n const w = new Array<number>(80);\n const rotl = (x: number, n: number) => (x << n) | (x >>> (32 - n));\n for (let off = 0; off < view.byteLength; off += 64) {\n for (let i = 0; i < 16; i++) w[i] = view.getUint32(off + i * 4, false);\n for (let i = 16; i < 80; i++) w[i] = rotl(w[i - 3]! ^ w[i - 8]! ^ w[i - 14]! ^ w[i - 16]!, 1);\n let [a, b, c, d, e] = h as [number, number, number, number, number];\n for (let i = 0; i < 80; i++) {\n const [f, k] = i < 20 ? [(b & c) | (~b & d), 0x5a827999] : i < 40 ? [b ^ c ^ d, 0x6ed9eba1] : i < 60 ? [(b & c) | (b & d) | (c & d), 0x8f1bbcdc] : [b ^ c ^ d, 0xca62c1d6];\n const t = (rotl(a, 5) + f + e + k + w[i]!) | 0;\n e = d;\n d = c;\n c = rotl(b, 30);\n b = a;\n a = t;\n }\n h[0] = (h[0]! + a) | 0;\n h[1] = (h[1]! + b) | 0;\n h[2] = (h[2]! + c) | 0;\n h[3] = (h[3]! + d) | 0;\n h[4] = (h[4]! + e) | 0;\n }\n return hex(h);\n}\n\n/** The git blob sha of a text file (what `git hash-object` and the GitHub contents API return). */\nexport function gitBlobSha(text: string): string {\n const body = utf8(text);\n const head = utf8(`blob ${body.length}\\0`);\n const all = new Uint8Array(head.length + body.length);\n all.set(head);\n all.set(body, head.length);\n return sha1Bytes(all);\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Canonical form and payload sha\n\n/** JSON with object keys sorted and no spaces; `undefined` members dropped, as JSON.stringify does. */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(v: unknown): unknown {\n if (Array.isArray(v)) return v.map((x) => (x === undefined ? null : sortKeys(x)));\n if (v && typeof v === 'object' && !((v as { toJSON?: unknown }).toJSON instanceof Function)) {\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(v as object).sort()) {\n const x = (v as Record<string, unknown>)[k];\n if (x !== undefined) out[k] = sortKeys(x);\n }\n return out;\n }\n return v;\n}\n\n/** The payload without transport fields (`files[].part`), the form its sha is computed on. */\nfunction shaForm(p: SuggestionPayloadV1): SuggestionPayloadV1 {\n if (!p.files) return p;\n return { ...p, files: p.files.map(({ part: _part, ...f }) => f) };\n}\n\n/** sha256 of the payload's canonical JSON: what approvals bind to and what the marker records. */\nexport function suggestionPayloadSha(p: SuggestionPayloadV1): string {\n return sha256Hex(canonicalJson(shaForm(p)));\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Title and labels\n\nconst KIND_SUBJECT: Record<SuggestionKind, string> = {\n 'token-change': 'Tokens',\n docs: 'Docs',\n 'component-spec': 'Component',\n brand: 'Brand',\n revert: 'Revert',\n config: 'Settings',\n};\n\n/** Subject of the title: the component for docs and component specs, else the kind (\"Tokens\", \"Brand\"). */\nexport function suggestionSubject(p: Pick<SuggestionPayloadV1, 'kind' | 'docs' | 'componentSpec'>): string {\n if (p.kind === 'component-spec' && p.componentSpec?.component) return p.componentSpec.component;\n if (p.kind === 'docs' && p.docs?.length) {\n const names = [...new Set(p.docs.map((d) => d.component))];\n return names.length === 1 ? names[0]! : KIND_SUBJECT.docs;\n }\n return KIND_SUBJECT[p.kind];\n}\n\n/** Issue title, like requests: \"Tokens: raise color.action.primary.bg contrast\", \"Button: docs for the danger tone\". */\nexport function suggestionIssueTitle(p: Pick<SuggestionPayloadV1, 'kind' | 'title' | 'docs' | 'componentSpec'>): string {\n const t = p.title.trim().replace(/\\.$/, '');\n return `${suggestionSubject(p)}: ${t.charAt(0).toLowerCase()}${t.slice(1)}`;\n}\n\n/**\n * The labels of a suggestion issue: the list key, kind, source, tier, one state label, then the marks it carries\n * (needed by a product, from Figma, exploration) and the caller's (governance or integrations labels). Labels are a\n * cache for filtering: status is always recomputed from comments and pull requests.\n */\nexport function suggestionLabels(p: SuggestionPayloadV1, opts: { state?: SuggestionState | undefined; labels?: string[] | undefined } = {}): string[] {\n return [\n ...new Set([\n SUGGESTION_LABEL,\n `suggestion: ${p.kind}`,\n `source: ${p.source}`,\n `tier: ${p.tier.tier}`,\n SUGGESTION_STATE_LABELS[opts.state ?? 'needs-review'],\n ...(p.links?.neededBy ? [NEEDED_BY_LABEL] : []),\n ...(p.links?.figma || p.source === 'figma' ? [FROM_FIGMA_LABEL] : []),\n ...(p.links?.exploration ? [EXPLORATION_LABEL] : []),\n ...(opts.labels ?? []),\n ]),\n ];\n}\n\n/** The kind a label set names, when the issue has a `suggestion: <kind>` label. */\nexport function suggestionKindFromLabels(labels: readonly string[]): SuggestionKind | undefined {\n for (const l of labels) {\n const m = /^suggestion: (.+)$/.exec(l);\n if (m && (SUGGESTION_KINDS as readonly string[]).includes(m[1]!)) return m[1] as SuggestionKind;\n }\n return undefined;\n}\n\n/** The state a label set records (the cache), when it has one. */\nexport function suggestionStateFromLabels(labels: readonly string[]): SuggestionState | undefined {\n return (Object.entries(SUGGESTION_STATE_LABELS) as [SuggestionState, string][]).find(([, l]) => labels.includes(l))?.[0];\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Status\n\nexport interface SuggestionStatusInput {\n state: 'open' | 'closed';\n stateReason?: string | null | undefined;\n /** Pull requests whose body closes the issue (\"Closes #n\"). */\n linkedPrs?: { state: 'open' | 'closed'; merged?: boolean | undefined }[] | undefined;\n /** From the review comments on the current payload sha (suggestionReviewState in suggestion-review.ts). */\n review?: 'needs-review' | 'changes-requested' | 'approved' | undefined;\n /** An \"applied\" marker comment exists (a developer applied it on a branch, see linkSuggestionPrOnGitHub). */\n applied?: boolean | undefined;\n /** The dry-run apply found a conflict with the current default branch. */\n outdated?: boolean | undefined;\n}\n\n/**\n * Where a suggestion stands. Closed: applied when a linked pull request merged or the issue was closed as completed,\n * declined otherwise. Open: applying when a linked pull request is open or an applied marker exists; outdated when the\n * dry run found a conflict; then the review state (changes requested, approved, needs review).\n */\nexport function suggestionStatus(i: SuggestionStatusInput): SuggestionStatus {\n const prs = i.linkedPrs ?? [];\n if (i.state === 'closed') return prs.some((p) => p.merged) || i.stateReason === 'completed' ? 'applied' : 'declined';\n if (prs.some((p) => p.state === 'open') || i.applied) return 'applying';\n if (i.outdated) return 'outdated';\n return i.review ?? 'needs-review';\n}\n\n/** The state label a status keeps on the issue, or null when none should stay (closed, outdated). */\nexport function suggestionStateLabel(status: SuggestionStatus): string | null {\n return status in SUGGESTION_STATE_LABELS ? SUGGESTION_STATE_LABELS[status as SuggestionState] : null;\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Compose\n\nexport interface SuggestionIssue {\n title: string;\n body: string;\n labels: string[];\n assignees: string[];\n /** Continuation comments to post right after the issue, in order. Empty when everything fits in the body. */\n parts: string[];\n /** sha256 of the payload (canonical JSON, contents included). */\n sha: string;\n}\n\nexport interface ComposeSuggestionOptions {\n labels?: string[] | undefined;\n assignees?: string[] | undefined;\n state?: SuggestionState | undefined;\n /**\n * Extra Markdown for the readable part, placed after the changes table (for example the risk tier reasons, contrast\n * and impact sections of composeProposalBody). Cut to fit the readable budget.\n */\n details?: string | undefined;\n /** \"owner/name\", for the Claude Code install line in \"How to apply\". Absent: a placeholder. */\n repo?: string | undefined;\n}\n\n/** The one-time command that gives Claude Code the Bridge MCP server for a repository. */\nexport const bridgeMcpInstallCommand = (repo?: string | null) => `claude mcp add bridge -s user -- npx -y @bridge-ds/mcp --repo ${repo?.trim() || '<owner/name>'}`;\n\nconst MARK = 'bridge-suggestion';\nconst PART_SCHEMA = 'bridge.suggestion-part/1';\nconst cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\r?\\n/g, ' ');\n/** Text people wrote, made safe to sit before the payload block (no fake marker, no HTML comment). */\nconst safeText = (s: string) => s.replace(/<!--/g, '<!--');\nconst sourceLabel = (s: RequestSource) => (s === 'figma' ? 'Figma' : s === 'studio' ? 'Bridge Studio' : s === 'cli' ? 'the CLI' : 'Claude (MCP)');\nconst show = (v: unknown): string => (v === undefined ? '' : typeof v === 'string' ? v : JSON.stringify(v));\n\nfunction table(head: string[], rows: string[][], max: number): string[] {\n if (!rows.length) return [];\n const shown = rows.slice(0, max);\n return [\n `| ${head.join(' | ')} |`,\n `| ${head.map(() => '---').join(' | ')} |`,\n ...shown.map((r) => `| ${r.map((c) => cell(c)).join(' | ')} |`),\n ...(rows.length > max ? ['', `and ${rows.length - max} more`] : []),\n ];\n}\n\nfunction changesSection(p: SuggestionPayloadV1, max: number): string[] {\n const out: string[] = [];\n if (p.tokens?.changes.length) {\n const rows = p.tokens.changes.map((c) => [\n `\\`${c.path}\\`${c.kind === 'renamed' && c.from ? ` (was \\`${c.from}\\`)` : c.kind === 'added' ? ' (new)' : c.kind === 'removed' ? ' (removed)' : ''}`,\n c.beforeCss ?? show(c.before),\n c.afterCss ?? show(c.after),\n ]);\n out.push(...table(['Token', 'Now', 'Suggested'], rows, max), '');\n } else if (p.tokens?.edits.length) {\n const rows = p.tokens.edits.map((e) => [`\\`${e.path}\\``, e.op === 'rename' ? `rename to \\`${e.newPath ?? ''}\\`` : e.op, show(e.value)]);\n out.push(...table(['Token', 'Edit', 'Value'], rows, max), '');\n }\n if (p.docs?.length) out.push(...table(['Component', 'Docs file'], p.docs.map((d) => [d.component, `\\`${d.path}\\``]), max), '');\n if (p.componentSpec) out.push(`**Component spec:** ${p.componentSpec.component} (\\`${p.componentSpec.specPath}\\`)`, '');\n if (p.files?.length) {\n const rows = p.files.map((f) => [`\\`${f.path}\\``, f.beforeSha === null ? 'new' : f.afterSha === null ? 'deleted' : 'changed']);\n out.push(...table(['File', 'Change'], rows, max), '');\n }\n return out;\n}\n\nfunction checksSection(p: SuggestionPayloadV1, max: number): string[] {\n const c = p.checks;\n const failing = c.contrast.filter((x) => !x.pass);\n const rows = [...failing, ...c.contrast.filter((x) => x.pass)].map((x) => [x.pair, x.mode ?? '', x.before.toFixed(2), x.after.toFixed(2), String(x.min), x.pass ? 'pass' : '**fails**']);\n return [\n '## Checks when suggested',\n '',\n `- Token validation: ${c.newErrors ? `**${c.newErrors} new error(s)**` : 'no new errors'}`,\n `- Contrast: ${c.contrast.length ? (failing.length ? `**${failing.length} failing pair(s)**` : `${c.contrast.length} pair(s) checked, all pass`) : 'no pair affected'}`,\n `- Risk tier: ${p.tier.tier} (\\`${p.tier.bump}\\`), ${p.tier.tier === 1 ? 'one approval' : 'design and tech approval'}`,\n `- Impact: ${c.impact ? `${c.impact} token(s) resolve to a new value` : 'no other token changes value'}`,\n '',\n ...(rows.length ? [...table(['Pair', 'Mode', 'Before', 'After', 'Min', 'Result'], rows, max), ''] : []),\n ];\n}\n\nfunction linksSection(p: SuggestionPayloadV1): string[] {\n const l = p.links ?? {};\n const out: string[] = [];\n if (l.neededBy) out.push(`- Needed by ${l.neededBy.productName}: [#${l.neededBy.pr} ${cell(l.neededBy.title)}](${l.neededBy.url})`);\n if (l.figma?.url) out.push(`- Design: [Open in Figma](${l.figma.url})`);\n const key = l.figma?.fileKey;\n const nodes = (l.figma?.nodes ?? []).filter((n) => n && typeof n.nodeId === 'string');\n for (const n of nodes) {\n const url = n.url ?? (key ? figmaNodeUrl(key, n.nodeId) : undefined);\n const what = `${n.state === 'before' ? 'Before' : n.state === 'after' ? 'After' : 'Node'}${n.name ? ` (${cell(n.name)})` : ''}`;\n out.push(`- ${what}: ${url ? `[node ${n.nodeId}](${url})` : `node ${n.nodeId}`}`);\n }\n if (key && (nodes.length || l.figma?.nodeId)) {\n const ids = nodes.length ? nodes.map((n) => n.nodeId) : [l.figma!.nodeId!];\n out.push(\n `- Claude Code reads this design straight from Figma: the Figma MCP server (\\`get_design_context\\` with file key \\`${key}\\` and node ${ids.map((i) => `\\`${i}\\``).join(', ')}) or the REST API (\\`GET https://api.figma.com/v1/files/${key}/nodes?ids=${ids.map(encodeURIComponent).join(',')}\\`). No image hosting is needed.`,\n );\n }\n if (l.exploration) out.push(`- Exploration: \\`${l.exploration}\\``);\n if (l.supersedes) out.push(`- Replaces suggestion #${l.supersedes}`);\n for (const v of p.previews ?? []) out.push(`- ${cell(v.label)}: ${v.url}`);\n return out.length ? ['## Previews and links', '', ...out, ''] : [];\n}\n\nfunction humanPart(p: SuggestionPayloadV1, details: string | undefined, max: number, repo: string | undefined): string {\n return [\n `## Suggested change: ${safeText(p.title.trim())}`,\n '',\n safeText(p.summary.trim()),\n '',\n ...changesSection(p, max),\n ...(details?.trim() ? [safeText(details.trim()), ''] : []),\n ...checksSection(p, max),\n ...linksSection(p),\n '## How to apply',\n '',\n '- CLI: `bridge apply <this issue number>` (add `--dry-run` to check it first, `--patch` for a patch file)',\n '- Claude Code with the Bridge MCP server: ask \"Apply Bridge suggestion #<this issue number>\" (tool `bridge_apply_suggestion`).',\n ` One-time install: \\`${bridgeMcpInstallCommand(repo)}\\``,\n '',\n 'The pull request that applies it must say `Closes #<this issue number>`, so this suggestion closes when it merges.',\n '',\n `<sub>Suggested from ${sourceLabel(p.source)}${p.suggestedBy ? ` by @${p.suggestedBy.replace(/^@/, '')}` : ''} with Bridge.</sub>`,\n ].join('\\n');\n}\n\n/** The readable part within the budget: fewer table rows first, then the text cut with a note. */\nfunction fitHuman(p: SuggestionPayloadV1, details: string | undefined, repo: string | undefined): string {\n for (const max of [50, 20, 8, 3]) {\n const h = humanPart(p, details, max, repo);\n if (h.length <= SUGGESTION_LIMITS.human) return h;\n }\n const h = humanPart(p, undefined, 3, repo);\n if (h.length <= SUGGESTION_LIMITS.human) return h;\n const note = '\\n\\n_The description is cut here: the full change is in the machine-readable block below._';\n return h.slice(0, SUGGESTION_LIMITS.human - note.length) + note;\n}\n\nconst pretty = (v: unknown) => JSON.stringify(sortKeys(v), null, 2);\n/** Indented for people when it fits the body budget, else the compact canonical form. */\nconst fit = (v: unknown) => {\n const p = pretty(v);\n return p.length <= SUGGESTION_LIMITS.inline ? p : canonicalJson(v);\n};\nconst fenced = (json: string) => ['```json', json, '```'].join('\\n');\n\nfunction payloadBlock(json: string, sha: string, parts: number): string {\n return [\n '<details><summary>Machine-readable change (Bridge suggestion v1)</summary>',\n '',\n `<!-- ${MARK}:v1 sha256=${sha}${parts ? ` parts=${parts}` : ''} -->`,\n fenced(json),\n '',\n '</details>',\n ].join('\\n');\n}\n\nfunction partComment(i: number, n: number, json: string): string {\n return [\n `<details><summary>Machine-readable change, part ${i} of ${n} (Bridge suggestion v1)</summary>`,\n '',\n `<!-- ${MARK}:v1 part ${i}/${n} sha256=${sha256Hex(json)} -->`,\n fenced(json),\n '',\n '</details>',\n ].join('\\n');\n}\n\n/** Where a slice of `s` starting at `from` stops fitting in `budget` characters once JSON-escaped (never splits a surrogate pair). */\nfunction escapedEnd(s: string, from: number, budget: number): number {\n let used = 0;\n let i = from;\n while (i < s.length) {\n const c = s.charCodeAt(i);\n let w = 1;\n let len = 1;\n if (c === 0x22 || c === 0x5c || c === 0x08 || c === 0x0c || c === 0x0a || c === 0x0d || c === 0x09) len = 2;\n else if (c < 0x20) len = 6;\n else if (c >= 0xd800 && c <= 0xdbff) {\n const d = s.charCodeAt(i + 1);\n if (d >= 0xdc00 && d <= 0xdfff) {\n w = 2;\n len = 2;\n } else len = 6;\n } else if (c >= 0xdc00 && c <= 0xdfff) len = 6;\n if (used + len > budget) break;\n used += len;\n i += w;\n }\n return i;\n}\n\ninterface PartChunk {\n i: number;\n path: string;\n text: string;\n}\n\n/** The suggestion as a GitHub issue: readable Markdown, labels, the payload block, and continuation comments when large. */\nexport function composeSuggestionIssue(payload: SuggestionPayloadV1, opts: ComposeSuggestionOptions = {}): SuggestionIssue {\n const problems = suggestionShapeProblems(payload);\n if (problems.length) throw new SuggestionError('invalid', problems.join(' '));\n if (payload.checks.blocked) throw new SuggestionError('invalid', `This change cannot be suggested: ${payload.checks.blocked}`);\n const full = shaForm(payload);\n const sha = suggestionPayloadSha(full);\n const human = fitHuman(full, opts.details, opts.repo);\n const base = { title: suggestionIssueTitle(full), labels: suggestionLabels(full, { state: opts.state, labels: opts.labels }), assignees: opts.assignees ?? [], sha };\n\n const inline = fit(full);\n if (inline.length <= SUGGESTION_LIMITS.inline) {\n return { ...base, body: `${human}\\n\\n${payloadBlock(inline, sha, 0)}\\n`, parts: [] };\n }\n\n // Too large inline: file contents move to continuation comments, split across them when one file is larger.\n const moved = (full.files ?? []).map((f, i) => ({ f, i })).filter(({ f }) => typeof f.content === 'string' && f.content.length > 0);\n const parts: PartChunk[][] = [];\n const firstPart = new Map<number, number>();\n const partJson = (chunks: PartChunk[], i: number, n: number) => pretty({ schema: PART_SCHEMA, part: i, of: n, files: chunks });\n const emptyOverhead = partJson([], 9, 9).length;\n let cur: PartChunk[] = [];\n let room = SUGGESTION_LIMITS.part - emptyOverhead - 64;\n for (const { f, i } of moved) {\n const text = f.content as string;\n let at = 0;\n while (at < text.length) {\n const entryOverhead = partJson([{ i, path: f.path, text: '' }], 9, 9).length - emptyOverhead + 8;\n if (room - entryOverhead < 256) {\n parts.push(cur);\n cur = [];\n room = SUGGESTION_LIMITS.part - emptyOverhead - 64;\n }\n const end = escapedEnd(text, at, room - entryOverhead);\n if (end === at) throw new SuggestionError('too-large', SUGGESTION_TOO_LARGE);\n if (!firstPart.has(i)) firstPart.set(i, parts.length + 1);\n const chunk = { i, path: f.path, text: text.slice(at, end) };\n cur.push(chunk);\n room -= partJson([chunk], 9, 9).length - emptyOverhead + 8;\n at = end;\n }\n }\n if (cur.length) parts.push(cur);\n if (parts.length > SUGGESTION_LIMITS.maxParts) throw new SuggestionError('too-large', SUGGESTION_TOO_LARGE);\n const skeleton: SuggestionPayloadV1 = {\n ...full,\n files: (full.files ?? []).map((f, i) => {\n if (!firstPart.has(i)) return f;\n const { content: _content, ...rest } = f;\n return { ...rest, part: firstPart.get(i)! };\n }),\n };\n const skeletonJson = fit(skeleton);\n if (skeletonJson.length > SUGGESTION_LIMITS.inline) throw new SuggestionError('too-large', SUGGESTION_TOO_LARGE);\n const n = parts.length;\n const partBodies = parts.map((chunks, k) => {\n const json = partJson(chunks, k + 1, n);\n if (json.length > SUGGESTION_LIMITS.part) throw new SuggestionError('too-large', SUGGESTION_TOO_LARGE);\n return partComment(k + 1, n, json);\n });\n const body = `${human}\\n\\n${payloadBlock(skeletonJson, sha, n)}\\n`;\n if (body.length > SUGGESTION_LIMITS.body || partBodies.some((b) => b.length > SUGGESTION_LIMITS.body)) throw new SuggestionError('too-large', SUGGESTION_TOO_LARGE);\n return { ...base, body, parts: partBodies };\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Parse\n\nexport type SuggestionParseFailure = 'no-block' | 'invalid' | 'unsupported-version' | 'missing-part';\n\nexport type ParsedSuggestion =\n | {\n ok: true;\n payload: SuggestionPayloadV1;\n /** sha256 of the payload as read now (what approvals bind to). */\n sha: string;\n /** The sha the marker recorded when Bridge wrote it. */\n markedSha: string;\n /** The payload or a part no longer matches what Bridge wrote: someone edited it by hand. */\n edited: boolean;\n /** Continuation comments read. */\n parts: number;\n }\n | { ok: false; reason: SuggestionParseFailure; message: string };\n\nexport interface SuggestionCommentInput {\n body: string;\n author?: string | undefined;\n}\n\n/** Whether a body carries a suggestion block (any version). */\nexport function hasSuggestionBlock(body: string | null | undefined): boolean {\n return new RegExp(`^<!-- ${MARK}:v\\\\d+ sha256=`, 'm').test(body ?? '');\n}\n\n/** The first ```json fenced block after `from` in `text`. */\nfunction fencedAfter(text: string, from: number): string | undefined {\n const m = /```json\\r?\\n([\\s\\S]*?)\\r?\\n```/.exec(text.slice(from));\n return m?.[1];\n}\n\nconst fail = (reason: SuggestionParseFailure, message: string): ParsedSuggestion => ({ ok: false, reason, message });\n\n/**\n * The suggestion in an issue body (plus its continuation comments when it has parts). Checks the schema, reassembles\n * the parts (only comments by the issue author count when `author` is given), recomputes the sha and compares it with\n * the marker: a mismatch sets `edited` (shown, applied only when the developer accepts it).\n */\nexport function parseSuggestionIssue(body: string | null | undefined, opts: { comments?: SuggestionCommentInput[] | undefined; author?: string | undefined } = {}): ParsedSuggestion {\n const text = body ?? '';\n // On its own line: a marker quoted inside the JSON (a string, never at a line start) or in the text is not one.\n const markers = [...text.matchAll(new RegExp(`^<!-- ${MARK}:v(\\\\d+) sha256=([0-9a-f]{64})(?: parts=(\\\\d+))? -->$`, 'gm'))];\n const marker = markers[markers.length - 1];\n if (!marker) return fail('no-block', 'This issue has no Bridge suggestion block.');\n if (marker[1] !== '1') return fail('unsupported-version', `This suggestion uses version ${marker[1]} of the format. Update Bridge to read it.`);\n const json = fencedAfter(text, marker.index! + marker[0].length);\n if (json === undefined) return fail('invalid', 'The suggestion block has no JSON. Someone may have edited it by hand: ask the author to send it again.');\n let raw: unknown;\n try {\n raw = JSON.parse(json);\n } catch {\n return fail('invalid', 'The suggestion JSON does not parse. Someone may have edited it by hand: ask the author to send it again.');\n }\n const schema = (raw as { schema?: unknown } | null)?.schema;\n if (typeof schema === 'string' && schema !== SUGGESTION_SCHEMA) {\n const v = /^bridge\\.suggestion\\/(\\d+)$/.exec(schema);\n return v ? fail('unsupported-version', `This suggestion uses ${schema}. Update Bridge to read it.`) : fail('invalid', `\"${schema}\" is not a Bridge suggestion schema.`);\n }\n const problems = suggestionShapeProblems(raw);\n if (problems.length) return fail('invalid', `The suggestion block is not valid: ${problems.join(' ')}`);\n const payload = raw as SuggestionPayloadV1;\n const markedSha = marker[2]!;\n const expected = marker[3] ? Number(marker[3]) : 0;\n let edited = false;\n\n if (expected > 0 || payload.files?.some((f) => f.part !== undefined)) {\n const want = Math.max(expected, ...(payload.files ?? []).map((f) => f.part ?? 0));\n const found = new Map<number, PartChunk[]>();\n const author = opts.author?.toLowerCase();\n for (const c of opts.comments ?? []) {\n if (author && c.author && c.author.toLowerCase() !== author) continue;\n const m = new RegExp(`^<!-- ${MARK}:v1 part (\\\\d+)/(\\\\d+) sha256=([0-9a-f]{64}) -->$`, 'm').exec(c.body);\n if (!m) continue;\n const i = Number(m[1]);\n if (found.has(i)) continue;\n const pj = fencedAfter(c.body, m.index + m[0].length);\n if (pj === undefined) continue;\n if (sha256Hex(pj) !== m[3]) edited = true;\n try {\n const part = JSON.parse(pj) as { schema?: string; files?: PartChunk[] };\n if (part.schema !== PART_SCHEMA || !Array.isArray(part.files)) continue;\n found.set(i, part.files.filter((x) => x && typeof x.i === 'number' && typeof x.text === 'string'));\n } catch {\n continue;\n }\n }\n for (let i = 1; i <= want; i++) {\n if (!found.has(i)) return fail('missing-part', `This suggestion is incomplete: part ${i} of ${want} is missing. It is still being written, or a comment was deleted: ask the author to send it again.`);\n }\n const files = (payload.files ?? []).map((f, idx) => {\n if (f.part === undefined) return f;\n let content = '';\n for (let i = 1; i <= want; i++) for (const ch of found.get(i)!) if (ch.i === idx && ch.path === f.path) content += ch.text;\n const { part: _part, ...rest } = f;\n return { ...rest, content };\n });\n payload.files = files;\n }\n const sha = suggestionPayloadSha(payload);\n return { ok: true, payload, sha, markedSha, edited: edited || sha !== markedSha, parts: expected };\n}\n\n/** Problems with a payload's shape, as sentences. Empty when it is a valid v1 payload. */\nexport function suggestionShapeProblems(raw: unknown): string[] {\n const out: string[] = [];\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return ['The payload must be a JSON object.'];\n const p = raw as Record<string, unknown>;\n if (p.schema !== SUGGESTION_SCHEMA) out.push(`\"schema\" must be \"${SUGGESTION_SCHEMA}\".`);\n if (!(SUGGESTION_KINDS as readonly unknown[]).includes(p.kind)) out.push(`\"kind\" must be one of ${SUGGESTION_KINDS.join(', ')}.`);\n if (typeof p.title !== 'string' || !p.title.trim()) out.push('\"title\" must be a sentence.');\n if (typeof p.summary !== 'string') out.push('\"summary\" must be text.');\n if (!['figma', 'studio', 'cli', 'mcp'].includes(p.source as string)) out.push('\"source\" must be figma, studio, cli or mcp.');\n if (typeof p.createdAt !== 'string') out.push('\"createdAt\" must be an ISO date.');\n const base = p.base as { ref?: unknown; sha?: unknown } | undefined;\n if (!base || typeof base.ref !== 'string' || typeof base.sha !== 'string' || !/^[0-9a-f]{7,64}$/.test(base.sha)) out.push('\"base\" must be { \"ref\", \"sha\" } with the commit the change was planned on.');\n const tier = p.tier as { tier?: unknown; bump?: unknown } | undefined;\n if (!tier || ![1, 2, 3].includes(tier.tier as number) || !['patch', 'minor', 'major'].includes(tier.bump as string)) out.push('\"tier\" must be { \"tier\": 1, 2 or 3, \"bump\": patch, minor or major }.');\n const checks = p.checks as Record<string, unknown> | undefined;\n if (!checks || typeof checks.newErrors !== 'number' || !Array.isArray(checks.contrast) || typeof checks.impact !== 'number' || !(checks.blocked === null || typeof checks.blocked === 'string'))\n out.push('\"checks\" must be { \"newErrors\", \"contrast\", \"blocked\", \"impact\" }.');\n const tokens = p.tokens as { edits?: unknown; changes?: unknown } | undefined;\n if (tokens !== undefined && (!tokens || !Array.isArray(tokens.edits) || !Array.isArray(tokens.changes))) out.push('\"tokens\" must be { \"edits\", \"changes\" }.');\n if (p.docs !== undefined && !(Array.isArray(p.docs) && p.docs.every((d) => d && typeof d.component === 'string' && typeof d.path === 'string'))) out.push('\"docs\" must be a list of { \"component\", \"path\", \"after\" }.');\n const spec = p.componentSpec as Record<string, unknown> | undefined;\n if (spec !== undefined && (!spec || typeof spec.component !== 'string' || typeof spec.specPath !== 'string' || typeof spec.brief !== 'string')) out.push('\"componentSpec\" must be { \"component\", \"specPath\", \"spec\", \"brief\" }.');\n const nodes = (p.links as { figma?: { nodes?: unknown } } | undefined)?.figma?.nodes;\n if (nodes !== undefined && !(Array.isArray(nodes) && nodes.every((n) => n && typeof n.nodeId === 'string'))) out.push('\"links.figma.nodes\" must be a list of { \"nodeId\", \"url\"?, \"name\"?, \"state\"? }.');\n if (p.files !== undefined) {\n if (!Array.isArray(p.files)) out.push('\"files\" must be a list.');\n else {\n const seen = new Set<string>();\n for (const f of p.files as Record<string, unknown>[]) {\n const ok =\n f &&\n typeof f.path === 'string' &&\n (f.beforeSha === null || typeof f.beforeSha === 'string') &&\n (f.afterSha === null || typeof f.afterSha === 'string') &&\n (f.content === undefined || f.content === null || typeof f.content === 'string') &&\n (f.part === undefined || (Number.isInteger(f.part) && (f.part as number) >= 1 && (f.part as number) <= SUGGESTION_LIMITS.maxParts));\n if (!ok) {\n out.push('Each of \"files\" must be { \"path\", \"beforeSha\", \"afterSha\", \"content\"? }.');\n break;\n }\n if (seen.has(f.path as string)) out.push(`\"${f.path}\" is listed twice in \"files\".`);\n seen.add(f.path as string);\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------------------------------------------\n// Path safety: issues are user-editable input, so every path is checked before anything reads or writes it.\n\n/** Problems with one repo-relative path, as sentences. Empty when it is a plain path inside the repo. */\nexport function unsafePathProblem(path: string): string | null {\n if (typeof path !== 'string' || !path.length) return 'A path is empty.';\n if (/[\\0-\\x1f\\x7f]/.test(path)) return `\"${path.replace(/[\\0-\\x1f\\x7f]/g, '?')}\" has control characters.`;\n if (path.includes('\\\\')) return `\"${path}\" uses backslashes: paths use forward slashes.`;\n if (path.startsWith('/') || /^[A-Za-z]:/.test(path) || path.startsWith('~')) return `\"${path}\" is absolute: paths are relative to the repository root.`;\n const segs = path.split('/');\n if (segs.some((s) => s === '' || s === '.' || s === '..')) return `\"${path}\" has an empty, \".\" or \"..\" part: paths stay inside the repository.`;\n if (segs.some((s) => s.toLowerCase() === '.git')) return `\"${path}\" is inside .git.`;\n return null;\n}\n\nconst under = (path: string, root: string) => {\n const r = root.replace(/\\/+$/, '');\n return !r || r === '.' || path === r || path.startsWith(`${r}/`);\n};\n\n/** Whether a path is a governance guardrail (a trailing \"/\" in the list matches a directory). */\nexport function isGuardrailPath(path: string, guardrails: readonly string[]): boolean {\n return guardrails.some((g) => (g.endsWith('/') ? path.startsWith(g) || path === g.slice(0, -1) : path === g));\n}\n\n/** Where each kind may write, repo-relative. Undefined: anywhere (revert), still subject to guardrails. */\nexport function suggestionAllowedRoots(kind: SuggestionKind, config: Pick<BridgeConfig, 'tokens' | 'changesets' | 'components'>): string[] | undefined {\n const tokenRoot = tokensPath(config as BridgeConfig) || '.';\n const changesets = config.changesets?.dir ? [config.changesets.dir] : [];\n switch (kind) {\n case 'token-change':\n return [tokenRoot, ...changesets];\n case 'docs':\n return [...(config.components?.dir ? [config.components.dir] : []), ...changesets];\n case 'component-spec':\n return ['.bridge/figma'];\n case 'brand':\n return [tokenRoot, ...changesets, CONFIG_FILE];\n case 'config':\n return [CONFIG_FILE];\n case 'revert':\n return undefined;\n }\n}\n\n/**\n * Every unsafe path in a payload, as sentences that say what is wrong: not a plain repo-relative path, outside the\n * folders its kind may touch, or a governance guardrail (bridge.config.json is allowed for config and brand only).\n * Token edit files are checked under the tokens root. Symlinks are checked where files are read (apply).\n */\nexport function suggestionPathProblems(p: SuggestionPayloadV1, config: Pick<BridgeConfig, 'tokens' | 'changesets' | 'components' | 'governance'>): string[] {\n const out: string[] = [];\n const roots = suggestionAllowedRoots(p.kind, config);\n const guardrails = config.governance.guardrails;\n const check = (path: string) => {\n const bad = unsafePathProblem(path);\n if (bad) return out.push(bad);\n if (roots && !roots.some((r) => under(path, r))) return out.push(`\"${path}\" is outside what a ${p.kind} suggestion may change (${roots.join(', ')}).`);\n const configAllowed = path === CONFIG_FILE && (p.kind === 'config' || p.kind === 'brand');\n if (!configAllowed && isGuardrailPath(path, guardrails)) return out.push(`\"${path}\" is a guardrail file: change it in a pull request, not a suggestion.`);\n return 0;\n };\n for (const f of p.files ?? []) check(f.path);\n for (const d of p.docs ?? []) check(d.path);\n if (p.componentSpec) check(p.componentSpec.specPath);\n for (const e of p.tokens?.edits ?? []) {\n if (e.file === undefined) continue;\n const bad = unsafePathProblem(e.file);\n if (bad) out.push(bad);\n }\n return [...new Set(out)];\n}\n","// Suggestions on GitHub: create (issue plus continuation comments), list, read with status, review, link the pull\n// request that applies it, decline. The same calls for Studio (the viewer's own token), the MCP server and the CLI.\n// Needs Issues read and write; never writes code (contents) or pull requests. Pure rules live in suggestions.ts and\n// suggestion-review.ts; declining reuses the request flow (requests-github.ts).\n\nimport { GitHubClient, GitHubError, type IssueSummary, type PullRequestSummary } from './github-client';\nimport { closingIssueNumbers } from './requests';\nimport { declineRequestOnGitHub } from './requests-github';\nimport {\n composeSuggestionAppliedComment,\n composeSuggestionReviewComment,\n parseSuggestionAppliedComment,\n suggestionReviewState,\n summarizeSuggestionApprovals,\n type SuggestionAppliedRecord,\n type SuggestionApprovals,\n type SuggestionCommentLike,\n type SuggestionGovernance,\n type SuggestionReviewEvent,\n} from './suggestion-review';\nimport {\n composeSuggestionIssue,\n parseSuggestionIssue,\n SUGGESTION_LABEL,\n SUGGESTION_STATE_LABELS,\n suggestionKindFromLabels,\n suggestionStateFromLabels,\n suggestionStateLabel,\n suggestionStatus,\n type ComposeSuggestionOptions,\n type ParsedSuggestion,\n type SuggestionKind,\n type SuggestionPayloadV1,\n type SuggestionStatus,\n} from './suggestions';\nimport type { ApprovalRole } from './review-gate';\n\nexport interface CreatedSuggestion {\n number: number;\n url: string;\n /** sha256 of the payload: what approvals bind to. */\n sha: string;\n /** Continuation comments posted. */\n parts: number;\n /** Sentences about parts that did not go through (labels refused). The suggestion itself holds. */\n warnings: string[];\n}\n\n/**\n * Files a suggestion: the issue (title, body, labels), then its continuation comments in order when the payload is\n * too large for the body. A part that fails leaves the suggestion incomplete (parsers refuse it) and throws with the\n * issue number, so the caller can say so.\n */\nexport async function createSuggestionOnGitHub(gh: GitHubClient, payload: SuggestionPayloadV1, opts: ComposeSuggestionOptions = {}): Promise<CreatedSuggestion> {\n const issue = composeSuggestionIssue(payload, { repo: gh.fullName, ...opts });\n const created = await gh.createIssue({ title: issue.title, body: issue.body, labels: issue.labels, assignees: issue.assignees });\n for (const [i, part] of issue.parts.entries()) {\n try {\n await gh.createIssueComment(created.number, part);\n } catch (err) {\n const why = err instanceof Error ? err.message : String(err);\n throw new GitHubError(err instanceof GitHubError ? err.status : 500, `Suggestion #${created.number} is incomplete: part ${i + 1} of ${issue.parts.length} could not be posted (${why}). Send it again, then close #${created.number}.`);\n }\n }\n const warnings: string[] = [];\n const missing = issue.labels.filter((l) => !created.labels.includes(l));\n if (created.labels.length && missing.length) warnings.push(`GitHub did not keep these labels on #${created.number}: ${missing.join(', ')}.`);\n return { number: created.number, url: created.url, sha: issue.sha, parts: issue.parts.length, warnings };\n}\n\n/** Linked pull requests of an issue, from the bodies that close it (\"Closes #n\"). */\nexport function linkedPullsOf(n: number, pulls: readonly Pick<PullRequestSummary, 'number' | 'state' | 'body' | 'url'>[]): { number: number; url: string; state: 'open' | 'closed'; merged: boolean }[] {\n return pulls\n .filter((p) => closingIssueNumbers(p.body).includes(n))\n .map((p) => ({ number: p.number, url: p.url, state: p.state === 'open' ? 'open' : 'closed', merged: p.state === 'merged' }));\n}\n\nexport interface SuggestionListItem {\n number: number;\n title: string;\n url: string;\n author: string;\n createdAt: string;\n state: 'open' | 'closed';\n stateReason: string | null;\n labels: string[];\n kind: SuggestionKind | undefined;\n /** Tier from the `tier: N` label. */\n tier: 1 | 2 | 3 | undefined;\n linkedPrs: { number: number; url: string; state: 'open' | 'closed'; merged: boolean }[];\n /**\n * Status from the issue state, linked pull requests and the state label (a cache: getSuggestionOnGitHub reads the\n * review comments for the real one).\n */\n status: SuggestionStatus;\n}\n\n/**\n * Suggestions in the repository, newest first. Status comes from labels and linked pull requests (one call per list,\n * no comment reads); open getSuggestionOnGitHub for the counted approvals.\n */\nexport async function listSuggestionsOnGitHub(gh: GitHubClient, opts: { state?: 'open' | 'closed' | 'all' | undefined; perPage?: number | undefined; pulls?: PullRequestSummary[] | undefined } = {}): Promise<SuggestionListItem[]> {\n const issues = await gh.listIssues({ label: SUGGESTION_LABEL, state: opts.state ?? 'open', perPage: opts.perPage ?? 50 });\n const pulls = opts.pulls ?? (issues.length ? await gh.listPullRequests('all').catch(() => [] as PullRequestSummary[]) : []);\n return issues.map((i) => listItem(i, pulls));\n}\n\nfunction listItem(i: IssueSummary, pulls: readonly PullRequestSummary[]): SuggestionListItem {\n const linkedPrs = linkedPullsOf(i.number, pulls);\n const cached = suggestionStateFromLabels(i.labels);\n const t = i.labels.map((l) => /^tier: ([123])$/.exec(l)?.[1]).find(Boolean);\n return {\n number: i.number,\n title: i.title,\n url: i.url,\n author: i.author,\n createdAt: i.createdAt,\n state: i.state,\n stateReason: i.stateReason,\n labels: i.labels,\n kind: suggestionKindFromLabels(i.labels),\n tier: t ? (Number(t) as 1 | 2 | 3) : undefined,\n linkedPrs,\n status: suggestionStatus({ state: i.state, stateReason: i.stateReason, linkedPrs, applied: cached === 'applying', review: cached === 'applying' ? undefined : cached }),\n };\n}\n\nexport interface SuggestionDetail {\n issue: IssueSummary;\n parsed: ParsedSuggestion;\n comments: (SuggestionCommentLike & { id: number })[];\n /** Counted on the current payload sha. Undefined when the payload does not parse. */\n approvals: SuggestionApprovals | undefined;\n linkedPrs: { number: number; url: string; state: 'open' | 'closed'; merged: boolean }[];\n applied: SuggestionAppliedRecord[];\n status: SuggestionStatus;\n}\n\n/**\n * One suggestion with everything its status needs: the payload (parts reassembled from the author's comments), the\n * review comments counted against the owners of the config read from the default branch, linked pull requests and\n * applied markers. `outdated` comes from the caller's dry run (it needs the current files).\n */\nexport async function getSuggestionOnGitHub(gh: GitHubClient, n: number, gov: SuggestionGovernance, opts: { pulls?: PullRequestSummary[] | undefined; outdated?: boolean | undefined } = {}): Promise<SuggestionDetail> {\n const [issue, comments, pulls] = await Promise.all([gh.getIssue(n), gh.listIssueComments(n), opts.pulls ? Promise.resolve(opts.pulls) : gh.listPullRequests('all').catch(() => [] as PullRequestSummary[])]);\n const parsed = parseSuggestionIssue(issue.body, { comments, author: issue.author || undefined });\n const linkedPrs = linkedPullsOf(n, pulls);\n const applied = comments.flatMap((c) => parseSuggestionAppliedComment(c.body) ?? []);\n const approvals = parsed.ok ? summarizeSuggestionApprovals(comments, gov, { payloadSha: parsed.sha, author: issue.author }) : undefined;\n const status = suggestionStatus({\n state: issue.state,\n stateReason: issue.stateReason,\n linkedPrs,\n applied: parsed.ok && applied.some((a) => a.payloadSha === parsed.sha),\n outdated: opts.outdated,\n review: parsed.ok && approvals ? suggestionReviewState(parsed.payload.tier.tier, approvals) : undefined,\n });\n return { issue, parsed, comments, approvals, linkedPrs, applied, status };\n}\n\n/**\n * Keeps exactly one state label on the issue, the one the status calls for (none once closed or outdated). Best\n * effort: returns a warning sentence when the labels could not be changed.\n */\nexport async function syncSuggestionStateLabel(gh: GitHubClient, n: number, labels: readonly string[], status: SuggestionStatus): Promise<string | null> {\n const want = suggestionStateLabel(status);\n let ok = true;\n for (const l of Object.values(SUGGESTION_STATE_LABELS)) {\n if (l === want || !labels.includes(l)) continue;\n try {\n await gh.removeLabel(n, l);\n } catch {\n ok = false;\n }\n }\n if (want && !labels.includes(want)) ok = (await gh.addLabels(n, [want])) && ok;\n return ok ? null : `The state label on #${n} could not be updated; the status shown in Bridge is still right.`;\n}\n\nexport interface SuggestionReviewResult {\n commentUrl: string;\n payloadSha: string;\n status: SuggestionStatus;\n /** Whether this review counts (the reviewer is an owner, or a collaborator when no owner is set). */\n counts: boolean;\n warnings: string[];\n}\n\n/**\n * Approves, requests changes on or comments on a suggestion as the token's user. `payloadSha` is the version the\n * reviewer saw: when the payload changed since, nothing is posted and the error says to reload. Then the state label\n * is re-synced from the recomputed status.\n */\nexport async function reviewSuggestionOnGitHub(\n gh: GitHubClient,\n n: number,\n input: { event: SuggestionReviewEvent; role?: ApprovalRole | undefined; message?: string | undefined; payloadSha?: string | undefined; by?: string | undefined; at?: Date | undefined },\n gov: SuggestionGovernance,\n): Promise<SuggestionReviewResult> {\n if (input.event === 'request-changes' && !input.message?.trim()) throw new GitHubError(422, 'Say what should change, in a sentence or two: the author reads it.');\n const before = await getSuggestionOnGitHub(gh, n, gov);\n if (!before.parsed.ok) throw new GitHubError(422, `#${n} cannot be reviewed: ${before.parsed.message}`);\n if (before.issue.state === 'closed') throw new GitHubError(422, `#${n} is closed. Reopen it on GitHub to review it again.`);\n const sha = before.parsed.sha;\n if (input.payloadSha && input.payloadSha !== sha) throw new GitHubError(409, `#${n} changed since you opened it. Reload it and review the new version.`);\n const by = input.by ?? (await gh.getViewer().catch(() => ({ login: '' }))).login;\n const body = composeSuggestionReviewComment({ event: input.event, role: input.role, payloadSha: sha, at: (input.at ?? new Date()).toISOString(), by: by || undefined, message: input.message });\n const posted = await gh.createIssueComment(n, body);\n // Read back: GitHub says who posted the comment and with which association, which is what counts.\n const after = await getSuggestionOnGitHub(gh, n, gov);\n const status = after.status;\n const who = (after.comments.find((c) => c.id === posted.id)?.author ?? by).toLowerCase();\n const counts = input.event === 'comment' || [...(after.approvals?.approvers ?? []), ...(after.approvals?.changesRequested ?? [])].some((l) => l.toLowerCase() === who);\n const warnings: string[] = [];\n if (!counts) warnings.push('Your review is posted but does not count: only the owners listed in bridge.config.json approve suggestions.');\n if (before.parsed.edited) warnings.push(`#${n} was edited by hand after Bridge wrote it: check the machine-readable block before applying it.`);\n const labelWarning = await syncSuggestionStateLabel(gh, n, before.issue.labels, status);\n if (labelWarning) warnings.push(labelWarning);\n return { commentUrl: posted.url, payloadSha: sha, status, counts, warnings };\n}\n\n/**\n * Records that a suggestion is being applied (the applied marker comment) and sets the `suggestion: applying` label.\n * Called after a developer pushed the branch or opened the pull request that says \"Closes #n\".\n */\nexport async function linkSuggestionPrOnGitHub(\n gh: GitHubClient,\n n: number,\n link: { pr?: number | undefined; branch?: string | undefined; commit?: string | undefined; by?: string | undefined; payloadSha: string; forced?: boolean | undefined; at?: Date | undefined },\n): Promise<{ warnings: string[] }> {\n if (!link.pr && !link.branch && !link.commit) throw new GitHubError(422, 'Say where it is applied: a pull request number, a branch or a commit.');\n const issue = await gh.getIssue(n);\n await gh.addComment(n, composeSuggestionAppliedComment({ by: link.by, branch: link.branch, commit: link.commit, pr: link.pr, payloadSha: link.payloadSha, forced: link.forced, at: (link.at ?? new Date()).toISOString() }));\n const warning = await syncSuggestionStateLabel(gh, n, issue.labels, 'applying');\n return { warnings: warning ? [warning] : [] };\n}\n\n/** Declines a suggestion like a request (reason comment, closed as not planned), then clears its state label. */\nexport async function declineSuggestionOnGitHub(gh: GitHubClient, n: number, reason: string, by?: string | null): Promise<{ warnings: string[] }> {\n const issue = await gh.getIssue(n);\n await declineRequestOnGitHub(gh, n, reason, by);\n const warning = await syncSuggestionStateLabel(gh, n, issue.labels, 'declined');\n return { warnings: warning ? [warning] : [] };\n}\n","// Component docs (docs.json) proposed as a reviewable change, shared by the Library edit mode in Bridge Studio, the MCP\n// server and the CLI: what blocks a docs.json (validateDocs), the editor's cleaning, and one pull request per set of\n// docs edits (Tier 1 under the shared classifier, a patch changeset), at most one open per component (a new send\n// continues the open one), and an author line that says who wrote the text. In suggest mode the same edits are filed\n// as a suggestion (an issue with the cleaned docs, applied by a developer) instead. The GitHub writes use the core client.\nimport type { ChangesMode } from './config';\nimport { formatDocsJson, missingProse, patchDocsJson, type ComponentDocsJson } from './docs-draft';\nimport type { GitHubClient, PullRequestSummary } from './github-client';\nimport type { RequestSource } from './requests';\nimport { classifyRisk, type RiskResult } from './risk';\nimport { branchWithJiraKey, titleWithJiraKey } from './jira';\nimport { createSuggestionOnGitHub } from './suggestions-github';\nimport { gitBlobSha, SUGGESTION_SCHEMA, type SuggestionPayloadV1 } from './suggestions';\n\n/** One component's docs.json, before (null: a new file) and after, at its repo path. */\nexport interface DocsFileEdit {\n path: string;\n component: string;\n slug: string;\n before: string | null;\n after: string;\n}\n\n/** Who wrote the docs, for the pull request body and its source label. */\nexport interface DocsOrigin {\n /** \"in the Bridge docs editor\". */\n where: string;\n footer: string;\n label: string;\n}\n\nexport const DOCS_EDITOR_ORIGIN: DocsOrigin = {\n where: 'in the Bridge docs editor',\n footer: 'Written by a person in the Bridge docs editor. No AI involved in this text.',\n label: 'source: bridge-web',\n};\n\nexport const DOCS_MCP_ORIGIN: DocsOrigin = {\n where: 'with Claude through the Bridge MCP server',\n footer: 'Proposed with the Bridge MCP server on behalf of a person. Docs Claude drafted say \"draftedBy\": \"claude\" until a reviewer accepts them.',\n label: 'source: mcp',\n};\n\nexport interface DocsIssue {\n field: string;\n message: string;\n}\n\nconst EM_DASH = /\\u2014/;\n\n/** What blocks proposing a docs.json: a summary, no empty list items, no em dash (Bridge voice). */\nexport function validateDocs(d: ComponentDocsJson): DocsIssue[] {\n const out: DocsIssue[] = [];\n if (!d.summary.trim()) out.push({ field: 'summary', message: 'Add a summary: one or two sentences on what it is for.' });\n const lists = ['whenToUse', 'whenNotToUse', 'accessibility', 'contentGuidelines'] as const;\n for (const k of lists) (d[k] ?? []).forEach((x, i) => !x.trim() && out.push({ field: `${k}.${i}`, message: 'Fill or remove the empty item.' }));\n for (const k of ['dos', 'donts'] as const) d[k].forEach((g, i) => (!g.title.trim() || !g.text.trim()) && out.push({ field: `${k}.${i}`, message: 'Give every item a title and a sentence.' }));\n const prose = JSON.stringify([d.summary, d.whenToUse, d.whenNotToUse, d.dos, d.donts, d.accessibility, d.contentGuidelines ?? [], d.anatomy ?? {}]);\n if (EM_DASH.test(prose)) out.push({ field: 'voice', message: 'Replace the em dashes with a colon, a comma or two sentences.' });\n return out;\n}\n\n/** Drops empty list items and trims text, the way the editor saves. */\nexport function cleanDocs(d: ComponentDocsJson): ComponentDocsJson {\n const list = (xs: string[] | undefined) => (xs ?? []).map((x) => x.trim()).filter(Boolean);\n const guide = (xs: ComponentDocsJson['dos']) => xs.map((g) => ({ ...g, title: g.title.trim(), text: g.text.trim() })).filter((g) => g.title || g.text);\n return {\n ...d,\n summary: d.summary.trim(),\n whenToUse: list(d.whenToUse),\n whenNotToUse: list(d.whenNotToUse),\n dos: guide(d.dos),\n donts: guide(d.donts),\n accessibility: list(d.accessibility),\n contentGuidelines: list(d.contentGuidelines),\n anatomy: Object.fromEntries(Object.entries(d.anatomy ?? {}).filter(([k, v]) => k.trim() && v.trim())),\n };\n}\n\n/** docs.json in the editor's canonical form: cleaned, in the Button.docs.json key order. Used to compare. */\nexport const docsText = (d: ComponentDocsJson) => formatDocsJson(cleanDocs(d));\n\n/** docs.json text the editor writes: cleaned, as a minimal diff of the file on main (or the branch) when there is one. */\nexport const docsFileText = (d: ComponentDocsJson, original: string | null) => patchDocsJson(original, cleanDocs(d));\n\nexport interface DocsProposal {\n branch: string;\n title: string;\n body: string;\n files: { path: string; content: string }[];\n risk: RiskResult;\n bump: 'patch';\n labels: string[];\n}\n\nconst slugDate = (d: Date) => d.toISOString().slice(0, 10).replace(/-/g, '');\n\n/** The branch slug of a component's docs: \"visually-hidden\" for VisuallyHidden or visually-hidden, at most 40 characters. */\nexport const docsSlug = (nameOrSlug: string) =>\n nameOrSlug\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-')\n .slice(0, 40);\n\n/* ------------------------------------------------------------------------------------------------------------------ */\n/* Who wrote the text */\n\n/** Section names (as the editor shows them) by who wrote their text in this send. */\nexport interface DocsAuthorship {\n /** Drafted by Claude, kept as Claude wrote it after review. */\n claude: string[];\n /** Drafted by Claude, then edited by the person. */\n edited: string[];\n /** Written by the person, no Claude draft involved. */\n written: string[];\n /** Drafted by Claude, not reviewed yet (they go out marked for review). */\n pending: string[];\n}\n\nconst listOf = (xs: string[]) => (xs.length < 2 ? (xs[0] ?? '') : `${xs.slice(0, -1).join(', ')} and ${xs[xs.length - 1]}`);\n\n/**\n * The author line of a docs proposal: \"by a person, no AI\" only when no Claude draft is in the text; \"drafted by\n * Claude AI, reviewed and sent by @ana\" when the person kept Claude's text as is; \"drafted by Claude AI, edited by\n * @ana\" with the edited sections when they changed parts of it.\n */\nexport function docsAuthorLine(a: DocsAuthorship, who: string | null | undefined, where = 'the Bridge docs editor'): string {\n const w = who?.trim() ? `@${who.trim().replace(/^@/, '')}` : 'a person';\n if (!a.claude.length && !a.edited.length && !a.pending.length) return `Written by ${w} in ${where}. No AI involved in this text.`;\n const head = a.edited.length\n ? `Drafted by Claude AI, edited by ${w} in ${where}.`\n : a.claude.length\n ? `Drafted by Claude AI, reviewed and sent by ${w} in ${where}.`\n : `Drafted by Claude AI, sent by ${w} in ${where} before review.`;\n const mixed = [a.edited, a.written, a.pending].some((x) => x.length);\n return [\n head,\n a.edited.length ? `Edited by ${w}: ${listOf(a.edited)}.` : '',\n a.claude.length && mixed ? `As Claude drafted them: ${listOf(a.claude)}.` : '',\n a.written.length ? `Written by ${w}: ${listOf(a.written)}.` : '',\n a.pending.length && (a.claude.length || a.edited.length || a.written.length) ? `Not reviewed yet: ${listOf(a.pending)}.` : '',\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/** Without an author line from the editor: the docs' own record (\"draftedBy\": \"claude\") decides, never \"no AI\" over it. */\nexport function defaultDocsFooter(edits: Pick<DocsFileEdit, 'after'>[], origin: DocsOrigin): string {\n if (origin.label !== DOCS_EDITOR_ORIGIN.label) return origin.footer;\n const claude = edits.some((e) => {\n try {\n return (JSON.parse(e.after) as ComponentDocsJson).draftedBy === 'claude';\n } catch {\n return false;\n }\n });\n return claude ? `Drafted by Claude AI (the docs say \"draftedBy\": \"claude\"), sent by a person ${origin.where}.` : origin.footer;\n}\n\n/** The body with its author line (the text after the last \"---\" line) replaced, or added when it has none. */\nexport function withAuthorLine(body: string, line: string): string {\n const i = body.lastIndexOf('\\n---\\n');\n return i < 0 ? `${body.trimEnd()}\\n\\n---\\n${line}` : `${body.slice(0, i + 5)}${line}`;\n}\n\n/* ------------------------------------------------------------------------------------------------------------------ */\n/* One open proposal per component */\n\n/** The open docs proposal of a component: the one a new send continues instead of opening a second one. */\nexport interface OpenDocsProposal {\n number: number;\n url: string;\n branch: string;\n author: string;\n title: string;\n updatedAt: string;\n}\n\nconst escapeRe = (s: string) => s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/**\n * True when `branch` is a docs proposal branch of this component: docs/<slug>-<yyyymmdd>-<id>, with an optional Jira\n * key before the slug (docs/DS-42-button-...). \"button\" does not match docs/button-group-... branches. Older MCP\n * branches used the lowercased name (docs/visuallyhidden-...): they match too.\n */\nexport function isDocsProposalBranch(branch: string, component: { name: string; slug?: string | undefined }): boolean {\n const slugs = new Set([docsSlug(component.slug ?? component.name), docsSlug(component.name), docsSlug(component.name.toLowerCase())]);\n return [...slugs].some((s) => new RegExp(`^docs/(?:[A-Z][A-Z0-9]*-\\\\d+-)?${escapeRe(s)}-\\\\d{8}-[a-z0-9]+$`).test(branch));\n}\n\ntype PullLike = Pick<PullRequestSummary, 'number' | 'state' | 'headRef' | 'author' | 'title' | 'url' | 'updatedAt'> & { baseRef?: string | undefined };\n\n/** The most recently updated open docs proposal of the component (into `base` when given), or null. */\nexport function findOpenDocsProposal(pulls: PullLike[], component: { name: string; slug?: string | undefined }, base?: string): OpenDocsProposal | null {\n const hit = pulls\n .filter((p) => p.state === 'open' && isDocsProposalBranch(p.headRef, component) && (!base || !p.baseRef || p.baseRef === base))\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))[0];\n return hit ? { number: hit.number, url: hit.url, branch: hit.headRef, author: hit.author, title: hit.title, updatedAt: hit.updatedAt } : null;\n}\n\n/** Reads the open pull requests and returns the component's open docs proposal, or null. */\nexport async function findOpenDocsProposalOnGitHub(gh: GitHubClient, component: { name: string; slug?: string | undefined }, base?: string): Promise<OpenDocsProposal | null> {\n return findOpenDocsProposal(await gh.listPullRequests('open'), component, base);\n}\n\n/**\n * Adds a send to the open proposal: one commit with the docs.json on its branch (nothing when the text is the same),\n * and the author line of its description brought up to date. Returns the commit sha, or '' when nothing changed.\n */\nexport async function continueDocsProposalOnGitHub(\n gh: GitHubClient,\n open: Pick<OpenDocsProposal, 'number' | 'branch'>,\n edit: Pick<DocsFileEdit, 'path' | 'component' | 'after'>,\n opts: { authorLine?: string | undefined; message?: string | undefined } = {},\n): Promise<string> {\n const message = opts.message ?? `docs(${docsSlug(edit.component)}): edit usage guidance in the Bridge docs editor`;\n const cur = await gh.getFile(edit.path, open.branch);\n if (cur?.text === edit.after) return '';\n const sha = await gh.putFile({ path: edit.path, content: edit.after, branch: open.branch, message, sha: cur?.sha });\n if (opts.authorLine) {\n const line = opts.authorLine;\n await gh\n .getPullRequest(open.number)\n .then((pr) => gh.updatePullRequest(open.number, { body: withAuthorLine(pr.body, line) }))\n .catch(() => undefined);\n }\n return sha;\n}\n\n/** One pull request for the docs edits of a draft: branch, title, body, files with a patch changeset, the tier. */\nexport function docsProposal(\n edits: DocsFileEdit[],\n opts: { title?: string | undefined; notes?: string | undefined; date: Date; packageName?: string | undefined; changesetDir?: string | undefined; origin?: DocsOrigin | undefined; authorLine?: string | undefined },\n): DocsProposal {\n const origin = opts.origin ?? DOCS_EDITOR_ORIGIN;\n if (!edits.length) throw new Error('No docs edits in the draft.');\n const names = edits.map((e) => e.component);\n const list = names.length === 1 ? names[0]! : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;\n const title = opts.title?.trim() || `docs(${names.length === 1 ? edits[0]!.slug : 'components'}): usage guidance for ${list}`;\n const slug = docsSlug(names.length === 1 ? edits[0]!.slug : `${edits[0]!.slug}-and-${names.length - 1}-more`);\n const branch = `docs/${slug}-${slugDate(opts.date)}-${opts.date.getTime().toString(36).slice(-4)}`;\n const csPath = `${opts.changesetDir ?? '.changeset'}/docs-${slug}-${opts.date.getTime().toString(36)}.md`;\n const pkg = opts.packageName ?? '@bridge-ds/react';\n const changeset = `---\\n\"${pkg}\": patch\\n---\\n\\nUsage guidance for ${list}.\\n`;\n const files = [...edits.map((e) => ({ path: e.path, content: e.after })), { path: csPath, content: changeset }];\n const risk = classifyRisk({ files: files.map((f) => ({ path: f.path, status: 'modified' })) });\n const rows = edits.map((e) => {\n let state = 'edited';\n try {\n const d = JSON.parse(e.after) as ComponentDocsJson;\n const gaps = missingProse(d);\n state = gaps.length ? `still missing: ${gaps.join(', ')}` : 'every section filled';\n } catch {\n state = 'not valid JSON';\n }\n return `- \\`${e.path}\\` (${e.before === null ? 'new' : 'changed'}, ${state})`;\n });\n const body = [\n `## Docs change`,\n '',\n `Usage guidance for ${list}, written ${origin.where}.`,\n '',\n ...rows,\n '',\n `**Risk:** ${risk.label}. Docs only: the published components do not change. Changeset: patch.`,\n '',\n opts.notes?.trim() ? `## Notes\\n\\n${opts.notes.trim()}\\n` : '',\n '---',\n opts.authorLine?.trim() || defaultDocsFooter(edits, origin),\n ]\n .filter((x, i, a) => !(x === '' && a[i - 1] === ''))\n .join('\\n');\n return { branch, title, body, files, risk, bump: 'patch', labels: ['docs', origin.label, `tier-${risk.tier}`] };\n}\n\n\nexport interface ProposeDocsOptions {\n base: string;\n title?: string | undefined;\n notes?: string | undefined;\n jira?: string | null | undefined;\n date?: Date | undefined;\n origin?: DocsOrigin | undefined;\n extraLabels?: string[] | undefined;\n commitNote?: string | undefined;\n /** Who wrote the text (docsAuthorLine). Without it, the origin's footer, never \"no AI\" over a Claude draft. */\n authorLine?: string | undefined;\n /** Default true: continue the component's open proposal. False always opens a new one. Direct mode only. */\n continueOpen?: boolean | undefined;\n /**\n * \"direct\" (default here, so existing callers keep their behaviour): a branch and a pull request. \"suggest\": a\n * suggestion issue with the cleaned docs, no branch. Callers pass changesMode(config).\n */\n mode?: ChangesMode | undefined;\n /** Suggest mode: where it was sent from (default from the origin: Studio, or MCP) and who sent it. */\n source?: RequestSource | undefined;\n suggestedBy?: string | undefined;\n /** Suggest mode: commit sha of `base`, when the caller already read it. */\n baseSha?: string | undefined;\n}\n\nexport interface ProposedDocs {\n status: 'opened' | 'continued';\n number: number;\n url: string;\n branch: string;\n title: string;\n continued: boolean;\n unchanged: boolean;\n}\n\nexport interface SuggestedDocs {\n status: 'suggested';\n /** The suggestion issue. */\n number: number;\n url: string;\n title: string;\n /** sha256 of the payload: what approvals bind to. */\n sha: string;\n warnings: string[];\n}\n\n/** The source a docs origin stands for, as suggestions name it. */\nconst docsSource = (origin: DocsOrigin): RequestSource => (origin.label === DOCS_MCP_ORIGIN.label ? 'mcp' : 'studio');\n\n/**\n * The suggestion payload (bridge.suggestion/1, kind docs) of a set of docs edits: the cleaned docs object of each\n * component (re-written at apply time as a minimal diff of the current file) and the patch changeset. Pure.\n */\nexport function docsSuggestionPayload(\n edits: DocsFileEdit[],\n opts: {\n base: { ref: string; sha: string };\n title?: string | undefined;\n notes?: string | undefined;\n date?: Date | undefined;\n origin?: DocsOrigin | undefined;\n source?: RequestSource | undefined;\n suggestedBy?: string | undefined;\n packageName?: string | undefined;\n changesetDir?: string | undefined;\n },\n): SuggestionPayloadV1 {\n const origin = opts.origin ?? DOCS_EDITOR_ORIGIN;\n const date = opts.date ?? new Date();\n const p = docsProposal(edits, { title: opts.title, date, origin, packageName: opts.packageName, changesetDir: opts.changesetDir });\n const names = edits.map((e) => e.component);\n const list = names.length === 1 ? names[0]! : `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;\n const docs = edits.map((e) => {\n let after: ComponentDocsJson;\n try {\n after = JSON.parse(e.after) as ComponentDocsJson;\n } catch {\n throw new Error(`${e.path} is not valid JSON: fix it before sending.`);\n }\n return { component: e.component, path: e.path, after: cleanDocs(after) };\n });\n const docPaths = new Set(edits.map((e) => e.path));\n const files = p.files.filter((f) => !docPaths.has(f.path)).map((f) => ({ path: f.path, beforeSha: null, afterSha: gitBlobSha(f.content), content: f.content }));\n const by = opts.suggestedBy?.replace(/^@/, '');\n return {\n schema: SUGGESTION_SCHEMA,\n kind: 'docs',\n title: opts.title?.trim() || (names.length === 1 ? 'Usage guidance' : `Usage guidance for ${list}`),\n summary: [`Usage guidance for ${list}, written ${origin.where}.`, opts.notes?.trim() ?? ''].filter(Boolean).join('\\n\\n'),\n source: opts.source ?? docsSource(origin),\n ...(by ? { suggestedBy: by } : {}),\n createdAt: date.toISOString(),\n base: opts.base,\n tier: { tier: p.risk.tier, bump: 'patch' },\n docs,\n files,\n checks: { newErrors: 0, contrast: [], blocked: null, impact: 0 },\n };\n}\n\n/**\n * Files docs edits as a suggestion (suggest mode): one issue with the cleaned docs of each component and the patch\n * changeset, the author line in its description, labelled docs. Needs Issues write only.\n */\nasync function suggestDocsOnGitHub(gh: GitHubClient, edits: DocsFileEdit[], opts: ProposeDocsOptions): Promise<SuggestedDocs> {\n if (!edits.length) throw new Error('No docs edits in the draft.');\n const sha = opts.baseSha ?? (await gh.getBranchSha(opts.base));\n if (!sha) throw new Error(`Branch ${opts.base} not found.`);\n const origin = opts.origin ?? DOCS_EDITOR_ORIGIN;\n const payload = docsSuggestionPayload(edits, { base: { ref: opts.base, sha }, title: opts.title, notes: opts.notes, date: opts.date, origin, source: opts.source, suggestedBy: opts.suggestedBy });\n const p = docsProposal(edits, { date: opts.date ?? new Date(), origin });\n const rows = p.body.split('\\n').filter((l) => l.startsWith('- `'));\n const details = [...rows, '', opts.authorLine?.trim() || defaultDocsFooter(edits, origin)].join('\\n');\n const created = await createSuggestionOnGitHub(gh, payload, { labels: ['docs', ...(opts.extraLabels ?? [])], details });\n return { status: 'suggested', number: created.number, url: created.url, title: payload.title, sha: created.sha, warnings: created.warnings };\n}\n\n/**\n * Opens one pull request with the docs edits from the default branch, the Jira key first in the title and the branch\n * name (Jira's GitHub integration links them). Returns its number, link and branch. Labels are best effort.\n * One open proposal per component: when the component already has one, the edit goes there as a new commit\n * (`continued`; `unchanged` when it already says this) instead of a second pull request.\n * In suggest mode (`mode: 'suggest'`) it files a suggestion instead: no branch, no pull request (`status: 'suggested'`).\n */\nexport function proposeDocsOnGitHub(gh: GitHubClient, edits: DocsFileEdit[], opts: ProposeDocsOptions & { mode?: 'direct' | undefined }): Promise<ProposedDocs>;\nexport function proposeDocsOnGitHub(gh: GitHubClient, edits: DocsFileEdit[], opts: ProposeDocsOptions): Promise<ProposedDocs | SuggestedDocs>;\nexport async function proposeDocsOnGitHub(gh: GitHubClient, edits: DocsFileEdit[], opts: ProposeDocsOptions): Promise<ProposedDocs | SuggestedDocs> {\n if (opts.mode === 'suggest') return suggestDocsOnGitHub(gh, edits, opts);\n if (opts.continueOpen !== false && edits.length === 1) {\n const e = edits[0]!;\n // A failed read does not block the send: it opens a new proposal, as before.\n const open = await findOpenDocsProposalOnGitHub(gh, { name: e.component, slug: e.slug }, opts.base).catch(() => null);\n if (open) {\n const sha = await continueDocsProposalOnGitHub(gh, open, e, { authorLine: opts.authorLine?.trim() || defaultDocsFooter(edits, opts.origin ?? DOCS_EDITOR_ORIGIN) });\n return { status: 'continued', number: open.number, url: open.url, branch: open.branch, title: open.title, continued: true, unchanged: !sha };\n }\n }\n const p = docsProposal(edits, { title: opts.title, notes: opts.notes, date: opts.date ?? new Date(), origin: opts.origin, authorLine: opts.authorLine });\n const prTitle = titleWithJiraKey(p.title, opts.jira ?? null);\n const branch = branchWithJiraKey(p.branch, opts.jira ?? null);\n const mainSha = await gh.getBranchSha(opts.base);\n if (!mainSha) throw new Error(`Branch ${opts.base} not found.`);\n const tree = await gh.createTree(await gh.getCommitTree(mainSha), p.files.map((f) => ({ path: f.path, content: f.content })));\n const commit = await gh.createCommit(`${prTitle}\\n\\n${opts.commitNote ?? 'Proposed with the Bridge docs editor.'}`, tree, [mainSha]);\n await gh.createBranch(branch, commit);\n const pr = await gh.createPullRequest({ title: prTitle, head: branch, base: opts.base, body: p.body, draft: false });\n await gh.addLabels(pr.number, [...p.labels, ...(opts.extraLabels ?? [])]).catch(() => false);\n return { status: 'opened', number: pr.number, url: pr.url, branch, title: prTitle, continued: false, unchanged: false };\n}\n\n/**\n * Rewrites one file on an open branch in one commit (`next` gets the current text). Returns the commit sha, or ''\n * when nothing changed. The Library editor saves an edited docs.json and accepts a Claude draft this way.\n */\nexport async function commitFileOnGitHub(gh: GitHubClient, input: { path: string; branch: string; message: string; next: (text: string) => string }): Promise<string> {\n const cur = await gh.getFile(input.path, input.branch);\n if (!cur) throw new Error(`${input.path} is not on ${input.branch}. Check the component name and the branch.`);\n const content = input.next(cur.text);\n if (content === cur.text) return '';\n return gh.putFile({ path: input.path, content, branch: input.branch, message: input.message, sha: cur.sha });\n}\n","// Applying a suggestion (suggestions.ts) to the code a developer has now, not the commit it was planned on. The\n// planner is pure logic over a small Workspace adapter (read a file, read it at the base commit, merge three texts), so\n// the same steps run in Node on a git checkout (node/suggestion-apply-node.ts) and, later, in a browser against the\n// GitHub API. Steps:\n// 1. refuse what must never be read or written: unsafe paths (suggestionPathProblems), symlinks, a payload edited by\n// hand (unless the developer accepts it), a payload whose content does not match its recorded sha;\n// 2. gate: the approvals on the current payload sha (summarizeSuggestionApprovals) must cover the tier;\n// 3. classify every change against the current tree: already applied, apply, apply after a 3-way merge, conflict.\n// Token edits are re-applied with applyTokenEdits on the current tokens (never a text patch); files are compared\n// by git blob sha with the 3-way merge as fallback; docs are patched field by field;\n// 4. re-run the checks on the result (validation, contrast, tier) and stop when the tier went up or a contrast pair\n// that passes today would fail;\n// 5. say what to write. Nothing here writes: the adapter does, or the dry run shows the plan.\n// Re-running on a tree that has the change is a no-op (\"already applied\" for every change).\n\nimport type { BridgeConfig } from './config';\nimport { docsFileText, validateDocs } from './docs-proposal';\nimport type { ComponentDocsJson } from './docs-draft';\nimport { LayeredTokenSet, selectTokenFiles, validateLayered, type LayerIssue } from './layered';\nimport { contrastDelta, diffLayered, runLayeredContrast, type ContrastDelta, type LayeredChange } from './layered-review';\nimport { pendingApprovals, type ApprovalRole } from './review-gate';\nimport { classifyRisk, type RiskResult, type RiskTier } from './risk';\nimport { composeSuggestionAppliedComment, summarizeSuggestionApprovals, suggestionReviewState, type SuggestionApprovals, type SuggestionCommentLike, type SuggestionGovernance } from './suggestion-review';\nimport { canonicalJson, gitBlobSha, suggestionPathProblems, type ParsedSuggestion, type SuggestionPayloadV1, type SuggestionTokenChange } from './suggestions';\nimport { applyTokenEdits, coerceValue, type TokenEdit } from './token-edits';\nimport { parseContrastChecks, type ContrastPair } from './wcag';\n\n/** What the planner reads. Paths are repo-relative and already checked by suggestionPathProblems. */\nexport interface SuggestionWorkspace {\n /** The file as it is now (text and git blob sha), or null when it does not exist. */\n read(path: string): Promise<{ text: string; sha: string } | null>;\n /** The file at a commit (the payload's base sha), or null when it is missing there or the commit is unknown. */\n readAt(ref: string, path: string): Promise<string | null>;\n /** Every file path now, repo-relative (used to find the token files). */\n list(): Promise<string[]>;\n /** True when the path, or a folder on the way to it, is a symbolic link. Absent: no symlinks (a browser). */\n isSymlink?(path: string): Promise<boolean>;\n /** 3-way merge of a text file. Absent: a file changed on both sides is a conflict. */\n merge?(input: { path: string; ours: string; base: string; theirs: string }): Promise<{ clean: boolean; text: string; conflicts: number }>;\n}\n\nexport type SuggestionApplyOpState = 'already-applied' | 'apply' | 'apply-merged' | 'conflict';\n\n/** One change of the suggestion against the current tree. */\nexport interface SuggestionApplyOp {\n type: 'token' | 'file' | 'docs' | 'component-spec';\n /** Token path for token edits, repo path otherwise. */\n path: string;\n /** Token edits: the edit as suggested. */\n edit?: TokenEdit | undefined;\n /** Token file the edit targets, relative to tokens.root, when known. */\n file?: string | undefined;\n state: SuggestionApplyOpState;\n /** One sentence: what happens or why it conflicts. */\n detail: string;\n /** Conflicts: the value when suggested, the suggested value, and the value now. */\n before?: unknown;\n after?: unknown;\n now?: unknown;\n /** 3-way merge conflicts: how many conflict regions git found. */\n hunks?: number | undefined;\n}\n\nexport type SuggestionApplyOutcome =\n /** The checks pass and every change can be written. */\n | 'ready'\n /** Every change is already in the tree: nothing to write. */\n | 'already-applied'\n /** At least one change conflicts with the current tree: nothing is written. */\n | 'conflict'\n /** The approvals on the current payload do not cover its tier. */\n | 'not-approved'\n /** The re-run checks stop it: the tier went up, a contrast pair would fail, or a new validation error. */\n | 'blocked'\n /** Not applied at all: unsafe path, symlink, edited payload, invalid content. */\n | 'refused';\n\n/** Exit codes the CLI uses: 0 ok (ready or already applied), 1 gate or checks, 2 usage, 3 conflict. */\nexport const SUGGESTION_APPLY_EXIT: Record<SuggestionApplyOutcome, 0 | 1 | 3> = {\n ready: 0,\n 'already-applied': 0,\n conflict: 3,\n 'not-approved': 1,\n blocked: 1,\n refused: 1,\n};\n\nexport interface SuggestionApplyGate {\n /** The payload's review state on its current sha. */\n review: 'needs-review' | 'changes-requested' | 'approved';\n /** Approvals still missing for the tier. */\n missing: ApprovalRole[];\n approvals: SuggestionApprovals;\n /** Applied without the approvals because the developer asked for it (recorded in the applied comment). */\n forced: boolean;\n /** The payload no longer matches what Bridge wrote; applied only because the developer accepted it. */\n edited: boolean;\n}\n\nexport interface SuggestionApplyChecks {\n /** Tier when suggested and recomputed on the current tree. */\n tierWhenSuggested: RiskTier;\n tier: RiskResult;\n tierIncreased: boolean;\n /** Validation errors the result adds to today's tokens. */\n newErrors: LayerIssue[];\n /** Contrast pairs that pass today and would fail. */\n newFailures: ContrastDelta[];\n /** Every contrast pair that moved. */\n contrast: ContrastDelta[];\n /** Token changes the result makes against today's tokens. */\n tokenChanges: LayeredChange[];\n}\n\nexport interface SuggestionApplyPlan {\n outcome: SuggestionApplyOutcome;\n exitCode: 0 | 1 | 3;\n /** One sentence for people: what happens, or what stops it and how to go on. */\n message: string;\n /** sha256 of the payload the plan applies (what approvals bound to). */\n payloadSha: string;\n payload: SuggestionPayloadV1;\n gate: SuggestionApplyGate | null;\n ops: SuggestionApplyOp[];\n /** Files to write when the outcome is \"ready\" (null content: delete). Empty otherwise. */\n writes: { path: string; content: string | null }[];\n checks: SuggestionApplyChecks | null;\n /** Why it is refused or blocked, as sentences. */\n problems: string[];\n /** Notes for the developer (token aliases left broken, a payload file the token edits replace...). */\n notes: string[];\n /** Component specs: the brief Claude or a developer implements from the spec file. */\n brief?: string | undefined;\n}\n\nexport interface PlanSuggestionApplyInput {\n /** The parsed issue (parseSuggestionIssue). */\n parsed: Extract<ParsedSuggestion, { ok: true }>;\n /** bridge.config.json as read from the code (the default branch or the checkout), never from the payload. */\n config: BridgeConfig;\n /** Issue comments, for the approvals. */\n comments: readonly SuggestionCommentLike[];\n /** Owners and rights from the same config (plus team members when read). Default: the config's. */\n governance?: SuggestionGovernance | undefined;\n /** The issue author: never approves their own suggestion. */\n author?: string | null | undefined;\n workspace: SuggestionWorkspace;\n /** Apply even though the payload was edited by hand since Bridge wrote it. */\n acceptEdited?: boolean | undefined;\n /** Apply without every approval, or with a tier that went up (recorded in the applied comment). */\n forceUnapproved?: boolean | undefined;\n}\n\nconst same = (a: unknown, b: unknown) => canonicalJson(a) === canonicalJson(b);\nconst show = (v: unknown) => (v === undefined ? 'nothing' : typeof v === 'string' ? v : JSON.stringify(v));\n\nfunction tokenRoot(config: BridgeConfig): string {\n const r = config.tokens.root.replace(/\\/+$/, '');\n return r === '.' ? '' : r;\n}\n\n/** The token file (relative to tokens.root) a repo path is, or null when it is not one under this config. */\nfunction tokenFileOf(config: BridgeConfig, path: string): string | null {\n const root = tokenRoot(config);\n if (root && !path.startsWith(`${root}/`)) return null;\n if (!selectTokenFiles(config, [path]).length) return null;\n return root ? path.slice(root.length + 1) : path;\n}\n\n/** Plans one token edit on `set`: its state, and the files after it when it applies. */\nfunction planTokenEdit(set: LayeredTokenSet, e: TokenEdit, changes: readonly SuggestionTokenChange[]): { op: SuggestionApplyOp; files?: Map<string, string>; notes: string[] } {\n const base = { type: 'token' as const, path: e.path, edit: e, ...(e.file ? { file: e.file } : {}) };\n const defsAt = (path: string) => set.defs.filter((d) => d.path === path && (!e.file || d.file === e.file));\n const recorded = (file: string, path = e.path) => changes.find((c) => c.path === path && c.file === file && (e.op === 'rename' ? c.kind === 'renamed' : true));\n const conflict = (detail: string, extra: Partial<SuggestionApplyOp> = {}) => ({ op: { ...base, state: 'conflict' as const, detail, ...extra }, notes: [] });\n const done = (detail: string) => ({ op: { ...base, state: 'already-applied' as const, detail }, notes: [] });\n\n let result: ReturnType<typeof applyTokenEdits>;\n try {\n result = applyTokenEdits(set, [e]);\n } catch (err) {\n const why = err instanceof Error ? err.message : String(err);\n switch (e.op) {\n case 'rename': {\n const hasOld = defsAt(e.path).length > 0;\n const hasNew = set.defs.some((d) => d.path === e.newPath);\n if (!hasOld && hasNew) return done(`Already renamed to ${e.newPath}.`);\n return conflict(hasOld && hasNew ? `Both ${e.path} and ${e.newPath} exist now: rename it by hand.` : `${e.path} no longer exists: ${why}`);\n }\n case 'remove':\n if (!defsAt(e.path).length) return done('Already removed.');\n return conflict(why);\n case 'add': {\n const existing = defsAt(e.path);\n if (!existing.length) return conflict(why);\n const want = (file: string) => {\n const c = recorded(file);\n if (c && c.after !== undefined) return c.after;\n return coerceValue(e.value, e.type ?? existing.find((d) => d.file === file)?.type);\n };\n const all = existing.every((d) => same(d.value, want(d.file)));\n if (all) return done('Already added with the suggested value.');\n const d = existing.find((x) => !same(x.value, want(x.file)))!;\n return conflict(`Someone added ${e.path} with another value since.`, { file: d.file, after: want(d.file), now: d.value });\n }\n default:\n return conflict(defsAt(e.path).length ? why : `${e.path} no longer exists, so its value cannot be set.`);\n }\n }\n if (!result.touched.length) return done('Already has the suggested value.');\n\n // It changes something: check the value it replaces is still the one the suggestion saw.\n if (e.op === 'set' || e.op === 'remove' || e.op === 'rename') {\n for (const d of defsAt(e.path)) {\n const c = recorded(d.file, e.op === 'rename' ? (e.newPath ?? e.path) : e.path);\n if (!c) continue;\n const okNow = same(d.value, c.before) || (e.op === 'set' && same(d.value, c.after));\n if (!okNow) return conflict(`${e.path} changed since it was suggested (now ${show(d.value)}, suggested from ${show(c.before)}).`, { file: d.file, before: c.before, after: c.after, now: d.value });\n }\n }\n const verb = e.op === 'set' ? 'Set' : e.op === 'add' ? 'Add' : e.op === 'remove' ? 'Remove' : `Rename to ${e.newPath ?? ''}`;\n return { op: { ...base, state: 'apply', detail: `${verb} in ${result.touched.join(', ')}.` }, files: result.files, notes: result.notes };\n}\n\n/** One whole-file change against the current tree: by blob sha, with the 3-way merge when both sides moved. */\nasync function planFile(ws: SuggestionWorkspace, baseSha: string, f: NonNullable<SuggestionPayloadV1['files']>[number]): Promise<{ op: SuggestionApplyOp; content?: string | null | undefined }> {\n const base = { type: 'file' as const, path: f.path };\n const cur = await ws.read(f.path);\n const curSha = cur?.sha ?? null;\n const theirs = f.afterSha === null ? null : (f.content ?? null);\n if (curSha === f.afterSha) return { op: { ...base, state: 'already-applied', detail: f.afterSha === null ? 'Already deleted.' : 'Already has the suggested content.' } };\n if (curSha === f.beforeSha) return { op: { ...base, state: 'apply', detail: f.afterSha === null ? 'Delete it.' : f.beforeSha === null ? 'Create it.' : 'Replace it with the suggested content.' }, content: theirs };\n if (f.beforeSha === null) return { op: { ...base, state: 'conflict', detail: 'The suggestion creates this file, but a different one exists now.' } };\n if (!cur) return { op: { ...base, state: 'conflict', detail: 'The suggestion changes this file, but it was deleted since.' } };\n if (theirs === null) return { op: { ...base, state: 'conflict', detail: 'The suggestion deletes this file, but it changed since.' } };\n const original = await ws.readAt(baseSha, f.path);\n if (original === null || gitBlobSha(original) !== f.beforeSha || !ws.merge) {\n return { op: { ...base, state: 'conflict', detail: original === null ? 'The file changed since and its version at the suggestion base cannot be read, so it cannot be merged.' : 'The file changed since and cannot be merged here.' } };\n }\n const merged = await ws.merge({ path: f.path, ours: cur.text, base: original, theirs });\n if (!merged.clean) return { op: { ...base, state: 'conflict', detail: `The file changed since and the merge has ${merged.conflicts} conflict(s).`, hunks: merged.conflicts } };\n if (merged.text === cur.text) return { op: { ...base, state: 'already-applied', detail: 'Already has the suggested lines.' } };\n return { op: { ...base, state: 'apply-merged', detail: 'The file changed since: merged with the suggested lines, no conflict.' }, content: merged.text };\n}\n\n/**\n * The plan to apply a suggestion to the current tree. Never writes; the adapter writes `writes` when the outcome is\n * \"ready\". Stops before reading any file when a path is unsafe.\n */\nexport async function planSuggestionApply(input: PlanSuggestionApplyInput): Promise<SuggestionApplyPlan> {\n const { parsed, config, workspace: ws } = input;\n const payload = parsed.payload;\n const notes: string[] = [];\n const out = (outcome: SuggestionApplyOutcome, message: string, rest: Partial<SuggestionApplyPlan> = {}): SuggestionApplyPlan => ({\n outcome,\n exitCode: SUGGESTION_APPLY_EXIT[outcome],\n message,\n payloadSha: parsed.sha,\n payload,\n gate: null,\n ops: [],\n writes: [],\n checks: null,\n problems: [],\n notes,\n ...(payload.componentSpec ? { brief: payload.componentSpec.brief } : {}),\n ...rest,\n });\n\n // 1. What must never be read or written.\n const problems = suggestionPathProblems(payload, config);\n if (payload.checks.blocked) problems.push(`It was suggested with a failing check (${payload.checks.blocked}): ask the author to fix it and send it again.`);\n for (const f of payload.files ?? []) {\n if (f.afterSha !== null && typeof f.content !== 'string') problems.push(`\"${f.path}\" has no content in the suggestion: it is incomplete, ask the author to send it again.`);\n else if (f.afterSha !== null && gitBlobSha(f.content as string) !== f.afterSha) problems.push(`\"${f.path}\" does not match the content it was suggested with: someone edited it by hand.`);\n }\n if (problems.length) return out('refused', 'Not applied: the suggestion asks for something Bridge never writes.', { problems: [...new Set(problems)] });\n if (parsed.edited && !input.acceptEdited) {\n return out('refused', 'Not applied: the suggestion was edited by hand since Bridge wrote it. Read the change, then apply it with \"accept edited\" if it is right.', {\n problems: ['The payload no longer matches the sha Bridge recorded.'],\n });\n }\n const root = tokenRoot(config);\n const tokenFiles = selectTokenFiles(config, await ws.list());\n const targets = [\n ...(payload.files ?? []).map((f) => f.path),\n ...(payload.docs ?? []).map((d) => d.path),\n ...(payload.componentSpec ? [payload.componentSpec.specPath] : []),\n ...(payload.tokens?.edits.length ? tokenFiles.map((f) => (root ? `${root}/${f}` : f)) : []),\n ];\n if (ws.isSymlink) {\n const links: string[] = [];\n for (const p of new Set(targets)) if (await ws.isSymlink(p)) links.push(`\"${p}\" is a symbolic link (or inside one): Bridge never writes through links.`);\n if (links.length) return out('refused', 'Not applied: the suggestion writes through a symbolic link.', { problems: links });\n }\n\n // 2. Gate: approvals by owners on the current payload sha.\n const governance = input.governance ?? { owners: config.governance.owners, rights: config.governance.rights ?? null, soloOwnerCanApproveBoth: config.governance.soloOwnerCanApproveBoth };\n const approvals = summarizeSuggestionApprovals(input.comments, governance, { payloadSha: parsed.sha, author: input.author });\n const review = suggestionReviewState(payload.tier.tier, approvals);\n const missing = pendingApprovals(payload.tier.tier, approvals);\n const approved = review === 'approved';\n const gate: SuggestionApplyGate = { review, missing, approvals, forced: !approved && Boolean(input.forceUnapproved), edited: parsed.edited };\n\n // 3. Classify every change against the current tree.\n const ops: SuggestionApplyOp[] = [];\n const writes = new Map<string, string | null>();\n const current = new Map<string, string>();\n for (const f of tokenFiles) {\n const r = await ws.read(root ? `${root}/${f}` : f);\n if (r) current.set(f, r.text);\n }\n const before = new LayeredTokenSet(config, current);\n let set = before;\n const appliedEdits: TokenEdit[] = [];\n for (const e of payload.tokens?.edits ?? []) {\n const r = planTokenEdit(set, e, payload.tokens!.changes);\n ops.push(r.op);\n notes.push(...r.notes);\n if (r.op.state === 'apply' && r.files) {\n set = new LayeredTokenSet(config, r.files);\n appliedEdits.push(e);\n }\n }\n for (const [f, text] of set.files) if (text !== before.files.get(f)) writes.set(set.repoPath(f), text);\n\n for (const f of payload.files ?? []) {\n if (writes.has(f.path)) {\n notes.push(`${f.path}: the token edits write this file, its copy in the suggestion is not used.`);\n continue;\n }\n const r = await planFile(ws, payload.base.sha, f);\n ops.push(r.op);\n if (r.op.state === 'apply' || r.op.state === 'apply-merged') writes.set(f.path, r.content ?? null);\n }\n\n for (const d of payload.docs ?? []) {\n const base = { type: 'docs' as const, path: d.path };\n const docs = d.after as ComponentDocsJson;\n let text: string;\n try {\n const issues = validateDocs(docs);\n if (issues.length) {\n problems.push(`${d.path}: ${issues.map((i) => i.message).join(' ')}`);\n continue;\n }\n const cur = await ws.read(d.path);\n text = docsFileText(docs, cur?.text ?? null);\n if (cur && text === cur.text) {\n ops.push({ ...base, state: 'already-applied', detail: 'The docs already say this.' });\n continue;\n }\n ops.push({ ...base, state: 'apply', detail: cur ? 'Update the changed fields; other fields stay as they are now.' : 'Create the docs file.' });\n writes.set(d.path, text);\n } catch (err) {\n problems.push(`${d.path}: the suggested docs are not a docs.json Bridge can read (${err instanceof Error ? err.message : String(err)}).`);\n }\n }\n\n if (payload.componentSpec) {\n const s = payload.componentSpec;\n const text = `${JSON.stringify(s.spec, null, 2)}\\n`;\n const cur = await ws.read(s.specPath);\n if (cur && cur.text === text) ops.push({ type: 'component-spec', path: s.specPath, state: 'already-applied', detail: 'The spec file is already there.' });\n else {\n ops.push({ type: 'component-spec', path: s.specPath, state: 'apply', detail: `Write the spec; the ${s.component} code itself is written from the brief.` });\n writes.set(s.specPath, text);\n }\n }\n\n // 4. Checks on the result, against today's tree.\n const afterFiles = new Map(set.files);\n for (const [p, content] of writes) {\n const tf = tokenFileOf(config, p);\n if (!tf) continue;\n if (content === null) afterFiles.delete(tf);\n else afterFiles.set(tf, content);\n }\n const after = new LayeredTokenSet(config, afterFiles);\n const tokenChanges = diffLayered(before, after);\n const issueKey = (i: LayerIssue) => `${i.code}|${i.path ?? ''}|${i.file ?? ''}|${i.message}`;\n const prevErrors = new Set(validateLayered(before).map(issueKey));\n const newErrors = tokenChanges.length ? validateLayered(after).filter((i) => i.level === 'error' && !prevErrors.has(issueKey(i))) : [];\n let pairs: ContrastPair[] = [];\n if (config.contrast && tokenChanges.length) {\n try {\n pairs = parseContrastChecks((await ws.read(config.contrast.path))?.text);\n } catch {\n notes.push(`${config.contrast.path} does not parse: contrast was not checked.`);\n }\n }\n const modes = config.contrast?.modes;\n const contrast = pairs.length ? contrastDelta(runLayeredContrast(before, pairs, modes), runLayeredContrast(after, pairs, modes)) : [];\n const newFailures = contrast.filter((d) => d.passBefore && !d.passAfter);\n const otherFiles = [...writes.keys()].filter((p) => !tokenFileOf(config, p));\n const tier = classifyRisk({ tokenChanges: tokenChanges.map((c) => ({ kind: c.kind, path: c.path, ...(c.kind === 'changed' ? { descriptionOnly: c.fields.length > 0 && c.fields.every((x) => x === 'description') } : {}) })), files: otherFiles.map((path) => ({ path })), config });\n const tierIncreased = writes.size > 0 && tier.tier > payload.tier.tier;\n const checks: SuggestionApplyChecks = { tierWhenSuggested: payload.tier.tier, tier, tierIncreased, newErrors, newFailures, contrast, tokenChanges };\n const rest = { gate, ops, checks, problems };\n\n // 5. Outcome.\n if (problems.length) return out('refused', 'Not applied: part of the suggestion is not valid.', rest);\n const conflicts = ops.filter((o) => o.state === 'conflict');\n if (conflicts.length) {\n return out('conflict', `Not applied: ${conflicts.length} change(s) conflict with the code now. Ask the author to refresh the suggestion on today's code, or apply those parts by hand.`, rest);\n }\n if (!writes.size) return out('already-applied', 'Already applied: the code has every change of this suggestion.', rest);\n if (newErrors.length || newFailures.length) {\n const why = [newErrors.length ? `${newErrors.length} new validation error(s)` : '', newFailures.length ? `${newFailures.length} contrast pair(s) would fail` : ''].filter(Boolean).join(' and ');\n return out('blocked', `Not applied: on today's code it would add ${why}. Ask the author to refresh the suggestion.`, rest);\n }\n if (tierIncreased && !input.forceUnapproved) {\n return out('blocked', `Not applied: on today's code it is a tier ${tier.tier} change, it was approved as tier ${payload.tier.tier}. It needs a new approval.`, rest);\n }\n if (!approved && !input.forceUnapproved) {\n const who = review === 'changes-requested' ? `changes requested by ${approvals.changesRequested.map((l) => `@${l}`).join(', ')}` : `missing ${missing.map((m) => (m === 'approval' ? 'an approval' : `${m} approval`)).join(' and ')}`;\n return out('not-approved', `Not applied: it is not approved yet (${who}). Ask the owners to review it on the issue.`, rest);\n }\n const forced = gate.forced || (tierIncreased && Boolean(input.forceUnapproved));\n return out('ready', `Ready: ${writes.size} file(s) to write${forced ? ', without every approval' : ''}.`, {\n ...rest,\n gate: { ...gate, forced },\n writes: [...writes].map(([path, content]) => ({ path, content })).sort((a, b) => a.path.localeCompare(b.path)),\n });\n}\n\n/** The comment recording where a planned suggestion was applied (posting it is the caller's job). */\nexport function suggestionAppliedComment(plan: Pick<SuggestionApplyPlan, 'payloadSha' | 'gate'>, where: { by?: string | undefined; branch?: string | undefined; commit?: string | undefined; pr?: number | undefined; at: string }): string {\n return composeSuggestionAppliedComment({ ...where, payloadSha: plan.payloadSha, ...(plan.gate?.forced ? { forced: true } : {}) });\n}\n\n/** The per-change table of a plan, as Markdown (the CLI dry run, the MCP answer). */\nexport function suggestionApplyTable(plan: Pick<SuggestionApplyPlan, 'ops'>): string {\n const label: Record<SuggestionApplyOpState, string> = { 'already-applied': 'already applied', apply: 'apply', 'apply-merged': 'apply (merged)', conflict: '**conflict**' };\n const cell = (s: string) => s.replace(/\\|/g, '\\\\|').replace(/\\r?\\n/g, ' ');\n return ['| Change | Result | Detail |', '| --- | --- | --- |', ...plan.ops.map((o) => `| \\`${cell(o.path)}\\` | ${label[o.state]} | ${cell(o.detail)} |`)].join('\\n');\n}\n","// RepoSource: the one way repository files reach the repo model (repo-model.ts). Every data path reads a design\n// system repo through it, so the same code runs at build time (fsSource in @bridge-ds/core/node), in the browser\n// (a GitHub source: one tree call, file bodies by sha) and from a published snapshot. Pure: no Node, no DOM.\n\n/** Which repository and commit a source reads. `sha` pins every read; a local checkout may say \"working-tree\". */\nexport interface RepoSourceRef {\n owner: string;\n repo: string;\n sha: string;\n}\n\nexport interface RepoSource {\n ref: RepoSourceRef;\n /**\n * Repo-relative paths of every file under `prefix` (a directory, repo-relative, no trailing slash), at any depth,\n * sorted. Omitted or empty: the whole repository. A missing directory lists nothing.\n */\n list(prefix?: string): Promise<string[]>;\n /** Body of a repo-relative file as UTF-8 text, or null when the file does not exist. */\n text(path: string): Promise<string | null>;\n}\n\n/** \"./a//b/\" -> \"a/b\". Paths in a RepoSource are repo-relative and use \"/\". */\nexport function normalizeRepoPath(path: string): string {\n return path\n .replace(/\\\\/g, '/')\n .split('/')\n .filter((s) => s && s !== '.')\n .join('/');\n}\n\n/** True when `path` is `prefix` itself or a file below it. An empty prefix holds everything. */\nexport function isUnder(path: string, prefix: string | undefined): boolean {\n const p = normalizeRepoPath(prefix ?? '');\n return !p || path === p || path.startsWith(`${p}/`);\n}\n\n/** Parent directory of a repo-relative path (\"\" for a top-level file). */\nexport const parentDir = (path: string): string => {\n const p = normalizeRepoPath(path);\n const i = p.lastIndexOf('/');\n return i < 0 ? '' : p.slice(0, i);\n};\n\n/** Joins repo-relative segments, dropping empty ones and \".\" (\"packages\", \"\", \"a.json\" -> \"packages/a.json\"). */\nexport const joinRepoPath = (...parts: (string | undefined)[]): string => normalizeRepoPath(parts.filter(Boolean).join('/'));\n\n/**\n * A source over files held in memory, keyed by repo-relative path. Used by tests, by snapshots and by any caller\n * that already has the bodies (a browser cache).\n */\nexport function memorySource(files: Record<string, string>, ref: Partial<RepoSourceRef> = {}): RepoSource {\n const map = new Map(Object.entries(files).map(([k, v]) => [normalizeRepoPath(k), v]));\n const paths = [...map.keys()].sort();\n return {\n ref: { owner: ref.owner ?? '', repo: ref.repo ?? '', sha: ref.sha ?? 'memory' },\n list: async (prefix) => paths.filter((p) => isUnder(p, prefix)),\n text: async (path) => map.get(normalizeRepoPath(path)) ?? null,\n };\n}\n\n/** How far a readRepoTexts call has gone: files settled (read, missing or skipped) out of the distinct paths asked. */\nexport type ReadProgress = (done: number, total: number) => void;\n\n/**\n * Reads many files with a few requests in flight (4 by default, like loadRepoFiles), keyed by the path asked for.\n * A missing file maps to null. `onError` decides about a read that throws: return null to skip the file, or throw\n * (the default) to fail the whole read. `onProgress` hears (0, total) first, then once per settled file: real counts,\n * so a progress bar never runs ahead of the reads.\n */\nexport async function readRepoTexts(\n source: RepoSource,\n paths: string[],\n concurrency = 4,\n onError: (path: string, err: unknown) => null = (_path, err) => {\n throw err;\n },\n onProgress?: ReadProgress,\n): Promise<Map<string, string | null>> {\n const unique = [...new Set(paths)];\n const out = new Map<string, string | null>();\n onProgress?.(0, unique.length);\n let next = 0;\n const worker = async () => {\n while (next < unique.length) {\n const path = unique[next++]!;\n let body: string | null;\n try {\n body = await source.text(path);\n } catch (err) {\n body = onError(path, err);\n }\n out.set(path, body);\n onProgress?.(out.size, unique.length);\n }\n };\n await Promise.all(Array.from({ length: Math.max(1, Math.min(concurrency, unique.length)) }, worker));\n return out;\n}\n"],"names":["same","cell","p","data","tokensPath","changesetBump","names","show","where","before","after","MARK","kindLabel","sourceLabel","a","lower","norm","list","values","b","h","n","tokenRoot","d","rest","issueKey"],"mappings":"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"}
|