@bridge-ds/core 0.6.0 → 0.8.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.
@@ -558,6 +558,103 @@ function visualImpactProblems(raw) {
558
558
  }
559
559
  return out;
560
560
  }
561
+ const DEFAULT_PRODUCTS = [
562
+ { key: "admin", name: "Admin demo", path: "apps/admin", framework: "react" },
563
+ { key: "library", name: "Library", default: true }
564
+ ];
565
+ const PRODUCT_LABEL_PREFIX = "product: ";
566
+ const productLabel = (key) => `${PRODUCT_LABEL_PREFIX}${key}`;
567
+ function productMarks(products, p) {
568
+ if (p.key === defaultProduct(products).key) return { labels: [], line: "" };
569
+ return { labels: [productLabel(p.key)], line: `**Product:** ${p.name}` };
570
+ }
571
+ function productsOf(config) {
572
+ const list2 = config?.products;
573
+ return Array.isArray(list2) && list2.length ? list2 : DEFAULT_PRODUCTS;
574
+ }
575
+ function defaultProduct(products) {
576
+ const list2 = products.length ? products : DEFAULT_PRODUCTS;
577
+ return list2.find((p) => p.default) ?? list2[list2.length - 1];
578
+ }
579
+ function findProduct(products, keyOrName) {
580
+ const k = (keyOrName ?? "").trim().toLowerCase();
581
+ if (!k) return void 0;
582
+ return products.find((p) => p.key.toLowerCase() === k) ?? products.find((p) => p.name.toLowerCase() === k);
583
+ }
584
+ const cleanPath = (p) => p.trim().replace(/^\.?\/+|\/+$/g, "");
585
+ function productOfBranch(products, branch) {
586
+ const fallback = defaultProduct(products);
587
+ for (const l of branch.labels ?? []) {
588
+ const name = typeof l === "string" ? l : l?.name;
589
+ if (typeof name !== "string" || !name.toLowerCase().startsWith(PRODUCT_LABEL_PREFIX)) continue;
590
+ const hit = findProduct(products, name.slice(PRODUCT_LABEL_PREFIX.length));
591
+ if (hit) return hit;
592
+ }
593
+ const files = branch.files ?? [];
594
+ for (const p of products) {
595
+ if (p === fallback || !p.path) continue;
596
+ const prefix = `${cleanPath(p.path)}/`;
597
+ if (prefix !== "/" && files.some((f) => f.startsWith(prefix))) return p;
598
+ }
599
+ return fallback;
600
+ }
601
+ function productForPlace(products, place) {
602
+ const repo = place.repo?.trim().toLowerCase();
603
+ if (repo && repo !== place.designSystemRepo?.trim().toLowerCase()) {
604
+ const hit = products.find((p) => p.repo?.toLowerCase() === repo);
605
+ if (hit) return { product: hit, how: "repo" };
606
+ }
607
+ const rel = cleanPath(place.relPath ?? "");
608
+ if (rel && rel !== ".") {
609
+ let best;
610
+ for (const p of products) {
611
+ if (!p.path) continue;
612
+ const dir = cleanPath(p.path);
613
+ if (dir && (rel === dir || rel.startsWith(`${dir}/`)) && (!best || dir.length > cleanPath(best.path).length)) best = p;
614
+ }
615
+ if (best) return { product: best, how: "path" };
616
+ }
617
+ return { product: defaultProduct(products), how: "default" };
618
+ }
619
+ const KEY = /^[a-z0-9][a-z0-9-]*$/;
620
+ const REPO = /^[\w.-]+\/[\w.-]+$/;
621
+ const FIELDS = ["key", "name", "repo", "path", "preview", "framework", "default"];
622
+ function productProblems(raw) {
623
+ if (raw === void 0) return [];
624
+ if (!Array.isArray(raw)) return ['"products" must be a list of { "key", "name" } objects'];
625
+ if (!raw.length) return ['"products" must list at least one product, or be left out to use the defaults'];
626
+ const problems = [];
627
+ const seen = /* @__PURE__ */ new Set();
628
+ let defaults = 0;
629
+ raw.forEach((p, i) => {
630
+ const at = `"products[${i}]`;
631
+ if (!p || typeof p !== "object" || Array.isArray(p)) {
632
+ problems.push(`${at}" must be an object with a "key" and a "name"`);
633
+ return;
634
+ }
635
+ const o = p;
636
+ for (const k of Object.keys(o)) if (!FIELDS.includes(k)) problems.push(`${at}.${k}" is not a known field (${FIELDS.join(", ")})`);
637
+ if (typeof o.key !== "string" || !KEY.test(o.key)) problems.push(`${at}.key" must be lowercase letters, digits and dashes, such as "admin"`);
638
+ else if (seen.has(o.key)) problems.push(`${at}.key" ("${o.key}") is used twice: give each product its own key`);
639
+ else seen.add(o.key);
640
+ if (typeof o.name !== "string" || !o.name.trim()) problems.push(`${at}.name" must be the name people read, such as "Admin demo"`);
641
+ if (o.repo !== void 0 && (typeof o.repo !== "string" || !REPO.test(o.repo))) problems.push(`${at}.repo" must be "owner/name"`);
642
+ if (o.path !== void 0) {
643
+ const bad = typeof o.path !== "string" || !o.path.trim() || o.path.startsWith("/") || o.path.split("/").includes("..");
644
+ if (bad) problems.push(`${at}.path" must be a folder relative to the repository root, without a leading "/" or "..", such as "apps/admin"`);
645
+ }
646
+ if (o.preview !== void 0 && (typeof o.preview !== "string" || !/^https?:\/\//.test(o.preview))) problems.push(`${at}.preview" must be an http(s) URL template, such as "https://app-git-{branch}.vercel.app"`);
647
+ if (o.framework !== void 0 && (typeof o.framework !== "string" || !o.framework.trim())) problems.push(`${at}.framework" must be a name such as "react", "vue" or "other"`);
648
+ if (o.default !== void 0 && typeof o.default !== "boolean") problems.push(`${at}.default" must be true or false`);
649
+ if (o.default === true) defaults++;
650
+ });
651
+ if (defaults > 1) problems.push('"products" marks more than one product as default: keep "default": true on the library only');
652
+ return problems;
653
+ }
654
+ function sameProducts(a, b) {
655
+ const norm2 = (l) => JSON.stringify(l.map((p) => FIELDS.map((f) => p[f] ?? null)));
656
+ return norm2(a) === norm2(b);
657
+ }
561
658
  const CONFIG_FILE = "bridge.config.json";
562
659
  const DEFAULT_OVERRIDE = { allowed: [], requireReason: true, minReasonLength: 20 };
563
660
  const DEFAULT_TOKEN_PATHS = {
@@ -697,6 +794,7 @@ function defineConfig(input) {
697
794
  } : {},
698
795
  ...g.rights ? { rights: normalizeRights(g.rights) } : {}
699
796
  },
797
+ products: input.products?.length ? input.products.map((p) => ({ ...p })) : DEFAULT_PRODUCTS.map((p) => ({ ...p })),
700
798
  ...input.audit ? { audit: { ...input.audit } } : {},
701
799
  ...input.visualImpact ? { visualImpact: { mode: input.visualImpact.mode === "on-demand" ? "on-demand" : "auto" } } : {},
702
800
  ...input.integrations ? { integrations: { ...input.integrations } } : {},
@@ -819,6 +917,7 @@ function loadConfig(source) {
819
917
  }
820
918
  }
821
919
  problems.push(...visualImpactProblems(d.visualImpact));
920
+ problems.push(...productProblems(d.products));
822
921
  const audit = d.audit;
823
922
  if (audit !== void 0) {
824
923
  if (!isObj(audit)) problems.push('"audit" must be an object');
@@ -865,7 +964,8 @@ function toConfigJson(config, schema = "./packages/core/bridge.config.schema.jso
865
964
  governance: config.governance,
866
965
  ...config.audit ? { audit: config.audit } : {},
867
966
  ...config.previews ? { previews: config.previews } : {},
868
- ...config.visualImpact ? { visualImpact: config.visualImpact } : {}
967
+ ...config.visualImpact ? { visualImpact: config.visualImpact } : {},
968
+ ...config.products && !sameProducts(config.products, DEFAULT_PRODUCTS) ? { products: config.products } : {}
869
969
  };
870
970
  }
871
971
  class JsonParseError extends Error {
@@ -2900,6 +3000,13 @@ const SPEC_FIELDS = [
2900
3000
  "textDecoration"
2901
3001
  ];
2902
3002
  const COLOR_FIELDS = /* @__PURE__ */ new Set(["fill", "stroke", "textFill"]);
3003
+ const TRIGGER_LABELS = {
3004
+ ON_HOVER: "While hovering",
3005
+ ON_PRESS: "While pressing",
3006
+ ON_CLICK: "On click",
3007
+ MOUSE_ENTER: "Mouse enter",
3008
+ MOUSE_LEAVE: "Mouse leave"
3009
+ };
2903
3010
  function coverageSummary(file) {
2904
3011
  const list2 = file.coverage ?? file.components.map((c) => ({ name: c.name, status: "generated" }));
2905
3012
  const generated = list2.filter((c) => c.status === "generated").length;
@@ -2984,6 +3091,16 @@ function validateComponentSpec(spec, tokenTypes) {
2984
3091
  for (const [id, vec] of Object.entries(v.vectors ?? {})) if (parts.get(id)?.kind !== "vector" || !/^<svg[\s>]/.test(vec.svg)) at(where, `vector "${id}" is not a vector part with an SVG`);
2985
3092
  for (const id of Object.keys(v.slots ?? {})) if (!parts.has(id)) at(where, `shows a component in "${id}", which is not a part`);
2986
3093
  }
3094
+ for (const [i, x] of (spec.interactions ?? []).entries()) {
3095
+ const where = `interaction ${i + 1}`;
3096
+ const axis = spec.axes.find((a) => a.name === x.axis);
3097
+ if (!(x.trigger in TRIGGER_LABELS)) at(where, `trigger ${String(x.trigger)} is not one Figma has`);
3098
+ if (!axis) at(where, `${x.axis} is not an axis`);
3099
+ else if (!axis.values.includes(x.from) || !axis.values.includes(x.to) || x.from === x.to) at(where, `${x.from} to ${x.to} are not two values of ${x.axis}`);
3100
+ for (const k of x.variants ?? []) if (!seen.has(k)) at(where, `variant ${k} does not exist`);
3101
+ const t = x.transition;
3102
+ if (t && (!(t.duration > 0) || t.easing.type === "CUSTOM_CUBIC_BEZIER" && (t.easing.bezier?.length !== 4 || t.easing.bezier.some((n) => typeof n !== "number")))) at(where, "the transition needs a duration and a valid easing");
3103
+ }
2987
3104
  return out;
2988
3105
  }
2989
3106
  function FIELD_TOKEN_TYPES(field) {
@@ -3008,6 +3125,48 @@ function hashSpec(spec) {
3008
3125
  }
3009
3126
  const variantName = (props) => Object.entries(props).map(([k, v]) => `${k}=${v}`).join(", ");
3010
3127
  const variantKeyOf = (props) => Object.keys(props).sort().map((k) => `${k}=${props[k]}`).join(", ") || "Default";
3128
+ const REDUCED_MOTION_NOTE = "In code, reduced motion turns this off.";
3129
+ function componentMotion(spec) {
3130
+ const keys = new Set(spec.variants.map((v) => variantKeyOf(v.props)));
3131
+ const reactions = [];
3132
+ const triggers = [];
3133
+ for (const x of spec.interactions ?? []) {
3134
+ const only = x.variants ? new Set(x.variants) : void 0;
3135
+ let count = 0;
3136
+ for (const v of spec.variants) {
3137
+ if (v.props[x.axis] !== x.from) continue;
3138
+ const fromKey = variantKeyOf(v.props);
3139
+ if (only && !only.has(fromKey)) continue;
3140
+ const to = { ...v.props, [x.axis]: x.to };
3141
+ const toKey = variantKeyOf(to);
3142
+ if (!keys.has(toKey)) continue;
3143
+ reactions.push({ trigger: x.trigger, label: TRIGGER_LABELS[x.trigger], from: { ...v.props }, to, fromKey, toKey, transition: x.transition });
3144
+ count++;
3145
+ }
3146
+ triggers.push({ ...x, label: TRIGGER_LABELS[x.trigger], count });
3147
+ }
3148
+ const transitions = (spec.interactions ?? []).map((x) => x.transition).filter((t) => !!t);
3149
+ const cannotPlay = [...spec.motion ?? []];
3150
+ const openNote = cannotPlay.find((n) => n.enter || n.exit);
3151
+ const opening = openNote ? { enter: openNote.enter ?? null, exit: openNote.exit ?? null } : void 0;
3152
+ const openTransitions = opening ? [opening.enter, opening.exit].filter((t) => !!t) : [];
3153
+ const tokens = [
3154
+ ...new Set([...transitions, ...openTransitions].flatMap((t) => [t.durationToken, t.easingToken]).concat(cannotPlay.map((n) => n.durationToken)).filter((t) => !!t))
3155
+ ].sort();
3156
+ const properties = [...new Set(transitions.flatMap((t) => t.properties))].sort();
3157
+ const approximations = [...new Set(transitions.map((t) => t.approximated).filter((t) => !!t))];
3158
+ const animates = transitions.length > 0 || openTransitions.length > 0 || cannotPlay.some((n) => /animation/i.test(n.what));
3159
+ return { name: spec.name, reactions, triggers, tokens, properties, approximations, cannotPlay, opening, reducedMotion: animates ? REDUCED_MOTION_NOTE : void 0 };
3160
+ }
3161
+ function componentsUsingMotionToken(specs, tokenPath, chainOf) {
3162
+ const out = /* @__PURE__ */ new Set();
3163
+ for (const c of specs.components) {
3164
+ for (const t of componentMotion(c).tokens) {
3165
+ if (t === tokenPath || (chainOf?.(t) ?? []).includes(tokenPath)) out.add(c.name);
3166
+ }
3167
+ }
3168
+ return [...out].sort();
3169
+ }
3011
3170
  function parseComponentSpecs(text) {
3012
3171
  let data;
3013
3172
  try {
@@ -3021,186 +3180,209 @@ function parseComponentSpecs(text) {
3021
3180
  return f;
3022
3181
  }
3023
3182
  const tokenCssVar = (path, prefix = "--", separator = "-") => `${prefix}${path.split(".").join(separator)}`;
3183
+ function figmaCell(entry) {
3184
+ if (!entry) return void 0;
3185
+ if (entry.status === "generated") return { label: "Yes" };
3186
+ if (entry.status === "drafted") return { label: "Drafted", title: "Drafted with Claude where the code cannot be read on its own: in Figma, check it against the code." };
3187
+ if (entry.status === "layout") return { label: "Auto layout", title: "A layout helper: nothing to draw, use auto layout in Figma." };
3188
+ return { label: "Not yet", ...entry.reason ? { title: `Not supported yet: ${entry.reason}` } : {} };
3189
+ }
3024
3190
  export {
3025
- buildHistoryEntry as $,
3026
- contextLabel as A,
3027
- pathId as B,
3191
+ applyTokenEdits as $,
3192
+ evaluatePairs as A,
3193
+ contrastScope as B,
3028
3194
  CONFIG_FILE as C,
3029
- flattenTokens as D,
3030
- serializeTokenFile as E,
3031
- removeToken as F,
3032
- upsertToken as G,
3033
- threeWayDiff as H,
3034
- emptyTokenFile as I,
3035
- parseTokenFile as J,
3036
- EXT_ID as K,
3037
- EXT_SCOPES as L,
3038
- resolve as M,
3039
- moveToken as N,
3040
- effectiveScopes as O,
3041
- sameScopes as P,
3042
- defaultScopes as Q,
3043
- readTokenAt as R,
3195
+ contextLabel as D,
3196
+ pathId as E,
3197
+ flattenTokens as F,
3198
+ serializeTokenFile as G,
3199
+ removeToken as H,
3200
+ upsertToken as I,
3201
+ threeWayDiff as J,
3202
+ emptyTokenFile as K,
3203
+ parseTokenFile as L,
3204
+ EXT_ID as M,
3205
+ EXT_SCOPES as N,
3206
+ moveToken as O,
3207
+ effectiveScopes as P,
3208
+ sameScopes as Q,
3209
+ defaultScopes as R,
3044
3210
  SINGLE_MODE as S,
3045
3211
  TIER_NAMES as T,
3046
- modeFile as U,
3047
- defaultFile as V,
3048
- DEFAULT_PROTECTED_BRANCHES as W,
3049
- ProtectedBranchError as X,
3050
- ConfigError as Y,
3051
- DEFAULT_TOKEN_PATHS as Z,
3052
- applyTokenEdits as _,
3212
+ readTokenAt as U,
3213
+ modeFile as V,
3214
+ defaultFile as W,
3215
+ DEFAULT_PROTECTED_BRANCHES as X,
3216
+ ProtectedBranchError as Y,
3217
+ ConfigError as Z,
3218
+ DEFAULT_TOKEN_PATHS as _,
3053
3219
  assertSafeBranch as a,
3054
- composeProposalBody as a$,
3055
- resolveBranchPreviews as a0,
3056
- tokensPath as a1,
3057
- coerceValue as a2,
3058
- toConfigJson as a3,
3059
- parseContrastChecks as a4,
3060
- checkLayeredPair as a5,
3061
- classifyRisk as a6,
3062
- formatChangeset as a7,
3063
- RISK_LABELS as a8,
3064
- parseJson as a9,
3065
- RIGHTS as aA,
3066
- RIGHT_LABEL as aB,
3067
- RISK_TIER as aC,
3068
- SPEC_FIELDS as aD,
3069
- TIER_ORDER as aE,
3070
- TeamDirectory as aF,
3071
- UNRELEASED as aG,
3072
- VISUAL_CHECK_LABEL as aH,
3073
- affectedContrast as aI,
3074
- appForProject as aJ,
3075
- appUrl as aK,
3076
- approverEntries as aL,
3077
- approverLists as aM,
3078
- assignVersions as aN,
3079
- baseBranchOf as aO,
3080
- branchName as aP,
3081
- branchSlug as aQ,
3082
- canShip as aR,
3083
- changeKind as aS,
3084
- changeTable as aT,
3085
- changedModes as aU,
3086
- changesetBump as aV,
3087
- classifyLayered as aW,
3088
- clearRawDeep as aX,
3089
- commitMessage as aY,
3090
- composeChangeset as aZ,
3091
- composePrBody as a_,
3092
- serializeJson as aa,
3093
- plainEqual as ab,
3094
- toPlain as ac,
3095
- getEntry as ad,
3096
- fromPlain as ae,
3097
- previewLinks as af,
3098
- slugify as ag,
3099
- readPreviewComment as ah,
3100
- findPreviewComment as ai,
3101
- previewsSettled as aj,
3102
- AAA_MIN as ak,
3103
- AA_MIN as al,
3104
- BULK_LIMIT as am,
3105
- CONTRAST_CELL_MAX as an,
3106
- CONTRAST_CHECKS_FILE as ao,
3107
- DEFAULT_COMPONENT_SPECS_FILE as ap,
3108
- DEFAULT_GOVERNANCE as aq,
3109
- DEFAULT_OVERRIDE as ar,
3110
- DEFAULT_RIGHTS as as,
3111
- DEFAULT_VISUAL_IMPACT as at,
3112
- JsonParseError as au,
3113
- OWNER_GROUPS as av,
3114
- PREVIEW_APP_LABELS as aw,
3115
- PREVIEW_COMMENT_MARKER as ax,
3116
- PREVIEW_PLACEHOLDERS as ay,
3117
- PRIMITIVE_MODE as az,
3220
+ changedModes as a$,
3221
+ buildHistoryEntry as a0,
3222
+ resolveBranchPreviews as a1,
3223
+ tokensPath as a2,
3224
+ coerceValue as a3,
3225
+ toConfigJson as a4,
3226
+ parseContrastChecks as a5,
3227
+ checkLayeredPair as a6,
3228
+ classifyRisk as a7,
3229
+ formatChangeset as a8,
3230
+ RISK_LABELS as a9,
3231
+ OWNER_GROUPS as aA,
3232
+ PREVIEW_APP_LABELS as aB,
3233
+ PREVIEW_COMMENT_MARKER as aC,
3234
+ PREVIEW_PLACEHOLDERS as aD,
3235
+ PRIMITIVE_MODE as aE,
3236
+ PRODUCT_LABEL_PREFIX as aF,
3237
+ REDUCED_MOTION_NOTE as aG,
3238
+ RIGHTS as aH,
3239
+ RIGHT_LABEL as aI,
3240
+ RISK_TIER as aJ,
3241
+ SPEC_FIELDS as aK,
3242
+ TIER_ORDER as aL,
3243
+ TRIGGER_LABELS as aM,
3244
+ TeamDirectory as aN,
3245
+ UNRELEASED as aO,
3246
+ VISUAL_CHECK_LABEL as aP,
3247
+ affectedContrast as aQ,
3248
+ appForProject as aR,
3249
+ appUrl as aS,
3250
+ approverEntries as aT,
3251
+ approverLists as aU,
3252
+ assignVersions as aV,
3253
+ baseBranchOf as aW,
3254
+ branchName as aX,
3255
+ branchSlug as aY,
3256
+ changeKind as aZ,
3257
+ changeTable as a_,
3258
+ parseJson as aa,
3259
+ serializeJson as ab,
3260
+ plainEqual as ac,
3261
+ toPlain as ad,
3262
+ getEntry as ae,
3263
+ fromPlain as af,
3264
+ previewLinks as ag,
3265
+ slugify as ah,
3266
+ readPreviewComment as ai,
3267
+ findPreviewComment as aj,
3268
+ previewsSettled as ak,
3269
+ canShip as al,
3270
+ whoCanShipSentence as am,
3271
+ unreadableShipTeams as an,
3272
+ AAA_MIN as ao,
3273
+ AA_MIN as ap,
3274
+ BULK_LIMIT as aq,
3275
+ CONTRAST_CELL_MAX as ar,
3276
+ CONTRAST_CHECKS_FILE as as,
3277
+ DEFAULT_COMPONENT_SPECS_FILE as at,
3278
+ DEFAULT_GOVERNANCE as au,
3279
+ DEFAULT_OVERRIDE as av,
3280
+ DEFAULT_PRODUCTS as aw,
3281
+ DEFAULT_RIGHTS as ax,
3282
+ DEFAULT_VISUAL_IMPACT as ay,
3283
+ JsonParseError as az,
3118
3284
  parseChangelog as b,
3119
- snapshotUrl as b$,
3120
- composite as b0,
3121
- contextFor as b1,
3122
- contrastDelta as b2,
3123
- contrastDeltaTable as b3,
3124
- contrastLevel as b4,
3125
- contrastPair as b5,
3126
- contrastRatio as b6,
3127
- countChanges as b7,
3128
- coverageSummary as b8,
3129
- defaultContext as b9,
3130
- isVercelComment as bA,
3131
- kindForMin as bB,
3132
- layeredImpact as bC,
3133
- luminance as bD,
3134
- modeLabel as bE,
3135
- nodesEqual as bF,
3136
- normalizeRights as bG,
3137
- overrideKey as bH,
3138
- ownerEntryProblems as bI,
3139
- pairKey as bJ,
3140
- parseChangesetText as bK,
3141
- parseComponentSpecs as bL,
3142
- parseOwnerEntry as bM,
3143
- parseVercelComment as bN,
3144
- planRestore as bO,
3145
- planRevert as bP,
3146
- planToJson as bQ,
3147
- previewComment as bR,
3148
- previewLinksOf as bS,
3149
- previewUrl as bT,
3150
- projectOfLabel as bU,
3151
- protectedBranchesOf as bV,
3152
- renderedColor as bW,
3153
- rightsProblems as bX,
3154
- runLayeredContrast as bY,
3155
- sameToken as bZ,
3156
- shipPolicy as b_,
3157
- defaultTitle as ba,
3158
- defineConfig as bb,
3159
- detectLayout as bc,
3160
- diffLayered as bd,
3161
- entriesFor as be,
3162
- entryLabel as bf,
3163
- expandEntries as bg,
3164
- expandOwners as bh,
3165
- fieldChanges as bi,
3166
- fileModes as bj,
3167
- filterHistory as bk,
3168
- findToken as bl,
3169
- findVercelComment as bm,
3170
- firstParagraph as bn,
3171
- formatNumber as bo,
3172
- formatOwnerEntry as bp,
3173
- getChild as bq,
3174
- groupsPhrase as br,
3175
- holdersOf as bs,
3176
- indexByPath as bt,
3177
- inheritedTypeAt as bu,
3178
- installCommand as bv,
3179
- installCommandFromPreviewComment as bw,
3180
- isGuardrail as bx,
3181
- isTeamEntry as by,
3182
- isTokenFile as bz,
3285
+ planToJson as b$,
3286
+ changesetBump as b0,
3287
+ classifyLayered as b1,
3288
+ clearRawDeep as b2,
3289
+ commitMessage as b3,
3290
+ componentMotion as b4,
3291
+ componentsUsingMotionToken as b5,
3292
+ composeChangeset as b6,
3293
+ composePrBody as b7,
3294
+ composeProposalBody as b8,
3295
+ composite as b9,
3296
+ formatOwnerEntry as bA,
3297
+ getChild as bB,
3298
+ groupsPhrase as bC,
3299
+ holdersOf as bD,
3300
+ indexByPath as bE,
3301
+ inheritedTypeAt as bF,
3302
+ installCommand as bG,
3303
+ installCommandFromPreviewComment as bH,
3304
+ isGuardrail as bI,
3305
+ isTeamEntry as bJ,
3306
+ isTokenFile as bK,
3307
+ isVercelComment as bL,
3308
+ kindForMin as bM,
3309
+ layeredImpact as bN,
3310
+ luminance as bO,
3311
+ modeLabel as bP,
3312
+ nodesEqual as bQ,
3313
+ normalizeRights as bR,
3314
+ overrideKey as bS,
3315
+ ownerEntryProblems as bT,
3316
+ pairKey as bU,
3317
+ parseChangesetText as bV,
3318
+ parseComponentSpecs as bW,
3319
+ parseOwnerEntry as bX,
3320
+ parseVercelComment as bY,
3321
+ planRestore as bZ,
3322
+ planRevert as b_,
3323
+ contextFor as ba,
3324
+ contrastDelta as bb,
3325
+ contrastDeltaTable as bc,
3326
+ contrastLevel as bd,
3327
+ contrastPair as be,
3328
+ contrastRatio as bf,
3329
+ countChanges as bg,
3330
+ coverageSummary as bh,
3331
+ defaultProduct as bi,
3332
+ defaultTitle as bj,
3333
+ defineConfig as bk,
3334
+ detectLayout as bl,
3335
+ diffLayered as bm,
3336
+ entriesFor as bn,
3337
+ entryLabel as bo,
3338
+ expandEntries as bp,
3339
+ expandOwners as bq,
3340
+ fieldChanges as br,
3341
+ figmaCell as bs,
3342
+ fileModes as bt,
3343
+ filterHistory as bu,
3344
+ findProduct as bv,
3345
+ findToken as bw,
3346
+ findVercelComment as bx,
3347
+ firstParagraph as by,
3348
+ formatNumber as bz,
3183
3349
  collectHistory as c,
3184
- summarizeTokenChange as c0,
3185
- tarballAssetName as c1,
3186
- tarballUrl as c2,
3187
- teamKey as c3,
3188
- teamKeyOf as c4,
3189
- teamUnreadableMessage as c5,
3190
- teamsIn as c6,
3191
- titleOf as c7,
3192
- toChangeSummary as c8,
3193
- toMap as c9,
3194
- tokenBump as ca,
3195
- tokenHistory as cb,
3196
- tokenNode as cc,
3197
- unreadableShipTeams as cd,
3198
- unreadableTeams as ce,
3199
- valueIn as cf,
3200
- variantName as cg,
3201
- versionTimeline as ch,
3202
- visualImpactProblems as ci,
3203
- whoCanShipSentence as cj,
3350
+ previewComment as c0,
3351
+ previewLinksOf as c1,
3352
+ previewUrl as c2,
3353
+ productForPlace as c3,
3354
+ productLabel as c4,
3355
+ productMarks as c5,
3356
+ productOfBranch as c6,
3357
+ productProblems as c7,
3358
+ productsOf as c8,
3359
+ projectOfLabel as c9,
3360
+ protectedBranchesOf as ca,
3361
+ renderedColor as cb,
3362
+ rightsProblems as cc,
3363
+ runLayeredContrast as cd,
3364
+ sameProducts as ce,
3365
+ sameToken as cf,
3366
+ shipPolicy as cg,
3367
+ snapshotUrl as ch,
3368
+ summarizeTokenChange as ci,
3369
+ tarballAssetName as cj,
3370
+ tarballUrl as ck,
3371
+ teamKey as cl,
3372
+ teamKeyOf as cm,
3373
+ teamUnreadableMessage as cn,
3374
+ teamsIn as co,
3375
+ titleOf as cp,
3376
+ toChangeSummary as cq,
3377
+ toMap as cr,
3378
+ tokenBump as cs,
3379
+ tokenHistory as ct,
3380
+ tokenNode as cu,
3381
+ unreadableTeams as cv,
3382
+ valueIn as cw,
3383
+ variantName as cx,
3384
+ versionTimeline as cy,
3385
+ visualImpactProblems as cz,
3204
3386
  buildReport as d,
3205
3387
  prNumberFromSubject as e,
3206
3388
  variantKeyOf as f,
@@ -3208,21 +3390,21 @@ export {
3208
3390
  hashSpec as h,
3209
3391
  iconComponentName as i,
3210
3392
  buildTokenSet as j,
3211
- COMPONENT_SPECS_VERSION as k,
3393
+ defaultContext as k,
3212
3394
  loadConfig as l,
3213
3395
  mergeReleases as m,
3214
- COLOR_FIELDS as n,
3215
- modeDisplayName as o,
3396
+ resolve as n,
3397
+ COMPONENT_SPECS_VERSION as o,
3216
3398
  packageDirCandidates as p,
3217
- modesOf as q,
3399
+ COLOR_FIELDS as q,
3218
3400
  releasesFromTags as r,
3219
3401
  specHash as s,
3220
3402
  tokenCssVar as t,
3221
- isMultiMode as u,
3403
+ modeDisplayName as u,
3222
3404
  validateComponentSpec as v,
3223
- TIER_AXIS as w,
3224
- findReferenceProblems as x,
3225
- evaluatePairs as y,
3226
- contrastScope as z
3405
+ modesOf as w,
3406
+ isMultiMode as x,
3407
+ TIER_AXIS as y,
3408
+ findReferenceProblems as z
3227
3409
  };
3228
- //# sourceMappingURL=component-spec-GFVEE6Fc.js.map
3410
+ //# sourceMappingURL=component-spec-SKuywZqr.js.map