@bridge-ds/core 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { m as modeDisplayName, b as modesOf$1, i as isMultiMode, T as TIER_NAMES, c as TIER_AXIS, d as collectRefs, f as findReferenceProblems, e as evaluatePairs, g as contrastScope, h as contextLabel, S as SINGLE_MODE, j as isAlias$1, k as aliasTarget, l as pathId, v as valuesEqual, n as flattenTokens, s as serializeTokenFile, r as removeToken, u as upsertToken, o as threeWayDiff, q as emptyTokenFile, w as parseTokenFile, E as EXT_ID, x as EXT_SCOPES, y as parseColor, z as rgbaToHex, A as formatValue, B as resolve, C as moveToken, D as effectiveScopes, F as sameScopes, G as defaultScopes, H as readTokenAt, I as modeFile, J as defaultFile, K as selectTokenFiles, L as LayeredTokenSet, M as resolveBranchPreviews, N as loadConfig, O as tokensPath, P as toConfigJson, Q as validateLayered, R as parseContrastChecks, U as classifyRisk, V as CONFIG_FILE, W as RISK_LABELS, X as previewLinks, Y as findPreviewComment, Z as previewsSettled, _ as DEFAULT_TOKEN_PATHS, $ as layoutOptions, a0 as buildTokenSet, a1 as readPreviewComment, a2 as linkStatus, a3 as libraryPreviewState, a4 as parsePiecesRecord, a5 as libraryBranchPlan, a6 as NEEDED_BY_LABEL, a7 as withNeededBy, a8 as withLink, a9 as withPiecesRecord, aa as productBranchSentence, ab as mergePiecesRecord, ac as productOfBranch, ad as defaultProduct, ae as slugify, af as defineConfig, ag as globToRegExp, ah as ConfigError, ai as DEFAULT_CHANGES_MODE, aj as DEFAULT_OVERRIDE, ak as DEFAULT_PRODUCTS, al as isGuardrail } from "./prod-branch-Bdx_2bRQ.js";
2
- import { am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM, aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ, a_, a$, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, bA, bB, bC, bD, bE, bF, bG, bH, bI, bJ, bK, bL, bM, bN, bO, bP, bQ, bR, bS, p, bT, bU, bV, bW, bX, bY, bZ, b_, b$, c0, c1, a, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm, cn, co, cp, cq, cr, t, cs, ct, cu, cv, cw, cx, cy, cz, cA } from "./prod-branch-Bdx_2bRQ.js";
3
- import { G as GitHubError, c as collectHistory, p as packageDirCandidates, a as parseChangelog, r as releasesFromTags, m as mergeReleases, b as buildReport, d as applyTokenEdits, e as buildHistoryEntry, f as coerceValue, g as checkLayeredPair, h as formatChangeset, P as PROSE_KEYS, i as markClaudeDraft, j as cleanDraftText, k as docsPrompt, D as DRAFT_LINE_MAX, R as REQUESTS_BRANCH, l as REQUEST_KINDS, s as sanitizeDraftLine, n as parseExplorationBody, E as EXPLORATION_PREFIX, o as explorationSlug, q as explorationStatus, t as explorationTryIt, u as isExplorationPull, v as promotionPlan, w as EXPLORATION_LABEL, x as explorationProblems, y as explorationNote, z as explorationNotePath, A as explorationPrTitle, B as explorationPrBody, C as compareSpecToMeasured, F as variantKeyOf, H as withoutAddedWrappers, I as pairParts, S as SPEC_FIELDS, J as COLOR_FIELDS, K as hashSpec, L as overrideComment, O as OVERRIDE_HEADING, M as overrideRefusedComment, N as suggestionStateFromLabels, Q as suggestionStatus, T as composeRequestIssue, U as EXPLORATION_NOTES_DIR, V as isExplorationBranch, W as diffLayered, X as contrastDelta, Y as runLayeredContrast, Z as layeredImpact, _ as classifyLayered, $ as composeProposalBody, a0 as createSuggestionOnGitHub, a1 as gitBlobSha, a2 as SUGGESTION_SCHEMA, a3 as branchWithJiraKey, a4 as titleWithJiraKey, a5 as figmaSpecPath, a6 as formatFigmaSpec, a7 as figmaDraftBrief, a8 as parseFigmaOrigin, a9 as figmaPushStatus, aa as parseFigmaSpec, ab as FIGMA_SPEC_DIR, ac as FROM_FIGMA_LABEL, ad as withFigmaOrigin, ae as WAITING_FOR_CLAUDE_LABEL, af as DRAFTED_BY_CLAUDE_LABEL, ag as planComponentPush, ah as figmaOriginSection, ai as figmaBranchTitle, aj as figmaSpecSlug, ak as figmaDraftBody, al as REQUEST_LABEL, am as figmaNodeUrl, an as parentDir, ao as parseComponentSpecs, ap as readRepoTexts, aq as normalizeRepoPath, ar as isUnder, as as componentMotion, at as GitHubClient, au as effectiveTier, av as parseRequestIssue, aw as requestStatus, ax as listSuggestionsOnGitHub, ay as getSuggestionOnGitHub, az as closingIssueNumbers, aA as requestIssueTitle, aB as pullState, aC as summarizeCi, aD as summarizeApprovals } from "./repo-source-m0Tc603o.js";
4
- import { aE as aE2, aF as aF2, aG as aG2, aH as aH2, aI as aI2, aJ as aJ2, aK as aK2, aL as aL2, aM as aM2, aN as aN2, aO as aO2, aP as aP2, aQ as aQ2, aR as aR2, aS as aS2, aT as aT2, aU as aU2, aV as aV2, aW as aW2, aX as aX2, aY as aY2, aZ as aZ2, a_ as a_2, a$ as a$2, b0 as b02, b1 as b12, b2 as b22, b3 as b32, b4 as b42, b5 as b52, b6 as b62, b7 as b72, b8 as b82, b9 as b92, ba as ba2, bb as bb2, bc as bc2, bd as bd2, be as be2, bf as bf2, bg as bg2, bh as bh2, bi as bi2, bj as bj2, bk as bk2, bl as bl2, bm as bm2, bn as bn2, bo as bo2, bp as bp2, bq as bq2, br as br2, bs as bs2, bt as bt2, bu as bu2, bv as bv2, bw as bw2, bx as bx2, by as by2, bz as bz2, bA as bA2, bB as bB2, bC as bC2, bD as bD2, bE as bE2, bF as bF2, bG as bG2, bH as bH2, bI as bI2, bJ as bJ2, bK as bK2, bL as bL2, bM as bM2, bN as bN2, bO as bO2, bP as bP2, bQ as bQ2, bR as bR2, bS as bS2, bT as bT2, bU as bU2, bV as bV2, bW as bW2, bX as bX2, bY as bY2, bZ as bZ2, b_ as b_2, b$ as b$2, c0 as c02, c1 as c12, c2 as c22, c3 as c32, c4 as c42, c5 as c52, c6 as c62, c7 as c72, c8 as c82, c9 as c92, ca as ca2, cb as cb2, cc as cc2, cd as cd2, ce as ce2, cf as cf2, cg as cg2, ch as ch2, ci as ci2, cj as cj2, ck as ck2, cl as cl2, cm as cm2, cn as cn2, co as co2, cp as cp2, cq as cq2, cr as cr2, cs as cs2, ct as ct2, cu as cu2, cv as cv2, cw as cw2, cx as cx2, cy as cy2, cz as cz2, cA as cA2, cB, cC, cD, cE, cF, cG, cH, cI, cJ, cK, cL, cM, cN, cO, cP, cQ, cR, cS, cT, cU, cV, cW, cX, cY, cZ, c_, c$, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df, dg, dh, di, dj, dk, dl, dm, dn, dp, dq, dr, ds, dt, du, dv, dw, dx, dy, dz, dA, dB, dC, dD, dE, dF, dG, dH, dI, dJ, dK, dL, dM, dN, dO, dP, dQ, dR, dS, dT, dU, dV, dW, dX, dY, dZ, d_, d$, e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef, eg, eh, ei, ej, ek, el, em } from "./repo-source-m0Tc603o.js";
1
+ import { m as modeDisplayName, b as modesOf$1, i as isMultiMode, T as TIER_NAMES, c as TIER_AXIS, d as collectRefs, f as findReferenceProblems, e as evaluatePairs, g as contrastScope, h as contextLabel, S as SINGLE_MODE, j as isAlias$1, k as aliasTarget, l as pathId, v as valuesEqual, n as flattenTokens, s as serializeTokenFile, r as removeToken, u as upsertToken, o as threeWayDiff, q as emptyTokenFile, w as parseTokenFile, E as EXT_ID, x as EXT_SCOPES, y as parseColor, z as rgbaToHex, A as formatValue, B as resolve, C as moveToken, D as effectiveScopes, F as sameScopes, G as defaultScopes, H as readTokenAt, I as modeFile, J as defaultFile, K as selectTokenFiles, L as LayeredTokenSet, M as resolveBranchPreviews, N as loadConfig, O as tokensPath, P as toConfigJson, Q as validateLayered, R as parseContrastChecks, U as classifyRisk, V as CONFIG_FILE, W as RISK_LABELS, X as previewLinks, Y as findPreviewComment, Z as previewsSettled, _ as baseBranchOf, $ as DEFAULT_TOKEN_PATHS, a0 as layoutOptions, a1 as buildTokenSet, a2 as readPreviewComment, a3 as linkStatus, a4 as libraryPreviewState, a5 as parsePiecesRecord, a6 as libraryBranchPlan, a7 as NEEDED_BY_LABEL, a8 as withNeededBy, a9 as withLink, aa as withPiecesRecord, ab as productBranchSentence, ac as mergePiecesRecord, ad as productOfBranch, ae as defaultProduct, af as slugify, ag as defineConfig, ah as globToRegExp, ai as ConfigError, aj as DEFAULT_CHANGES_MODE, ak as DEFAULT_OVERRIDE, al as DEFAULT_PRODUCTS, am as isGuardrail } from "./prod-branch-CJZwMfVD.js";
2
+ import { an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM, aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ, a_, a$, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, bA, bB, bC, bD, bE, bF, bG, bH, bI, bJ, bK, bL, bM, bN, bO, bP, bQ, bR, bS, p, bT, bU, bV, bW, bX, bY, bZ, b_, b$, c0, c1, a, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, ck, cl, cm, cn, co, cp, cq, cr, t, cs, ct, cu, cv, cw, cx, cy, cz, cA } from "./prod-branch-CJZwMfVD.js";
3
+ import { G as GitHubError, c as collectHistory, p as packageDirCandidates, a as parseChangelog, r as releasesFromTags, m as mergeReleases, b as buildReport, d as applyTokenEdits, e as buildHistoryEntry, f as coerceValue, g as checkLayeredPair, h as formatChangeset, P as PROSE_KEYS, i as markClaudeDraft, j as cleanDraftText, k as docsPrompt, D as DRAFT_LINE_MAX, R as REQUESTS_BRANCH, l as REQUEST_KINDS, s as sanitizeDraftLine, n as parseExplorationBody, E as EXPLORATION_PREFIX, o as explorationSlug, q as explorationStatus, t as explorationTryIt, u as isExplorationPull, v as promotionPlan, w as EXPLORATION_LABEL, x as explorationProblems, y as explorationNote, z as explorationNotePath, A as explorationPrTitle, B as explorationPrBody, C as compareSpecToMeasured, F as variantKeyOf, H as withoutAddedWrappers, I as pairParts, S as SPEC_FIELDS, J as COLOR_FIELDS, K as hashSpec, L as DRAFTED_BY_CLAUDE_LABEL, M as overrideComment, O as OVERRIDE_HEADING, N as overrideRefusedComment, Q as suggestionStateFromLabels, T as suggestionStatus, U as composeRequestIssue, V as EXPLORATION_NOTES_DIR, W as isExplorationBranch, X as diffLayered, Y as contrastDelta, Z as runLayeredContrast, _ as layeredImpact, $ as classifyLayered, a0 as composeProposalBody, a1 as createSuggestionOnGitHub, a2 as gitBlobSha, a3 as SUGGESTION_SCHEMA, a4 as branchWithJiraKey, a5 as titleWithJiraKey, a6 as figmaSpecPath, a7 as formatFigmaSpec, a8 as figmaDraftBrief, a9 as parseFigmaOrigin, aa as figmaPushStatus, ab as parseFigmaSpec, ac as FIGMA_SPEC_DIR, ad as FROM_FIGMA_LABEL, ae as withFigmaOrigin, af as WAITING_FOR_CLAUDE_LABEL, ag as planComponentPush, ah as figmaOriginSection, ai as figmaBranchTitle, aj as figmaSpecSlug, ak as figmaDraftBody, al as REQUEST_LABEL, am as figmaNodeUrl, an as parentDir, ao as parseComponentSpecs, ap as readRepoTexts, aq as normalizeRepoPath, ar as isUnder, as as componentMotion, at as GitHubClient, au as effectiveTier, av as parseRequestIssue, aw as requestStatus, ax as listSuggestionsOnGitHub, ay as getSuggestionOnGitHub, az as closingIssueNumbers, aA as requestIssueTitle, aB as pullState, aC as summarizeCi, aD as summarizeApprovals } from "./repo-source-CshjjC7x.js";
4
+ import { aE as aE2, aF as aF2, aG as aG2, aH as aH2, aI as aI2, aJ as aJ2, aK as aK2, aL as aL2, aM as aM2, aN as aN2, aO as aO2, aP as aP2, aQ as aQ2, aR as aR2, aS as aS2, aT as aT2, aU as aU2, aV as aV2, aW as aW2, aX as aX2, aY as aY2, aZ as aZ2, a_ as a_2, a$ as a$2, b0 as b02, b1 as b12, b2 as b22, b3 as b32, b4 as b42, b5 as b52, b6 as b62, b7 as b72, b8 as b82, b9 as b92, ba as ba2, bb as bb2, bc as bc2, bd as bd2, be as be2, bf as bf2, bg as bg2, bh as bh2, bi as bi2, bj as bj2, bk as bk2, bl as bl2, bm as bm2, bn as bn2, bo as bo2, bp as bp2, bq as bq2, br as br2, bs as bs2, bt as bt2, bu as bu2, bv as bv2, bw as bw2, bx as bx2, by as by2, bz as bz2, bA as bA2, bB as bB2, bC as bC2, bD as bD2, bE as bE2, bF as bF2, bG as bG2, bH as bH2, bI as bI2, bJ as bJ2, bK as bK2, bL as bL2, bM as bM2, bN as bN2, bO as bO2, bP as bP2, bQ as bQ2, bR as bR2, bS as bS2, bT as bT2, bU as bU2, bV as bV2, bW as bW2, bX as bX2, bY as bY2, bZ as bZ2, b_ as b_2, b$ as b$2, c0 as c02, c1 as c12, c2 as c22, c3 as c32, c4 as c42, c5 as c52, c6 as c62, c7 as c72, c8 as c82, c9 as c92, ca as ca2, cb as cb2, cc as cc2, cd as cd2, ce as ce2, cf as cf2, cg as cg2, ch as ch2, ci as ci2, cj as cj2, ck as ck2, cl as cl2, cm as cm2, cn as cn2, co as co2, cp as cp2, cq as cq2, cr as cr2, cs as cs2, ct as ct2, cu as cu2, cv as cv2, cw as cw2, cx as cx2, cy as cy2, cz as cz2, cA as cA2, cB, cC, cD, cE, cF, cG, cH, cI, cJ, cK, cL, cM, cN, cO, cP, cQ, cR, cS, cT, cU, cV, cW, cX, cY, cZ, c_, c$, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df, dg, dh, di, dj, dk, dl, dm, dn, dp, dq, dr, ds, dt, du, dv, dw, dx, dy, dz, dA, dB, dC, dD, dE, dF, dG, dH, dI, dJ, dK, dL, dM, dN, dO, dP, dQ, dR, dS, dT, dU, dV, dW, dX, dY, dZ, d_, d$, e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ea, eb, ec, ed, ee, ef, eg, eh, ei, ej, ek, el, em, en, eo, ep, eq, er, es } from "./repo-source-CshjjC7x.js";
5
5
  const issueKey$1 = (i) => `${i.code}|${i.path ?? ""}|${i.mode ?? ""}|${i.code === "file-problem" ? i.message : ""}`;
6
6
  const modeName = (mode) => mode === SINGLE_MODE ? "all modes" : modeDisplayName(mode);
7
7
  const isPalette = (t2) => t2.tier === "brand" && t2.path.startsWith("palette.");
