@bridge-ds/core 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/components.d.ts +1 -1
- package/dist/audit/index.js +1 -1
- package/dist/{component-spec-cvrSvIZj.js → component-spec-GFVEE6Fc.js} +288 -190
- package/dist/component-spec-GFVEE6Fc.js.map +1 -0
- package/dist/component-spec.d.ts +124 -7
- package/dist/explorations.d.ts +2 -0
- package/dist/fidelity-references.d.ts +78 -0
- package/dist/fidelity.d.ts +138 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +557 -283
- package/dist/index.js.map +1 -1
- package/dist/node/component-specs.d.ts +57 -4
- package/dist/node/index.js +1725 -118
- package/dist/node/index.js.map +1 -1
- package/dist/node/spec-css.d.ts +11 -0
- package/dist/{report-4Z008HSf.js → report-iPSnsjYi.js} +3 -2
- package/dist/report-iPSnsjYi.js.map +1 -0
- package/dist/rights.d.ts +2 -2
- package/package.json +1 -1
- package/dist/component-spec-cvrSvIZj.js.map +0 -1
- package/dist/report-4Z008HSf.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { o as modeDisplayName, q as modesOf$1, u as isMultiMode, T as TIER_NAMES, w as TIER_AXIS, x as findReferenceProblems, y as evaluatePairs, z as contrastScope, A as contextLabel, S as SINGLE_MODE, B as pathId, D as flattenTokens, E as serializeTokenFile, F as removeToken, G as upsertToken, H as threeWayDiff, I as emptyTokenFile, J as parseTokenFile, K as EXT_ID, L as EXT_SCOPES, M as resolve, N as moveToken, O as effectiveScopes, P as sameScopes, Q as defaultScopes, R as readTokenAt, U as modeFile, V as defaultFile, W as DEFAULT_PROTECTED_BRANCHES, a as assertSafeBranch, X as ProtectedBranchError, C as CONFIG_FILE, l as loadConfig, Y as ConfigError, Z as DEFAULT_TOKEN_PATHS, c as collectHistory, p as packageDirCandidates, b as parseChangelog, r as releasesFromTags, m as mergeReleases, d as buildReport, _ as applyTokenEdits, $ as buildHistoryEntry, a0 as resolveBranchPreviews, a1 as tokensPath, a2 as coerceValue, a3 as toConfigJson, a4 as parseContrastChecks, a5 as checkLayeredPair, a6 as classifyRisk, a7 as formatChangeset, a8 as RISK_LABELS, a9 as parseJson, aa as serializeJson, ab as plainEqual, ac as toPlain, ad as getEntry, ae as fromPlain, af as previewLinks, ag as slugify, ah as readPreviewComment, ai as findPreviewComment, aj as previewsSettled, f as variantKeyOf } from "./component-spec-GFVEE6Fc.js";
|
|
2
|
+
import { ak, al, am, n, k, 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, j, 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, h, bs, i, bt, bu, bv, bw, bx, by, bz, bA, bB, bC, g, bD, bE, bF, bG, bH, bI, bJ, bK, bL, bM, bN, bO, bP, bQ, e, bR, bS, bT, bU, bV, bW, bX, bY, bZ, b_, b$, s, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, t, cb, cc, cd, ce, v, cf, cg, ch, ci, cj } from "./component-spec-GFVEE6Fc.js";
|
|
3
3
|
import { a as collectRefs, i as isAlias, b as aliasTarget, v as valuesEqual, p as parseColor, e as rgbaToHex, f as formatValue, s as selectTokenFiles, L as LayeredTokenSet, j as validateLayered } from "./layered-BnbmToGs.js";
|
|
4
|
-
import { D, d, k as k2, l, c, m, n, g as g2, h as h2, o, q, r, t as t2, u } from "./layered-BnbmToGs.js";
|
|
4
|
+
import { D, d, k as k2, l, c, m, n as n2, g as g2, h as h2, o, q, r, t as t2, u } from "./layered-BnbmToGs.js";
|
|
5
5
|
const issueKey = (i2) => `${i2.code}|${i2.path ?? ""}|${i2.mode ?? ""}|${i2.code === "file-problem" ? i2.message : ""}`;
|
|
6
6
|
const modeName = (mode) => mode === SINGLE_MODE ? "all modes" : modeDisplayName(mode);
|
|
7
7
|
const isPalette = (t3) => t3.tier === "brand" && t3.path.startsWith("palette.");
|
|
@@ -236,14 +236,14 @@ function reconcileIds(figma, git) {
|
|
|
236
236
|
if (best) suggestions.push(best);
|
|
237
237
|
}
|
|
238
238
|
const byGit = /* @__PURE__ */ new Map();
|
|
239
|
-
for (const
|
|
240
|
-
const prev = byGit.get(
|
|
241
|
-
if (!prev ||
|
|
239
|
+
for (const s2 of suggestions) {
|
|
240
|
+
const prev = byGit.get(s2.gitId);
|
|
241
|
+
if (!prev || s2.similarity > prev.similarity) byGit.set(s2.gitId, s2);
|
|
242
242
|
}
|
|
243
243
|
return { tokens, adoptedByName, suggestions: [...byGit.values()] };
|
|
244
244
|
}
|
|
245
245
|
function applyConfirmedRenames(tokens, confirmed) {
|
|
246
|
-
const map = new Map(confirmed.map((
|
|
246
|
+
const map = new Map(confirmed.map((s2) => [s2.figmaId, s2.gitId]));
|
|
247
247
|
return tokens.map((t3) => map.has(t3.id) ? { ...t3, id: map.get(t3.id) } : t3);
|
|
248
248
|
}
|
|
249
249
|
function idExtensionFor(t3) {
|
|
@@ -404,8 +404,8 @@ function combineConflicts(changes) {
|
|
|
404
404
|
return out;
|
|
405
405
|
}
|
|
406
406
|
function pickedOption(c10, picks) {
|
|
407
|
-
const
|
|
408
|
-
return
|
|
407
|
+
const n3 = picks[c10.key];
|
|
408
|
+
return n3 === void 0 ? null : c10.options.find((o2) => o2.changes.includes(n3)) ?? null;
|
|
409
409
|
}
|
|
410
410
|
const unpicked = (conflicts, picks) => conflicts.filter((c10) => !pickedOption(c10, picks));
|
|
411
411
|
function combineChanges(latest, changes, picks = {}, opts = {}) {
|
|
@@ -458,16 +458,16 @@ function combineChanges(latest, changes, picks = {}, opts = {}) {
|
|
|
458
458
|
return { files, included: on.map((c10) => c10.number), edits: groups.size, tokens, conflicts, missing, from, problems };
|
|
459
459
|
}
|
|
460
460
|
function encodePicks(picks) {
|
|
461
|
-
return Object.entries(picks).filter(([,
|
|
461
|
+
return Object.entries(picks).filter(([, n3]) => Number.isSafeInteger(n3) && n3 > 0).sort(([a], [b]) => a.localeCompare(b)).map(([key, n3]) => `${n3}:${key}`).join("~");
|
|
462
462
|
}
|
|
463
463
|
function decodePicks(raw) {
|
|
464
464
|
const out = {};
|
|
465
465
|
for (const part of (raw ?? "").split("~")) {
|
|
466
466
|
const i2 = part.indexOf(":");
|
|
467
467
|
if (i2 < 1) continue;
|
|
468
|
-
const
|
|
468
|
+
const n3 = Number(part.slice(0, i2));
|
|
469
469
|
const key = part.slice(i2 + 1);
|
|
470
|
-
if (/^\d{1,7}$/.test(part.slice(0, i2)) &&
|
|
470
|
+
if (/^\d{1,7}$/.test(part.slice(0, i2)) && n3 > 0 && key.includes("#")) out[key] = n3;
|
|
471
471
|
}
|
|
472
472
|
return out;
|
|
473
473
|
}
|
|
@@ -595,7 +595,7 @@ function requiredCheckNames(defaultBranchRuns, pullRequestRuns) {
|
|
|
595
595
|
const names2 = [...new Set(defaultBranchRuns.filter((r2) => !isVercel(r2) && ran(r2)).map((r2) => r2.name))];
|
|
596
596
|
if (!pullRequestRuns?.length) return names2;
|
|
597
597
|
const onPulls = new Set(pullRequestRuns.filter((r2) => !isVercel(r2)).map((r2) => r2.name));
|
|
598
|
-
return names2.filter((
|
|
598
|
+
return names2.filter((n3) => onPulls.has(n3));
|
|
599
599
|
}
|
|
600
600
|
function refPattern(pattern) {
|
|
601
601
|
const src = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "\0").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(/\u0000/g, ".*");
|
|
@@ -664,8 +664,8 @@ function protectionSentence(state) {
|
|
|
664
664
|
case "unprotected":
|
|
665
665
|
return "Your library can be changed without review.";
|
|
666
666
|
case "partial": {
|
|
667
|
-
const
|
|
668
|
-
return `Partly protected: ${
|
|
667
|
+
const s2 = joinAnd(state.missing.map((p) => PROTECTION_PART_PHRASE[p]));
|
|
668
|
+
return `Partly protected: ${s2}.`;
|
|
669
669
|
}
|
|
670
670
|
default:
|
|
671
671
|
return "Protection status unknown: GitHub did not let this token read it.";
|
|
@@ -989,37 +989,37 @@ class GitHubClient {
|
|
|
989
989
|
* Marks a draft pull request ready for review. REST cannot unset `draft`, so this is the GraphQL mutation
|
|
990
990
|
* markPullRequestReadyForReview, with the same token (pull requests: write).
|
|
991
991
|
*/
|
|
992
|
-
async markReadyForReview(
|
|
992
|
+
async markReadyForReview(n3) {
|
|
993
993
|
this.assertToken("Marking a pull request ready for review");
|
|
994
|
-
const pr = await this.request("GET", `${this.repoPath}/pulls/${
|
|
994
|
+
const pr = await this.request("GET", `${this.repoPath}/pulls/${n3}`);
|
|
995
995
|
if (pr.draft === false) return;
|
|
996
|
-
if (!pr.node_id) throw new GitHubError(422, `Pull request #${
|
|
996
|
+
if (!pr.node_id) throw new GitHubError(422, `Pull request #${n3} has no node id: mark it ready for review on GitHub.`);
|
|
997
997
|
const r2 = await this.request("POST", "/graphql", {
|
|
998
998
|
query: "mutation($id: ID!) { markPullRequestReadyForReview(input: { pullRequestId: $id }) { pullRequest { number isDraft } } }",
|
|
999
999
|
variables: { id: pr.node_id }
|
|
1000
1000
|
});
|
|
1001
1001
|
if (r2?.errors?.length) {
|
|
1002
1002
|
const detail = r2.errors.map((e2) => e2.message).filter(Boolean).join(" ");
|
|
1003
|
-
throw new GitHubError(422, `GitHub refused to mark #${
|
|
1003
|
+
throw new GitHubError(422, `GitHub refused to mark #${n3} ready for review${detail ? `: ${detail}` : "."} Use "Ready for review" on GitHub instead.`, detail);
|
|
1004
1004
|
}
|
|
1005
1005
|
}
|
|
1006
1006
|
/**
|
|
1007
1007
|
* Turns an open pull request back into a draft: the GraphQL mutation convertPullRequestToDraft (REST cannot set
|
|
1008
1008
|
* `draft` either), same token. No-op when it is already a draft.
|
|
1009
1009
|
*/
|
|
1010
|
-
async convertToDraft(
|
|
1010
|
+
async convertToDraft(n3) {
|
|
1011
1011
|
this.assertToken("Turning a pull request back into a draft");
|
|
1012
|
-
const pr = await this.request("GET", `${this.repoPath}/pulls/${
|
|
1012
|
+
const pr = await this.request("GET", `${this.repoPath}/pulls/${n3}`);
|
|
1013
1013
|
if (pr.draft === true) return;
|
|
1014
|
-
if (pr.state && pr.state !== "open") throw new GitHubError(422, `Pull request #${
|
|
1015
|
-
if (!pr.node_id) throw new GitHubError(422, `Pull request #${
|
|
1014
|
+
if (pr.state && pr.state !== "open") throw new GitHubError(422, `Pull request #${n3} is ${pr.state}: only an open one can go back to draft.`);
|
|
1015
|
+
if (!pr.node_id) throw new GitHubError(422, `Pull request #${n3} has no node id: convert it to draft on GitHub.`);
|
|
1016
1016
|
const r2 = await this.request("POST", "/graphql", {
|
|
1017
1017
|
query: "mutation($id: ID!) { convertPullRequestToDraft(input: { pullRequestId: $id }) { pullRequest { number isDraft } } }",
|
|
1018
1018
|
variables: { id: pr.node_id }
|
|
1019
1019
|
});
|
|
1020
1020
|
if (r2?.errors?.length) {
|
|
1021
1021
|
const detail = r2.errors.map((e2) => e2.message).filter(Boolean).join(" ");
|
|
1022
|
-
throw new GitHubError(422, `GitHub refused to turn #${
|
|
1022
|
+
throw new GitHubError(422, `GitHub refused to turn #${n3} back into a draft${detail ? `: ${detail}` : "."} Use "Convert to draft" on GitHub instead.`, detail);
|
|
1023
1023
|
}
|
|
1024
1024
|
}
|
|
1025
1025
|
async createPullRequest(input) {
|
|
@@ -1073,18 +1073,18 @@ class GitHubClient {
|
|
|
1073
1073
|
const r2 = await this.request("GET", `${this.repoPath}/issues?${q2}`);
|
|
1074
1074
|
return r2.filter((i2) => !i2.pull_request).map(toIssue);
|
|
1075
1075
|
}
|
|
1076
|
-
async getIssue(
|
|
1077
|
-
return toIssue(await this.request("GET", `${this.repoPath}/issues/${
|
|
1076
|
+
async getIssue(n3) {
|
|
1077
|
+
return toIssue(await this.request("GET", `${this.repoPath}/issues/${n3}`));
|
|
1078
1078
|
}
|
|
1079
1079
|
/** Edits an issue: its body, or closes it with a reason ("not_planned" for a declined request). */
|
|
1080
|
-
async updateIssue(
|
|
1080
|
+
async updateIssue(n3, patch) {
|
|
1081
1081
|
this.assertToken("Editing an issue");
|
|
1082
|
-
return toIssue(await this.request("PATCH", `${this.repoPath}/issues/${
|
|
1082
|
+
return toIssue(await this.request("PATCH", `${this.repoPath}/issues/${n3}`, patch));
|
|
1083
1083
|
}
|
|
1084
1084
|
/** Adds people to an issue's assignees (GitHub ignores logins that cannot be assigned: the result says who is). */
|
|
1085
|
-
async addAssignees(
|
|
1085
|
+
async addAssignees(n3, logins) {
|
|
1086
1086
|
this.assertToken("Assigning an issue");
|
|
1087
|
-
const r2 = await this.request("POST", `${this.repoPath}/issues/${
|
|
1087
|
+
const r2 = await this.request("POST", `${this.repoPath}/issues/${n3}/assignees`, { assignees: logins });
|
|
1088
1088
|
return (r2.assignees ?? []).map((a) => a.login);
|
|
1089
1089
|
}
|
|
1090
1090
|
/** People with at least `permission` on the repository (reading the list needs push access). First 100. */
|
|
@@ -1266,7 +1266,7 @@ class GitHubClient {
|
|
|
1266
1266
|
]);
|
|
1267
1267
|
const checks = [
|
|
1268
1268
|
...runs.map((c10) => ({ name: c10.name, status: c10.status, conclusion: c10.conclusion })),
|
|
1269
|
-
...combined.statuses.map((
|
|
1269
|
+
...combined.statuses.map((s2) => ({ name: s2.context, status: s2.state === "pending" ? "in_progress" : "completed", conclusion: s2.state === "pending" ? null : s2.state }))
|
|
1270
1270
|
];
|
|
1271
1271
|
const failing = checks.some((c10) => c10.conclusion && !["success", "neutral", "skipped"].includes(c10.conclusion));
|
|
1272
1272
|
const pending = checks.some((c10) => c10.status !== "completed");
|
|
@@ -1275,7 +1275,7 @@ class GitHubClient {
|
|
|
1275
1275
|
/** Commit statuses of a commit, newest first (Vercel reports each project as "Vercel – <project>"). */
|
|
1276
1276
|
async listCommitStatuses(sha) {
|
|
1277
1277
|
const r2 = await this.request("GET", `${this.repoPath}/commits/${encodeRef(sha)}/statuses?per_page=100`);
|
|
1278
|
-
return r2.map((
|
|
1278
|
+
return r2.map((s2) => ({ context: s2.context, state: s2.state, target_url: s2.target_url ?? null, description: s2.description ?? null }));
|
|
1279
1279
|
}
|
|
1280
1280
|
/**
|
|
1281
1281
|
* GitHub deployments of a commit with their latest status (environment "Preview – <project>", environment_url the
|
|
@@ -1288,30 +1288,30 @@ class GitHubClient {
|
|
|
1288
1288
|
return Promise.all(
|
|
1289
1289
|
[...latest.values()].map(async (d2) => {
|
|
1290
1290
|
const st = await this.request("GET", `${this.repoPath}/deployments/${d2.id}/statuses?per_page=1`).catch(() => []);
|
|
1291
|
-
const
|
|
1292
|
-
return { id: d2.id, environment: d2.environment, state:
|
|
1291
|
+
const s2 = st[0];
|
|
1292
|
+
return { id: d2.id, environment: d2.environment, state: s2?.state ?? null, environmentUrl: s2?.environment_url || null };
|
|
1293
1293
|
})
|
|
1294
1294
|
);
|
|
1295
1295
|
}
|
|
1296
|
-
async getPullRequest(
|
|
1297
|
-
const r2 = await this.request("GET", `${this.repoPath}/pulls/${
|
|
1296
|
+
async getPullRequest(n3) {
|
|
1297
|
+
const r2 = await this.request("GET", `${this.repoPath}/pulls/${n3}`);
|
|
1298
1298
|
return { ...toSummary(r2), body: r2.body ?? "", mergeable: r2.mergeable ?? null };
|
|
1299
1299
|
}
|
|
1300
|
-
async listPullRequestFiles(
|
|
1301
|
-
const r2 = await this.request("GET", `${this.repoPath}/pulls/${
|
|
1300
|
+
async listPullRequestFiles(n3) {
|
|
1301
|
+
const r2 = await this.request("GET", `${this.repoPath}/pulls/${n3}/files?per_page=100`);
|
|
1302
1302
|
return r2.map((f) => ({ filename: f.filename, status: f.status, additions: f.additions, deletions: f.deletions }));
|
|
1303
1303
|
}
|
|
1304
|
-
async updatePullRequest(
|
|
1305
|
-
await this.request("PATCH", `${this.repoPath}/pulls/${
|
|
1304
|
+
async updatePullRequest(n3, patch) {
|
|
1305
|
+
await this.request("PATCH", `${this.repoPath}/pulls/${n3}`, patch);
|
|
1306
1306
|
}
|
|
1307
|
-
async listReviews(
|
|
1308
|
-
const r2 = await this.request("GET", `${this.repoPath}/pulls/${
|
|
1307
|
+
async listReviews(n3) {
|
|
1308
|
+
const r2 = await this.request("GET", `${this.repoPath}/pulls/${n3}/reviews`);
|
|
1309
1309
|
return r2.map((x) => ({ id: x.id, user: x.user?.login, state: x.state, body: x.body ?? "", ...x.submitted_at ? { submittedAt: x.submitted_at } : {} }));
|
|
1310
1310
|
}
|
|
1311
1311
|
/** Submit a review. `COMMENT` works for any collaborator; approving your own PR is refused by GitHub. */
|
|
1312
|
-
async createReview(
|
|
1312
|
+
async createReview(n3, input) {
|
|
1313
1313
|
this.assertToken("Reviewing a pull request");
|
|
1314
|
-
const r2 = await this.request("POST", `${this.repoPath}/pulls/${
|
|
1314
|
+
const r2 = await this.request("POST", `${this.repoPath}/pulls/${n3}/reviews`, input);
|
|
1315
1315
|
return { id: r2.id, user: r2.user?.login, state: r2.state, body: r2.body ?? "" };
|
|
1316
1316
|
}
|
|
1317
1317
|
async listCheckRuns(ref) {
|
|
@@ -1816,19 +1816,19 @@ const LIGHTNESS = { 50: 0.975, 100: 0.952, 200: 0.912, 300: 0.85, 400: 0.735, 50
|
|
|
1816
1816
|
const BELL = { 50: 0.12, 100: 0.22, 200: 0.4, 300: 0.62, 400: 0.85, 500: 1, 600: 1, 700: 0.92, 800: 0.8, 900: 0.62, 950: 0.5 };
|
|
1817
1817
|
const NEUTRAL_ANCHORS = { 200: "#E3E8EE", 600: "#5B6672", 900: "#15202B" };
|
|
1818
1818
|
const PIN_TOLERANCE = 0.04;
|
|
1819
|
-
const bellChroma = (peak) => (
|
|
1820
|
-
const neutralChroma = (scale = 1, low = 4e-3, base = 0.01, slope = 0.022) => (
|
|
1821
|
-
function oklchToLinear(L,
|
|
1819
|
+
const bellChroma = (peak) => (s2) => peak * BELL[s2];
|
|
1820
|
+
const neutralChroma = (scale = 1, low = 4e-3, base = 0.01, slope = 0.022) => (s2) => (s2 <= 100 ? low : base + slope * (s2 / 950)) * scale;
|
|
1821
|
+
function oklchToLinear(L, C, h3) {
|
|
1822
1822
|
const hr = h3 * Math.PI / 180;
|
|
1823
|
-
const a =
|
|
1824
|
-
const b =
|
|
1823
|
+
const a = C * Math.cos(hr);
|
|
1824
|
+
const b = C * Math.sin(hr);
|
|
1825
1825
|
const l2 = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3;
|
|
1826
1826
|
const m2 = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3;
|
|
1827
|
-
const
|
|
1827
|
+
const s2 = (L - 0.0894841775 * a - 1.291485548 * b) ** 3;
|
|
1828
1828
|
return [
|
|
1829
|
-
4.0767416621 * l2 - 3.3077115913 * m2 + 0.2309699292 *
|
|
1830
|
-
-1.2684380046 * l2 + 2.6097574011 * m2 - 0.3413193965 *
|
|
1831
|
-
-0.0041960863 * l2 - 0.7034186147 * m2 + 1.707614701 *
|
|
1829
|
+
4.0767416621 * l2 - 3.3077115913 * m2 + 0.2309699292 * s2,
|
|
1830
|
+
-1.2684380046 * l2 + 2.6097574011 * m2 - 0.3413193965 * s2,
|
|
1831
|
+
-0.0041960863 * l2 - 0.7034186147 * m2 + 1.707614701 * s2
|
|
1832
1832
|
];
|
|
1833
1833
|
}
|
|
1834
1834
|
const encode = (x) => {
|
|
@@ -1836,8 +1836,8 @@ const encode = (x) => {
|
|
|
1836
1836
|
return c10 <= 31308e-7 ? 12.92 * c10 : 1.055 * c10 ** (1 / 2.4) - 0.055;
|
|
1837
1837
|
};
|
|
1838
1838
|
const decode = (x) => x <= 0.04045 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;
|
|
1839
|
-
function oklch(L,
|
|
1840
|
-
let c10 =
|
|
1839
|
+
function oklch(L, C, h3) {
|
|
1840
|
+
let c10 = C;
|
|
1841
1841
|
let lin = oklchToLinear(L, c10, h3);
|
|
1842
1842
|
for (let i2 = 0; i2 < 60 && !lin.every((x) => x >= -5e-4 && x <= 1.0005); i2++) {
|
|
1843
1843
|
c10 *= 0.95;
|
|
@@ -1849,15 +1849,15 @@ function toOklch(rgb) {
|
|
|
1849
1849
|
const [r2, g3, b] = rgb.map(decode);
|
|
1850
1850
|
const l2 = Math.cbrt(0.4122214708 * r2 + 0.5363325363 * g3 + 0.0514459929 * b);
|
|
1851
1851
|
const m2 = Math.cbrt(0.2119034982 * r2 + 0.6806995451 * g3 + 0.1073969566 * b);
|
|
1852
|
-
const
|
|
1853
|
-
const L = 0.2104542553 * l2 + 0.793617785 * m2 - 0.0040720468 *
|
|
1854
|
-
const A = 1.9779984951 * l2 - 2.428592205 * m2 + 0.4505937099 *
|
|
1855
|
-
const B = 0.0259040371 * l2 + 0.7827717662 * m2 - 0.808675766 *
|
|
1856
|
-
const
|
|
1857
|
-
const h3 =
|
|
1858
|
-
return { L, C
|
|
1859
|
-
}
|
|
1860
|
-
const isHex = (
|
|
1852
|
+
const s2 = Math.cbrt(0.0883024619 * r2 + 0.2817188376 * g3 + 0.6299787005 * b);
|
|
1853
|
+
const L = 0.2104542553 * l2 + 0.793617785 * m2 - 0.0040720468 * s2;
|
|
1854
|
+
const A = 1.9779984951 * l2 - 2.428592205 * m2 + 0.4505937099 * s2;
|
|
1855
|
+
const B = 0.0259040371 * l2 + 0.7827717662 * m2 - 0.808675766 * s2;
|
|
1856
|
+
const C = Math.sqrt(A * A + B * B);
|
|
1857
|
+
const h3 = C < 1e-6 ? 0 : (Math.atan2(B, A) * 180 / Math.PI + 360) % 360;
|
|
1858
|
+
return { L, C, h: h3 };
|
|
1859
|
+
}
|
|
1860
|
+
const isHex = (s2) => typeof s2 === "string" && /^#[0-9a-f]{6}$/i.test(s2.trim());
|
|
1861
1861
|
const fromHex = (hex) => [1, 3, 5].map((i2) => parseInt(hex.slice(i2, i2 + 2), 16) / 255);
|
|
1862
1862
|
const round3 = (x) => Math.round(x * 1e3) / 1e3;
|
|
1863
1863
|
const toHex = (rgb) => "#" + rgb.map((x) => Math.round(x * 255).toString(16).padStart(2, "0")).join("");
|
|
@@ -1868,35 +1868,35 @@ function dtcgColor(rgb, alpha) {
|
|
|
1868
1868
|
}
|
|
1869
1869
|
function generateRamp({ hue, chroma, offset = () => 0, pins = {} }) {
|
|
1870
1870
|
const out = {};
|
|
1871
|
-
for (const
|
|
1872
|
-
const pin = pins[
|
|
1873
|
-
out[
|
|
1871
|
+
for (const s2 of STEPS) {
|
|
1872
|
+
const pin = pins[s2];
|
|
1873
|
+
out[s2] = pin ? fromHex(pin) : oklch(LIGHTNESS[s2] + offset(s2), chroma(s2), hue);
|
|
1874
1874
|
}
|
|
1875
1875
|
return out;
|
|
1876
1876
|
}
|
|
1877
1877
|
function nearestStep(rgb) {
|
|
1878
1878
|
const { L } = toOklch(rgb);
|
|
1879
1879
|
let best = STEPS[0];
|
|
1880
|
-
for (const
|
|
1880
|
+
for (const s2 of STEPS) if (Math.abs(LIGHTNESS[s2] - L) < Math.abs(LIGHTNESS[best] - L)) best = s2;
|
|
1881
1881
|
return best;
|
|
1882
1882
|
}
|
|
1883
1883
|
function anchoredRamp(hex, pinStep) {
|
|
1884
1884
|
const rgb = fromHex(hex);
|
|
1885
|
-
const { L, C
|
|
1885
|
+
const { L, C, h: h3 } = toOklch(rgb);
|
|
1886
1886
|
const step = pinStep ?? nearestStep(rgb);
|
|
1887
|
-
const peak = Math.min(0.24, Math.max(0.02,
|
|
1887
|
+
const peak = Math.min(0.24, Math.max(0.02, C / BELL[step]));
|
|
1888
1888
|
return { hue: h3, peak, step, distance: Math.abs(L - LIGHTNESS[step]), ramp: generateRamp({ hue: h3, chroma: bellChroma(peak), pins: { [step]: hex.toUpperCase() } }) };
|
|
1889
1889
|
}
|
|
1890
1890
|
function neutralOffset() {
|
|
1891
1891
|
const off = {};
|
|
1892
|
-
for (const [
|
|
1893
|
-
return (
|
|
1892
|
+
for (const [s2, hex] of Object.entries(NEUTRAL_ANCHORS)) off[s2] = toOklch(fromHex(hex)).L - LIGHTNESS[s2];
|
|
1893
|
+
return (s2) => off[s2] ?? 0;
|
|
1894
1894
|
}
|
|
1895
1895
|
function tintedNeutral(hex) {
|
|
1896
1896
|
const rgb = fromHex(hex);
|
|
1897
|
-
const { C
|
|
1897
|
+
const { C, h: h3 } = toOklch(rgb);
|
|
1898
1898
|
const ref = neutralChroma()(nearestStep(rgb));
|
|
1899
|
-
const scale =
|
|
1899
|
+
const scale = C < 4e-3 ? 0 : Math.min(2.5, C / ref);
|
|
1900
1900
|
return { hue: h3, scale, ramp: generateRamp({ hue: h3, chroma: neutralChroma(scale), offset: neutralOffset() }) };
|
|
1901
1901
|
}
|
|
1902
1902
|
const BRAND_FONTS = [
|
|
@@ -1968,8 +1968,8 @@ function rampFor(input, pinStep, kind) {
|
|
|
1968
1968
|
const hex = String(input).trim();
|
|
1969
1969
|
if (!isHex(hex)) throw new Error(`"${hex}" is not a color. Use #rrggbb or a hue in degrees (0 to 360).`);
|
|
1970
1970
|
if (kind === "neutral") {
|
|
1971
|
-
const
|
|
1972
|
-
return { ramp:
|
|
1971
|
+
const n3 = tintedNeutral(hex);
|
|
1972
|
+
return { ramp: n3.ramp, anchor: `${hex.toUpperCase()} (hue ${Math.round(n3.hue)})` };
|
|
1973
1973
|
}
|
|
1974
1974
|
const a = anchoredRamp(hex, pinStep);
|
|
1975
1975
|
const issue = a.distance > PIN_TOLERANCE ? {
|
|
@@ -1982,9 +1982,9 @@ function rampFor(input, pinStep, kind) {
|
|
|
1982
1982
|
function aliasRamp(doc, role, ramp, description) {
|
|
1983
1983
|
const group = getAt(doc, `palette.${role}`);
|
|
1984
1984
|
if (!group) return;
|
|
1985
|
-
for (const
|
|
1986
|
-
if (!(String(
|
|
1987
|
-
setAt(doc, `palette.${role}.${
|
|
1985
|
+
for (const s2 of STEPS) {
|
|
1986
|
+
if (!(String(s2) in group)) continue;
|
|
1987
|
+
setAt(doc, `palette.${role}.${s2}`, { $value: `{color.${ramp}.${s2}}` });
|
|
1988
1988
|
}
|
|
1989
1989
|
group.$description = description;
|
|
1990
1990
|
}
|
|
@@ -2031,15 +2031,15 @@ function listBrands(source) {
|
|
|
2031
2031
|
}
|
|
2032
2032
|
function checkBrandSlug(config, files, slug) {
|
|
2033
2033
|
const out = [];
|
|
2034
|
-
const
|
|
2035
|
-
if (!
|
|
2036
|
-
if (
|
|
2034
|
+
const s2 = slug.trim();
|
|
2035
|
+
if (!s2) return [{ level: "error", code: "slug-empty", message: "Give the brand a name." }];
|
|
2036
|
+
if (s2.length < 2 || s2.length > 24 || !BRAND_SLUG_RE.test(s2)) 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".' });
|
|
2037
2037
|
const taken = Object.values(config.axes).flatMap((a) => a.values);
|
|
2038
|
-
if (config.axes.brand?.values.includes(
|
|
2039
|
-
else if (taken.includes(
|
|
2038
|
+
if (config.axes.brand?.values.includes(s2)) out.push({ level: "error", code: "slug-taken", message: `A brand called "${s2}" already exists. Pick another name or edit that brand.` });
|
|
2039
|
+
else if (taken.includes(s2) || RESERVED.has(s2)) out.push({ level: "error", code: "slug-reserved", message: `"${s2}" is a reserved mode name. Pick another name.` });
|
|
2040
2040
|
const layer = brandLayers(config).brand;
|
|
2041
2041
|
const map = fileMap(files);
|
|
2042
|
-
if (layer && !config.axes.brand?.values.includes(
|
|
2042
|
+
if (layer && !config.axes.brand?.values.includes(s2) && map.has(fill(layer, { brand: s2 }))) out.push({ level: "error", code: "slug-file-exists", message: `${tokensPath(config, fill(layer, { brand: s2 }))} already exists. Pick another name or add it to bridge.config.json.` });
|
|
2043
2043
|
return out;
|
|
2044
2044
|
}
|
|
2045
2045
|
function planNewBrand(source, input) {
|
|
@@ -2219,7 +2219,7 @@ function planNewBrand(source, input) {
|
|
|
2219
2219
|
const ramps = {};
|
|
2220
2220
|
if (inGate) {
|
|
2221
2221
|
const combo = after.normalizeCombo({ brand: slug });
|
|
2222
|
-
const read = (role) => STEPS.map((
|
|
2222
|
+
const read = (role) => STEPS.map((s2) => ({ step: s2, hex: after.resolve(`palette.${role}.${s2}`, combo).css })).filter((x) => /^#[0-9a-f]{6}$/i.test(x.hex));
|
|
2223
2223
|
ramps.primary = read("primary");
|
|
2224
2224
|
ramps.neutral = read("neutral");
|
|
2225
2225
|
for (const role of ["accent", "link"]) {
|
|
@@ -2281,13 +2281,13 @@ function brandPreviewVariables(source, plan, theme) {
|
|
|
2281
2281
|
}
|
|
2282
2282
|
return out;
|
|
2283
2283
|
}
|
|
2284
|
-
const code = (
|
|
2284
|
+
const code = (s2) => `\`${s2}\``;
|
|
2285
2285
|
function newBrandSection(plan) {
|
|
2286
2286
|
const roles = Object.keys(plan.ramps);
|
|
2287
2287
|
const rampTable = roles.length ? [
|
|
2288
2288
|
`| Step | ${roles.map((r2) => r2[0].toUpperCase() + r2.slice(1)).join(" | ")} |`,
|
|
2289
2289
|
`| --- | ${roles.map(() => "---").join(" | ")} |`,
|
|
2290
|
-
...STEPS.map((
|
|
2290
|
+
...STEPS.map((s2) => `| ${s2}${s2 === plan.actionStep ? " (actions)" : ""} | ${roles.map((r2) => code(plan.ramps[r2].find((x) => x.step === s2)?.hex ?? "")).join(" | ")} |`)
|
|
2291
2291
|
].join("\n") : "_No ramps resolved._";
|
|
2292
2292
|
const c10 = plan.contrast;
|
|
2293
2293
|
const contrastLine = c10.failing.length ? `**${c10.failing.length} of ${c10.checks} pairs fail** for ${plan.name} (${c10.themes.join(" and ")}).` : `All ${c10.checks} contrast checks pass for ${plan.name} in ${c10.themes.join(" and ")}.`;
|
|
@@ -2311,7 +2311,7 @@ function newBrandSection(plan) {
|
|
|
2311
2311
|
}
|
|
2312
2312
|
function composeNewBrandBody(plan, opts) {
|
|
2313
2313
|
const t3 = plan.risk.tier;
|
|
2314
|
-
const box = (
|
|
2314
|
+
const box = (n3) => `- ${n3 === t3 ? "[x]" : "[ ]"} ${RISK_LABELS[n3]}`;
|
|
2315
2315
|
const errors = plan.issues.filter((i2) => i2.level === "error");
|
|
2316
2316
|
const warnings = plan.issues.filter((i2) => i2.level === "warning");
|
|
2317
2317
|
return [
|
|
@@ -2376,7 +2376,7 @@ function cssModuleClasses(css) {
|
|
|
2376
2376
|
}
|
|
2377
2377
|
return out;
|
|
2378
2378
|
}
|
|
2379
|
-
const cell$1 = (
|
|
2379
|
+
const cell$1 = (s2) => s2.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
2380
2380
|
function propsTable(name, props, inherits) {
|
|
2381
2381
|
if (!props.length) return inherits ? `${name} has no props of its own. It accepts every native <${inherits}> attribute.` : "";
|
|
2382
2382
|
const rows = props.map((p) => `| \`${p.name}\`${p.required ? " (required)" : ""} | \`${cell$1(p.type)}\` | ${p.defaultValue ? `\`${cell$1(p.defaultValue)}\`` : ""} | ${cell$1(p.description ?? "")} |`);
|
|
@@ -2519,9 +2519,9 @@ function formatDocsJson(d2) {
|
|
|
2519
2519
|
function patchNode(old, next) {
|
|
2520
2520
|
if (plainEqual(toPlain(old), next)) return old;
|
|
2521
2521
|
if (old.kind === "object" && next && typeof next === "object" && !Array.isArray(next)) {
|
|
2522
|
-
const
|
|
2523
|
-
const kept = old.entries.filter((e2) =>
|
|
2524
|
-
const added = Object.keys(
|
|
2522
|
+
const n3 = next;
|
|
2523
|
+
const kept = old.entries.filter((e2) => n3[e2.key] !== void 0).map((e2) => ({ key: e2.key, value: patchNode(e2.value, n3[e2.key]) }));
|
|
2524
|
+
const added = Object.keys(n3).filter((k3) => n3[k3] !== void 0 && !getEntry(old, k3)).map((k3) => ({ key: k3, value: fromPlain(n3[k3], void 0, old.inline) }));
|
|
2525
2525
|
return { kind: "object", inline: old.inline, entries: [...kept, ...added] };
|
|
2526
2526
|
}
|
|
2527
2527
|
if (old.kind === "array" && Array.isArray(next)) {
|
|
@@ -2547,16 +2547,16 @@ const DOCS_CHANGE_BUMP = "patch";
|
|
|
2547
2547
|
function cleanDraftText(text) {
|
|
2548
2548
|
return text.replace(/\s*\u2014\s*/g, ", ").replace(/,\s*,/g, ",").replace(/^,\s*/, "").replace(/[ \t]+/g, " ").trim();
|
|
2549
2549
|
}
|
|
2550
|
-
const values = (
|
|
2550
|
+
const values = (s2) => (s2 ?? "").split(", ").map((x) => x.trim()).filter(Boolean);
|
|
2551
2551
|
const article = (word) => /^[aeiou]/i.test(word) ? "an" : "a";
|
|
2552
2552
|
const andList = (xs) => xs.length <= 1 ? xs[0] ?? "" : `${xs.slice(0, -1).join(", ")} and ${xs[xs.length - 1]}`;
|
|
2553
|
-
const plural = (
|
|
2554
|
-
const capital = (
|
|
2555
|
-
const lower = (
|
|
2556
|
-
function propShape(
|
|
2557
|
-
if (!
|
|
2558
|
-
const m2 = /^(.*?), default (.*)$/.exec(
|
|
2559
|
-
return m2 ? { type: m2[1], def: m2[2] } : { type:
|
|
2553
|
+
const plural = (n3, word, many = `${word}s`) => `${n3} ${n3 === 1 ? word : many}`;
|
|
2554
|
+
const capital = (s2) => s2.charAt(0).toUpperCase() + s2.slice(1);
|
|
2555
|
+
const lower = (s2) => s2.charAt(0).toLowerCase() + s2.slice(1);
|
|
2556
|
+
function propShape(s2) {
|
|
2557
|
+
if (!s2) return void 0;
|
|
2558
|
+
const m2 = /^(.*?), default (.*)$/.exec(s2);
|
|
2559
|
+
return m2 ? { type: m2[1], def: m2[2] } : { type: s2, def: "" };
|
|
2560
2560
|
}
|
|
2561
2561
|
const VARIANT_FIRST = ["variant", "tone", "intent", "appearance", "kind", "type", "style"];
|
|
2562
2562
|
function shortVariant(key) {
|
|
@@ -2842,19 +2842,19 @@ function parseDocsReply(text) {
|
|
|
2842
2842
|
if (!json || typeof json !== "object" || Array.isArray(json)) throw new Error("The reply is not a docs.json object.");
|
|
2843
2843
|
return json;
|
|
2844
2844
|
}
|
|
2845
|
-
const cleanDocsText = (
|
|
2845
|
+
const cleanDocsText = (s2) => cleanDraftText(s2.replace(/[\r\n]+/g, " "));
|
|
2846
2846
|
const isExample = (x) => {
|
|
2847
2847
|
if (typeof x === "string") return true;
|
|
2848
2848
|
if (!x || typeof x !== "object" || Array.isArray(x)) return false;
|
|
2849
|
-
const
|
|
2850
|
-
if (typeof
|
|
2851
|
-
if (
|
|
2852
|
-
return
|
|
2849
|
+
const n3 = x;
|
|
2850
|
+
if (typeof n3.c !== "string" || !n3.c) return false;
|
|
2851
|
+
if (n3.p !== void 0 && (!n3.p || typeof n3.p !== "object" || Array.isArray(n3.p))) return false;
|
|
2852
|
+
return n3.children === void 0 || Array.isArray(n3.children) && n3.children.every(isExample);
|
|
2853
2853
|
};
|
|
2854
2854
|
const textList = (x) => {
|
|
2855
2855
|
if (typeof x === "string") x = [x];
|
|
2856
2856
|
if (!Array.isArray(x)) return void 0;
|
|
2857
|
-
const out = x.filter((
|
|
2857
|
+
const out = x.filter((s2) => typeof s2 === "string").map(cleanDocsText).filter(Boolean);
|
|
2858
2858
|
return out.length ? out : void 0;
|
|
2859
2859
|
};
|
|
2860
2860
|
const guidanceList = (x, examples) => {
|
|
@@ -2877,8 +2877,8 @@ function sanitizeDocsSections(raw, keys = PROSE_KEYS, opts = {}) {
|
|
|
2877
2877
|
for (const k3 of keys) {
|
|
2878
2878
|
const v2 = r2[k3];
|
|
2879
2879
|
if (k3 === "summary") {
|
|
2880
|
-
const
|
|
2881
|
-
if (
|
|
2880
|
+
const s2 = typeof v2 === "string" ? cleanDocsText(v2) : "";
|
|
2881
|
+
if (s2) out.summary = s2;
|
|
2882
2882
|
} else if (k3 === "dos" || k3 === "donts") {
|
|
2883
2883
|
const g3 = guidanceList(v2, opts.examples ?? false);
|
|
2884
2884
|
if (g3) out[k3] = g3;
|
|
@@ -2970,9 +2970,9 @@ const EXPLORATION_STATUS_LABEL = { active: "Running", promoted: "Promoted to rev
|
|
|
2970
2970
|
const MARK$1 = "bridge-exploration";
|
|
2971
2971
|
const SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
2972
2972
|
function explorationSlug(name) {
|
|
2973
|
-
const
|
|
2974
|
-
if (!/[a-z0-9]/i.test(
|
|
2975
|
-
return slugify(
|
|
2973
|
+
const s2 = name.trim().replace(/^explore\//i, "");
|
|
2974
|
+
if (!/[a-z0-9]/i.test(s2)) return "";
|
|
2975
|
+
return slugify(s2, 40);
|
|
2976
2976
|
}
|
|
2977
2977
|
function explorationBranch(nameOrBranch) {
|
|
2978
2978
|
return `${EXPLORATION_PREFIX}${explorationSlug(nameOrBranch)}`;
|
|
@@ -3013,8 +3013,8 @@ function explorationNote(e2) {
|
|
|
3013
3013
|
].join("\n");
|
|
3014
3014
|
}
|
|
3015
3015
|
function explorationPrTitle(e2) {
|
|
3016
|
-
const
|
|
3017
|
-
return `Exploration: ${
|
|
3016
|
+
const n3 = e2.name.trim().replace(/\.$/, "");
|
|
3017
|
+
return `Exploration: ${n3.charAt(0).toLowerCase()}${n3.slice(1)}`;
|
|
3018
3018
|
}
|
|
3019
3019
|
function explorationPrBody(e2, ctx) {
|
|
3020
3020
|
const slug = e2.slug || explorationSlug(e2.name);
|
|
@@ -3079,6 +3079,8 @@ function explorationStatus(p) {
|
|
|
3079
3079
|
const isActiveExploration = (labels) => labelNames(labels).includes(EXPLORATION_LABEL);
|
|
3080
3080
|
function promotionPlan(input) {
|
|
3081
3081
|
const exploration = parseExplorationBody(input.body);
|
|
3082
|
+
const jira = /^([A-Z][A-Z0-9_]*-\d+)\s+/.exec(input.title)?.[1] ?? null;
|
|
3083
|
+
const title = jira ? input.title.slice(jira.length).trim() : input.title;
|
|
3082
3084
|
const removeFiles = input.files.filter((f) => f.path.startsWith(`${EXPLORATION_NOTES_DIR}/`) && f.status !== "removed").map((f) => f.path);
|
|
3083
3085
|
const files = input.files.filter((f) => !f.path.startsWith(`${EXPLORATION_NOTES_DIR}/`));
|
|
3084
3086
|
const risk = classifyRisk({ files, ...input.config ? { config: input.config } : {} });
|
|
@@ -3086,18 +3088,18 @@ function promotionPlan(input) {
|
|
|
3086
3088
|
const addLabels = [`tier: ${risk.tier}`, ...risk.tier === 3 && tokens ? ["tokens"] : []];
|
|
3087
3089
|
const date = (input.date ?? /* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
3088
3090
|
const existing = new Set(input.body ? [...input.body.matchAll(/\b(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi)].map((m2) => Number(m2[1])) : []);
|
|
3089
|
-
const closes = [...new Set(input.requests ?? [])].filter((
|
|
3091
|
+
const closes = [...new Set(input.requests ?? [])].filter((n3) => !existing.has(n3));
|
|
3090
3092
|
const kept = (input.body ?? "").replace(/^> Not mergeable as is\..*$\n?\n?/m, "").replace(/### When it is done[\s\S]*?(?=<!-- |$)/, "").replace(/^## Exploration: /m, "## ").trim();
|
|
3091
3093
|
const body = [
|
|
3092
3094
|
`**Promoted from an exploration on ${date}.** Review it like any change: the tier below comes from the files it touches.`,
|
|
3093
3095
|
"",
|
|
3094
|
-
kept || `## ${
|
|
3096
|
+
kept || `## ${title.replace(/^Exploration:\s*/i, "")}`,
|
|
3095
3097
|
"",
|
|
3096
3098
|
`**Risk tier:** ${risk.tier}.`,
|
|
3097
3099
|
...risk.reasons.slice(0, 8).map((r2) => `- ${r2}`),
|
|
3098
|
-
...closes.length ? ["", ...closes.map((
|
|
3100
|
+
...closes.length ? ["", ...closes.map((n3) => `Closes #${n3}`)] : []
|
|
3099
3101
|
].join("\n");
|
|
3100
|
-
const t3 =
|
|
3102
|
+
const t3 = title.replace(/^Exploration:\s*/i, "").trim() || exploration?.name || title;
|
|
3101
3103
|
return {
|
|
3102
3104
|
tier: risk.tier,
|
|
3103
3105
|
reasons: risk.reasons,
|
|
@@ -3105,7 +3107,7 @@ function promotionPlan(input) {
|
|
|
3105
3107
|
addLabels,
|
|
3106
3108
|
removeFiles,
|
|
3107
3109
|
body,
|
|
3108
|
-
title: t3.charAt(0).toUpperCase()
|
|
3110
|
+
title: `${jira ? `${jira} ` : ""}${t3.charAt(0).toUpperCase()}${t3.slice(1)}`,
|
|
3109
3111
|
markReady: true
|
|
3110
3112
|
};
|
|
3111
3113
|
}
|
|
@@ -3249,8 +3251,8 @@ function requestBrief(r2, ctx) {
|
|
|
3249
3251
|
"- If the request is unclear or conflicts with the guidance, comment on the issue instead of guessing."
|
|
3250
3252
|
].join("\n");
|
|
3251
3253
|
}
|
|
3252
|
-
const cell = (
|
|
3253
|
-
const sourceLabel = (
|
|
3254
|
+
const cell = (s2) => s2.replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
3255
|
+
const sourceLabel = (s2) => s2 === "figma" ? "Figma" : s2 === "studio" ? "Bridge Studio" : s2 === "cli" ? "the CLI" : "Claude (MCP)";
|
|
3254
3256
|
function validateIntegrations(i2) {
|
|
3255
3257
|
const out = [];
|
|
3256
3258
|
if (!i2?.jira) return out;
|
|
@@ -3308,7 +3310,7 @@ function newDraftSessionId(random = Math.random) {
|
|
|
3308
3310
|
return out;
|
|
3309
3311
|
}
|
|
3310
3312
|
const SESSION_RE = /^[a-z0-9-]{6,64}$/;
|
|
3311
|
-
const isDraftSessionId = (
|
|
3313
|
+
const isDraftSessionId = (s2) => typeof s2 === "string" && SESSION_RE.test(s2);
|
|
3312
3314
|
function draftSessionPath(sessionId) {
|
|
3313
3315
|
if (!isDraftSessionId(sessionId)) throw new Error(`"${sessionId}" is not a draft session id.`);
|
|
3314
3316
|
return `${DRAFTS_DIR}/${sessionId}.json`;
|
|
@@ -3345,8 +3347,8 @@ function validatePendingDrafts(x) {
|
|
|
3345
3347
|
if (p.source !== "figma" && p.source !== "studio") out.push('source must be "figma" or "studio".');
|
|
3346
3348
|
if (!Array.isArray(p.items) || !p.items.length) out.push("A draft session needs at least one item.");
|
|
3347
3349
|
const ids = /* @__PURE__ */ new Set();
|
|
3348
|
-
for (const [
|
|
3349
|
-
const at2 = `Item ${
|
|
3350
|
+
for (const [n3, i2] of (Array.isArray(p.items) ? p.items : []).entries()) {
|
|
3351
|
+
const at2 = `Item ${n3 + 1}`;
|
|
3350
3352
|
if (!i2 || typeof i2 !== "object") {
|
|
3351
3353
|
out.push(`${at2} is not an object.`);
|
|
3352
3354
|
continue;
|
|
@@ -3405,7 +3407,7 @@ function clip(text, max) {
|
|
|
3405
3407
|
function sentences(text) {
|
|
3406
3408
|
const t3 = text.replace(/\s+/g, " ").trim();
|
|
3407
3409
|
const parts = t3.match(/[^.!?]+(?:[.!?]+(?=\s|$)|$)/g) ?? [t3];
|
|
3408
|
-
let out = parts.slice(0, DRAFT_SUMMARY_SENTENCES).map((
|
|
3410
|
+
let out = parts.slice(0, DRAFT_SUMMARY_SENTENCES).map((s2) => s2.trim()).join(" ");
|
|
3409
3411
|
if (out.length > SUMMARY_MAX) out = `${clip(out, SUMMARY_MAX)}.`;
|
|
3410
3412
|
return out;
|
|
3411
3413
|
}
|
|
@@ -3478,7 +3480,7 @@ function draftItemBrief(i2) {
|
|
|
3478
3480
|
return [`Item ${i2.id}: component docs${i2.component ? ` of ${i2.component}` : ""} from Bridge Studio (${i2.docs.path ?? i2.docs.slug}): ${what}.`, "", i2.docs.prompt].join("\n");
|
|
3479
3481
|
}
|
|
3480
3482
|
const kind = i2.kind ? REQUEST_KINDS.find((k3) => k3.value === i2.kind)?.label : void 0;
|
|
3481
|
-
const cell2 = (
|
|
3483
|
+
const cell2 = (s2) => (s2 ?? "").replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
3482
3484
|
const lines = [`Item ${i2.id}: ${i2.scope === "request" ? "a component change request (a GitHub issue developers implement)" : "the description of a pull request with design token (variable) edits from Figma"}.`];
|
|
3483
3485
|
if (i2.component) lines.push(`Component: ${i2.component}`);
|
|
3484
3486
|
if (kind) lines.push(`Kind: ${kind}`);
|
|
@@ -3645,7 +3647,7 @@ class DraftPoller {
|
|
|
3645
3647
|
}
|
|
3646
3648
|
}
|
|
3647
3649
|
}
|
|
3648
|
-
function explorationSummary(p, _owner, _repo,
|
|
3650
|
+
function explorationSummary(p, _owner, _repo, s2) {
|
|
3649
3651
|
const e2 = parseExplorationBody(p.body);
|
|
3650
3652
|
const slug = p.headRef?.startsWith(EXPLORATION_PREFIX) ? p.headRef.slice(EXPLORATION_PREFIX.length) : e2?.slug ?? explorationSlug(p.title);
|
|
3651
3653
|
return {
|
|
@@ -3653,7 +3655,7 @@ function explorationSummary(p, _owner, _repo, s) {
|
|
|
3653
3655
|
url: p.url,
|
|
3654
3656
|
branch: p.headRef,
|
|
3655
3657
|
slug,
|
|
3656
|
-
name: e2?.name ?? p.title.replace(/^Exploration:\s*/i, ""),
|
|
3658
|
+
name: e2?.name ?? p.title.replace(/^[A-Z][A-Z0-9_]*-\d+\s+/, "").replace(/^Exploration:\s*/i, ""),
|
|
3657
3659
|
purpose: e2?.purpose ?? "",
|
|
3658
3660
|
...e2?.useCase ? { useCase: e2.useCase } : {},
|
|
3659
3661
|
status: explorationStatus({ state: p.state, labels: p.labels, headRef: p.headRef, body: p.body }),
|
|
@@ -3663,14 +3665,14 @@ function explorationSummary(p, _owner, _repo, s) {
|
|
|
3663
3665
|
...e2?.agent ? { agent: e2.agent } : {},
|
|
3664
3666
|
updatedAt: p.updatedAt,
|
|
3665
3667
|
headSha: p.headSha,
|
|
3666
|
-
previews: previewLinks(
|
|
3668
|
+
previews: previewLinks(s2.apps, { branch: p.headRef, pr: p.number, sha: p.headSha })
|
|
3667
3669
|
};
|
|
3668
3670
|
}
|
|
3669
|
-
async function listExplorationsOnGitHub(gh,
|
|
3671
|
+
async function listExplorationsOnGitHub(gh, s2, opts = {}) {
|
|
3670
3672
|
const pulls = await gh.listPullRequests(opts.state ?? "open");
|
|
3671
|
-
return pulls.filter((p) => isExplorationPull({ state: p.state, labels: p.labels, headRef: p.headRef, body: p.body })).map((p) => explorationSummary(p, gh.owner, gh.name,
|
|
3673
|
+
return pulls.filter((p) => isExplorationPull({ state: p.state, labels: p.labels, headRef: p.headRef, body: p.body })).map((p) => explorationSummary(p, gh.owner, gh.name, s2));
|
|
3672
3674
|
}
|
|
3673
|
-
async function startExplorationOnGitHub(gh, e2,
|
|
3675
|
+
async function startExplorationOnGitHub(gh, e2, s2) {
|
|
3674
3676
|
const problems = explorationProblems(e2);
|
|
3675
3677
|
if (problems.length) throw new GitHubError(422, problems.join(" "));
|
|
3676
3678
|
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).");
|
|
@@ -3680,7 +3682,7 @@ async function startExplorationOnGitHub(gh, e2, s) {
|
|
|
3680
3682
|
if (await x.getBranchSha(branch)) throw new GitHubError(422, `An exploration named "${slug}" already exists (${branch}). Pick another name, or continue that one.`);
|
|
3681
3683
|
const full = { ...e2, slug, startedAt: e2.startedAt ?? (/* @__PURE__ */ new Date()).toISOString() };
|
|
3682
3684
|
const commit = await x.commitToNewBranch({
|
|
3683
|
-
base:
|
|
3685
|
+
base: s2.base,
|
|
3684
3686
|
branch,
|
|
3685
3687
|
message: `chore(explore): start ${full.name.trim()}
|
|
3686
3688
|
|
|
@@ -3689,8 +3691,9 @@ ${full.purpose.trim()}
|
|
|
3689
3691
|
Exploration: never merged as is. Promote it to review or close it.`,
|
|
3690
3692
|
files: [{ path: explorationNotePath(slug), content: explorationNote(full) }]
|
|
3691
3693
|
});
|
|
3692
|
-
const ctx = { owner: gh.owner, repo: gh.name, packages:
|
|
3693
|
-
const
|
|
3694
|
+
const ctx = { owner: gh.owner, repo: gh.name, packages: s2.packages, apps: s2.apps, ...s2.requests?.length ? { requests: s2.requests } : {} };
|
|
3695
|
+
const title = full.jira ? `${full.jira.trim().toUpperCase()} ${explorationPrTitle(full)}` : explorationPrTitle(full);
|
|
3696
|
+
const pr = await x.createPullRequest({ title, head: branch, base: s2.base, body: explorationPrBody(full, ctx), draft: true });
|
|
3694
3697
|
await x.addLabels(pr.number, [EXPLORATION_LABEL]);
|
|
3695
3698
|
await x.updatePullRequest(pr.number, { body: explorationPrBody(full, { ...ctx, pr: pr.number }) }).catch(() => void 0);
|
|
3696
3699
|
return {
|
|
@@ -3700,7 +3703,7 @@ Exploration: never merged as is. Promote it to review or close it.`,
|
|
|
3700
3703
|
url: pr.url,
|
|
3701
3704
|
commit: commit.sha,
|
|
3702
3705
|
tryIt: { state: "building" },
|
|
3703
|
-
previews: previewLinks(
|
|
3706
|
+
previews: previewLinks(s2.apps, { branch, pr: pr.number, sha: commit.sha })
|
|
3704
3707
|
};
|
|
3705
3708
|
}
|
|
3706
3709
|
async function explorationTryItOnGitHub(gh, e2) {
|
|
@@ -3756,59 +3759,313 @@ async function closeExplorationOnGitHub(gh, ref) {
|
|
|
3756
3759
|
await gh.updatePullRequest(p.number, { state: "closed" });
|
|
3757
3760
|
return { number: p.number, url: p.url, branch: p.headRef };
|
|
3758
3761
|
}
|
|
3759
|
-
async function linkRequestToExplorationOnGitHub(gh,
|
|
3762
|
+
async function linkRequestToExplorationOnGitHub(gh, n3, branch, opts = {}) {
|
|
3760
3763
|
if (!isExplorationBranch(branch)) throw new GitHubError(422, `"${branch}" is not an exploration branch. Exploration branches are named explore/<name>.`);
|
|
3761
|
-
const issue = await gh.getIssue(
|
|
3764
|
+
const issue = await gh.getIssue(n3);
|
|
3762
3765
|
const body = withRequestExploration(issue.body, branch);
|
|
3763
|
-
if (!body) throw new GitHubError(422, `#${
|
|
3764
|
-
await gh.updateIssue(
|
|
3766
|
+
if (!body) throw new GitHubError(422, `#${n3} has no Bridge request block, so it cannot be linked. Add "exploration: ${branch}" to it on GitHub.`);
|
|
3767
|
+
await gh.updateIssue(n3, { body });
|
|
3765
3768
|
const warnings = [];
|
|
3766
|
-
if (!await gh.addLabels(
|
|
3769
|
+
if (!await gh.addLabels(n3, [EXPLORATION_LABEL])) warnings.push(`The ${EXPLORATION_LABEL} label could not be added to #${n3}.`);
|
|
3767
3770
|
let assignees = [];
|
|
3768
3771
|
if (opts.assignee) {
|
|
3769
3772
|
try {
|
|
3770
|
-
assignees = await gh.addAssignees(
|
|
3773
|
+
assignees = await gh.addAssignees(n3, [opts.assignee.replace(/^@/, "")]);
|
|
3771
3774
|
} catch {
|
|
3772
|
-
warnings.push(`@${opts.assignee.replace(/^@/, "")} could not be assigned to #${
|
|
3775
|
+
warnings.push(`@${opts.assignee.replace(/^@/, "")} could not be assigned to #${n3}.`);
|
|
3773
3776
|
}
|
|
3774
3777
|
}
|
|
3775
|
-
return { number:
|
|
3778
|
+
return { number: n3, branch, assignees, warnings };
|
|
3776
3779
|
}
|
|
3777
|
-
async function assignRequestOnGitHub(gh,
|
|
3780
|
+
async function assignRequestOnGitHub(gh, n3, login) {
|
|
3778
3781
|
const who = login.trim().replace(/^@/, "");
|
|
3779
3782
|
if (!who) throw new GitHubError(422, "Pick who should work on it.");
|
|
3780
|
-
const assignees = await gh.addAssignees(
|
|
3783
|
+
const assignees = await gh.addAssignees(n3, [who]);
|
|
3781
3784
|
if (!assignees.some((a) => a.toLowerCase() === who.toLowerCase())) throw new GitHubError(422, `GitHub did not assign @${who}: they need access to this repository.`);
|
|
3782
3785
|
return assignees;
|
|
3783
3786
|
}
|
|
3784
|
-
async function declineRequestOnGitHub(gh,
|
|
3787
|
+
async function declineRequestOnGitHub(gh, n3, reason, by2) {
|
|
3785
3788
|
const problems = declineReasonProblems(reason);
|
|
3786
3789
|
if (problems.length) throw new GitHubError(422, problems.join(" "));
|
|
3787
|
-
await gh.addComment(
|
|
3788
|
-
await gh.updateIssue(
|
|
3790
|
+
await gh.addComment(n3, declineComment(reason, by2));
|
|
3791
|
+
await gh.updateIssue(n3, { state: "closed", state_reason: "not_planned" });
|
|
3792
|
+
}
|
|
3793
|
+
const FIDELITY_DEFAULTS = { scale: 2, threshold: 0.1, maxPercent: 3, sizeTolerance: 1 };
|
|
3794
|
+
const MAX_DELTA = 35215;
|
|
3795
|
+
const STRICT_THRESHOLD = 0.02;
|
|
3796
|
+
function rgbAt(img, x, y) {
|
|
3797
|
+
if (x < 0 || y < 0 || x >= img.width || y >= img.height) return [255, 255, 255];
|
|
3798
|
+
const i2 = (y * img.width + x) * 4;
|
|
3799
|
+
const a = img.data[i2 + 3] / 255;
|
|
3800
|
+
return [255 + (img.data[i2] - 255) * a, 255 + (img.data[i2 + 1] - 255) * a, 255 + (img.data[i2 + 2] - 255) * a];
|
|
3801
|
+
}
|
|
3802
|
+
function colorDelta(a, b) {
|
|
3803
|
+
const dr = a[0] - b[0];
|
|
3804
|
+
const dg = a[1] - b[1];
|
|
3805
|
+
const db = a[2] - b[2];
|
|
3806
|
+
const y = dr * 0.29889531 + dg * 0.58662247 + db * 0.11448223;
|
|
3807
|
+
const i2 = dr * 0.59597799 - dg * 0.2741761 - db * 0.32180189;
|
|
3808
|
+
const q2 = dr * 0.21147017 - dg * 0.52261711 + db * 0.31114694;
|
|
3809
|
+
return 0.5053 * y * y + 0.299 * i2 * i2 + 0.1957 * q2 * q2;
|
|
3810
|
+
}
|
|
3811
|
+
function foundNear(img, x, y, c10, radius, max) {
|
|
3812
|
+
for (let dy = -radius; dy <= radius; dy++) for (let dx = -radius; dx <= radius; dx++) if (colorDelta(c10, rgbAt(img, x + dx, y + dy)) <= max) return true;
|
|
3813
|
+
return false;
|
|
3814
|
+
}
|
|
3815
|
+
function compareImages(figma, code2, options = {}) {
|
|
3816
|
+
const scale = options.scale ?? FIDELITY_DEFAULTS.scale;
|
|
3817
|
+
const radius = Math.max(0, Math.round(options.radius ?? scale));
|
|
3818
|
+
const max = MAX_DELTA * (options.threshold ?? FIDELITY_DEFAULTS.threshold) ** 2;
|
|
3819
|
+
const strict = MAX_DELTA * STRICT_THRESHOLD ** 2;
|
|
3820
|
+
const width = Math.max(figma.width, code2.width);
|
|
3821
|
+
const height = Math.max(figma.height, code2.height);
|
|
3822
|
+
const total = width * height;
|
|
3823
|
+
const wantDiff = options.diffImage !== false;
|
|
3824
|
+
const out = wantDiff ? new Uint8ClampedArray(total * 4) : void 0;
|
|
3825
|
+
let different = 0;
|
|
3826
|
+
for (let y = 0; y < height; y++) {
|
|
3827
|
+
for (let x = 0; x < width; x++) {
|
|
3828
|
+
const a = rgbAt(figma, x, y);
|
|
3829
|
+
const b = rgbAt(code2, x, y);
|
|
3830
|
+
const m2 = x < Math.min(figma.width, code2.width) && y < Math.min(figma.height, code2.height) ? max : strict;
|
|
3831
|
+
const same = colorDelta(a, b) <= m2 || foundNear(code2, x, y, a, radius, m2) && foundNear(figma, x, y, b, radius, m2);
|
|
3832
|
+
if (!same) different++;
|
|
3833
|
+
if (out) {
|
|
3834
|
+
const o2 = (y * width + x) * 4;
|
|
3835
|
+
if (same) {
|
|
3836
|
+
const gray = 255 + (b[0] * 0.299 + b[1] * 0.587 + b[2] * 0.114 - 255) * 0.1;
|
|
3837
|
+
out[o2] = out[o2 + 1] = out[o2 + 2] = gray;
|
|
3838
|
+
} else {
|
|
3839
|
+
out[o2] = 220;
|
|
3840
|
+
out[o2 + 1] = 38;
|
|
3841
|
+
out[o2 + 2] = 38;
|
|
3842
|
+
}
|
|
3843
|
+
out[o2 + 3] = 255;
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
const css = (img) => ({ width: Math.round(img.width / scale), height: Math.round(img.height / scale) });
|
|
3848
|
+
const size = { figma: css(figma), code: css(code2) };
|
|
3849
|
+
const tol = options.sizeTolerance ?? FIDELITY_DEFAULTS.sizeTolerance;
|
|
3850
|
+
const sizeMatches = Math.abs(size.figma.width - size.code.width) <= tol && Math.abs(size.figma.height - size.code.height) <= tol;
|
|
3851
|
+
const percent = total ? Math.round(different / total * 1e4) / 100 : 0;
|
|
3852
|
+
return {
|
|
3853
|
+
matches: sizeMatches && percent <= (options.maxPercent ?? FIDELITY_DEFAULTS.maxPercent),
|
|
3854
|
+
percent,
|
|
3855
|
+
differentPixels: different,
|
|
3856
|
+
totalPixels: total,
|
|
3857
|
+
size,
|
|
3858
|
+
sizeMatches,
|
|
3859
|
+
...out ? { diff: { width, height, data: out } } : {}
|
|
3860
|
+
};
|
|
3861
|
+
}
|
|
3862
|
+
function summarizeComponent(component, variants, reason) {
|
|
3863
|
+
const compared = variants.filter((v2) => v2.status !== "skipped");
|
|
3864
|
+
const differing = compared.filter((v2) => v2.status === "differs");
|
|
3865
|
+
const rank = (v2) => (v2.status === "differs" ? 1e3 : 0) + (v2.percent ?? 0) + (v2.size && !sameSize(v2.size) ? 500 : 0);
|
|
3866
|
+
const worst = [...compared].sort((a, b) => rank(b) - rank(a))[0];
|
|
3867
|
+
return {
|
|
3868
|
+
component,
|
|
3869
|
+
status: compared.length === 0 ? "not-checked" : differing.length ? "differs" : "matches",
|
|
3870
|
+
checked: compared.length,
|
|
3871
|
+
differing: differing.length,
|
|
3872
|
+
skipped: variants.length - compared.length,
|
|
3873
|
+
...worst && worst.size ? { worst: { key: worst.key, percent: worst.percent ?? 0, size: worst.size } } : {},
|
|
3874
|
+
...compared.length === 0 ? { reason: reason ?? variants.find((v2) => v2.reason)?.reason } : {},
|
|
3875
|
+
variants
|
|
3876
|
+
};
|
|
3877
|
+
}
|
|
3878
|
+
const sameSize = (s2) => s2.figma.width === s2.code.width && s2.figma.height === s2.code.height;
|
|
3879
|
+
function buildFidelityReport(input) {
|
|
3880
|
+
const o2 = input.options ?? {};
|
|
3881
|
+
const scale = o2.scale ?? FIDELITY_DEFAULTS.scale;
|
|
3882
|
+
const c10 = input.components;
|
|
3883
|
+
return {
|
|
3884
|
+
version: 1,
|
|
3885
|
+
checkedAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
3886
|
+
...input.file ? { file: input.file } : {},
|
|
3887
|
+
reference: input.reference,
|
|
3888
|
+
options: {
|
|
3889
|
+
scale,
|
|
3890
|
+
threshold: o2.threshold ?? FIDELITY_DEFAULTS.threshold,
|
|
3891
|
+
radius: Math.round(o2.radius ?? scale),
|
|
3892
|
+
maxPercent: o2.maxPercent ?? FIDELITY_DEFAULTS.maxPercent,
|
|
3893
|
+
sizeTolerance: o2.sizeTolerance ?? FIDELITY_DEFAULTS.sizeTolerance
|
|
3894
|
+
},
|
|
3895
|
+
components: c10,
|
|
3896
|
+
summary: {
|
|
3897
|
+
components: c10.length,
|
|
3898
|
+
matches: c10.filter((x) => x.status === "matches").length,
|
|
3899
|
+
differs: c10.filter((x) => x.status === "differs").length,
|
|
3900
|
+
notChecked: c10.filter((x) => x.status === "not-checked").length,
|
|
3901
|
+
variantsChecked: c10.reduce((n3, x) => n3 + x.checked, 0),
|
|
3902
|
+
variantsSkipped: c10.reduce((n3, x) => n3 + x.skipped, 0)
|
|
3903
|
+
}
|
|
3904
|
+
};
|
|
3905
|
+
}
|
|
3906
|
+
const fmtPercent = (p) => p >= 10 ? `${Math.round(p)}%` : p >= 1 ? `${Math.round(p * 10) / 10}%` : p > 0 ? "under 1%" : "0%";
|
|
3907
|
+
const fmtSize = (s2) => `${s2.width}x${s2.height}`;
|
|
3908
|
+
function fidelityVerdict(v2) {
|
|
3909
|
+
if (v2.status === "skipped") return `Not compared: ${v2.reason ?? "no image of the code"}`;
|
|
3910
|
+
if (v2.status === "matches") return "Matches the code";
|
|
3911
|
+
const parts = [`${fmtPercent(v2.percent ?? 0)} of pixels`];
|
|
3912
|
+
if (v2.size && !sameSize(v2.size)) parts.push(`size ${fmtSize(v2.size.figma)} vs ${fmtSize(v2.size.code)}`);
|
|
3913
|
+
return `Differs from the code: ${parts.join(", ")}`;
|
|
3914
|
+
}
|
|
3915
|
+
function fidelityComponentLine(c10) {
|
|
3916
|
+
if (c10.status === "not-checked") return `Not compared: ${c10.reason ?? "no image of the code"}`;
|
|
3917
|
+
if (c10.status === "matches") return c10.checked === 1 ? "Matches the code" : `Matches the code (${c10.checked} variants)`;
|
|
3918
|
+
const w = c10.worst;
|
|
3919
|
+
const head = fidelityVerdict({ status: "differs", percent: w.percent, size: w.size });
|
|
3920
|
+
return c10.checked > 1 ? `${head} (${c10.differing} of ${c10.checked} variants)` : head;
|
|
3921
|
+
}
|
|
3922
|
+
const FIGMA_REFERENCES_BRANCH = "bridge-visual";
|
|
3923
|
+
const FIGMA_REFERENCES_DIR = "figma-references";
|
|
3924
|
+
const FIGMA_REFERENCES_MANIFEST = `${FIGMA_REFERENCES_DIR}/manifest.json`;
|
|
3925
|
+
const FIGMA_REFERENCE_STORY = "internal-figma-reference--variant";
|
|
3926
|
+
const FIGMA_FILL_WIDTH_TOKEN = "size.80";
|
|
3927
|
+
const STATE_PSEUDO = {
|
|
3928
|
+
default: "rest",
|
|
3929
|
+
rest: "rest",
|
|
3930
|
+
enabled: "rest",
|
|
3931
|
+
hover: "hover",
|
|
3932
|
+
hovered: "hover",
|
|
3933
|
+
pressed: "active",
|
|
3934
|
+
active: "active",
|
|
3935
|
+
focus: "focus-visible",
|
|
3936
|
+
focused: "focus-visible",
|
|
3937
|
+
"focus visible": "focus-visible",
|
|
3938
|
+
disabled: "disabled"
|
|
3939
|
+
};
|
|
3940
|
+
const iconName = (component) => component.replace(/^Icon\//, "");
|
|
3941
|
+
const exportName = (name) => name.replace(/[^A-Za-z0-9]+/g, "");
|
|
3942
|
+
function planReference(spec, variant, file) {
|
|
3943
|
+
if (spec.view === "popup") return { ok: false, reason: "drawn open in Figma; the code image shows it closed" };
|
|
3944
|
+
const props = { ...spec.fixed ?? {} };
|
|
3945
|
+
let pseudo;
|
|
3946
|
+
for (const axis of spec.axes) {
|
|
3947
|
+
const value = variant.props[axis.name];
|
|
3948
|
+
if (value === void 0) return { ok: false, reason: `the variant has no ${axis.name} value` };
|
|
3949
|
+
if (axis.prop) {
|
|
3950
|
+
props[axis.prop] = value === "true" ? true : value === "false" ? false : value;
|
|
3951
|
+
continue;
|
|
3952
|
+
}
|
|
3953
|
+
if (axis.name === "Checked") {
|
|
3954
|
+
props.checked = value === "true";
|
|
3955
|
+
if (value === "mixed") props.indeterminate = true;
|
|
3956
|
+
continue;
|
|
3957
|
+
}
|
|
3958
|
+
if (axis.name.toLowerCase() !== "state") return { ok: false, reason: `${axis.name} has no matching option in code` };
|
|
3959
|
+
const s2 = STATE_PSEUDO[value.toLowerCase()];
|
|
3960
|
+
if (!s2) return { ok: false, reason: `the ${value} state has no code equivalent to render` };
|
|
3961
|
+
if (s2 === "disabled") props.disabled = true;
|
|
3962
|
+
else if (s2 !== "rest") pseudo = s2;
|
|
3963
|
+
}
|
|
3964
|
+
const root = spec.parts.find((p) => !p.parent);
|
|
3965
|
+
if (!root) return { ok: false, reason: "the spec has no root layer" };
|
|
3966
|
+
const children = (id) => spec.parts.filter((p) => p.parent === id);
|
|
3967
|
+
const textOf = (part) => {
|
|
3968
|
+
const swapTo = variant.slots?.[part.id] ?? part.swap?.default;
|
|
3969
|
+
if (part.swap && swapTo) {
|
|
3970
|
+
const slot = file?.slots?.find((s2) => s2.name === swapTo);
|
|
3971
|
+
if (!slot) return { reason: `${swapTo} is not in the specs` };
|
|
3972
|
+
if (slot.kind !== "text" || !slot.text) return { reason: `Figma shows a placeholder (${swapTo}) that code has no example of` };
|
|
3973
|
+
return slot.text.default;
|
|
3974
|
+
}
|
|
3975
|
+
const prop = spec.properties.find((p) => p.name === part.text && p.type === "TEXT");
|
|
3976
|
+
return typeof prop?.default === "string" ? prop.default : part.name;
|
|
3977
|
+
};
|
|
3978
|
+
let text;
|
|
3979
|
+
const icons = {};
|
|
3980
|
+
for (const prop of spec.properties) {
|
|
3981
|
+
if (prop.type === "TEXT") {
|
|
3982
|
+
const hidden = spec.properties.some((b) => b.type === "BOOLEAN" && b.prop === prop.prop && b.default === false);
|
|
3983
|
+
if (hidden && prop.prop) continue;
|
|
3984
|
+
if (prop.prop === "children") text = String(prop.default);
|
|
3985
|
+
else if (prop.prop) props[prop.prop] = String(prop.default);
|
|
3986
|
+
continue;
|
|
3987
|
+
}
|
|
3988
|
+
const iconPart = spec.parts.find((p) => p.kind === "icon" && p.visible === prop.name);
|
|
3989
|
+
if (prop.default === true && !iconPart && prop.prop && props[prop.prop] === void 0 && spec.example?.p?.[prop.prop] === void 0) props[prop.prop] = true;
|
|
3990
|
+
}
|
|
3991
|
+
for (const part of spec.parts) {
|
|
3992
|
+
if (part.kind !== "icon" || !part.swap) continue;
|
|
3993
|
+
const shown = part.visible ? spec.properties.find((p) => p.name === part.visible)?.default === true : true;
|
|
3994
|
+
if (!shown) continue;
|
|
3995
|
+
if (!part.swap.prop) return { ok: false, reason: `the ${part.name} icon has no matching option in code` };
|
|
3996
|
+
icons[part.swap.prop] = iconName(variant.slots?.[part.id] ?? part.swap.default);
|
|
3997
|
+
}
|
|
3998
|
+
let parts;
|
|
3999
|
+
const loose = spec.properties.filter((p) => p.type === "TEXT" && !p.prop);
|
|
4000
|
+
const frames = children(root.id).filter((p) => p.kind === "frame");
|
|
4001
|
+
const compound = text === void 0 && frames.length > 0 && frames.every((f) => spec.parts.some((p) => p.parent === f.id && p.kind === "text" && (p.swap || p.text === f.name)));
|
|
4002
|
+
if (compound) {
|
|
4003
|
+
parts = [];
|
|
4004
|
+
for (const f of frames) {
|
|
4005
|
+
const t3 = spec.parts.find((p) => p.parent === f.id && p.kind === "text");
|
|
4006
|
+
const value = textOf(t3);
|
|
4007
|
+
if (typeof value !== "string") return { ok: false, reason: value.reason };
|
|
4008
|
+
parts.push({ component: `${exportName(spec.name)}${exportName(f.name)}`, text: value });
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
for (const p of loose) {
|
|
4012
|
+
if (p.name === "Value") continue;
|
|
4013
|
+
const part = spec.parts.find((x) => x.text === p.name);
|
|
4014
|
+
if (compound && part && part.parent !== root.id) continue;
|
|
4015
|
+
if (part && /placeholder$/.test(part.id)) {
|
|
4016
|
+
props.placeholder = String(p.default);
|
|
4017
|
+
continue;
|
|
4018
|
+
}
|
|
4019
|
+
return { ok: false, reason: `the ${p.name} text has no matching option in code` };
|
|
4020
|
+
}
|
|
4021
|
+
const example = spec.example;
|
|
4022
|
+
const exampleChildren = example?.children?.length ? example.children : void 0;
|
|
4023
|
+
return {
|
|
4024
|
+
ok: true,
|
|
4025
|
+
render: {
|
|
4026
|
+
component: exportName(spec.view || spec.fixed || example ? example?.c ?? spec.component ?? spec.name : spec.name),
|
|
4027
|
+
props: { ...example?.p ?? {}, ...props },
|
|
4028
|
+
...exampleChildren ? { children: exampleChildren } : {},
|
|
4029
|
+
...text !== void 0 && !exampleChildren ? { text } : {},
|
|
4030
|
+
...parts && !exampleChildren ? { parts } : {},
|
|
4031
|
+
...Object.keys(icons).length ? { icons } : {},
|
|
4032
|
+
...pseudo ? { pseudo } : {},
|
|
4033
|
+
...root.fill ? { width: FIGMA_FILL_WIDTH_TOKEN } : {}
|
|
4034
|
+
}
|
|
4035
|
+
};
|
|
4036
|
+
}
|
|
4037
|
+
function referenceImagePath(component, key) {
|
|
4038
|
+
const slug = (s2) => s2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
4039
|
+
const file = key.split(",").map((kv) => slug(kv)).filter(Boolean).join("__");
|
|
4040
|
+
return `${slug(component)}/${file || "default"}.png`;
|
|
4041
|
+
}
|
|
4042
|
+
function planReferences(file) {
|
|
4043
|
+
return file.components.flatMap(
|
|
4044
|
+
(spec) => spec.variants.map((v2) => ({ component: spec.name, specHash: spec.hash, key: variantKeyOf(v2.props), plan: planReference(spec, v2, file) }))
|
|
4045
|
+
);
|
|
3789
4046
|
}
|
|
3790
4047
|
export {
|
|
3791
|
-
|
|
3792
|
-
|
|
4048
|
+
ak as AAA_MIN,
|
|
4049
|
+
al as AA_MIN,
|
|
3793
4050
|
ADMIN_ROLE_ID,
|
|
3794
4051
|
ANTHROPIC_MESSAGES_URL,
|
|
3795
4052
|
BELL,
|
|
3796
4053
|
BRAND_FONTS,
|
|
3797
4054
|
BRAND_SLUG_RE,
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
4055
|
+
am as BULK_LIMIT,
|
|
4056
|
+
n as COLOR_FIELDS,
|
|
4057
|
+
k as COMPONENT_SPECS_VERSION,
|
|
3801
4058
|
CONFIG_FILE,
|
|
3802
|
-
|
|
3803
|
-
|
|
4059
|
+
an as CONTRAST_CELL_MAX,
|
|
4060
|
+
ao as CONTRAST_CHECKS_FILE,
|
|
3804
4061
|
ConfigError,
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
4062
|
+
ap as DEFAULT_COMPONENT_SPECS_FILE,
|
|
4063
|
+
aq as DEFAULT_GOVERNANCE,
|
|
4064
|
+
ar as DEFAULT_OVERRIDE,
|
|
3808
4065
|
DEFAULT_PROTECTED_BRANCHES,
|
|
3809
|
-
|
|
4066
|
+
as as DEFAULT_RIGHTS,
|
|
3810
4067
|
DEFAULT_TOKEN_PATHS,
|
|
3811
|
-
|
|
4068
|
+
at as DEFAULT_VISUAL_IMPACT,
|
|
3812
4069
|
DEMO_RELEASES,
|
|
3813
4070
|
DOCS_CHANGE_BUMP,
|
|
3814
4071
|
DOCS_DRAFT_MODEL,
|
|
@@ -3835,18 +4092,24 @@ export {
|
|
|
3835
4092
|
EXPLORATION_USE_CASES,
|
|
3836
4093
|
EXT_ID,
|
|
3837
4094
|
EXT_SCOPES,
|
|
4095
|
+
FIDELITY_DEFAULTS,
|
|
4096
|
+
FIGMA_FILL_WIDTH_TOKEN,
|
|
4097
|
+
FIGMA_REFERENCES_BRANCH,
|
|
4098
|
+
FIGMA_REFERENCES_DIR,
|
|
4099
|
+
FIGMA_REFERENCES_MANIFEST,
|
|
4100
|
+
FIGMA_REFERENCE_STORY,
|
|
3838
4101
|
GitHubClient,
|
|
3839
4102
|
GitHubError,
|
|
3840
|
-
|
|
4103
|
+
au as JsonParseError,
|
|
3841
4104
|
LIGHTNESS,
|
|
3842
4105
|
LayeredTokenSet,
|
|
3843
4106
|
NEUTRAL_ANCHORS,
|
|
3844
|
-
|
|
4107
|
+
av as OWNER_GROUPS,
|
|
3845
4108
|
PIN_TOLERANCE,
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
4109
|
+
aw as PREVIEW_APP_LABELS,
|
|
4110
|
+
ax as PREVIEW_COMMENT_MARKER,
|
|
4111
|
+
ay as PREVIEW_PLACEHOLDERS,
|
|
4112
|
+
az as PRIMITIVE_MODE,
|
|
3850
4113
|
PROSE_KEYS,
|
|
3851
4114
|
PROTECTION_PARTS,
|
|
3852
4115
|
PROTECTION_PART_PHRASE,
|
|
@@ -3856,100 +4119,104 @@ export {
|
|
|
3856
4119
|
REQUEST_KINDS,
|
|
3857
4120
|
REQUEST_LABEL,
|
|
3858
4121
|
REQUEST_STATUS_LABEL,
|
|
3859
|
-
|
|
3860
|
-
|
|
4122
|
+
aA as RIGHTS,
|
|
4123
|
+
aB as RIGHT_LABEL,
|
|
3861
4124
|
RISK_LABELS,
|
|
3862
|
-
|
|
4125
|
+
aC as RISK_TIER,
|
|
3863
4126
|
SIMILARITY_THRESHOLD,
|
|
3864
4127
|
SINGLE_MODE,
|
|
3865
|
-
|
|
4128
|
+
aD as SPEC_FIELDS,
|
|
3866
4129
|
STEPS,
|
|
3867
4130
|
TIER_AXIS,
|
|
3868
4131
|
TIER_NAMES,
|
|
3869
|
-
|
|
4132
|
+
aE as TIER_ORDER,
|
|
3870
4133
|
TOKEN_REJECTED_MESSAGE,
|
|
3871
4134
|
TOKEN_SETTINGS_URL,
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
4135
|
+
aF as TeamDirectory,
|
|
4136
|
+
aG as UNRELEASED,
|
|
4137
|
+
aH as VISUAL_CHECK_LABEL,
|
|
3875
4138
|
acceptDocsDraft,
|
|
3876
4139
|
acceptDocsText,
|
|
3877
4140
|
addBrandToConfigText,
|
|
3878
|
-
|
|
4141
|
+
aI as affectedContrast,
|
|
3879
4142
|
d as aliasOf,
|
|
3880
4143
|
aliasTarget,
|
|
3881
4144
|
anatomyLabel,
|
|
3882
4145
|
anchoredRamp,
|
|
3883
4146
|
anthropicReplyText,
|
|
3884
4147
|
anthropicRequest,
|
|
3885
|
-
|
|
3886
|
-
|
|
4148
|
+
aJ as appForProject,
|
|
4149
|
+
aK as appUrl,
|
|
3887
4150
|
applyConfirmedRenames,
|
|
3888
4151
|
applyDocsSections,
|
|
3889
4152
|
applyTokenEdits,
|
|
3890
4153
|
applyTokenMerge,
|
|
3891
|
-
|
|
3892
|
-
|
|
4154
|
+
aL as approverEntries,
|
|
4155
|
+
aM as approverLists,
|
|
3893
4156
|
assertSafeBranch,
|
|
3894
4157
|
assignRequestOnGitHub,
|
|
3895
|
-
|
|
4158
|
+
aN as assignVersions,
|
|
3896
4159
|
base64ToUtf8,
|
|
3897
|
-
|
|
4160
|
+
aO as baseBranchOf,
|
|
3898
4161
|
bellChroma,
|
|
3899
|
-
|
|
4162
|
+
aP as branchName,
|
|
3900
4163
|
branchPreviewUrls,
|
|
3901
|
-
|
|
4164
|
+
aQ as branchSlug,
|
|
3902
4165
|
brandDisplayName,
|
|
3903
4166
|
brandPreviewVariables,
|
|
4167
|
+
buildFidelityReport,
|
|
3904
4168
|
buildHistoryEntry,
|
|
3905
4169
|
buildReport,
|
|
3906
|
-
|
|
4170
|
+
j as buildTokenSet,
|
|
3907
4171
|
buildUsageIndex,
|
|
3908
|
-
|
|
4172
|
+
aR as canShip,
|
|
3909
4173
|
changeEdits,
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
4174
|
+
aS as changeKind,
|
|
4175
|
+
aT as changeTable,
|
|
4176
|
+
aU as changedModes,
|
|
4177
|
+
aV as changesetBump,
|
|
3914
4178
|
checkBrandSlug,
|
|
3915
4179
|
checkLayeredPair,
|
|
3916
4180
|
choiceFor,
|
|
3917
4181
|
classifyAuth,
|
|
3918
|
-
|
|
4182
|
+
aW as classifyLayered,
|
|
3919
4183
|
classifyRisk,
|
|
3920
4184
|
cleanDocsText,
|
|
3921
4185
|
cleanDraftText,
|
|
3922
|
-
|
|
4186
|
+
aX as clearRawDeep,
|
|
3923
4187
|
closeExplorationOnGitHub,
|
|
3924
4188
|
closingIssueNumbers,
|
|
3925
4189
|
coerceValue,
|
|
3926
4190
|
collectHistory,
|
|
3927
4191
|
collectRefs,
|
|
4192
|
+
colorDelta,
|
|
3928
4193
|
k2 as colorToCss,
|
|
3929
4194
|
l as colorsEqual,
|
|
3930
4195
|
combineChanges,
|
|
3931
4196
|
combineConflicts,
|
|
3932
4197
|
c as comboKey,
|
|
3933
|
-
|
|
4198
|
+
aY as commitMessage,
|
|
3934
4199
|
m as compactJson,
|
|
4200
|
+
compareImages,
|
|
3935
4201
|
componentForPath,
|
|
3936
|
-
|
|
4202
|
+
aZ as composeChangeset,
|
|
3937
4203
|
composeFiles,
|
|
3938
4204
|
composeNewBrandBody,
|
|
3939
4205
|
composePendingDrafts,
|
|
3940
|
-
|
|
3941
|
-
|
|
4206
|
+
a_ as composePrBody,
|
|
4207
|
+
a$ as composeProposalBody,
|
|
3942
4208
|
composeRequestIssue,
|
|
3943
|
-
|
|
3944
|
-
|
|
4209
|
+
b0 as composite,
|
|
4210
|
+
b1 as contextFor,
|
|
3945
4211
|
contextLabel,
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
4212
|
+
b2 as contrastDelta,
|
|
4213
|
+
b3 as contrastDeltaTable,
|
|
4214
|
+
b4 as contrastLevel,
|
|
4215
|
+
b5 as contrastPair,
|
|
4216
|
+
b6 as contrastRatio,
|
|
3951
4217
|
contrastScope,
|
|
3952
|
-
|
|
4218
|
+
b7 as countChanges,
|
|
4219
|
+
b8 as coverageSummary,
|
|
3953
4220
|
createDocsDraftSession,
|
|
3954
4221
|
createPendingDrafts,
|
|
3955
4222
|
cssModuleClasses,
|
|
@@ -3961,15 +4228,15 @@ export {
|
|
|
3961
4228
|
declineRequestOnGitHub,
|
|
3962
4229
|
decodePicks,
|
|
3963
4230
|
defaultChoiceFor,
|
|
3964
|
-
|
|
4231
|
+
b9 as defaultContext,
|
|
3965
4232
|
defaultFile,
|
|
3966
4233
|
defaultScopes,
|
|
3967
|
-
|
|
3968
|
-
|
|
4234
|
+
ba as defaultTitle,
|
|
4235
|
+
bb as defineConfig,
|
|
3969
4236
|
deletePendingDrafts,
|
|
3970
4237
|
demoHistory,
|
|
3971
|
-
|
|
3972
|
-
|
|
4238
|
+
bc as detectLayout,
|
|
4239
|
+
bd as diffLayered,
|
|
3973
4240
|
docsPrompt,
|
|
3974
4241
|
docsSectionShapes,
|
|
3975
4242
|
docsSectionsAnswer,
|
|
@@ -3988,11 +4255,11 @@ export {
|
|
|
3988
4255
|
emptyTokenFile,
|
|
3989
4256
|
encodePicks,
|
|
3990
4257
|
ensureRequestsBranch,
|
|
3991
|
-
|
|
3992
|
-
|
|
4258
|
+
be as entriesFor,
|
|
4259
|
+
bf as entryLabel,
|
|
3993
4260
|
evaluatePairs,
|
|
3994
|
-
|
|
3995
|
-
|
|
4261
|
+
bg as expandEntries,
|
|
4262
|
+
bh as expandOwners,
|
|
3996
4263
|
explorationBranch,
|
|
3997
4264
|
explorationNote,
|
|
3998
4265
|
explorationNotePath,
|
|
@@ -4008,61 +4275,63 @@ export {
|
|
|
4008
4275
|
explorationTestBuildOnGitHub,
|
|
4009
4276
|
explorationTryIt,
|
|
4010
4277
|
explorationTryItOnGitHub,
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4278
|
+
fidelityComponentLine,
|
|
4279
|
+
fidelityVerdict,
|
|
4280
|
+
bi as fieldChanges,
|
|
4281
|
+
bj as fileModes,
|
|
4282
|
+
bk as filterHistory,
|
|
4014
4283
|
findExplorationOnGitHub,
|
|
4015
4284
|
findPreviewComment,
|
|
4016
4285
|
findReferenceProblems,
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4286
|
+
bl as findToken,
|
|
4287
|
+
bm as findVercelComment,
|
|
4288
|
+
bn as firstParagraph,
|
|
4289
|
+
n2 as flattenLayerFile,
|
|
4021
4290
|
flattenTokens,
|
|
4022
4291
|
formatChangeset,
|
|
4023
4292
|
formatDocsJson,
|
|
4024
|
-
|
|
4025
|
-
|
|
4293
|
+
bo as formatNumber,
|
|
4294
|
+
bp as formatOwnerEntry,
|
|
4026
4295
|
formatValue,
|
|
4027
4296
|
friendlyMessage,
|
|
4028
4297
|
fromHex,
|
|
4029
4298
|
fromPlain,
|
|
4030
4299
|
generateRamp,
|
|
4031
|
-
|
|
4300
|
+
bq as getChild,
|
|
4032
4301
|
getEntry,
|
|
4033
4302
|
gitHubHistoryBackend,
|
|
4034
4303
|
g2 as globToRegExp,
|
|
4035
|
-
|
|
4304
|
+
br as groupsPhrase,
|
|
4036
4305
|
h as hashSpec,
|
|
4037
4306
|
h2 as hexToRgba,
|
|
4038
|
-
|
|
4039
|
-
|
|
4307
|
+
bs as holdersOf,
|
|
4308
|
+
i as iconComponentName,
|
|
4040
4309
|
idExtensionFor,
|
|
4041
4310
|
impactedModules,
|
|
4042
4311
|
importsIn,
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4312
|
+
bt as indexByPath,
|
|
4313
|
+
bu as inheritedTypeAt,
|
|
4314
|
+
bv as installCommand,
|
|
4315
|
+
bw as installCommandFromPreviewComment,
|
|
4047
4316
|
isActiveExploration,
|
|
4048
4317
|
isAlias,
|
|
4049
4318
|
isDocsSelectionMode,
|
|
4050
4319
|
isDraftSessionId,
|
|
4051
4320
|
isExplorationBranch,
|
|
4052
4321
|
isExplorationPull,
|
|
4053
|
-
|
|
4322
|
+
bx as isGuardrail,
|
|
4054
4323
|
isHex,
|
|
4055
4324
|
isMissingPermission,
|
|
4056
4325
|
isMultiMode,
|
|
4057
4326
|
isPlanRefusal,
|
|
4058
4327
|
isProseKey,
|
|
4059
|
-
|
|
4060
|
-
|
|
4328
|
+
by as isTeamEntry,
|
|
4329
|
+
bz as isTokenFile,
|
|
4061
4330
|
isTokenRejected,
|
|
4062
|
-
|
|
4331
|
+
bA as isVercelComment,
|
|
4063
4332
|
jiraIssueFields,
|
|
4064
|
-
|
|
4065
|
-
|
|
4333
|
+
bB as kindForMin,
|
|
4334
|
+
bC as layeredImpact,
|
|
4066
4335
|
o as layeredParityIssues,
|
|
4067
4336
|
g as layoutOptions,
|
|
4068
4337
|
levenshtein,
|
|
@@ -4075,7 +4344,7 @@ export {
|
|
|
4075
4344
|
loadProtection,
|
|
4076
4345
|
loadRepoFiles,
|
|
4077
4346
|
loadRequiredChecks,
|
|
4078
|
-
|
|
4347
|
+
bD as luminance,
|
|
4079
4348
|
markClaudeDraft,
|
|
4080
4349
|
mergeDocsDraft,
|
|
4081
4350
|
mergeDraftResults,
|
|
@@ -4085,7 +4354,7 @@ export {
|
|
|
4085
4354
|
missingProse,
|
|
4086
4355
|
modeDisplayName,
|
|
4087
4356
|
modeFile,
|
|
4088
|
-
|
|
4357
|
+
bE as modeLabel,
|
|
4089
4358
|
modesOf$1 as modesOf,
|
|
4090
4359
|
moveToken,
|
|
4091
4360
|
nearestStep,
|
|
@@ -4094,31 +4363,31 @@ export {
|
|
|
4094
4363
|
neutralOffset,
|
|
4095
4364
|
newBrandSection,
|
|
4096
4365
|
newDraftSessionId,
|
|
4097
|
-
|
|
4098
|
-
|
|
4366
|
+
bF as nodesEqual,
|
|
4367
|
+
bG as normalizeRights,
|
|
4099
4368
|
oklch,
|
|
4100
4369
|
oklchToLinear,
|
|
4101
|
-
|
|
4102
|
-
|
|
4370
|
+
bH as overrideKey,
|
|
4371
|
+
bI as ownerEntryProblems,
|
|
4103
4372
|
packageDirCandidates,
|
|
4104
|
-
|
|
4373
|
+
bJ as pairKey,
|
|
4105
4374
|
parseChangelog,
|
|
4106
|
-
|
|
4375
|
+
bK as parseChangesetText,
|
|
4107
4376
|
parseColor,
|
|
4108
|
-
|
|
4377
|
+
bL as parseComponentSpecs,
|
|
4109
4378
|
parseContrastChecks,
|
|
4110
4379
|
q as parseDimension,
|
|
4111
4380
|
parseDocsReply,
|
|
4112
4381
|
parseDocsTaskAnswer,
|
|
4113
4382
|
parseExplorationBody,
|
|
4114
4383
|
parseJson,
|
|
4115
|
-
|
|
4384
|
+
bM as parseOwnerEntry,
|
|
4116
4385
|
parsePendingDrafts,
|
|
4117
4386
|
parseRepo,
|
|
4118
4387
|
parseRequestIssue,
|
|
4119
4388
|
parseStructureChange,
|
|
4120
4389
|
parseTokenFile,
|
|
4121
|
-
|
|
4390
|
+
bN as parseVercelComment,
|
|
4122
4391
|
patchDocsJson,
|
|
4123
4392
|
pathId,
|
|
4124
4393
|
pathSimilarity,
|
|
@@ -4126,25 +4395,27 @@ export {
|
|
|
4126
4395
|
pickedOption,
|
|
4127
4396
|
plainEqual,
|
|
4128
4397
|
planNewBrand,
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4398
|
+
planReference,
|
|
4399
|
+
planReferences,
|
|
4400
|
+
bO as planRestore,
|
|
4401
|
+
bP as planRevert,
|
|
4402
|
+
bQ as planToJson,
|
|
4132
4403
|
planTokenMerge,
|
|
4133
4404
|
e as prNumberFromSubject,
|
|
4134
4405
|
prefillDocs,
|
|
4135
|
-
|
|
4406
|
+
bR as previewComment,
|
|
4136
4407
|
previewLinks,
|
|
4137
|
-
|
|
4408
|
+
bS as previewLinksOf,
|
|
4138
4409
|
previewOverrides,
|
|
4139
|
-
|
|
4410
|
+
bT as previewUrl,
|
|
4140
4411
|
previewsSettled,
|
|
4141
|
-
|
|
4412
|
+
bU as projectOfLabel,
|
|
4142
4413
|
promoteExplorationOnGitHub,
|
|
4143
4414
|
promotionPlan,
|
|
4144
4415
|
propsTable,
|
|
4145
4416
|
protectLibrary,
|
|
4146
4417
|
protectRefusal,
|
|
4147
|
-
|
|
4418
|
+
bV as protectedBranchesOf,
|
|
4148
4419
|
protectionRuleset,
|
|
4149
4420
|
protectionRulesetName,
|
|
4150
4421
|
protectionSentence,
|
|
@@ -4155,10 +4426,11 @@ export {
|
|
|
4155
4426
|
readPreviewComment,
|
|
4156
4427
|
readTokenAt,
|
|
4157
4428
|
reconcileIds,
|
|
4429
|
+
referenceImagePath,
|
|
4158
4430
|
releasesFromTags,
|
|
4159
4431
|
removeToken,
|
|
4160
4432
|
removedSide,
|
|
4161
|
-
|
|
4433
|
+
bW as renderedColor,
|
|
4162
4434
|
requestBrief,
|
|
4163
4435
|
requestImagePath,
|
|
4164
4436
|
requestIssueTitle,
|
|
@@ -4169,13 +4441,13 @@ export {
|
|
|
4169
4441
|
resolveBranchPreviews,
|
|
4170
4442
|
r as rgbaToDtcg,
|
|
4171
4443
|
rgbaToHex,
|
|
4172
|
-
|
|
4444
|
+
bX as rightsProblems,
|
|
4173
4445
|
round3,
|
|
4174
4446
|
rulesSettingsUrl,
|
|
4175
4447
|
rulesetTargetsDefault,
|
|
4176
|
-
|
|
4448
|
+
bY as runLayeredContrast,
|
|
4177
4449
|
sameScopes,
|
|
4178
|
-
|
|
4450
|
+
bZ as sameToken,
|
|
4179
4451
|
sanitizeDocsReplacement,
|
|
4180
4452
|
sanitizeDocsResult,
|
|
4181
4453
|
sanitizeDocsSections,
|
|
@@ -4189,57 +4461,59 @@ export {
|
|
|
4189
4461
|
serializePendingDrafts,
|
|
4190
4462
|
serializeTokenFile,
|
|
4191
4463
|
shadowedEdits,
|
|
4192
|
-
|
|
4464
|
+
b_ as shipPolicy,
|
|
4193
4465
|
shortVariant,
|
|
4194
4466
|
shortVariants,
|
|
4195
4467
|
slugify,
|
|
4196
|
-
|
|
4197
|
-
|
|
4468
|
+
b$ as snapshotUrl,
|
|
4469
|
+
s as specHash,
|
|
4198
4470
|
startExplorationOnGitHub,
|
|
4199
|
-
|
|
4471
|
+
summarizeComponent,
|
|
4472
|
+
c0 as summarizeTokenChange,
|
|
4200
4473
|
takeMine,
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4474
|
+
c1 as tarballAssetName,
|
|
4475
|
+
c2 as tarballUrl,
|
|
4476
|
+
c3 as teamKey,
|
|
4477
|
+
c4 as teamKeyOf,
|
|
4478
|
+
c5 as teamUnreadableMessage,
|
|
4479
|
+
c6 as teamsIn,
|
|
4207
4480
|
threeWayDiff,
|
|
4208
4481
|
tintedNeutral,
|
|
4209
|
-
|
|
4482
|
+
c7 as titleOf,
|
|
4210
4483
|
t2 as toAlias,
|
|
4211
|
-
|
|
4484
|
+
c8 as toChangeSummary,
|
|
4212
4485
|
toConfigJson,
|
|
4213
4486
|
toHex,
|
|
4214
|
-
|
|
4487
|
+
c9 as toMap,
|
|
4215
4488
|
toOklch,
|
|
4216
4489
|
toPlain,
|
|
4217
|
-
|
|
4490
|
+
ca as tokenBump,
|
|
4218
4491
|
t as tokenCssVar,
|
|
4219
|
-
|
|
4220
|
-
|
|
4492
|
+
cb as tokenHistory,
|
|
4493
|
+
cc as tokenNode,
|
|
4221
4494
|
tokenUsage,
|
|
4222
4495
|
tokensPath,
|
|
4223
4496
|
unpicked,
|
|
4224
|
-
|
|
4225
|
-
|
|
4497
|
+
cd as unreadableShipTeams,
|
|
4498
|
+
ce as unreadableTeams,
|
|
4226
4499
|
updatePendingDrafts,
|
|
4227
4500
|
upsertToken,
|
|
4228
4501
|
utf8ToBase64,
|
|
4502
|
+
v as validateComponentSpec,
|
|
4229
4503
|
validateDocsTask,
|
|
4230
4504
|
validateIntegrations,
|
|
4231
4505
|
validateLayered,
|
|
4232
4506
|
validatePendingDrafts,
|
|
4233
4507
|
validateProposal,
|
|
4234
4508
|
validateSet,
|
|
4235
|
-
|
|
4509
|
+
cf as valueIn,
|
|
4236
4510
|
u as valueToCss,
|
|
4237
4511
|
valuesEqual,
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4512
|
+
variantKeyOf,
|
|
4513
|
+
cg as variantName,
|
|
4514
|
+
ch as versionTimeline,
|
|
4515
|
+
ci as visualImpactProblems,
|
|
4516
|
+
cj as whoCanShipSentence,
|
|
4243
4517
|
withRequestExploration,
|
|
4244
4518
|
writeDraftResults
|
|
4245
4519
|
};
|