@@ -162,7 +162,7 @@ function validateProposal(proposed, head, pairs, typeChanges = []) {
162
162
  const warnings = [];
163
163
  for (const i of after.issues) {
164
164
  if (i.severity === "warning") warnings.push(i);
165
- else if (existing.has(issueKey$1(i))) warnings.push({ ...i, severity: "warning", message: `Already on main: ${i.message}` });
165
+ else if (existing.has(issueKey$1(i))) warnings.push({ ...i, severity: "warning", message: `Already in the design system: ${i.message}` });
166
166
  else blocking.push(i);
167
167
  }
168
168
  for (const c of typeChanges) {
@@ -726,7 +726,7 @@ function importsIn(text) {
726
726
  for (const m of text.matchAll(IMPORT_RE)) out.add(m[1] ?? m[2]);
727
727
  return [...out];
728
728
  }
729
- const norm = (p2) => p2.replace(/\\/g, "/").replace(/\/+$/, "");
729
+ const norm$1 = (p2) => p2.replace(/\\/g, "/").replace(/\/+$/, "");
730
730
  const isStory = (p2) => /\.stories\.[cm]?[jt]sx?$/.test(p2);
731
731
  const isTest = (p2) => /\.(test|spec)\.[cm]?[jt]sx?$/.test(p2);
732
732
  const isCss = (p2) => /\.(css|scss|less)$/.test(p2);
@@ -744,14 +744,14 @@ function componentOf(from, spec, componentsDir) {
744
744
  return abs.slice(componentsDir.length + 1).split("/")[0] || null;
745
745
  }
746
746
  function componentForPath(path, componentsDir) {
747
- const dir = norm(componentsDir);
748
- const p2 = norm(path);
747
+ const dir = norm$1(componentsDir);
748
+ const p2 = norm$1(path);
749
749
  if (!p2.startsWith(`${dir}/`)) return null;
750
750
  const rest = p2.slice(dir.length + 1).split("/");
751
751
  return rest.length >= 2 ? rest[0] : null;
752
752
  }
753
753
  function buildUsageIndex(files, componentsDir) {
754
- const dir = norm(componentsDir);
754
+ const dir = norm$1(componentsDir);
755
755
  const modules = {};
756
756
  const vars = /* @__PURE__ */ new Map();
757
757
  const imports = /* @__PURE__ */ new Map();
@@ -759,7 +759,7 @@ function buildUsageIndex(files, componentsDir) {
759
759
  const globalVars = {};
760
760
  const get = (m, k) => m.get(k) ?? m.set(k, /* @__PURE__ */ new Set()).get(k);
761
761
  for (const f of files) {
762
- const path = norm(f.path);
762
+ const path = norm$1(f.path);
763
763
  const id = componentForPath(path, dir);
764
764
  if (!id) {
765
765
  if (isCss(path)) {
@@ -803,7 +803,7 @@ function impactedModules(index, input) {
803
803
  for (const v of changedVars) for (const id of index.byVar[v] ?? []) add(id, `uses ${v}`, false);
804
804
  for (const f of input.files ?? []) {
805
805
  const id = componentForPath(f, index.componentsDir);
806
- if (id && index.modules[id]) add(id, `file changed: ${norm(f)}`, false);
806
+ if (id && index.modules[id]) add(id, `file changed: ${norm$1(f)}`, false);
807
807
  }
808
808
  const renderedBy = /* @__PURE__ */ new Map();
809
809
  for (const m of Object.values(index.modules)) for (const d of m.imports) (renderedBy.get(d) ?? renderedBy.set(d, []).get(d)).push(m.id);
@@ -1130,7 +1130,7 @@ const BRAND_SLUG_RE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
1130
1130
  const DEFAULT_PRIMARY_CHROMA = 0.14;
1131
1131
  const isObj$4 = (x) => !!x && typeof x === "object" && !Array.isArray(x);
1132
1132
  const fileMap = (f) => f instanceof Map ? new Map(f) : new Map(Object.entries(f));
1133
- const brandDisplayName = (slug) => slug.split("-").filter(Boolean).map((w) => w[0].toUpperCase() + w.slice(1)).join(" ");
1133
+ const brandDisplayName = (slug2) => slug2.split("-").filter(Boolean).map((w) => w[0].toUpperCase() + w.slice(1)).join(" ");
1134
1134
  function brandLayers(config) {
1135
1135
  const out = {};
1136
1136
  for (const l of config.tokens.layers) {
@@ -1200,7 +1200,7 @@ function aliasRamp(doc, role, ramp, description) {
1200
1200
  }
1201
1201
  group.$description = description;
1202
1202
  }
1203
- function addBrandToConfigText(text, slug) {
1203
+ function addBrandToConfigText(text, slug2) {
1204
1204
  const canonical = /("brand"\s*:\s*\{\s*"values"\s*:\s*\[)([^\]]*)(\])/;
1205
1205
  const flat = /("brands"\s*:\s*\[)([^\]]*)(\])/;
1206
1206
  for (const re of [canonical, flat]) {
@@ -1208,7 +1208,7 @@ function addBrandToConfigText(text, slug) {
1208
1208
  if (!m) continue;
1209
1209
  const items = m[2].trim();
1210
1210
  const sep = items.includes("\n") ? `,${/\n(\s*)"/.exec(m[2])?.[0]?.replace(/"$/, "") ?? " "}` : ", ";
1211
- return text.slice(0, m.index) + m[1] + (items ? `${m[2].replace(/\s*$/, "")}${sep}"${slug}"` : `"${slug}"`) + (m[2].match(/\s*$/)?.[0] ?? "") + m[3] + text.slice(m.index + m[0].length);
1211
+ return text.slice(0, m.index) + m[1] + (items ? `${m[2].replace(/\s*$/, "")}${sep}"${slug2}"` : `"${slug2}"`) + (m[2].match(/\s*$/)?.[0] ?? "") + m[3] + text.slice(m.index + m[0].length);
1212
1212
  }
1213
1213
  throw new Error("bridge.config.json has no modes.brand.values list to add the brand to.");
1214
1214
  }
@@ -1219,21 +1219,21 @@ function listBrands(source) {
1219
1219
  const layers = brandLayers(config);
1220
1220
  const brandAxis = config.axes.brand;
1221
1221
  if (!brandAxis || !layers.brand) return [];
1222
- return brandAxis.values.map((slug) => {
1223
- const file = fill(layers.brand, { brand: slug });
1222
+ return brandAxis.values.map((slug2) => {
1223
+ const file = fill(layers.brand, { brand: slug2 });
1224
1224
  let doc = {};
1225
1225
  try {
1226
1226
  doc = JSON.parse(files.get(file) ?? "{}");
1227
1227
  } catch {
1228
1228
  }
1229
1229
  const meta = isObj$4(doc.$extensions) && isObj$4(doc.$extensions["dev.bridge.brand"]) ? doc.$extensions["dev.bridge.brand"] : {};
1230
- const combo = set.normalizeCombo({ brand: slug });
1230
+ const combo = set.normalizeCombo({ brand: slug2 });
1231
1231
  const primary = set.resolve("color.action.primary.bg", combo);
1232
- const overrides = layers.override ? (config.axes[layers.overrideAxis]?.values ?? []).map((v) => fill(layers.override, { brand: slug, [layers.overrideAxis]: v })).filter((f) => files.has(f)) : [];
1232
+ const overrides = layers.override ? (config.axes[layers.overrideAxis]?.values ?? []).map((v) => fill(layers.override, { brand: slug2, [layers.overrideAxis]: v })).filter((f) => files.has(f)) : [];
1233
1233
  return {
1234
- slug,
1235
- name: typeof meta.name === "string" ? meta.name : brandDisplayName(slug),
1236
- default: slug === brandAxis.default,
1234
+ slug: slug2,
1235
+ name: typeof meta.name === "string" ? meta.name : brandDisplayName(slug2),
1236
+ default: slug2 === brandAxis.default,
1237
1237
  file: tokensPath(config, file),
1238
1238
  ...typeof doc.$description === "string" ? { description: doc.$description } : {},
1239
1239
  ...primary.css && !primary.error ? { primary: primary.css } : {},
@@ -1241,9 +1241,9 @@ function listBrands(source) {
1241
1241
  };
1242
1242
  });
1243
1243
  }
1244
- function checkBrandSlug(config, files, slug) {
1244
+ function checkBrandSlug(config, files, slug2) {
1245
1245
  const out = [];
1246
- const s = slug.trim();
1246
+ const s = slug2.trim();
1247
1247
  if (!s) return [{ level: "error", code: "slug-empty", message: "Give the brand a name." }];
1248
1248
  if (s.length < 2 || s.length > 24 || !BRAND_SLUG_RE.test(s)) out.push({ level: "error", code: "slug-format", message: 'Use 2 to 24 lowercase letters, digits and single dashes, starting with a letter: "acme" or "north-star".' });
1249
1249
  const taken = Object.values(config.axes).flatMap((a2) => a2.values);
@@ -1258,12 +1258,12 @@ function planNewBrand(source, input) {
1258
1258
  const { config } = source;
1259
1259
  const files = fileMap(source.files);
1260
1260
  const issues = [];
1261
- const slug = input.slug.trim();
1262
- const name = input.name?.trim() || brandDisplayName(slug);
1261
+ const slug2 = input.slug.trim();
1262
+ const name = input.name?.trim() || brandDisplayName(slug2);
1263
1263
  const layers = brandLayers(config);
1264
1264
  const brandAxis = config.axes.brand;
1265
1265
  if (!brandAxis || !layers.brand) throw new Error("This repo has no brand mode: bridge.config.json needs modes.brand and a tokens layer with {brand}.");
1266
- issues.push(...checkBrandSlug(config, files, slug));
1266
+ issues.push(...checkBrandSlug(config, files, slug2));
1267
1267
  const from = input.from?.trim() || brandAxis.default;
1268
1268
  const blank = from === "blank";
1269
1269
  if (!blank && !brandAxis.values.includes(from)) throw new Error(`Unknown brand "${from}" to start from. Brands: ${brandAxis.values.join(", ")} (or "blank").`);
@@ -1290,8 +1290,8 @@ function planNewBrand(source, input) {
1290
1290
  const prims = /* @__PURE__ */ new Map();
1291
1291
  const addRamp = (role, ramp, description) => {
1292
1292
  const steps = new Map(STEPS.map((st) => [st, dtcgColor(ramp[st])]));
1293
- prims.set(`${slug}-${role}`, { description, steps });
1294
- return `${slug}-${role}`;
1293
+ prims.set(`${slug2}-${role}`, { description, steps });
1294
+ return `${slug2}-${role}`;
1295
1295
  };
1296
1296
  if (input.primaryHue !== void 0 && input.primaryHue !== "") {
1297
1297
  const ramp = safeRamp("primary", input.primaryHue, "color", actionStep);
@@ -1358,7 +1358,7 @@ function planNewBrand(source, input) {
1358
1358
  if (role.startsWith("$") || !isObj$4(group)) continue;
1359
1359
  for (const [step, node] of Object.entries(group)) {
1360
1360
  if (step.startsWith("$") || !isObj$4(node) || !("$value" in node) || typeof node.$value === "string") continue;
1361
- const ramp = `${slug}-${role}`;
1361
+ const ramp = `${slug2}-${role}`;
1362
1362
  const entry = prims.get(ramp) ?? { description: `${name} ${role}. Exact values set when the brand was created.`, steps: /* @__PURE__ */ new Map() };
1363
1363
  entry.steps.set(Number(step), node.$value);
1364
1364
  prims.set(ramp, entry);
@@ -1366,13 +1366,13 @@ function planNewBrand(source, input) {
1366
1366
  }
1367
1367
  }
1368
1368
  const primDir = config.tokens.tiers.primitive?.[0]?.replace(/\/$/, "") ?? config.tokens.primitives;
1369
- const primFile = `${primDir}/${slug}.tokens.json`;
1369
+ const primFile = `${primDir}/${slug2}.tokens.json`;
1370
1370
  if (prims.size && files.has(primFile)) issues.push({ level: "error", code: "slug-file-exists", message: `${tokensPath(config, primFile)} already exists. Pick another name.` });
1371
1371
  for (const r of prims.keys()) if (before.allPaths().some((p2) => p2.startsWith(`color.${r}.`))) issues.push({ level: "error", code: "ramp-exists", message: `A primitive ramp color.${r} already exists. Pick another name.` });
1372
1372
  doc.$description = `${name}: created with Bridge, started from ${blank ? "a blank brand" : brandDisplayName(from)}.`;
1373
1373
  doc.$extensions = { ...isObj$4(doc.$extensions) ? doc.$extensions : {}, "dev.bridge.brand": { name, from, ...Object.keys(anchors).length ? { anchors } : {} } };
1374
1374
  const { $description, $extensions, ...rest } = doc;
1375
- const brandFile = fill(layers.brand, { brand: slug });
1375
+ const brandFile = fill(layers.brand, { brand: slug2 });
1376
1376
  const nextFiles = new Map(files);
1377
1377
  const created = [];
1378
1378
  if (prims.size) {
@@ -1382,7 +1382,7 @@ function planNewBrand(source, input) {
1382
1382
  for (const st of [...steps.keys()].sort((a2, b) => a2 - b)) ramp[String(st)] = { $value: steps.get(st) };
1383
1383
  color[r] = ramp;
1384
1384
  }
1385
- const prim = { $description: `${name} brand ramps, generated by Bridge (@bridge-ds/core ramp engine). Never used by components directly: brands/${slug}.tokens.json maps them to palette roles.`, color };
1385
+ const prim = { $description: `${name} brand ramps, generated by Bridge (@bridge-ds/core ramp engine). Never used by components directly: brands/${slug2}.tokens.json maps them to palette roles.`, color };
1386
1386
  nextFiles.set(primFile, `${JSON.stringify(prim, null, 2)}
1387
1387
  `);
1388
1388
  created.push(primFile);
@@ -1397,7 +1397,7 @@ function planNewBrand(source, input) {
1397
1397
  if (!text2) continue;
1398
1398
  const o = JSON.parse(text2);
1399
1399
  const out = { ...o, $description: `${name} overrides on top of semantic/${v}, copied from ${brandDisplayName(from)}.` };
1400
- const dst = fill(layers.override, { brand: slug, [layers.overrideAxis]: v });
1400
+ const dst = fill(layers.override, { brand: slug2, [layers.overrideAxis]: v });
1401
1401
  nextFiles.set(dst, `${JSON.stringify(out, null, 2)}
1402
1402
  `);
1403
1403
  created.push(dst);
@@ -1408,7 +1408,7 @@ function planNewBrand(source, input) {
1408
1408
  let configText = baseConfigText;
1409
1409
  let nextConfig = config;
1410
1410
  try {
1411
- configText = addBrandToConfigText(baseConfigText, slug);
1411
+ configText = addBrandToConfigText(baseConfigText, slug2);
1412
1412
  nextConfig = issues.some((i) => i.code.startsWith("slug-")) ? config : loadConfig(configText);
1413
1413
  } catch (e) {
1414
1414
  issues.push({ level: "error", code: "config", message: e.message });
@@ -1416,21 +1416,21 @@ function planNewBrand(source, input) {
1416
1416
  const after = new LayeredTokenSet(nextConfig, nextFiles);
1417
1417
  const key2 = (i) => `${i.code}|${i.path ?? ""}|${i.message}`;
1418
1418
  const known = new Set(validateLayered(before).map(key2));
1419
- const brandKey = `brand=${slug}`;
1419
+ const brandKey = `brand=${slug2}`;
1420
1420
  for (const i of validateLayered(after)) {
1421
1421
  if (known.has(key2(i))) continue;
1422
1422
  if (i.modes && !i.modes.some((m) => m.split(",").includes(brandKey)) && !created.includes(i.file ?? "")) continue;
1423
1423
  issues.push({ level: i.level, code: i.code, message: i.message, ...i.path ? { path: i.path } : {}, ...i.file ? { file: tokensPath(config, i.file) } : {} });
1424
1424
  }
1425
1425
  const pairs = parseContrastChecks(source.contrastText);
1426
- const inGate = nextConfig.axes.brand?.values.includes(slug);
1427
- const combos = inGate ? after.combos(nextConfig.contrast?.modes).filter((c) => c.brand === slug) : [];
1426
+ const inGate = nextConfig.axes.brand?.values.includes(slug2);
1427
+ const combos = inGate ? after.combos(nextConfig.contrast?.modes).filter((c) => c.brand === slug2) : [];
1428
1428
  const results = combos.flatMap((c) => pairs.map((p2) => checkLayeredPair(after, p2, c)));
1429
1429
  const failing = results.filter((r) => !r.pass);
1430
1430
  const themes = [...new Set(combos.map((c) => c.theme).filter((t2) => !!t2))];
1431
1431
  const ramps = {};
1432
1432
  if (inGate) {
1433
- const combo = after.normalizeCombo({ brand: slug });
1433
+ const combo = after.normalizeCombo({ brand: slug2 });
1434
1434
  const read = (role) => STEPS.map((s) => ({ step: s, hex: after.resolve(`palette.${role}.${s}`, combo).css })).filter((x) => /^#[0-9a-f]{6}$/i.test(x.hex));
1435
1435
  ramps.primary = read("primary");
1436
1436
  ramps.neutral = read("neutral");
@@ -1447,19 +1447,19 @@ function planNewBrand(source, input) {
1447
1447
  ];
1448
1448
  const cs3 = config.changesets ?? (config.changeset ? { dir: ".changeset", package: config.changeset.package } : void 0);
1449
1449
  const changeset = cs3 ? {
1450
- path: `${cs3.dir}/bridge-brand-${slug}.md`,
1451
- content: formatChangeset(cs3.package, "minor", `Add the ${name} brand (\`${slug}\`), started from ${blank ? "a blank brand" : brandDisplayName(from)}.`, `- ${created.map((f) => `\`${tokensPath(config, f)}\``).join("\n- ")}
1452
- - \`${CONFIG_FILE}\`: modes.brand gains "${slug}", so the token build and the contrast gate cover it.`)
1450
+ path: `${cs3.dir}/bridge-brand-${slug2}.md`,
1451
+ content: formatChangeset(cs3.package, "minor", `Add the ${name} brand (\`${slug2}\`), started from ${blank ? "a blank brand" : brandDisplayName(from)}.`, `- ${created.map((f) => `\`${tokensPath(config, f)}\``).join("\n- ")}
1452
+ - \`${CONFIG_FILE}\`: modes.brand gains "${slug2}", so the token build and the contrast gate cover it.`)
1453
1453
  } : void 0;
1454
1454
  if (changeset) planned.push({ path: changeset.path, action: "create", content: changeset.content });
1455
1455
  const errors = issues.filter((i) => i.level === "error");
1456
1456
  return {
1457
1457
  ok: errors.length === 0 && failing.length === 0 && results.length > 0,
1458
- slug,
1458
+ slug: slug2,
1459
1459
  name,
1460
1460
  from,
1461
1461
  title: `Add the ${name} brand`,
1462
- branch: `${config.governance.branchPrefix}brand-${slug || "new"}`,
1462
+ branch: `${config.governance.branchPrefix}brand-${slug2 || "new"}`,
1463
1463
  files: planned,
1464
1464
  tokenFiles: Object.fromEntries(nextFiles),
1465
1465
  configText,
@@ -2137,12 +2137,12 @@ function localTryCommand(branch) {
2137
2137
  }
2138
2138
  function explorationSummary(p2, _owner, _repo, s) {
2139
2139
  const e = parseExplorationBody(p2.body);
2140
- const slug = p2.headRef?.startsWith(EXPLORATION_PREFIX) ? p2.headRef.slice(EXPLORATION_PREFIX.length) : e?.slug ?? explorationSlug(p2.title);
2140
+ const slug2 = p2.headRef?.startsWith(EXPLORATION_PREFIX) ? p2.headRef.slice(EXPLORATION_PREFIX.length) : e?.slug ?? explorationSlug(p2.title);
2141
2141
  return {
2142
2142
  number: p2.number,
2143
2143
  url: p2.url,
2144
2144
  branch: p2.headRef,
2145
- slug,
2145
+ slug: slug2,
2146
2146
  name: e?.name ?? p2.title.replace(/^[A-Z][A-Z0-9_]*-\d+\s+/, "").replace(/^Exploration:\s*/i, ""),
2147
2147
  purpose: e?.purpose ?? "",
2148
2148
  ...e?.useCase ? { useCase: e.useCase } : {},
@@ -2164,11 +2164,11 @@ async function startExplorationOnGitHub(gh, e, s) {
2164
2164
  const problems = explorationProblems(e);
2165
2165
  if (problems.length) throw new GitHubError(422, problems.join(" "));
2166
2166
  if (!gh.canWrite) throw new GitHubError(401, "Starting an exploration needs a GitHub token (contents and pull requests, read and write, on this repository only).");
2167
- const slug = e.slug || explorationSlug(e.name);
2168
- const branch = `${EXPLORATION_PREFIX}${slug}`;
2167
+ const slug2 = e.slug || explorationSlug(e.name);
2168
+ const branch = `${EXPLORATION_PREFIX}${slug2}`;
2169
2169
  const x = gh.withBranchPrefix(EXPLORATION_PREFIX);
2170
- if (await x.getBranchSha(branch)) throw new GitHubError(422, `An exploration named "${slug}" already exists (${branch}). Pick another name, or continue that one.`);
2171
- const full = { ...e, slug, startedAt: e.startedAt ?? (/* @__PURE__ */ new Date()).toISOString() };
2170
+ if (await x.getBranchSha(branch)) throw new GitHubError(422, `An exploration named "${slug2}" already exists (${branch}). Pick another name, or continue that one.`);
2171
+ const full = { ...e, slug: slug2, startedAt: e.startedAt ?? (/* @__PURE__ */ new Date()).toISOString() };
2172
2172
  const commit = await x.commitToNewBranch({
2173
2173
  base: s.base,
2174
2174
  branch,
@@ -2177,7 +2177,7 @@ async function startExplorationOnGitHub(gh, e, s) {
2177
2177
  ${full.purpose.trim()}
2178
2178
 
2179
2179
  Exploration: never merged as is. Promote it to review or close it.`,
2180
- files: [{ path: explorationNotePath(slug), content: explorationNote(full) }]
2180
+ files: [{ path: explorationNotePath(slug2), content: explorationNote(full) }]
2181
2181
  });
2182
2182
  const ctx = { owner: gh.owner, repo: gh.name, packages: s.packages, apps: s.apps, ...s.requests?.length ? { requests: s.requests } : {} };
2183
2183
  const title = full.jira ? `${full.jira.trim().toUpperCase()} ${explorationPrTitle(full)}` : explorationPrTitle(full);
@@ -2186,7 +2186,7 @@ Exploration: never merged as is. Promote it to review or close it.`,
2186
2186
  await x.updatePullRequest(pr.number, { body: explorationPrBody(full, { ...ctx, pr: pr.number }) }).catch(() => void 0);
2187
2187
  return {
2188
2188
  branch,
2189
- slug,
2189
+ slug: slug2,
2190
2190
  pr: pr.number,
2191
2191
  url: pr.url,
2192
2192
  commit: commit.sha,
@@ -2664,8 +2664,8 @@ function colorDelta(a2, b) {
2664
2664
  const db2 = a2[2] - b[2];
2665
2665
  const y = dr2 * 0.29889531 + dg2 * 0.58662247 + db2 * 0.11448223;
2666
2666
  const i = dr2 * 0.59597799 - dg2 * 0.2741761 - db2 * 0.32180189;
2667
- const q = dr2 * 0.21147017 - dg2 * 0.52261711 + db2 * 0.31114694;
2668
- return 0.5053 * y * y + 0.299 * i * i + 0.1957 * q * q;
2667
+ const q2 = dr2 * 0.21147017 - dg2 * 0.52261711 + db2 * 0.31114694;
2668
+ return 0.5053 * y * y + 0.299 * i * i + 0.1957 * q2 * q2;
2669
2669
  }
2670
2670
  function foundNear(img, x, y, c, radius, max) {
2671
2671
  for (let dy2 = -radius; dy2 <= radius; dy2++) for (let dx2 = -radius; dx2 <= radius; dx2++) if (colorDelta(c, rgbAt(img, x + dx2, y + dy2)) <= max) return true;
@@ -2764,10 +2764,20 @@ function buildFidelityReport(input) {
2764
2764
  }
2765
2765
  const fmtPercent = (p2) => p2 >= 10 ? `${Math.round(p2)}%` : p2 >= 1 ? `${Math.round(p2 * 10) / 10}%` : p2 > 0 ? "under 1%" : "0%";
2766
2766
  const fmtSize = (s) => `${s.width}x${s.height}`;
2767
+ function sizeGap(s, tolerance = FIDELITY_DEFAULTS.sizeTolerance) {
2768
+ const r = (n) => Math.round(n);
2769
+ const parts = [];
2770
+ if (Math.abs(s.figma.width - s.code.width) > tolerance) parts.push(`width ${r(s.figma.width)} in Figma vs ${r(s.code.width)} in code`);
2771
+ if (Math.abs(s.figma.height - s.code.height) > tolerance) parts.push(`height ${r(s.figma.height)} in Figma vs ${r(s.code.height)} in code`);
2772
+ return parts.length ? parts.join(", ") : void 0;
2773
+ }
2767
2774
  function fidelityVerdict(v) {
2768
2775
  if (v.status === "skipped") return `Not compared: ${v.reason ?? "no image of the code"}`;
2769
2776
  if (v.status === "matches") return "Matches the code";
2770
- const parts = [`${fmtPercent(v.percent ?? 0)} of pixels`];
2777
+ const pixels = `${fmtPercent(v.percent ?? 0)} of pixels`;
2778
+ const gap = v.size ? sizeGap(v.size) : void 0;
2779
+ if (gap) return `Differs from the code: ${gap}, ${pixels}`;
2780
+ const parts = [pixels];
2771
2781
  if (v.size && !sameSize(v.size)) parts.push(`size ${fmtSize(v.size.figma)} vs ${fmtSize(v.size.code)}`);
2772
2782
  return `Differs from the code: ${parts.join(", ")}`;
2773
2783
  }
@@ -2920,9 +2930,9 @@ function planPopup(spec, variant) {
2920
2930
  };
2921
2931
  }
2922
2932
  function referenceImagePath(component, key2) {
2923
- const slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2924
- const file = key2.split(",").map((kv) => slug(kv)).filter(Boolean).join("__");
2925
- return `${slug(component)}/${file || "default"}.png`;
2933
+ const slug2 = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
2934
+ const file = key2.split(",").map((kv) => slug2(kv)).filter(Boolean).join("__");
2935
+ return `${slug2(component)}/${file || "default"}.png`;
2926
2936
  }
2927
2937
  function planReferences(file) {
2928
2938
  return file.components.flatMap(
@@ -2961,8 +2971,10 @@ function storyForVariant(spec, props, stories, shot) {
2961
2971
  }
2962
2972
  return order(ok).find(fits);
2963
2973
  }
2974
+ const ICON_LIBRARY = /^(lucide|heroicons?|phosphor|tabler|feather|material-?icons?|fa|fontawesome|svg)(?:$|[-_])/i;
2964
2975
  function partWords(part, id = part?.id ?? "") {
2965
2976
  if (id === "root") return "component";
2977
+ if (ICON_LIBRARY.test(part?.id ?? id)) return "icon";
2966
2978
  const base = (part?.id ?? id).replace(/^[a-z]{1,6}--/i, "").replace(/[-_]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").trim().toLowerCase();
2967
2979
  return base || (part?.name ?? id).toLowerCase();
2968
2980
  }
@@ -3226,6 +3238,8 @@ function gapSummary(component, variants, checked, fidelity) {
3226
3238
  if (!variants.length) return checked ? `${component} matches the code on ${checked} variant${checked === 1 ? "" : "s"}.` : `${component} has no variant to compare.`;
3227
3239
  const first2 = variants.flatMap((v) => v.differences)[0];
3228
3240
  const head = `${component} differs from the code on ${variants.length} of ${checked} variant${checked === 1 ? "" : "s"}`;
3241
+ const sized = variants.map((v) => v.size ? sizeGap(v.size) : void 0).find(Boolean);
3242
+ if (!first2 && sized) return `${head}: ${sized}.`;
3229
3243
  if (!first2) return variants.some((v) => (v.percent ?? 0) > UNMEASURED_PERCENT) ? `${head}: Bridge doesn't measure what differs here yet (the measured values agree, the images do not).` : `${head}: the measure agrees, compare the images.`;
3230
3244
  const more = variants.reduce((n, v) => n + v.differences.length, 0) - 1;
3231
3245
  return `${head}. ${first2.text}${more > 0 ? `, and ${more} more` : ""}.`;
@@ -3952,10 +3966,13 @@ function drawnAxes(axes, variants) {
3952
3966
  }
3953
3967
  function specsFromMeasure(file, opts = {}) {
3954
3968
  const known = opts.known ?? (() => true);
3969
+ const key2 = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
3970
+ const only = opts.only === void 0 ? void 0 : key2(opts.only);
3955
3971
  const groups = /* @__PURE__ */ new Map();
3956
3972
  for (const s of file.stories) {
3957
3973
  if (s.error || !s.spec) continue;
3958
3974
  const name = setNameOf$1(s.title);
3975
+ if (only !== void 0 && key2(name) !== only) continue;
3959
3976
  groups.set(name, [...groups.get(name) ?? [], s]);
3960
3977
  }
3961
3978
  const argTypesOf = (name) => Object.assign({}, ...(file.components ?? []).filter((c) => setNameOf$1(c.title) === name).map((c) => c.argTypes));
@@ -4048,7 +4065,7 @@ function figmaGaps(measured, run) {
4048
4065
  }
4049
4066
  function gapCaseFor(input) {
4050
4067
  const fixed = input.fixes ? applyFixes(input.measured, input.fixes).file : input.measured;
4051
- const { specs, shots } = specsFromMeasure(fixed);
4068
+ const { specs, shots } = specsFromMeasure(fixed, { only: input.component });
4052
4069
  const spec = specs.components.find((c) => lc(c.name) === lc(input.component));
4053
4070
  const fidelity = input.run?.report.components.find((c) => lc(c.component) === lc(input.component));
4054
4071
  const setShots = byName(shots, input.component) ?? {};
@@ -4110,10 +4127,10 @@ function tryFigmaFixes(input) {
4110
4127
  const before = gapCaseFor({ component, measured: input.measured, fixes: input.fixes, run: input.run });
4111
4128
  const afterRun = applyFixes(input.measured, file);
4112
4129
  const applied = afterRun.applied.filter((a2) => proposedIds.has(a2.id));
4113
- const afterBuilt = specsFromMeasure(afterRun.file);
4130
+ const afterBuilt = specsFromMeasure(afterRun.file, { only: component });
4114
4131
  const afterSpec = afterBuilt.specs.components.find((c) => lc(c.name) === lc(component));
4115
4132
  const hintsA = afterSpec ? afterBuilt.hints[afterSpec.name] : void 0;
4116
- const hintsB = before.spec ? specsFromMeasure(before.measured).hints[before.spec.name] : void 0;
4133
+ const hintsB = before.spec ? specsFromMeasure(before.measured, { only: before.spec.name }).hints[before.spec.name] : void 0;
4117
4134
  const resolve2 = measuredResolver(before.measured);
4118
4135
  const built = byName(input.run?.built, component);
4119
4136
  const stories = storiesOfComponent(before.measured, component);
@@ -4150,7 +4167,7 @@ function tryFigmaFixes(input) {
4150
4167
  verdict,
4151
4168
  referee: "values",
4152
4169
  variants,
4153
- summary: trySummary(component, before.gap, all, regressions, verdict, notFound, proposed),
4170
+ summary: trySummary(component, before.gap, all, regressions, verdict, notFound, proposed, variants.filter((v) => v.verdict === "gone").length),
4154
4171
  detail: tryDetail(variants, applied),
4155
4172
  file
4156
4173
  };
@@ -4284,17 +4301,22 @@ function sizeShift(field, specB, vb, specA, va, built, resolve2) {
4284
4301
  walk(root);
4285
4302
  return unknown ? void 0 : round(shift);
4286
4303
  }
4287
- function trySummary(component, gap, diffs, regressions, verdict, notFound, proposed) {
4304
+ function trySummary(component, gap, diffs, regressions, verdict, notFound, proposed, gone) {
4288
4305
  if (!gap.variants.length) return `${component} has no differing variant in the gap case: nothing for these fixes to move (the values referee needs a Check fidelity report or a difference in the measure).`;
4306
+ const absent = notFound.length ? ` ${notFound.map((a2) => a2.id).join(", ")} found nothing in the measure.` : "";
4307
+ if (!diffs.length && gone) {
4308
+ const n = gap.variants.length;
4309
+ const which = gone < n ? `${gone} of the ${n} differing variants are not` : n === 1 ? "the differing variant is not" : `none of the ${n} differing variants is`;
4310
+ return `The values referee compared nothing: ${which} in the rebuilt set.${absent} Pull this branch in the DS Bridge Figma plugin and run Check fidelity to see what the fixes do.`;
4311
+ }
4289
4312
  const resolved = diffs.filter((d) => d.result === "resolved").length;
4290
4313
  const closer = diffs.filter((d) => d.result === "closer").length;
4291
4314
  const worse = diffs.filter((d) => d.result === "worse").length;
4292
- const bits = [`${resolved} of ${diffs.length} difference${diffs.length === 1 ? "" : "s"} resolved`, ...closer ? [`${closer} closer`] : [], ...worse ? [`${worse} worse`] : [], ...regressions ? [`${regressions} new`] : []];
4315
+ const bits = [`${resolved} of ${diffs.length} difference${diffs.length === 1 ? "" : "s"} resolved`, ...closer ? [`${closer} closer`] : [], ...worse ? [`${worse} worse`] : [], ...regressions ? [`${regressions} new`] : [], ...gone ? [`${gone} not in the rebuilt set`] : []];
4293
4316
  const word = verdict === "closer" ? "Closer to the code" : verdict === "worse" ? "Further from the code" : "No closer to the code";
4294
4317
  const statusOnly = proposed.length > 0 && proposed.every((f) => f.kind === "status" || f.kind === "axis" && f.action === "map");
4295
- const missing = notFound.length ? ` ${notFound.map((a2) => a2.id).join(", ")} found nothing in the measure.` : "";
4296
4318
  const note = statusOnly && verdict === "same" ? " These fixes change how the set is named or labelled, not what it draws." : "";
4297
- return `${word} on the measured values: ${bits.join(", ")}.${missing}${note} The pixel check runs in the plugin after the next pull.`;
4319
+ return `${word} on the measured values: ${bits.join(", ")}.${absent}${note} The pixel check runs in the plugin after the next pull.`;
4298
4320
  }
4299
4321
  function tryDetail(variants, applied) {
4300
4322
  const fmt = (v) => v === null ? "none" : v === void 0 ? "unknown" : typeof v === "string" ? v : JSON.stringify(v);
@@ -4319,6 +4341,32 @@ function fixWords(f) {
4319
4341
  function touchesLayout(f) {
4320
4342
  return f.kind === "part" && (f.width !== void 0 || f.height !== void 0 || f.direction !== void 0 || f.align !== void 0 || f.overlay !== void 0);
4321
4343
  }
4344
+ const VARIANTS_INLINE = 8;
4345
+ const valueWords = (v) => v === null ? "none" : v === void 0 ? "unknown" : typeof v === "string" ? v : JSON.stringify(v);
4346
+ function triedHighlights(variants) {
4347
+ const groups = /* @__PURE__ */ new Map();
4348
+ for (const v of variants) {
4349
+ for (const d of v.differences) {
4350
+ const key2 = [d.part, d.property, valueWords(d.before), valueWords(d.expected), valueWords(d.after), d.result].join("|");
4351
+ const seen = groups.get(key2);
4352
+ if (seen) seen.n += 1;
4353
+ else groups.set(key2, { n: 1, d });
4354
+ }
4355
+ }
4356
+ return [...groups.values()].map(
4357
+ ({ n, d }) => `- ${d.part} ${d.property}, ${n === 1 ? "1 variant" : `${n} variants`}: ${valueWords(d.before)} in Figma against ${valueWords(d.expected)} in code, now ${valueWords(d.after)}: ${d.result}`
4358
+ );
4359
+ }
4360
+ function triedEvidence(variants) {
4361
+ const lines = variants.flatMap((v) => [
4362
+ `- ${v.key}: ${v.verdict === "gone" ? "not in the rebuilt set" : v.verdict}`,
4363
+ ...v.differences.map((d) => ` - ${d.text}: ${d.result}${d.deltaBefore !== void 0 ? ` (${d.deltaBefore} px, now ${d.deltaAfter ?? "?"} px${d.estimated ? ", estimated" : ""})` : ""}`),
4364
+ ...v.regressions.map((r) => ` - new difference: ${r.text}`)
4365
+ ]);
4366
+ if (variants.length <= VARIANTS_INLINE) return [...lines, ""];
4367
+ const highlights = triedHighlights(variants);
4368
+ return [...highlights.length ? [...highlights, ""] : [], "<details>", `<summary>Variant by variant (${variants.length})</summary>`, "", ...lines, "", "</details>", ""];
4369
+ }
4322
4370
  function figmaFixesPrBody(input) {
4323
4371
  const { tried } = input;
4324
4372
  const where = (f) => {
@@ -4345,13 +4393,9 @@ function figmaFixesPrBody(input) {
4345
4393
  "",
4346
4394
  tried.summary,
4347
4395
  "",
4348
- ...tried.variants.flatMap((v) => [
4349
- `- ${v.key}: ${v.verdict}`,
4350
- ...v.differences.map((d) => ` - ${d.text}: ${d.result}${d.deltaBefore !== void 0 ? ` (${d.deltaBefore} px, now ${d.deltaAfter ?? "?"} px${d.estimated ? ", estimated" : ""})` : ""}`),
4351
- ...v.regressions.map((r) => ` - new difference: ${r.text}`)
4352
- ]),
4353
- "",
4396
+ // The caveat is the reader's key to the section, so it comes before the evidence, not after it.
4354
4397
  ...tried.verdict === "same" && input.fixes.some(touchesLayout) ? ["These fixes size, place or lay out parts. The values referee can't judge layout, so it says same: Check fidelity decides.", ""] : [],
4398
+ ...triedEvidence(tried.variants),
4355
4399
  "The values referee compares the rebuilt set with what the code renders. The story shot is the final referee: pull this branch in the DS Bridge Figma plugin and run Check fidelity before approving. A fix stays only when the variant moved closer to its shot.",
4356
4400
  "",
4357
4401
  `Drafted by Claude through ${input.tool}. figma-fixes.json only: no component, token or plugin change.`
@@ -4402,6 +4446,345 @@ function statusFixFor(gap, existingIds = []) {
4402
4446
  const reason = `${gap.summary.replace(/\u2014/g, ",").replace(/\.$/, "")}. Claude found no fix that brings it closer in ${FIX_LOOP_MAX_ROUNDS} rounds.`;
4403
4447
  return { id, kind: "status", component: gap.component, status: "differs", reason, by: "claude" };
4404
4448
  }
4449
+ const DEFAULT_MEASURED_SPECS_FILE = "measured-specs.json";
4450
+ const FIGMA_FIXES_LABEL = "figma-fixes";
4451
+ const startFixLoop = (component) => ({ component, round: 0, attempts: [], done: false });
4452
+ async function fixLoopRound(input, state, ask, gap = gapCaseFor(input).gap) {
4453
+ if (state.done || state.round >= FIX_LOOP_MAX_ROUNDS) return { state: { ...state, done: true }, round: { round: state.round, fixes: [], summary: "No round left." } };
4454
+ const round2 = state.round + 1;
4455
+ const reply = await ask(fixPrompt(gap, state.attempts));
4456
+ const next = (attempt2, r2, extra = {}) => {
4457
+ const s = { ...state, ...extra, round: round2, attempts: [...state.attempts, attempt2] };
4458
+ if (s.round >= FIX_LOOP_MAX_ROUNDS) s.done = true;
4459
+ return { state: s, round: r2 };
4460
+ };
4461
+ let fixes;
4462
+ try {
4463
+ fixes = parseFixReply(reply);
4464
+ } catch (e) {
4465
+ const msg = e.message;
4466
+ return next({ fixes: [], feedback: `${msg} Answer with a JSON array of fix objects only.` }, { round: round2, fixes: [], summary: msg });
4467
+ }
4468
+ const tried = tryFigmaFixes({ ...input, proposed: fixes });
4469
+ if (tried.status === "invalid") return next({ fixes, feedback: `Invalid, fix these problems:
4470
+ ${tried.problems.join("\n")}` }, { round: round2, fixes, verdict: "invalid", summary: tried.summary });
4471
+ const r = { round: round2, fixes, verdict: tried.verdict, summary: tried.summary };
4472
+ const attempt = { fixes, feedback: `${tried.summary}
4473
+ ${tried.detail}`, verdict: tried.verdict };
4474
+ if (tried.verdict !== "closer") return next(attempt, r);
4475
+ const all = tried.variants.flatMap((v) => v.differences);
4476
+ const score = all.filter((d) => d.result === "resolved").length * 2 + all.filter((d) => d.result === "closer").length - tried.variants.reduce((n, v) => n + v.regressions.length, 0);
4477
+ const best = !state.best || score > state.best.score ? { fixes, score, summary: tried.summary } : state.best;
4478
+ const resolved = all.every((d) => d.result === "resolved");
4479
+ return next(attempt, r, { best, ...resolved ? { done: true } : {} });
4480
+ }
4481
+ function fixLoopOutcome(gap, state, existingIds = []) {
4482
+ if (state.best) return { kind: "fixes", fixes: state.best.fixes, summary: `Claude's fixes bring ${gap.component} closer to its story. ${state.best.summary}` };
4483
+ return {
4484
+ kind: "status",
4485
+ fixes: [statusFixFor(gap, existingIds)],
4486
+ summary: `No fix brought ${gap.component} closer to its story in ${FIX_LOOP_MAX_ROUNDS} rounds: it keeps an honest Differs status with the reason.`
4487
+ };
4488
+ }
4489
+ const slug = (s) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "component";
4490
+ const figmaFixesBranchStem = (config, component) => `${config.governance.branchPrefix}figma-fixes-${slug(component)}`;
4491
+ function figmaFixesProposal(input) {
4492
+ const { config } = input;
4493
+ const tried = tryFigmaFixes(input);
4494
+ if (tried.status === "invalid") throw new Error(`Not proposed: ${tried.problems.join("; ")}.`);
4495
+ const summary = (input.summary ?? "").trim();
4496
+ if (summary.length < 8) throw new Error("Not proposed: summary is one or two sentences a reviewer reads first (what the fixes do for the designer).");
4497
+ if (/—/.test(summary)) throw new Error("Not proposed: the summary uses an em dash: use a colon or a comma.");
4498
+ const ids = new Set(input.proposed.map((f) => f.id));
4499
+ const proposed = tried.file.fixes.filter((f) => ids.has(f.id));
4500
+ const { gap } = gapCaseFor(input);
4501
+ const drawing = proposed.some((f) => f.kind === "part" || f.kind === "story" || f.kind === "axis" && f.action !== "map");
4502
+ const measurable = gap.variants.some((v) => v.differences.length);
4503
+ if (tried.verdict === "worse" || drawing && measurable && tried.verdict === "same" && !proposed.some(touchesLayout)) {
4504
+ return {
4505
+ status: "blocked",
4506
+ verdict: tried.verdict,
4507
+ why: `${tried.summary} Bridge does not open fixes that move ${gap.component} ${tried.verdict === "worse" ? "further from" : "no closer to"} the code.`,
4508
+ detail: tried.detail,
4509
+ component: gap.component
4510
+ };
4511
+ }
4512
+ const content = `${JSON.stringify(tried.file, null, 2)}
4513
+ `;
4514
+ const fileContents = [{ path: input.fixesPath, content }];
4515
+ const risk = classifyRisk({ files: [{ path: input.fixesPath, status: input.fixes ? "modified" : "added" }], config });
4516
+ const prBody = `${figmaFixesPrBody({ component: gap.component, summary, gap, tried, fixes: proposed, tool: input.tool })}
4517
+
4518
+ Risk: ${risk.label}.`;
4519
+ const title = `fix(figma): ${gap.component} drawn closer to its story`;
4520
+ const message = `${title}
4521
+
4522
+ ${summary}
4523
+
4524
+ Fixes: ${proposed.map((f) => f.id).join(", ")}. Drafted by Claude through ${input.tool}.`;
4525
+ const labels = [.../* @__PURE__ */ new Set([...config.governance.labels, `tier: ${risk.tier}`, `source: ${input.source}`, FIGMA_FIXES_LABEL, DRAFTED_BY_CLAUDE_LABEL])];
4526
+ const report = { component: gap.component, verdict: tried.verdict, summary: tried.summary, variants: tried.variants, fixes: proposed.map((f) => f.id), tier: risk.tier, prTitle: title };
4527
+ return { status: "ready", report, fixes: proposed, labels, prBody, fileContents, title, message, draft: risk.tier >= 2, base: baseBranchOf(config), branchStem: figmaFixesBranchStem(config, gap.component) };
4528
+ }
4529
+ const MEASURE_BRANCH = REQUESTS_BRANCH;
4530
+ const MEASURED_SHOTS_DIR = "measured-shots";
4531
+ const MEASURE_WORKFLOW_FILE = ".github/workflows/bridge-measure.yml";
4532
+ const MEASURE_SETUP_ACTION = "Set up automatic measure";
4533
+ const MEASURE_MISSING_TEXT = `Bridge hasn't measured your components yet. A developer turns it on once: ${MEASURE_SETUP_ACTION}.`;
4534
+ function measureSetupSteps(repo) {
4535
+ return [
4536
+ `${MEASURE_SETUP_ACTION}${repo ? ` for ${repo}` : ""}, once:`,
4537
+ `- In Bridge Studio: Settings, For developers, ${MEASURE_SETUP_ACTION}. It opens a pull request that adds ${MEASURE_WORKFLOW_FILE}.`,
4538
+ `- Or in the repository: npx @bridge-ds/cli measure setup, then commit ${MEASURE_WORKFLOW_FILE}.`,
4539
+ `Once it is merged, the workflow measures the Storybook each time it changes and publishes ${DEFAULT_MEASURED_SPECS_FILE} to the ${MEASURE_BRANCH} branch.`
4540
+ ];
4541
+ }
4542
+ async function findMeasure(files, path = DEFAULT_MEASURED_SPECS_FILE) {
4543
+ const local = await files.repo(path);
4544
+ if (local) return { text: local, path };
4545
+ if (!files.branch) return void 0;
4546
+ const remote = await files.branch(path, MEASURE_BRANCH).catch(() => void 0);
4547
+ return remote ? { text: remote, path, branch: MEASURE_BRANCH } : void 0;
4548
+ }
4549
+ const measureFromWords = (m) => m.branch ? `${m.path} on ${m.branch}` : m.path;
4550
+ const measureDir = (path) => path.includes("/") ? path.replace(/\/[^/]*$/, "") : "";
4551
+ class MeasureMissingError extends Error {
4552
+ code = "measure-missing";
4553
+ steps;
4554
+ constructor(repo, extra = []) {
4555
+ const steps = [...measureSetupSteps(repo), ...extra];
4556
+ super([MEASURE_MISSING_TEXT, "", ...steps].join("\n"));
4557
+ this.name = "MeasureMissingError";
4558
+ this.steps = steps;
4559
+ }
4560
+ }
4561
+ const MEASURE_CLI_PACKAGE = "@bridge-ds/cli@^0.13.0";
4562
+ const MEASURE_FLAGS = "--variants --states rest,hover,active,disabled --tokens --shots --check";
4563
+ const MEASURE_DEFAULT_PATHS = ["src/**", "packages/**", ".storybook/**", "package.json", "package-lock.json"];
4564
+ function measureWorkflowOptionsFromConfig(config) {
4565
+ const c = config && typeof config === "object" ? config : {};
4566
+ const str2 = (v) => typeof v === "string" && v.trim() ? v.trim() : void 0;
4567
+ const storybook = str2(c.previews?.production?.storybook);
4568
+ const dir = str2(c.components?.dir)?.replace(/^\.?\/+|\/+$/g, "");
4569
+ const tokens = str2(c.tokens?.root)?.replace(/^\.?\/+|\/+$/g, "");
4570
+ const source = dir ? dir.includes("/") ? dir.replace(/\/[^/]*$/, "") : dir : void 0;
4571
+ const paths = [.../* @__PURE__ */ new Set([...source ? [`${source}/**`] : [], ...tokens ? [`${tokens}/**`] : [], ".storybook/**", "package.json", "package-lock.json"])];
4572
+ return {
4573
+ ...str2(c.repo?.defaultBranch) ? { defaultBranch: str2(c.repo?.defaultBranch) } : {},
4574
+ ...storybook && /^https:\/\//.test(storybook) ? { storybookUrl: storybook } : {},
4575
+ ...source || tokens ? { paths } : {}
4576
+ };
4577
+ }
4578
+ const q = (s) => `'${s.replace(/'/g, "''")}'`;
4579
+ const MEASURE_WORKFLOW_HEADER = `# Bridge measure: keeps the measure of your components fresh, so Claude can fix what differs in Figma.
4580
+ # Copy it to ${MEASURE_WORKFLOW_FILE} in your design system repository, or let Bridge add it: Studio, Settings,
4581
+ # For developers, Set up automatic measure (a pull request), or \`npx @bridge-ds/cli measure setup\`.
4582
+ #
4583
+ # It measures what your Storybook really draws (\`bridge specs --measure\`, headless Chrome): every variant at rest, on
4584
+ # hover, pressed and disabled, the CSS variables behind each value, and a screenshot of each. It publishes
4585
+ # ${DEFAULT_MEASURED_SPECS_FILE} and ${MEASURED_SHOTS_DIR}/ to the \`${MEASURE_BRANCH}\` branch, next to figma-fidelity.json (the Figma plugin's
4586
+ # Compare with code). The Claude fix tools, the Figma plugin ("Ask Claude to fix it") and Studio read it there.
4587
+ # It commits only when the measure changed.
4588
+ #
4589
+ # When: after each deploy of your Storybook (deployed Storybook), or on each push to the default branch that changes it
4590
+ # (built here), every Monday as a fallback, and by hand (Actions, Bridge measure, Run workflow).
4591
+ #
4592
+ # Token: only the GITHUB_TOKEN of this run, with \`contents: write\` to push the \`${MEASURE_BRANCH}\` branch. Your
4593
+ # default branch is never written. No secret to add.
4594
+ # A Storybook behind a login: set it up without an address (\`npx @bridge-ds/cli measure setup --build\`), the run then
4595
+ # builds Storybook itself. If installing needs a private registry, add an NPM_TOKEN repository secret (optional); the
4596
+ # install step passes it as NODE_AUTH_TOKEN.
4597
+ # Docs: https://bridge.floriangouloubi.com/docs/automatic-measure/`;
4598
+ function measureWorkflowYaml(o = {}) {
4599
+ const branch = o.defaultBranch?.trim() || "main";
4600
+ const url = o.storybookUrl?.trim().replace(/\/+$/, "") ?? "";
4601
+ const deployed = Boolean(url);
4602
+ const deployName = (o.deployName?.trim() || "storybook").toLowerCase();
4603
+ const paths = o.paths?.length ? o.paths : MEASURE_DEFAULT_PATHS;
4604
+ const install = o.install?.trim() || "npm ci";
4605
+ const build = o.buildCommand?.trim() || "npm run build-storybook";
4606
+ const dir = o.storybookDir?.trim().replace(/\/+$/, "") || "storybook-static";
4607
+ const cli = o.cli?.trim() || `npx --yes ${MEASURE_CLI_PACKAGE}`;
4608
+ const node = o.node?.trim() || "20";
4609
+ const nodeLine = node.startsWith("file:") ? `node-version-file: ${node.slice(5)}` : `node-version: ${q(node)}`;
4610
+ const pathList = paths.map((p2) => ` - ${q(p2)}`).join("\n");
4611
+ const deployIf = `(github.event_name == 'status' && github.event.state == 'success' && contains(github.event.branches.*.name, github.event.repository.default_branch) && contains(github.event.context, ${q(deployName)})) || (github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success' && contains(github.event.deployment.environment, ${q(deployName)}) && !contains(github.event.deployment.environment, 'preview'))`;
4612
+ const triggers = deployed ? `on:
4613
+ # After each successful deploy of the Storybook from the default branch (Vercel and Netlify report it as a commit
4614
+ # status, others as a GitHub deployment).
4615
+ status:
4616
+ deployment_status:
4617
+ schedule:
4618
+ - cron: '17 5 * * 1' # Mondays, a fallback
4619
+ workflow_dispatch:` : `on:
4620
+ push:
4621
+ branches: [${branch}]
4622
+ # What changes the Storybook: a push touching these measures again.
4623
+ paths:
4624
+ ${pathList}
4625
+ schedule:
4626
+ - cron: '17 5 * * 1' # Mondays, a fallback
4627
+ workflow_dispatch:`;
4628
+ const jobIf = deployed ? ` # A manual run from another branch would measure another branch. A deploy: the Storybook's, from the default branch.
4629
+ if: >-
4630
+ (github.event_name == 'schedule')
4631
+ || (github.event_name == 'workflow_dispatch' && github.ref_name == github.event.repository.default_branch)
4632
+ || ${deployIf}` : ` # A manual run from another branch would measure another branch.
4633
+ if: github.event_name != 'workflow_dispatch' || github.ref_name == github.event.repository.default_branch`;
4634
+ const changedGuard = deployed ? `
4635
+ # A deploy runs on every change to the default branch: measure only when this one can change the Storybook.
4636
+ - name: Did the Storybook change?
4637
+ id: changed
4638
+ run: |
4639
+ if [ "$GITHUB_EVENT_NAME" = "status" ] || [ "$GITHUB_EVENT_NAME" = "deployment_status" ]; then
4640
+ if git rev-parse -q --verify HEAD^ > /dev/null && git diff --quiet HEAD^ HEAD -- ${paths.map(q).join(" ")}; then
4641
+ echo "Nothing that changes the Storybook in this deploy: the measure stays as it is."
4642
+ echo "skip=true" >> "$GITHUB_OUTPUT"
4643
+ fi
4644
+ fi
4645
+ ` : "";
4646
+ const whenStep = (s) => deployed ? s.replace(/^( {6}- name: .*\n)/, `$1 if: steps.changed.outputs.skip != 'true'
4647
+ `) : s;
4648
+ const storybookSteps = deployed ? "" : whenStep(` - name: Build Storybook
4649
+ run: ${build}
4650
+
4651
+ - name: Serve the build
4652
+ run: |
4653
+ python3 -m http.server 6006 --bind 127.0.0.1 --directory ${q(dir)} > /dev/null 2>&1 &
4654
+ for i in $(seq 1 30); do curl -sf http://127.0.0.1:6006/index.json > /dev/null && exit 0; sleep 1; done
4655
+ echo "Storybook did not answer on http://127.0.0.1:6006 (is ${dir} the build folder?)"; exit 1
4656
+
4657
+ `);
4658
+ const storybook = deployed ? url : "http://127.0.0.1:6006";
4659
+ const steps = ` - uses: actions/checkout@v4
4660
+ with:
4661
+ # A deploy status names its commit; other events run on the default branch head.
4662
+ ref: \${{ github.event.sha || github.sha }}
4663
+ fetch-depth: 2
4664
+ ${changedGuard}
4665
+ ${whenStep(` - name: Set up Node
4666
+ uses: actions/setup-node@v4
4667
+ with:
4668
+ ${nodeLine}
4669
+ cache: npm
4670
+ `)}
4671
+ ${whenStep(` - name: Install
4672
+ env:
4673
+ NODE_AUTH_TOKEN: \${{ secrets.NPM_TOKEN }}
4674
+ run: ${install}
4675
+ `)}${o.prepare ? `
4676
+ ${whenStep(` - name: Prepare
4677
+ run: ${o.prepare}
4678
+ `)}` : ""}
4679
+ ${storybookSteps}${whenStep(` - name: Measure the Storybook
4680
+ env:
4681
+ # ubuntu-latest ships Google Chrome; the measure drives it headless, no browser download.
4682
+ BRIDGE_CHROME_CHANNEL: chrome
4683
+ run: |
4684
+ set -o pipefail
4685
+ ${cli} specs --measure --storybook "$STORYBOOK_URL" ${MEASURE_FLAGS} --out "$RUNNER_TEMP/bridge-measure/${DEFAULT_MEASURED_SPECS_FILE}" | tail -n 40 | tee -a "$GITHUB_STEP_SUMMARY"
4686
+ `)}
4687
+ ${whenStep(` - name: Publish to the ${MEASURE_BRANCH} branch, if the measure changed
4688
+ env:
4689
+ OUT: \${{ runner.temp }}/bridge-measure
4690
+ run: |
4691
+ set -euo pipefail
4692
+ git config --global user.name "github-actions[bot]"
4693
+ git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
4694
+ dir="$RUNNER_TEMP/measure-branch"
4695
+ if git ls-remote --exit-code --heads origin "$MEASURE_BRANCH" > /dev/null; then
4696
+ git fetch -q --depth 1 origin "$MEASURE_BRANCH"
4697
+ git worktree add -q --detach "$dir" FETCH_HEAD
4698
+ else
4699
+ # Like the Figma plugin: the requests branch starts from the default branch.
4700
+ git worktree add -q --detach "$dir" HEAD
4701
+ fi
4702
+ # The same measure at another time is not a change: compare without the timestamps.
4703
+ same() { node -e 'const f=require("fs");const r=(p)=>{try{const j=JSON.parse(f.readFileSync(p,"utf8"));delete j.measuredAt;delete j.createdAt;return JSON.stringify(j)}catch{return null}};const a=r(process.argv[1]);process.exit(a!==null&&a===r(process.argv[2])?0:1)' "$1" "$2"; }
4704
+ if same "$dir/${DEFAULT_MEASURED_SPECS_FILE}" "$OUT/${DEFAULT_MEASURED_SPECS_FILE}" && { [ ! -f "$OUT/${MEASURED_SHOTS_DIR}/manifest.json" ] || same "$dir/${MEASURED_SHOTS_DIR}/manifest.json" "$OUT/${MEASURED_SHOTS_DIR}/manifest.json"; }; then
4705
+ echo "The measure did not change: nothing to publish." | tee -a "$GITHUB_STEP_SUMMARY"
4706
+ exit 0
4707
+ fi
4708
+ rm -rf "$dir/${DEFAULT_MEASURED_SPECS_FILE}" "$dir/${MEASURED_SHOTS_DIR}"
4709
+ cp "$OUT/${DEFAULT_MEASURED_SPECS_FILE}" "$dir/"
4710
+ if [ -d "$OUT/${MEASURED_SHOTS_DIR}" ]; then cp -R "$OUT/${MEASURED_SHOTS_DIR}" "$dir/"; fi
4711
+ cd "$dir"
4712
+ git add -A
4713
+ git commit -qm "bridge measure: \${GITHUB_SHA:0:7}"
4714
+ # The Figma plugin writes to this branch too: on a race, rebase and retry.
4715
+ for i in 1 2 3 4; do
4716
+ if git push -q origin "HEAD:refs/heads/$MEASURE_BRANCH"; then echo "Published to $MEASURE_BRANCH." | tee -a "$GITHUB_STEP_SUMMARY"; exit 0; fi
4717
+ sleep $((i * 3))
4718
+ git fetch -q --depth 20 origin "$MEASURE_BRANCH" && git rebase -q FETCH_HEAD
4719
+ done
4720
+ exit 1
4721
+ `)}`;
4722
+ return `${o.header ?? MEASURE_WORKFLOW_HEADER}
4723
+
4724
+ name: Bridge measure
4725
+
4726
+ ${triggers}
4727
+
4728
+ concurrency:
4729
+ # One measure at a time; a newer one replaces a waiting one.
4730
+ group: bridge-measure
4731
+ cancel-in-progress: false
4732
+
4733
+ permissions:
4734
+ contents: write # push to the ${MEASURE_BRANCH} branch only
4735
+
4736
+ env:
4737
+ MEASURE_BRANCH: ${MEASURE_BRANCH}
4738
+ # ${deployed ? "The deployed Storybook the measure reads." : "Storybook as this run builds and serves it (below)."}
4739
+ STORYBOOK_URL: ${q(storybook)}
4740
+
4741
+ jobs:
4742
+ measure:
4743
+ name: Measure the Storybook
4744
+ ${jobIf}
4745
+ runs-on: ubuntu-latest
4746
+ timeout-minutes: 120
4747
+ steps:
4748
+ ${steps.replace(/\n{3,}/g, "\n\n").replace(/\n+$/, "")}
4749
+ `;
4750
+ }
4751
+ const leadsPublishTier1On = (gov) => gov?.leadsPublishTier1 !== false;
4752
+ const CODE_TIER1 = [/\.stories\.[cm]?[jt]sx?$/, /\.test\.[cm]?[jt]sx?$/];
4753
+ function tier1Domain(paths) {
4754
+ return paths.some((p2) => CODE_TIER1.some((r) => r.test(p2))) ? "tech" : "design";
4755
+ }
4756
+ const norm = (x) => x.trim().replace(/^@/, "").toLowerCase();
4757
+ function canPublishTier1(x) {
4758
+ if (!x.enabled || x.tier !== 1 || !x.viewer) return false;
4759
+ if (x.admin) return true;
4760
+ const list = x.domain === "design" ? x.approvers.design : x.approvers.tech;
4761
+ return list.some((l) => !l.includes("/") && norm(l) === norm(x.viewer));
4762
+ }
4763
+ const PUBLISH_LABEL = "Publish";
4764
+ const TIER1_PUBLISH_HEADING = "**Bridge: published without review (Tier 1)**";
4765
+ const publishedWithoutReview = (name) => `Published by ${name.trim() || "a lead"} without review (Tier 1).`;
4766
+ function tier1PublishReviewBody(name, login) {
4767
+ return `${TIER1_PUBLISH_HEADING}
4768
+
4769
+ ${publishedWithoutReview(name)} @${norm(login)} leads this part of the design system and the team lets leads publish Tier 1 changes (governance.leadsPublishTier1). It merges once the automatic checks pass; a failing check sends it to review instead.`;
4770
+ }
4771
+ function tier1PublishedBy(body) {
4772
+ if (!body || !body.trimStart().startsWith(TIER1_PUBLISH_HEADING)) return null;
4773
+ const m = /Published by (.+?) without review \(Tier 1\)\./.exec(body);
4774
+ return m ? m[1] : null;
4775
+ }
4776
+ function tier1PublishOf(reviews, headSha) {
4777
+ for (const r of [...reviews ?? []].reverse()) {
4778
+ if (r.state !== "APPROVED") continue;
4779
+ if (headSha && r.commit_id && r.commit_id !== headSha) continue;
4780
+ const by3 = tier1PublishedBy(r.body);
4781
+ if (by3) return by3;
4782
+ }
4783
+ return null;
4784
+ }
4785
+ function tier1PublishSentence(enabled) {
4786
+ return enabled ? "Tier 1 (docs, guidance, token descriptions, story and test fixes): team admins and the reviewers of that part publish it without review; Bridge merges it once the checks pass." : "Tier 1 needs one owner approval: leads publishing small changes without review is off.";
4787
+ }
4405
4788
  const plural = (n, one, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
4406
4789
  const names$1 = (files) => files.flatMap((f) => f.previous_filename ? [f.filename, f.previous_filename] : [f.filename]);
4407
4790
  function overlap(changeFiles, libraryFiles, isTokenFile) {
@@ -4939,15 +5322,15 @@ function planTokenProposal(input) {
4939
5322
  const tier = classifyLayered(changes, [], config);
4940
5323
  const summary = input.summary?.trim() || input.title;
4941
5324
  const body = [composeProposalBody({ summary, changes, contrast, impact, tier, validationErrors: newErrors.length, tool: input.tool ?? "Bridge MCP", ...input.fromFigma ? { fromFigma: true } : {} }), ...input.bodyExtra ?? []].filter(Boolean).join("\n\n");
4942
- const slug = slugify(input.title, 48);
4943
- const changesetPath = `${config.changesets?.dir ?? ".changeset"}/bridge-${slug}.md`;
5325
+ const slug2 = slugify(input.title, 48);
5326
+ const changesetPath = `${config.changesets?.dir ?? ".changeset"}/bridge-${slug2}.md`;
4944
5327
  const touched = r.touched.map((f) => after.repoPath(f));
4945
5328
  const files = [
4946
5329
  ...r.touched.map((f) => ({ path: after.repoPath(f), content: after.files.get(f) })),
4947
5330
  ...config.changesets ? [{ path: changesetPath, content: formatChangeset(config.changesets.package, tier.bump, summary) }] : []
4948
5331
  ];
4949
5332
  const blocked = newErrors.length || newFailures.length ? [newErrors.length ? `${newErrors.length} new validation error(s)` : "", newFailures.length ? `${newFailures.length} contrast pair(s) would fail` : ""].filter(Boolean).join(" and ") : null;
4950
- return { title: input.title, summary, edits: input.edits, before, after, changes, tier, contrast, newFailures, newErrors, impact, notes: r.notes, touched, files, body, slug, blocked };
5333
+ return { title: input.title, summary, edits: input.edits, before, after, changes, tier, contrast, newFailures, newErrors, impact, notes: r.notes, touched, files, body, slug: slug2, blocked };
4951
5334
  }
4952
5335
  async function writeTokenProposalOnGitHub(gh, plan, opts) {
4953
5336
  if (plan.blocked) throw new Error(`Not opened: ${plan.blocked}. Bridge never opens a branch that breaks the gate.`);
@@ -5656,6 +6039,7 @@ function siteRepoFromConfig(config, raw, fallback = REPO_MODEL_DEFAULTS.repo) {
5656
6039
  override: g.override ? { ...g.override } : { ...DEFAULT_OVERRIDE },
5657
6040
  rights: g.rights ?? null,
5658
6041
  soloOwnerCanApproveBoth: g.soloOwnerCanApproveBoth === true,
6042
+ leadsPublishTier1: g.leadsPublishTier1 !== false,
5659
6043
  visualImpact: { mode: config.visualImpact?.mode === "on-demand" ? "on-demand" : "auto" },
5660
6044
  tokensRoot: config.tokens.root,
5661
6045
  integrations: config.integrations ?? {},
@@ -6563,8 +6947,8 @@ function activityKey(url) {
6563
6947
  parts[2] = parts[2].toLowerCase();
6564
6948
  parts[3] = parts[3].toLowerCase();
6565
6949
  } else if (parts[1] === "users" && parts.length > 2) parts[2] = parts[2].toLowerCase();
6566
- const q = [...u.searchParams].sort(([a2, av2], [b, bv3]) => a2 === b ? av2 < bv3 ? -1 : 1 : a2 < b ? -1 : 1);
6567
- const search = q.length ? `?${new URLSearchParams(q).toString()}` : "";
6950
+ const q2 = [...u.searchParams].sort(([a2, av2], [b, bv3]) => a2 === b ? av2 < bv3 ? -1 : 1 : a2 < b ? -1 : 1);
6951
+ const search = q2.length ? `?${new URLSearchParams(q2).toString()}` : "";
6568
6952
  return parts.join("/") + search;
6569
6953
  }
6570
6954
  const KEPT_URLS = /* @__PURE__ */ new Set(["html_url", "avatar_url", "target_url", "details_url", "environment_url", "raw_url"]);
@@ -7386,8 +7770,8 @@ async function libraryArrivalOnGitHub(gh, n) {
7386
7770
  return libraryArrival({ state: pr.state, mergeable: pr.mergeable, ci: ci3, changesRequested: approvals.changesRequested.length });
7387
7771
  }
7388
7772
  export {
7389
- am as AAA_MIN,
7390
- an as AA_MIN,
7773
+ an as AAA_MIN,
7774
+ ao as AA_MIN,
7391
7775
  ACTIVITY_FILE,
7392
7776
  ACTIVITY_LIMITS,
7393
7777
  ACTIVITY_MAX_AGE_MS,
@@ -7410,7 +7794,7 @@ export {
7410
7794
  aE2 as BULK_LIMIT,
7411
7795
  CANT_CHECK_COPY,
7412
7796
  CHANGELOG_DETAIL_MAX,
7413
- ao as CHANGES_MODES,
7797
+ ap as CHANGES_MODES,
7414
7798
  aF2 as CI_STATE_LABEL,
7415
7799
  COLOR_FIELDS,
7416
7800
  COMBINE_COMPARE_LIMIT,
@@ -7418,21 +7802,22 @@ export {
7418
7802
  aG2 as COMPONENT_SPECS_VERSION,
7419
7803
  CONFIG_FILE,
7420
7804
  aH2 as CONFLICT_REASON,
7421
- ap as CONTRAST_CELL_MAX,
7422
- aq as CONTRAST_CHECKS_FILE,
7805
+ aq as CONTRAST_CELL_MAX,
7806
+ ar as CONTRAST_CHECKS_FILE,
7423
7807
  CONTRAST_THRESHOLDS,
7424
7808
  ConfigError,
7425
7809
  DEFAULT_CHANGES_MODE,
7426
7810
  aI2 as DEFAULT_COMPONENT_SPECS_FILE,
7427
7811
  DEFAULT_FIDELITY_RUN_FILE,
7428
7812
  DEFAULT_FIGMA_FIXES_FILE,
7429
- ar as DEFAULT_GOVERNANCE,
7813
+ as as DEFAULT_GOVERNANCE,
7814
+ DEFAULT_MEASURED_SPECS_FILE,
7430
7815
  DEFAULT_OVERRIDE,
7431
7816
  DEFAULT_PRODUCTS,
7432
7817
  aJ2 as DEFAULT_PROTECTED_BRANCHES,
7433
- as as DEFAULT_RIGHTS,
7818
+ at as DEFAULT_RIGHTS,
7434
7819
  DEFAULT_TOKEN_PATHS,
7435
- at as DEFAULT_VISUAL_IMPACT,
7820
+ au as DEFAULT_VISUAL_IMPACT,
7436
7821
  DEMO_RELEASES,
7437
7822
  aK2 as DOCS_CHANGE_BUMP,
7438
7823
  aL2 as DOCS_CLI_ORIGIN,
@@ -7452,7 +7837,7 @@ export {
7452
7837
  DRAFT_SUMMARY_SENTENCES,
7453
7838
  DRAFT_TITLE_MAX,
7454
7839
  DRAFT_VOICE_RULES,
7455
- au as DTCG_TYPES,
7840
+ av as DTCG_TYPES,
7456
7841
  DraftPoller,
7457
7842
  aP2 as EXPLORATION_CHECK,
7458
7843
  EXPLORATION_LABEL,
@@ -7465,6 +7850,7 @@ export {
7465
7850
  EXT_SCOPES,
7466
7851
  FIDELITY_DEFAULTS,
7467
7852
  FIGMA_FILL_WIDTH_TOKEN,
7853
+ FIGMA_FIXES_LABEL,
7468
7854
  FIGMA_FIXES_VERSION,
7469
7855
  FIGMA_REFERENCES_BRANCH,
7470
7856
  FIGMA_REFERENCES_DIR,
@@ -7482,30 +7868,41 @@ export {
7482
7868
  GitHubClient,
7483
7869
  GitHubError,
7484
7870
  HISTORY_MAX_CHANGES,
7485
- av as JsonParseError,
7871
+ aw as JsonParseError,
7486
7872
  LIGHTNESS,
7487
- aw as LINK_STATUS_TONE,
7873
+ ax as LINK_STATUS_TONE,
7488
7874
  LLMS_MAX_TOKENS,
7489
7875
  aU2 as LOOK_AGAIN_STATUS_LABEL,
7490
7876
  LayeredTokenSet,
7491
7877
  MAX_TOGETHER,
7878
+ MEASURED_SHOTS_DIR,
7879
+ MEASURE_BRANCH,
7880
+ MEASURE_CLI_PACKAGE,
7881
+ MEASURE_DEFAULT_PATHS,
7882
+ MEASURE_FLAGS,
7883
+ MEASURE_MISSING_TEXT,
7884
+ MEASURE_SETUP_ACTION,
7885
+ MEASURE_WORKFLOW_FILE,
7886
+ MEASURE_WORKFLOW_HEADER,
7492
7887
  MIN_TOGETHER,
7888
+ MeasureMissingError,
7493
7889
  aV2 as MeasuredSpecsError,
7494
7890
  NEEDED_BY_LABEL,
7495
7891
  NEUTRAL_ANCHORS,
7496
7892
  OVERRIDE_HEADING,
7497
- ax as OWNER_GROUPS,
7893
+ ay as OWNER_GROUPS,
7498
7894
  OverrideMergeError,
7499
7895
  PIECES_FILE_LIMIT,
7500
7896
  PIN_TOLERANCE,
7501
- ay as PREVIEW_APP_LABELS,
7502
- az as PREVIEW_COMMENT_MARKER,
7503
- aA as PREVIEW_PLACEHOLDERS,
7504
- aB as PRIMITIVE_MODE,
7505
- aC as PRODUCT_LABEL_PREFIX,
7897
+ az as PREVIEW_APP_LABELS,
7898
+ aA as PREVIEW_COMMENT_MARKER,
7899
+ aB as PREVIEW_PLACEHOLDERS,
7900
+ aC as PRIMITIVE_MODE,
7901
+ aD as PRODUCT_LABEL_PREFIX,
7506
7902
  PROSE_KEYS,
7507
7903
  PROTECTION_PARTS,
7508
7904
  PROTECTION_PART_PHRASE,
7905
+ PUBLISH_LABEL,
7509
7906
  PUBLISH_ROUTE_COPY,
7510
7907
  aW2 as PULL_STATE_PILL,
7511
7908
  aX2 as ProtectedBranchError,
@@ -7518,10 +7915,10 @@ export {
7518
7915
  aZ2 as REQUEST_STATUS_LABEL,
7519
7916
  a_2 as REVIEW_STATUS_LABEL,
7520
7917
  a$2 as REVIEW_STATUS_ORDER,
7521
- aD as RIGHTS,
7522
- aE as RIGHT_LABEL,
7918
+ aE as RIGHTS,
7919
+ aF as RIGHT_LABEL,
7523
7920
  RISK_LABELS,
7524
- aF as RISK_TIER,
7921
+ aG as RISK_TIER,
7525
7922
  SHARE_EXPLAIN,
7526
7923
  SIMILARITY_THRESHOLD,
7527
7924
  SINGLE_MODE,
@@ -7542,30 +7939,32 @@ export {
7542
7939
  b32 as SUGGESTION_KINDS,
7543
7940
  b42 as SUGGESTION_LABEL,
7544
7941
  b52 as SUGGESTION_LIMITS,
7545
- b62 as SUGGESTION_REVIEW_MARK,
7942
+ b62 as SUGGESTION_OVERRIDE_MARK,
7943
+ b72 as SUGGESTION_REVIEW_MARK,
7546
7944
  SUGGESTION_SCHEMA,
7547
- b72 as SUGGESTION_STATE_LABELS,
7548
- b82 as SUGGESTION_STATUS_LABEL,
7549
- b92 as SUGGESTION_STATUS_LABELS,
7550
- ba2 as SUGGESTION_TOO_LARGE,
7945
+ b82 as SUGGESTION_STATE_LABELS,
7946
+ b92 as SUGGESTION_STATUS_LABEL,
7947
+ ba2 as SUGGESTION_STATUS_LABELS,
7948
+ bb2 as SUGGESTION_TOO_LARGE,
7551
7949
  SnapshotError,
7552
- bb2 as StorybookIndexError,
7553
- bc2 as SuggestionError,
7554
- aG as TEAM_NAME_MAX,
7950
+ bc2 as StorybookIndexError,
7951
+ bd2 as SuggestionError,
7952
+ aH as TEAM_NAME_MAX,
7953
+ TIER1_PUBLISH_HEADING,
7555
7954
  TIER_AXIS,
7556
7955
  TIER_NAMES,
7557
- aH as TIER_ORDER,
7558
- bd2 as TOKEN_REJECTED_MESSAGE,
7559
- be2 as TOKEN_SETTINGS_URL,
7560
- bf2 as TRIGGER_LABELS,
7561
- aI as TeamDirectory,
7562
- bg2 as UNRELEASED,
7563
- aJ as VISUAL_CHECKS_DOCS,
7564
- aK as VISUAL_CHECK_LABEL,
7565
- aL as VISUAL_WORKFLOW_FILES,
7956
+ aI as TIER_ORDER,
7957
+ be2 as TOKEN_REJECTED_MESSAGE,
7958
+ bf2 as TOKEN_SETTINGS_URL,
7959
+ bg2 as TRIGGER_LABELS,
7960
+ aJ as TeamDirectory,
7961
+ bh2 as UNRELEASED,
7962
+ aK as VISUAL_CHECKS_DOCS,
7963
+ aL as VISUAL_CHECK_LABEL,
7964
+ aM as VISUAL_WORKFLOW_FILES,
7566
7965
  WAITING_FOR_CLAUDE_LABEL,
7567
- bh2 as acceptDocsDraft,
7568
- bi2 as acceptDocsText,
7966
+ bi2 as acceptDocsDraft,
7967
+ bj2 as acceptDocsText,
7569
7968
  accessAtLeast,
7570
7969
  accessState,
7571
7970
  activityAge,
@@ -7578,45 +7977,45 @@ export {
7578
7977
  activityTreeFilter,
7579
7978
  addBrandToConfigText,
7580
7979
  addedComment,
7581
- aM as affectedContrast,
7582
- aN as aliasOf,
7980
+ aN as affectedContrast,
7981
+ aO as aliasOf,
7583
7982
  aliasTarget,
7584
- bj2 as allowedMergeMethods,
7585
- bk2 as anatomyLabel,
7983
+ bk2 as allowedMergeMethods,
7984
+ bl2 as anatomyLabel,
7586
7985
  anchoredRamp,
7587
7986
  anthropicReplyText,
7588
7987
  anthropicRequest,
7589
- aO as appForProject,
7590
- aP as appUrl,
7988
+ aP as appForProject,
7989
+ aQ as appUrl,
7591
7990
  appliedFixLines,
7592
- bl2 as appliedStatus,
7991
+ bm2 as appliedStatus,
7593
7992
  applyConfirmedRenames,
7594
7993
  applyDocsSections,
7595
7994
  applyFixes,
7596
7995
  applyTokenEdits,
7597
7996
  applyTokenMerge,
7598
- bm2 as approvedSuggestionNumber,
7599
- bn2 as approvedSuggestionOnGitHub,
7600
- aQ as approverEntries,
7601
- aR as approverLists,
7997
+ bn2 as approvedSuggestionNumber,
7998
+ bo2 as approvedSuggestionOnGitHub,
7999
+ aR as approverEntries,
8000
+ aS as approverLists,
7602
8001
  askOthersToReviewOnGitHub,
7603
8002
  assembleBuildRequests,
7604
- bo2 as assertSafeBranch,
7605
- bp2 as assignRequestOnGitHub,
7606
- bq2 as assignVersions,
8003
+ bp2 as assertSafeBranch,
8004
+ bq2 as assignRequestOnGitHub,
8005
+ br2 as assignVersions,
7607
8006
  auditId,
7608
- br2 as base64ToUtf8,
7609
- aS as baseBranchOf,
8007
+ bs2 as base64ToUtf8,
8008
+ baseBranchOf,
7610
8009
  bellChroma,
7611
8010
  boundedCombos,
7612
8011
  aT as branchName,
7613
8012
  branchPreviewUrls,
7614
8013
  aU as branchSlug,
7615
- bs2 as branchVerdict,
8014
+ bt2 as branchVerdict,
7616
8015
  branchWithJiraKey,
7617
8016
  brandDisplayName,
7618
8017
  brandPreviewVariables,
7619
- bt2 as bridgeMcpInstallCommand,
8018
+ bu2 as bridgeMcpInstallCommand,
7620
8019
  buildFidelityReport,
7621
8020
  buildGapCase,
7622
8021
  buildHistoryEntry,
@@ -7631,30 +8030,31 @@ export {
7631
8030
  buildTokenSet,
7632
8031
  buildUsageIndex,
7633
8032
  canAddTo,
7634
- bu2 as canOverride,
8033
+ bv2 as canOverride,
8034
+ canPublishTier1,
7635
8035
  canShare,
7636
8036
  aV as canShip,
7637
- bv2 as canonicalJson,
8037
+ bw2 as canonicalJson,
7638
8038
  capHistory,
7639
8039
  changeEdits,
7640
8040
  aW as changeKind,
7641
8041
  changeList,
7642
- bw2 as changeTable,
8042
+ bx2 as changeTable,
7643
8043
  aX as changedModes,
7644
8044
  aY as changesMode,
7645
- bx2 as changesetBump,
8045
+ by2 as changesetBump,
7646
8046
  checkBrandSlug,
7647
8047
  checkLayeredPair,
7648
8048
  choiceFor,
7649
- by2 as classifyAuth,
8049
+ bz2 as classifyAuth,
7650
8050
  classifyLayered,
7651
8051
  classifyRisk,
7652
- bz2 as claudeStage,
7653
- bA2 as cleanDocs,
8052
+ bA2 as claudeStage,
8053
+ bB2 as cleanDocs,
7654
8054
  cleanDocsText,
7655
8055
  cleanDraftText,
7656
8056
  aZ as clearRawDeep,
7657
- bB2 as clearSharedEtags,
8057
+ bC2 as clearSharedEtags,
7658
8058
  closeExplorationOnGitHub,
7659
8059
  closeOnGitHub,
7660
8060
  closingIssueNumbers,
@@ -7670,61 +8070,62 @@ export {
7670
8070
  combineConflicts,
7671
8071
  b0 as comboKey,
7672
8072
  commentOnGitHub,
7673
- bC2 as commitFileOnGitHub,
8073
+ bD2 as commitFileOnGitHub,
7674
8074
  commitLibraryResolution,
7675
8075
  b1 as commitMessage,
7676
8076
  b2 as compactJson,
7677
8077
  compareImages,
7678
8078
  compareSpecToMeasured,
7679
- bD2 as componentContrastPairs,
8079
+ bE2 as componentContrastPairs,
7680
8080
  componentForPath,
7681
8081
  componentMotion,
7682
8082
  componentSlug,
7683
8083
  componentSpecSuggestionPayload,
7684
8084
  componentStatus,
7685
- bE2 as componentsUsingMotionToken,
8085
+ bF2 as componentsUsingMotionToken,
7686
8086
  composeBuildRequestIssue,
7687
- bF2 as composeChangeset,
8087
+ bG2 as composeChangeset,
7688
8088
  composeFiles,
7689
8089
  composeNewBrandBody,
7690
8090
  composePendingDrafts,
7691
8091
  b3 as composePrBody,
7692
8092
  composeProposalBody,
7693
8093
  composeRequestIssue,
7694
- bG2 as composeSuggestionAppliedComment,
7695
- bH2 as composeSuggestionIssue,
7696
- bI2 as composeSuggestionReviewComment,
8094
+ bH2 as composeSuggestionAppliedComment,
8095
+ bI2 as composeSuggestionIssue,
8096
+ bJ2 as composeSuggestionOverrideComment,
8097
+ bK2 as composeSuggestionReviewComment,
7697
8098
  b4 as composite,
7698
8099
  conflictRoute,
7699
8100
  b5 as contextFor,
7700
8101
  contextLabel,
7701
- bJ2 as continueDocsProposalOnGitHub,
8102
+ bL2 as continueDocsProposalOnGitHub,
7702
8103
  contrastDelta,
7703
- bK2 as contrastDeltaTable,
8104
+ bM2 as contrastDeltaTable,
7704
8105
  b6 as contrastLevel,
7705
8106
  b7 as contrastPair,
7706
8107
  b8 as contrastRatio,
7707
8108
  contrastScope,
7708
- bL2 as countChanges,
7709
- bM2 as coverageSummary,
8109
+ bN2 as countChanges,
8110
+ bO2 as coverageSummary,
7710
8111
  createBuildRequestOnGitHub,
7711
8112
  createDocsDraftSession,
7712
8113
  createPendingDrafts,
7713
8114
  createSuggestionOnGitHub,
7714
- bN2 as cssColorToRgb,
7715
- bO2 as cssColorsToRgb,
7716
- bP2 as cssModuleClasses,
8115
+ bP2 as cssColorToRgb,
8116
+ bQ2 as cssColorsToRgb,
8117
+ bR2 as cssModuleClasses,
7717
8118
  cssOf,
7718
8119
  cssVarOf,
7719
8120
  cssVarsIn,
7720
- bQ2 as declineComment,
7721
- bR2 as declineReasonProblems,
7722
- bS2 as declineRequestOnGitHub,
7723
- bT2 as declineSuggestionOnGitHub,
8121
+ bS2 as declineComment,
8122
+ bT2 as declineReasonProblems,
8123
+ bU2 as declineRequestOnGitHub,
8124
+ bV2 as declineSuggestionOnGitHub,
7724
8125
  decodePicks,
7725
8126
  defaultChoiceFor,
7726
8127
  b9 as defaultContext,
7727
- bU2 as defaultDocsFooter,
8128
+ bW2 as defaultDocsFooter,
7728
8129
  defaultFile,
7729
8130
  defaultModelConfig,
7730
8131
  defaultProduct,
@@ -7738,67 +8139,69 @@ export {
7738
8139
  bb as detectLayout,
7739
8140
  diffLayered,
7740
8141
  dismissStaleFrom,
7741
- bV2 as docsAuthorLine,
7742
- bW2 as docsFileText,
8142
+ bX2 as docsAuthorLine,
8143
+ bY2 as docsFileText,
7743
8144
  docsPrompt,
7744
- bX2 as docsProposal,
7745
- bY2 as docsSectionShapes,
8145
+ bZ2 as docsProposal,
8146
+ b_2 as docsSectionShapes,
7746
8147
  docsSectionsAnswer,
7747
8148
  docsSectionsResult,
7748
8149
  docsSelectionPrompt,
7749
- bZ2 as docsSlug,
7750
- b_2 as docsSuggestionPayload,
8150
+ b$2 as docsSlug,
8151
+ c02 as docsSuggestionPayload,
7751
8152
  docsTaskKeys,
7752
8153
  docsTaskPrompt,
7753
- b$2 as docsText,
7754
- c02 as draftChangeLine,
8154
+ c12 as docsText,
8155
+ c22 as draftChangeLine,
7755
8156
  draftImagePath,
7756
8157
  draftItemBrief,
7757
- c12 as draftPushDescription,
7758
- c22 as draftRequestText,
8158
+ c32 as draftPushDescription,
8159
+ c42 as draftRequestText,
7759
8160
  draftSessionPath,
7760
8161
  dtcgColor,
7761
8162
  durationValue,
7762
8163
  easingValue,
7763
8164
  effectiveScopes,
7764
8165
  effectiveTier,
7765
- c32 as eligibleReviewers,
8166
+ c52 as eligibleReviewers,
7766
8167
  emptyTokenFile,
7767
8168
  encodePicks,
7768
8169
  ensureRequestsBranch,
7769
8170
  bc as entriesFor,
7770
8171
  bd as entryLabel,
7771
- c42 as evalCalc,
8172
+ c62 as evalCalc,
7772
8173
  evaluateContrastPairs,
7773
8174
  evaluatePairs,
7774
8175
  be as expandEntries,
7775
8176
  bf as expandOwners,
7776
- c52 as explorationBranch,
8177
+ c72 as explorationBranch,
7777
8178
  explorationNote,
7778
8179
  explorationNotePath,
7779
8180
  explorationPrBody,
7780
8181
  explorationPrTitle,
7781
8182
  explorationProblems,
7782
- c62 as explorationRules,
7783
- c72 as explorationShareMessage,
8183
+ c82 as explorationRules,
8184
+ c92 as explorationShareMessage,
7784
8185
  explorationSlug,
7785
- c82 as explorationSlugFromBranch,
8186
+ ca2 as explorationSlugFromBranch,
7786
8187
  explorationStatus,
7787
8188
  explorationSummary,
7788
8189
  explorationTestBuildOnGitHub,
7789
8190
  explorationTryIt,
7790
8191
  explorationTryItOnGitHub,
7791
- c92 as fetchStorybookIndex,
8192
+ cb2 as fetchStorybookIndex,
7792
8193
  fidelityComponentLine,
7793
8194
  fidelityVerdict,
7794
8195
  bg as fieldChanges,
7795
8196
  figmaAheadLine,
7796
8197
  figmaBranchTitle,
7797
- ca2 as figmaCell,
8198
+ cc2 as figmaCell,
7798
8199
  figmaChangeOnGitHub,
7799
8200
  figmaDraftBody,
7800
8201
  figmaDraftBrief,
8202
+ figmaFixesBranchStem,
7801
8203
  figmaFixesPrBody,
8204
+ figmaFixesProposal,
7802
8205
  figmaGaps,
7803
8206
  figmaNodeUrl,
7804
8207
  figmaNodes,
@@ -7812,31 +8215,34 @@ export {
7812
8215
  figmaShipReviewBody,
7813
8216
  figmaSpecPath,
7814
8217
  figmaSpecSlug,
7815
- cb2 as fileModes,
7816
- cc2 as filterHistory,
8218
+ cd2 as fileModes,
8219
+ ce2 as filterHistory,
7817
8220
  findExplorationOnGitHub,
7818
- cd2 as findOpenDocsProposal,
7819
- ce2 as findOpenDocsProposalOnGitHub,
8221
+ findMeasure,
8222
+ cf2 as findOpenDocsProposal,
8223
+ cg2 as findOpenDocsProposalOnGitHub,
7820
8224
  findPreviewComment,
7821
8225
  bj as findProduct,
7822
8226
  findReferenceProblems,
7823
8227
  bk as findToken,
7824
8228
  bl as findVercelComment,
7825
- cf2 as firstParagraph,
8229
+ ch2 as firstParagraph,
7826
8230
  fitActivity,
8231
+ fixLoopOutcome,
8232
+ fixLoopRound,
7827
8233
  fixPrompt,
7828
8234
  fixWords,
7829
8235
  bm as flattenLayerFile,
7830
8236
  flattenTokenFile,
7831
8237
  flattenTokens,
7832
8238
  formatChangeset,
7833
- cg2 as formatDocsJson,
8239
+ ci2 as formatDocsJson,
7834
8240
  formatFigmaSpec,
7835
8241
  bn as formatNumber,
7836
8242
  bo as formatOwnerEntry,
7837
8243
  formatValue,
7838
8244
  freshness,
7839
- ch2 as friendlyMessage,
8245
+ cj2 as friendlyMessage,
7840
8246
  fromHex,
7841
8247
  bp as fromPlain,
7842
8248
  gapCaseFor,
@@ -7847,22 +8253,22 @@ export {
7847
8253
  gitBlobSha,
7848
8254
  gitHubHistoryBackend,
7849
8255
  gitHubSource,
7850
- ci2 as githubSuggestionWorkspace,
8256
+ ck2 as githubSuggestionWorkspace,
7851
8257
  globBase,
7852
8258
  globToRegExp,
7853
8259
  groupReleases,
7854
- cj2 as groupStorybookComponents,
8260
+ cl2 as groupStorybookComponents,
7855
8261
  bs as groupsPhrase,
7856
- ck2 as hasOwnerApproval,
7857
- cl2 as hasSuggestionBlock,
8262
+ cm2 as hasOwnerApproval,
8263
+ cn2 as hasSuggestionBlock,
7858
8264
  bt as hasVisualWorkflow,
7859
- cm2 as hasWriteAccess,
8265
+ co2 as hasWriteAccess,
7860
8266
  hashSpec,
7861
8267
  hexContrastRatio,
7862
8268
  hexLuminance,
7863
8269
  bu as hexToRgba,
7864
8270
  bv as holdersOf,
7865
- cn2 as iconComponentName,
8271
+ cp2 as iconComponentName,
7866
8272
  idExtensionFor,
7867
8273
  impactedModules,
7868
8274
  importsIn,
@@ -7870,55 +8276,56 @@ export {
7870
8276
  bx as inheritedTypeAt,
7871
8277
  by as installCommand,
7872
8278
  bz as installCommandFromPreviewComment,
7873
- co2 as installationFor,
7874
- cp2 as isActiveExploration,
8279
+ cq2 as installationFor,
8280
+ cr2 as isActiveExploration,
7875
8281
  isAlias$1 as isAlias,
7876
- cq2 as isAutomationPull,
8282
+ cs2 as isAutomationPull,
7877
8283
  isBuildRequestIssue,
7878
- cr2 as isDocsProposalBranch,
8284
+ ct2 as isDocsProposalBranch,
7879
8285
  isDocsSelectionMode,
7880
- cs2 as isDraft,
8286
+ cu2 as isDraft,
7881
8287
  isDraftSessionId,
7882
8288
  isExplorationBranch,
7883
8289
  isExplorationPull,
7884
8290
  isFigmaPush,
7885
8291
  isGuardrail,
7886
- ct2 as isGuardrailPath,
8292
+ cv2 as isGuardrailPath,
7887
8293
  isHex,
7888
- cu2 as isJiraKey,
7889
- cv2 as isMissingPermission,
8294
+ cw2 as isJiraKey,
8295
+ cx2 as isMissingPermission,
7890
8296
  isMultiMode,
7891
8297
  isPlanRefusal,
7892
- cw2 as isPlatformRefusal,
8298
+ cy2 as isPlatformRefusal,
7893
8299
  isProseKey,
7894
- cx2 as isReleasePull,
8300
+ cz2 as isReleasePull,
7895
8301
  bA as isTeamEntry,
7896
8302
  bB as isTokenFile,
7897
8303
  isTokenPath,
7898
- cy2 as isTokenRejected,
8304
+ cA2 as isTokenRejected,
7899
8305
  isTokenValueChange,
7900
8306
  isUnder,
7901
8307
  bC as isVercelComment,
7902
- cz2 as jiraIssueFields,
7903
- cA2 as jiraKeyOf,
8308
+ cB as jiraIssueFields,
8309
+ cC as jiraKeyOf,
7904
8310
  jiraKeyOfLabels,
7905
- cB as joinRepoPath,
8311
+ cD as joinRepoPath,
7906
8312
  bD as kindForMin,
7907
8313
  layeredImpact,
7908
8314
  bE as layeredParityIssues,
7909
8315
  layoutOptions,
8316
+ leadsPublishTier1On,
7910
8317
  levenshtein,
7911
8318
  libraryArrival,
7912
8319
  libraryArrivalOnGitHub,
7913
8320
  libraryBranchPlan,
7914
8321
  bF as libraryIsPublic,
7915
8322
  libraryPreviewState,
7916
- cC as linkRequestToExplorationOnGitHub,
8323
+ cE as linkRequestToExplorationOnGitHub,
7917
8324
  linkStatus,
7918
- cD as linkSuggestionPrOnGitHub,
8325
+ cF as linkSuggestionPrOnGitHub,
7919
8326
  linkedIssueNumbers,
7920
8327
  linkedLibraryBranchOnGitHub,
7921
- cE as linkedPullsOf,
8328
+ cG as linkedPullsOf,
7922
8329
  listBrands,
7923
8330
  listBuildRequestsOnGitHub,
7924
8331
  listExplorationsOnGitHub,
@@ -7929,37 +8336,42 @@ export {
7929
8336
  loadConfig,
7930
8337
  loadGitHubHistory,
7931
8338
  loadProtection,
7932
- cF as loadRepoFiles,
8339
+ cH as loadRepoFiles,
7933
8340
  loadRepoModel,
7934
8341
  loadRequiredChecks,
7935
8342
  localTryCommand,
7936
- cG as lookAgainReviewers,
7937
- cH as lowerFirstWord,
8343
+ cI as lookAgainReviewers,
8344
+ cJ as lowerFirstWord,
7938
8345
  bG as luminance,
7939
8346
  mailtoHref,
7940
8347
  mapPropsToFigma,
7941
8348
  markClaudeDraft,
7942
8349
  markFigmaChangeDraftedOnGitHub,
7943
- cI as markSuggestionsAppliedOnGitHub,
7944
- cJ as markUsedTokens,
8350
+ cK as markSuggestionsAppliedOnGitHub,
8351
+ cL as markUsedTokens,
7945
8352
  matchesBuildFilter,
7946
8353
  mayBeTokenValueChange,
8354
+ measureDir,
8355
+ measureFromWords,
8356
+ measureSetupSteps,
8357
+ measureWorkflowOptionsFromConfig,
8358
+ measureWorkflowYaml,
7947
8359
  measuredResolver,
7948
- cK as memoryEtagStore,
7949
- cL as memorySource,
8360
+ cM as memoryEtagStore,
8361
+ cN as memorySource,
7950
8362
  mergeDocsDraft,
7951
8363
  mergeDraftResults,
7952
8364
  mergeFigmaFixes,
7953
- cM as mergeGate,
8365
+ cO as mergeGate,
7954
8366
  mergeOnGitHub,
7955
8367
  mergePiecesRecord,
7956
8368
  mergeReleases,
7957
8369
  missingChoices,
7958
- cN as missingPermissionMessage,
7959
- cO as missingProse,
8370
+ cP as missingPermissionMessage,
8371
+ cQ as missingProse,
7960
8372
  modeDisplayName,
7961
8373
  modeFile,
7962
- cP as modeLabel,
8374
+ cR as modeLabel,
7963
8375
  modesOf$1 as modesOf,
7964
8376
  motionDocs,
7965
8377
  motionMoments,
@@ -7967,7 +8379,7 @@ export {
7967
8379
  bH as nearestQuestion,
7968
8380
  nearestStep,
7969
8381
  bI as neededBySection,
7970
- cQ as needsDocsReview,
8382
+ cS as needsDocsReview,
7971
8383
  neutralChroma,
7972
8384
  neutralOffset,
7973
8385
  newBrandSection,
@@ -7976,7 +8388,7 @@ export {
7976
8388
  bJ as nodesEqual,
7977
8389
  normalizeRepoPath,
7978
8390
  bK as normalizeRights,
7979
- cR as normalizeStorybookUrl,
8391
+ cT as normalizeStorybookUrl,
7980
8392
  noteSentences,
7981
8393
  oklch,
7982
8394
  oklchToLinear,
@@ -7984,30 +8396,31 @@ export {
7984
8396
  openBuildRequests,
7985
8397
  openComponentPushOnGitHub,
7986
8398
  openLibraryBranchOnGitHub,
7987
- cS as openPulls,
8399
+ cU as openPulls,
7988
8400
  overlap,
7989
8401
  overrideComment,
7990
- cT as overrideHolders,
8402
+ cV as overrideHolders,
7991
8403
  bL as overrideKey,
7992
8404
  overrideMergeOnGitHub,
7993
- cU as overrideReasonMin,
7994
- cV as overrideReasonProblem,
8405
+ cW as overrideReasonMin,
8406
+ cX as overrideReasonProblem,
7995
8407
  overrideRefusedComment,
8408
+ cY as overrideSuggestionOnGitHub,
7996
8409
  bM as ownerEntryProblems,
7997
- cW as ownerOverridePolicy,
8410
+ cZ as ownerOverridePolicy,
7998
8411
  packageDir,
7999
8412
  packageDirCandidates,
8000
8413
  bN as pairKey,
8001
8414
  pairParts,
8002
8415
  parentDir,
8003
8416
  parseActivity,
8004
- cX as parseBoxShadow,
8417
+ c_ as parseBoxShadow,
8005
8418
  parseBuildRequestIssue,
8006
8419
  parseBuildSpec,
8007
8420
  parseChangelog,
8008
8421
  parseChangelogSections,
8009
8422
  parseChangeset,
8010
- cY as parseChangesetText,
8423
+ c$ as parseChangesetText,
8011
8424
  parseColor,
8012
8425
  parseComponentCss,
8013
8426
  parseComponentFamilies,
@@ -8025,33 +8438,34 @@ export {
8025
8438
  parseFigmaOrigin,
8026
8439
  parseFigmaSpec,
8027
8440
  parseFixReply,
8028
- cZ as parseJiraKey,
8441
+ d0 as parseJiraKey,
8029
8442
  bP as parseJson,
8030
- c_ as parseMeasuredSpecsFile,
8443
+ d1 as parseMeasuredSpecsFile,
8031
8444
  parseModelConfig,
8032
8445
  bQ as parseNeededBy,
8033
- c$ as parseOverrideComment,
8446
+ d2 as parseOverrideComment,
8034
8447
  bR as parseOwnerEntry,
8035
8448
  parsePendingDrafts,
8036
8449
  parsePiecesRecord,
8037
- d0 as parseRepo,
8450
+ d3 as parseRepo,
8038
8451
  parseRequestIssue,
8039
8452
  parseSnapshot,
8040
- d1 as parseStorybookIndex,
8041
- d2 as parseStructureChange,
8042
- d3 as parseSuggestionAppliedComment,
8043
- d4 as parseSuggestionIssue,
8044
- d5 as parseSuggestionReviewComment,
8045
- d6 as parseTier,
8453
+ d4 as parseStorybookIndex,
8454
+ d5 as parseStructureChange,
8455
+ d6 as parseSuggestionAppliedComment,
8456
+ d7 as parseSuggestionIssue,
8457
+ d8 as parseSuggestionOverrideComment,
8458
+ d9 as parseSuggestionReviewComment,
8459
+ da as parseTier,
8046
8460
  parseTokenFile,
8047
8461
  bS as parseVercelComment,
8048
8462
  partLabel,
8049
8463
  partWords,
8050
- d7 as patchDocsJson,
8464
+ db as patchDocsJson,
8051
8465
  pathId,
8052
8466
  pathSimilarity,
8053
- d8 as pendingApprovals,
8054
- d9 as permissionLabel,
8467
+ dc as pendingApprovals,
8468
+ dd as permissionLabel,
8055
8469
  pickedOption,
8056
8470
  p as pieceId,
8057
8471
  bT as piecesSection,
@@ -8060,15 +8474,15 @@ export {
8060
8474
  planNewBrand,
8061
8475
  planReference,
8062
8476
  planReferences,
8063
- da as planRestore,
8064
- db as planRevert,
8065
- dc as planSuggestionApply,
8066
- dd as planToJson,
8477
+ de as planRestore,
8478
+ df as planRevert,
8479
+ dg as planSuggestionApply,
8480
+ dh as planToJson,
8067
8481
  planTokenMerge,
8068
8482
  planTokenProposal,
8069
8483
  planVariantMeasures,
8070
- de as prNumberFromSubject,
8071
- df as prefillDocs,
8484
+ di as prNumberFromSubject,
8485
+ dj as prefillDocs,
8072
8486
  bV as previewComment,
8073
8487
  previewLinks,
8074
8488
  bW as previewLinksOf,
@@ -8089,9 +8503,9 @@ export {
8089
8503
  promoteExplorationOnGitHub,
8090
8504
  promotionPlan,
8091
8505
  propertyWords,
8092
- dg as proposeDocsOnGitHub,
8506
+ dk as proposeDocsOnGitHub,
8093
8507
  a as proposedTokenPath,
8094
- dh as propsTable,
8508
+ dl as propsTable,
8095
8509
  protectLibrary,
8096
8510
  protectRefusal,
8097
8511
  c2 as protectedBranchesOf,
@@ -8100,9 +8514,10 @@ export {
8100
8514
  protectionSentence,
8101
8515
  protectionState,
8102
8516
  publishSummary,
8517
+ publishedWithoutReview,
8103
8518
  pullState,
8104
- di as pushChangeRows,
8105
- dj as rateLimitMessage,
8519
+ dm as pushChangeRows,
8520
+ dn as rateLimitMessage,
8106
8521
  readCombineBranch,
8107
8522
  readLibraryConflicts,
8108
8523
  readPendingDrafts,
@@ -8118,24 +8533,24 @@ export {
8118
8533
  referenceImagePath,
8119
8534
  releaseAnnouncement,
8120
8535
  releasePackagesLabel,
8121
- dk as releasePull,
8536
+ dp as releasePull,
8122
8537
  releasesFromTags,
8123
8538
  remoteRenames,
8124
8539
  removeToken,
8125
8540
  removedSide,
8126
8541
  c3 as renderedColor,
8127
- dl as reopenEligibility,
8542
+ dq as reopenEligibility,
8128
8543
  reopenOnGitHub,
8129
- dm as requestBrief,
8130
- dn as requestImagePath,
8544
+ dr as requestBrief,
8545
+ ds as requestImagePath,
8131
8546
  requestIssueTitle,
8132
8547
  requestStatus,
8133
- dp as requesterFirstName,
8134
- dq as requesterLine,
8135
- dr as requesterOf,
8136
- ds as requiredApprovals,
8548
+ dt as requesterFirstName,
8549
+ du as requesterLine,
8550
+ dv as requesterOf,
8551
+ dw as requiredApprovals,
8137
8552
  requiredCheckNames,
8138
- dt as requiredPermission,
8553
+ dx as requiredPermission,
8139
8554
  resolutionMessage,
8140
8555
  resolve,
8141
8556
  resolveBranchPreviews,
@@ -8143,11 +8558,11 @@ export {
8143
8558
  resolveRepoAccess,
8144
8559
  resolvedTokenFiles,
8145
8560
  reviewOnGitHub,
8146
- du as reviewQueue,
8147
- dv as reviewStatusKind,
8148
- dw as reviewStatusLabel,
8149
- dx as reviewSuggestionOnGitHub,
8150
- dy as reviewersToAsk,
8561
+ dy as reviewQueue,
8562
+ dz as reviewStatusKind,
8563
+ dA as reviewStatusLabel,
8564
+ dB as reviewSuggestionOnGitHub,
8565
+ dC as reviewersToAsk,
8151
8566
  c4 as rgbaToDtcg,
8152
8567
  rgbaToHex,
8153
8568
  c5 as rightsProblems,
@@ -8166,24 +8581,25 @@ export {
8166
8581
  sanitizeDraftTitle,
8167
8582
  sanitizeResultLines,
8168
8583
  scanComponents,
8169
- dz as sectionsNeedingReview,
8584
+ dD as sectionsNeedingReview,
8170
8585
  selectTokenFiles,
8171
8586
  c8 as serializeJson,
8172
8587
  serializePendingDrafts,
8173
8588
  serializeTokenFile,
8174
- dA as sha256Hex,
8589
+ dE as sha256Hex,
8175
8590
  shadowedEdits,
8176
8591
  shareDescription,
8177
8592
  shareMessage,
8178
8593
  shareState,
8179
- dB as sharedTokenPrefix,
8594
+ dF as sharedTokenPrefix,
8180
8595
  c9 as shipPolicy,
8181
8596
  shipsByItself,
8182
8597
  shortPackage,
8183
- dC as shortVariant,
8184
- dD as shortVariants,
8598
+ dG as shortVariant,
8599
+ dH as shortVariants,
8185
8600
  showShare,
8186
8601
  siteRepoFromConfig,
8602
+ sizeGap,
8187
8603
  slugify,
8188
8604
  snapshotAudit,
8189
8605
  snapshotIsFresh,
@@ -8196,52 +8612,55 @@ export {
8196
8612
  cc as soloOwnerOf,
8197
8613
  cd as soloOwnerSentence,
8198
8614
  sortChangelogEntries,
8199
- dE as specHash,
8615
+ dI as specHash,
8200
8616
  specsFromMeasure,
8201
- dF as specsUsage,
8617
+ dJ as specsUsage,
8202
8618
  splitNote,
8203
8619
  stableCommand,
8204
- dG as stalenessStatus,
8620
+ dK as stalenessStatus,
8205
8621
  startExplorationOnGitHub,
8622
+ startFixLoop,
8206
8623
  stateSentence,
8207
8624
  statusFixFor,
8208
8625
  storiesOfComponent,
8209
8626
  storyForVariant,
8210
8627
  storyMatchesWhere,
8211
8628
  storyState,
8212
- dH as storybookIframeUrl,
8213
- dI as storybookIndexUrls,
8214
- dJ as storybookManagerUrl,
8629
+ dL as storybookIframeUrl,
8630
+ dM as storybookIndexUrls,
8631
+ dN as storybookManagerUrl,
8215
8632
  ce as storybookUrl,
8216
8633
  styleGlobs,
8217
- dK as subjectTitle,
8634
+ dO as subjectTitle,
8218
8635
  cf as suggestNearestComment,
8219
8636
  suggestTokenProposalOnGitHub,
8220
- dL as suggestionAllowedRoots,
8221
- dM as suggestionAppliedComment,
8222
- dN as suggestionApplyTable,
8223
- dO as suggestionIsTokenValues,
8224
- dP as suggestionIssueTitle,
8225
- dQ as suggestionKindFromLabels,
8226
- dR as suggestionLabelChanges,
8227
- dS as suggestionLabels,
8228
- dT as suggestionPathProblems,
8229
- dU as suggestionPayloadSha,
8230
- dV as suggestionReviewState,
8231
- dW as suggestionShapeProblems,
8232
- dX as suggestionStalenessOnGitHub,
8637
+ dP as suggestionAllowedRoots,
8638
+ dQ as suggestionAppliedComment,
8639
+ dR as suggestionApplyTable,
8640
+ dS as suggestionIsTokenValues,
8641
+ dT as suggestionIssueTitle,
8642
+ dU as suggestionKindFromLabels,
8643
+ dV as suggestionLabelChanges,
8644
+ dW as suggestionLabels,
8645
+ dX as suggestionOverrideOf,
8646
+ dY as suggestionOverrideProblem,
8647
+ dZ as suggestionPathProblems,
8648
+ d_ as suggestionPayloadSha,
8649
+ d$ as suggestionReviewState,
8650
+ e0 as suggestionShapeProblems,
8651
+ e1 as suggestionStalenessOnGitHub,
8233
8652
  suggestionStateFromLabels,
8234
- dY as suggestionStateLabel,
8653
+ e2 as suggestionStateLabel,
8235
8654
  suggestionStatus,
8236
- dZ as suggestionSubject,
8237
- d_ as suggestionTouches,
8655
+ e3 as suggestionSubject,
8656
+ e4 as suggestionTouches,
8238
8657
  summarizeApprovals,
8239
8658
  summarizeCi,
8240
8659
  summarizeComponent,
8241
- d$ as summarizeSuggestionApprovals,
8660
+ e5 as summarizeSuggestionApprovals,
8242
8661
  cg as summarizeTokenChange,
8243
8662
  switchToPublishedOnGitHub,
8244
- e0 as syncSuggestionStateLabel,
8663
+ e6 as syncSuggestionStateLabel,
8245
8664
  takeMine,
8246
8665
  ch as tarballAssetName,
8247
8666
  ci as tarballUrl,
@@ -8251,22 +8670,27 @@ export {
8251
8670
  cm as teamUnreadableMessage,
8252
8671
  cn as teamsIn,
8253
8672
  threeWayDiff,
8673
+ tier1Domain,
8674
+ tier1PublishOf,
8675
+ tier1PublishReviewBody,
8676
+ tier1PublishSentence,
8677
+ tier1PublishedBy,
8254
8678
  tintedNeutral,
8255
- e1 as titleOf,
8679
+ e7 as titleOf,
8256
8680
  titleWithJiraKey,
8257
8681
  co as toAlias,
8258
- e2 as toChangeSummary,
8682
+ e8 as toChangeSummary,
8259
8683
  toConfigJson,
8260
8684
  toHex,
8261
8685
  cp as toMap,
8262
8686
  toOklch,
8263
8687
  cq as toPlain,
8264
8688
  cr as tokenBump,
8265
- e3 as tokenCssVar,
8689
+ e9 as tokenCssVar,
8266
8690
  tokenFileChanges,
8267
8691
  tokenFilesOf,
8268
- e4 as tokenFingerprint,
8269
- e5 as tokenHistory,
8692
+ ea as tokenFingerprint,
8693
+ eb as tokenHistory,
8270
8694
  t as tokenLabel,
8271
8695
  cs as tokenNode,
8272
8696
  tokenPublishRoute,
@@ -8279,7 +8703,7 @@ export {
8279
8703
  tokenSuggestionPayload,
8280
8704
  tokenUsage,
8281
8705
  tokenValueCss,
8282
- e6 as tokenVariablePath,
8706
+ ec as tokenVariablePath,
8283
8707
  tokensPath,
8284
8708
  touchesLayout,
8285
8709
  touchesPackages,
@@ -8290,16 +8714,16 @@ export {
8290
8714
  unpicked,
8291
8715
  ct as unreadableShipTeams,
8292
8716
  cu as unreadableTeams,
8293
- e7 as unsafePathProblem,
8717
+ ed as unsafePathProblem,
8294
8718
  updatePendingDrafts,
8295
8719
  upsertToken,
8296
8720
  useLibraryPreviewOnGitHub,
8297
- e8 as utf8ToBase64,
8298
- e9 as validateComponentSpec,
8299
- ea as validateDocs,
8721
+ ee as utf8ToBase64,
8722
+ ef as validateComponentSpec,
8723
+ eg as validateDocs,
8300
8724
  validateDocsTask,
8301
8725
  validateFigmaFixes,
8302
- eb as validateIntegrations,
8726
+ eh as validateIntegrations,
8303
8727
  validateLayered,
8304
8728
  validatePendingDrafts,
8305
8729
  validateProposal,
@@ -8310,28 +8734,28 @@ export {
8310
8734
  variantCombosFromMapping,
8311
8735
  variantDifferences,
8312
8736
  variantKeyOf,
8313
- ec as variantName,
8737
+ ei as variantName,
8314
8738
  variantValuesFromMapping,
8315
- ed as versionTimeline,
8739
+ ej as versionTimeline,
8316
8740
  cx as visualImpactProblems,
8317
8741
  cy as visualOffer,
8318
- ee as webStorageEtagStore,
8742
+ ek as webStorageEtagStore,
8319
8743
  cz as whoCanShipSentence,
8320
8744
  cA as whyItExists,
8321
- ef as withAuthorLine,
8745
+ el as withAuthorLine,
8322
8746
  withFigmaOrigin,
8323
- eg as withFigmaPushApprovals,
8747
+ em as withFigmaPushApprovals,
8324
8748
  withLink,
8325
8749
  withNeededBy,
8326
- eh as withOutdated,
8750
+ en as withOutdated,
8327
8751
  withPiecesRecord,
8328
8752
  withRepoTokenPaths,
8329
- ei as withRequestExploration,
8330
- ej as withSrgbColors,
8331
- ek as withSuggestionApprovals,
8332
- el as withTokenValueApprovals,
8753
+ eo as withRequestExploration,
8754
+ ep as withSrgbColors,
8755
+ eq as withSuggestionApprovals,
8756
+ er as withTokenValueApprovals,
8333
8757
  withoutAddedWrappers,
8334
- em as withoutJiraKey,
8758
+ es as withoutJiraKey,
8335
8759
  writeDraftResults,
8336
8760
  writeTokenProposalOnGitHub
8337
8761
  };