@bridge-ds/core 0.12.0 → 0.13.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/README.md CHANGED
@@ -275,7 +275,7 @@ parseSuggestionIssue(body, { comments?, author? }): { ok: true; payload; sha; ma
275
275
  suggestionPayloadSha(payload); canonicalJson(value); sha256Hex(text); gitBlobSha(text);
276
276
  suggestionLabels(payload, { state?, labels? }); suggestionIssueTitle(payload); suggestionStatus({ state, stateReason?, linkedPrs?, review?, applied?, outdated? });
277
277
  suggestionPathProblems(payload, config): string[]; unsafePathProblem(path): string | null;
278
- summarizeSuggestionApprovals(comments, { owners, rights?, teams? }, { payloadSha, author? }); suggestionReviewState(tier, approvals);
278
+ summarizeSuggestionApprovals(comments, { owners, rights?, teams?, soloOwnerCanApproveBoth? }, { payloadSha, author? }); suggestionReviewState(tier, approvals);
279
279
  composeSuggestionReviewComment(record); parseSuggestionReviewComment(body); composeSuggestionAppliedComment(record); parseSuggestionAppliedComment(body);
280
280
  // GitHub (Issues read and write only)
281
281
  createSuggestionOnGitHub(gh, payload, opts); listSuggestionsOnGitHub(gh, { state? }); getSuggestionOnGitHub(gh, n, gov, { outdated? });
@@ -437,6 +437,11 @@
437
437
  }
438
438
  }
439
439
  },
440
+ "soloOwnerCanApproveBoth": {
441
+ "type": "boolean",
442
+ "description": "For a design system run by one person. When true and the owners resolve to exactly one person who holds both roles, that person's approval counts as the design and the tech approval, so Tier 2 and Tier 3 changes can be approved. The author of a change still never approves it. Default false: one person never covers both approvals alone.",
443
+ "default": false
444
+ },
440
445
  "rights": {
441
446
  "type": "object",
442
447
  "additionalProperties": false,
@@ -1,6 +1,6 @@
1
- import { i as isAuditable, a as auditFile } from "../report-DOnKUw8G.js";
2
- import { A, b, c, C, D, d, F, I, L, e, M, N, f, g, h, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, B, E, G, H, J, K, O, P, Q, R, S, T, U, V, W, X, Y, Z } from "../report-DOnKUw8G.js";
3
- import { p as pieceId, a as proposedTokenPath, t as tokenLabel } from "../prod-branch-BdMPKffE.js";
1
+ import { i as isAuditable, a as auditFile } from "../report-BeWNSjPk.js";
2
+ import { A, b, c, C, D, d, F, I, L, e, M, N, f, g, h, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, B, E, G, H, J, K, O, P, Q, R, S, T, U, V, W, X, Y, Z } from "../report-BeWNSjPk.js";
3
+ import { p as pieceId, a as proposedTokenPath, t as tokenLabel } from "../prod-branch-6ftQWwdu.js";
4
4
  const lines = (text) => text.split(/\r?\n/);
5
5
  function lineBag(text) {
6
6
  const bag = /* @__PURE__ */ new Map();
package/dist/config.d.ts CHANGED
@@ -114,6 +114,11 @@ export interface GovernanceConfig {
114
114
  * and anyone with write access may ship, as before the field existed.
115
115
  */
116
116
  rights?: Rights | undefined;
117
+ /**
118
+ * A design system run by one person: when the owners resolve to exactly one person holding both roles, that
119
+ * person's approval counts for design and tech. Default false: one person never covers both approvals alone.
120
+ */
121
+ soloOwnerCanApproveBoth?: boolean | undefined;
117
122
  }
118
123
  /** `bridge audit` settings: how product code that consumes the design system is measured. */
119
124
  export interface AuditConfig {
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { m as modeDisplayName, b as modesOf$1, i as isMultiMode, T as TIER_NAMES, c as TIER_AXIS, d as collectRefs, f as findReferenceProblems, e as evaluatePairs, g as contrastScope, h as contextLabel, S as SINGLE_MODE, j as isAlias, k as aliasTarget, l as pathId, v as valuesEqual, n as flattenTokens, s as serializeTokenFile, r as removeToken, u as upsertToken, o as threeWayDiff, q as emptyTokenFile, w as parseTokenFile, E as EXT_ID, x as EXT_SCOPES, y as parseColor, z as rgbaToHex, A as formatValue, B as resolve, C as moveToken, D as effectiveScopes, F as sameScopes, G as defaultScopes, H as readTokenAt, I as modeFile, J as defaultFile, K as selectTokenFiles, L as LayeredTokenSet, M as resolveBranchPreviews, N as loadConfig, O as tokensPath, P as toConfigJson, Q as validateLayered, R as parseContrastChecks, U as classifyRisk, V as CONFIG_FILE, W as RISK_LABELS, X as previewLinks, Y as findPreviewComment, Z as previewsSettled, _ as DEFAULT_TOKEN_PATHS, $ as layoutOptions, a0 as buildTokenSet, a1 as readPreviewComment, a2 as linkStatus, a3 as libraryPreviewState, a4 as parsePiecesRecord, a5 as libraryBranchPlan, a6 as NEEDED_BY_LABEL, a7 as withNeededBy, a8 as withLink, a9 as withPiecesRecord, aa as productBranchSentence, ab as mergePiecesRecord, ac as productOfBranch, ad as defaultProduct, ae as slugify } from "./prod-branch-BdMPKffE.js";
2
- import { af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM, aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ, a_, a$, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, bA, bB, bC, bD, bE, bF, bG, bH, bI, bJ, bK, bL, p, bM, bN, bO, bP, bQ, bR, bS, bT, bU, bV, bW, a, bX, bY, bZ, b_, b$, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf, cg, t, ch, ci, cj, ck, cl, cm, cn, co } from "./prod-branch-BdMPKffE.js";
3
- import { G as GitHubError, c as collectHistory, p as packageDirCandidates, a as parseChangelog, r as releasesFromTags, m as mergeReleases, b as buildReport, d as applyTokenEdits, e as buildHistoryEntry, f as coerceValue, g as checkLayeredPair, h as formatChangeset, P as PROSE_KEYS, i as markClaudeDraft, j as cleanDraftText, k as docsPrompt, D as DRAFT_LINE_MAX, R as REQUESTS_BRANCH, l as REQUEST_KINDS, s as sanitizeDraftLine, n as parseExplorationBody, E as EXPLORATION_PREFIX, o as explorationSlug, q as explorationStatus, t as explorationTryIt, u as isExplorationPull, v as promotionPlan, w as EXPLORATION_LABEL, x as explorationProblems, y as explorationNote, z as explorationNotePath, A as explorationPrTitle, B as explorationPrBody, C as variantKeyOf, F as overrideComment, O as OVERRIDE_HEADING, H as overrideRefusedComment, I as suggestionStateFromLabels, J as suggestionStatus, K as composeRequestIssue, L as EXPLORATION_NOTES_DIR, M as isExplorationBranch, N as diffLayered, Q as contrastDelta, S as runLayeredContrast, T as layeredImpact, U as classifyLayered, V as composeProposalBody, W as createSuggestionOnGitHub, X as gitBlobSha, Y as SUGGESTION_SCHEMA, Z as branchWithJiraKey, _ as titleWithJiraKey, $ as figmaSpecPath, a0 as formatFigmaSpec, a1 as figmaDraftBrief, a2 as parseFigmaOrigin, a3 as figmaPushStatus, a4 as parseFigmaSpec, a5 as FIGMA_SPEC_DIR, a6 as FROM_FIGMA_LABEL, a7 as withFigmaOrigin, a8 as WAITING_FOR_CLAUDE_LABEL, a9 as DRAFTED_BY_CLAUDE_LABEL, aa as planComponentPush, ab as figmaOriginSection, ac as figmaBranchTitle, ad as figmaSpecSlug, ae as figmaDraftBody, af as REQUEST_LABEL, ag as figmaNodeUrl } from "./suggestion-apply-DxXRGQrO.js";
4
- import { ah as ah2, ai as ai2, aj as aj2, ak as ak2, al as al2, am as am2, an as an2, ao as ao2, ap as ap2, aq as aq2, ar as ar2, as as as2, at as at2, au as au2, av as av2, aw as aw2, ax as ax2, ay as ay2, az as az2, aA as aA2, aB as aB2, aC as aC2, aD as aD2, aE as aE2, aF as aF2, aG as aG2, aH as aH2, aI as aI2, aJ as aJ2, aK as aK2, aL as aL2, aM as aM2, aN as aN2, aO as aO2, aP as aP2, aQ as aQ2, aR as aR2, aS as aS2, aT as aT2, aU as aU2, aV as aV2, aW as aW2, aX as aX2, aY as aY2, aZ as aZ2, a_ as a_2, a$ as a$2, b0 as b02, b1 as b12, b2 as b22, b3 as b32, b4 as b42, b5 as b52, b6 as b62, b7 as b72, b8 as b82, b9 as b92, ba as ba2, bb as bb2, bc as bc2, bd as bd2, be as be2, bf as bf2, bg as bg2, bh as bh2, bi as bi2, bj as bj2, bk as bk2, bl as bl2, bm as bm2, bn as bn2, bo as bo2, bp as bp2, bq as bq2, br as br2, bs as bs2, bt as bt2, bu as bu2, bv as bv2, bw as bw2, bx as bx2, by as by2, bz as bz2, bA as bA2, bB as bB2, bC as bC2, bD as bD2, bE as bE2, bF as bF2, bG as bG2, bH as bH2, bI as bI2, bJ as bJ2, bK as bK2, bL as bL2, bM as bM2, bN as bN2, bO as bO2, bP as bP2, bQ as bQ2, bR as bR2, bS as bS2, bT as bT2, bU as bU2, bV as bV2, bW as bW2, bX as bX2, bY as bY2, bZ as bZ2, b_ as b_2, b$ as b$2, c0 as c02, c1 as c12, c2 as c22, c3 as c32, c4 as c42, c5 as c52, c6 as c62, c7 as c72, c8 as c82, c9 as c92, ca as ca2, cb as cb2, cc as cc2, cd as cd2, ce as ce2, cf as cf2, cg as cg2, ch as ch2, ci as ci2, cj as cj2, ck as ck2, cl as cl2, cm as cm2, cn as cn2, co as co2, cp, cq, cr, cs, ct, cu, cv, cw, cx, cy, cz, cA, cB, cC, cD, cE, cF, cG, cH, cI, cJ, cK, cL, cM, cN, cO, cP, cQ, cR, cS, cT, cU, cV, cW, cX, cY, cZ, c_, c$, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df, dg, dh } from "./suggestion-apply-DxXRGQrO.js";
1
+ import { m as modeDisplayName, b as modesOf$1, i as isMultiMode, T as TIER_NAMES, c as TIER_AXIS, d as collectRefs, f as findReferenceProblems, e as evaluatePairs, g as contrastScope, h as contextLabel, S as SINGLE_MODE, j as isAlias, k as aliasTarget, l as pathId, v as valuesEqual, n as flattenTokens, s as serializeTokenFile, r as removeToken, u as upsertToken, o as threeWayDiff, q as emptyTokenFile, w as parseTokenFile, E as EXT_ID, x as EXT_SCOPES, y as parseColor, z as rgbaToHex, A as formatValue, B as resolve, C as moveToken, D as effectiveScopes, F as sameScopes, G as defaultScopes, H as readTokenAt, I as modeFile, J as defaultFile, K as selectTokenFiles, L as LayeredTokenSet, M as resolveBranchPreviews, N as loadConfig, O as tokensPath, P as toConfigJson, Q as validateLayered, R as parseContrastChecks, U as classifyRisk, V as CONFIG_FILE, W as RISK_LABELS, X as previewLinks, Y as findPreviewComment, Z as previewsSettled, _ as DEFAULT_TOKEN_PATHS, $ as layoutOptions, a0 as buildTokenSet, a1 as readPreviewComment, a2 as linkStatus, a3 as libraryPreviewState, a4 as parsePiecesRecord, a5 as libraryBranchPlan, a6 as NEEDED_BY_LABEL, a7 as withNeededBy, a8 as withLink, a9 as withPiecesRecord, aa as productBranchSentence, ab as mergePiecesRecord, ac as productOfBranch, ad as defaultProduct, ae as slugify } from "./prod-branch-6ftQWwdu.js";
2
+ import { af, ag, ah, ai, aj, ak, al, am, an, ao, ap, aq, ar, as, at, au, av, aw, ax, ay, az, aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM, aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ, a_, a$, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf, bg, bh, bi, bj, bk, bl, bm, bn, bo, bp, bq, br, bs, bt, bu, bv, bw, bx, by, bz, bA, bB, bC, bD, bE, bF, bG, bH, bI, bJ, bK, bL, p, bM, bN, bO, bP, bQ, bR, bS, bT, bU, bV, bW, a, bX, bY, bZ, b_, b$, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, ca, cb, cc, cd, ce, cf, cg, ch, ci, cj, t, ck, cl, cm, cn, co, cp, cq, cr } from "./prod-branch-6ftQWwdu.js";
3
+ import { G as GitHubError, c as collectHistory, p as packageDirCandidates, a as parseChangelog, r as releasesFromTags, m as mergeReleases, b as buildReport, d as applyTokenEdits, e as buildHistoryEntry, f as coerceValue, g as checkLayeredPair, h as formatChangeset, P as PROSE_KEYS, i as markClaudeDraft, j as cleanDraftText, k as docsPrompt, D as DRAFT_LINE_MAX, R as REQUESTS_BRANCH, l as REQUEST_KINDS, s as sanitizeDraftLine, n as parseExplorationBody, E as EXPLORATION_PREFIX, o as explorationSlug, q as explorationStatus, t as explorationTryIt, u as isExplorationPull, v as promotionPlan, w as EXPLORATION_LABEL, x as explorationProblems, y as explorationNote, z as explorationNotePath, A as explorationPrTitle, B as explorationPrBody, C as variantKeyOf, F as overrideComment, O as OVERRIDE_HEADING, H as overrideRefusedComment, I as suggestionStateFromLabels, J as suggestionStatus, K as composeRequestIssue, L as EXPLORATION_NOTES_DIR, M as isExplorationBranch, N as diffLayered, Q as contrastDelta, S as runLayeredContrast, T as layeredImpact, U as classifyLayered, V as composeProposalBody, W as createSuggestionOnGitHub, X as gitBlobSha, Y as SUGGESTION_SCHEMA, Z as branchWithJiraKey, _ as titleWithJiraKey, $ as figmaSpecPath, a0 as formatFigmaSpec, a1 as figmaDraftBrief, a2 as parseFigmaOrigin, a3 as figmaPushStatus, a4 as parseFigmaSpec, a5 as FIGMA_SPEC_DIR, a6 as FROM_FIGMA_LABEL, a7 as withFigmaOrigin, a8 as WAITING_FOR_CLAUDE_LABEL, a9 as DRAFTED_BY_CLAUDE_LABEL, aa as planComponentPush, ab as figmaOriginSection, ac as figmaBranchTitle, ad as figmaSpecSlug, ae as figmaDraftBody, af as REQUEST_LABEL, ag as figmaNodeUrl } from "./suggestion-apply-bH6-gZrE.js";
4
+ import { ah as ah2, ai as ai2, aj as aj2, ak as ak2, al as al2, am as am2, an as an2, ao as ao2, ap as ap2, aq as aq2, ar as ar2, as as as2, at as at2, au as au2, av as av2, aw as aw2, ax as ax2, ay as ay2, az as az2, aA as aA2, aB as aB2, aC as aC2, aD as aD2, aE as aE2, aF as aF2, aG as aG2, aH as aH2, aI as aI2, aJ as aJ2, aK as aK2, aL as aL2, aM as aM2, aN as aN2, aO as aO2, aP as aP2, aQ as aQ2, aR as aR2, aS as aS2, aT as aT2, aU as aU2, aV as aV2, aW as aW2, aX as aX2, aY as aY2, aZ as aZ2, a_ as a_2, a$ as a$2, b0 as b02, b1 as b12, b2 as b22, b3 as b32, b4 as b42, b5 as b52, b6 as b62, b7 as b72, b8 as b82, b9 as b92, ba as ba2, bb as bb2, bc as bc2, bd as bd2, be as be2, bf as bf2, bg as bg2, bh as bh2, bi as bi2, bj as bj2, bk as bk2, bl as bl2, bm as bm2, bn as bn2, bo as bo2, bp as bp2, bq as bq2, br as br2, bs as bs2, bt as bt2, bu as bu2, bv as bv2, bw as bw2, bx as bx2, by as by2, bz as bz2, bA as bA2, bB as bB2, bC as bC2, bD as bD2, bE as bE2, bF as bF2, bG as bG2, bH as bH2, bI as bI2, bJ as bJ2, bK as bK2, bL as bL2, bM as bM2, bN as bN2, bO as bO2, bP as bP2, bQ as bQ2, bR as bR2, bS as bS2, bT as bT2, bU as bU2, bV as bV2, bW as bW2, bX as bX2, bY as bY2, bZ as bZ2, b_ as b_2, b$ as b$2, c0 as c02, c1 as c12, c2 as c22, c3 as c32, c4 as c42, c5 as c52, c6 as c62, c7 as c72, c8 as c82, c9 as c92, ca as ca2, cb as cb2, cc as cc2, cd as cd2, ce as ce2, cf as cf2, cg as cg2, ch as ch2, ci as ci2, cj as cj2, ck as ck2, cl as cl2, cm as cm2, cn as cn2, co as co2, cp as cp2, cq as cq2, cr as cr2, cs, ct, cu, cv, cw, cx, cy, cz, cA, cB, cC, cD, cE, cF, cG, cH, cI, cJ, cK, cL, cM, cN, cO, cP, cQ, cR, cS, cT, cU, cV, cW, cX, cY, cZ, c_, c$, d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, da, db, dc, dd, de, df, dg, dh } from "./suggestion-apply-bH6-gZrE.js";
5
5
  const issueKey$1 = (i) => `${i.code}|${i.path ?? ""}|${i.mode ?? ""}|${i.code === "file-problem" ? i.message : ""}`;
6
6
  const modeName = (mode) => mode === SINGLE_MODE ? "all modes" : modeDisplayName(mode);
7
7
  const isPalette = (t2) => t2.tier === "brand" && t2.path.startsWith("palette.");
@@ -3853,11 +3853,11 @@ export {
3853
3853
  planReferences,
3854
3854
  cn2 as planRestore,
3855
3855
  co2 as planRevert,
3856
- cp as planSuggestionApply,
3857
- cq as planToJson,
3856
+ cp2 as planSuggestionApply,
3857
+ cq2 as planToJson,
3858
3858
  planTokenMerge,
3859
3859
  planTokenProposal,
3860
- cr as prNumberFromSubject,
3860
+ cr2 as prNumberFromSubject,
3861
3861
  cs as prefillDocs,
3862
3862
  bO as previewComment,
3863
3863
  previewLinks,
@@ -3956,6 +3956,9 @@ export {
3956
3956
  showShare,
3957
3957
  slugify,
3958
3958
  c3 as snapshotUrl,
3959
+ c4 as soloApprover,
3960
+ c5 as soloOwnerOf,
3961
+ c6 as soloOwnerSentence,
3959
3962
  cO as specHash,
3960
3963
  cP as specsUsage,
3961
3964
  stableCommand,
@@ -3964,8 +3967,8 @@ export {
3964
3967
  storybookIframeUrl,
3965
3968
  storybookIndexUrls,
3966
3969
  storybookManagerUrl,
3967
- c4 as storybookUrl,
3968
- c5 as suggestNearestComment,
3970
+ c7 as storybookUrl,
3971
+ c8 as suggestNearestComment,
3969
3972
  suggestTokenProposalOnGitHub,
3970
3973
  cQ as suggestionAllowedRoots,
3971
3974
  cR as suggestionAppliedComment,
@@ -3985,33 +3988,33 @@ export {
3985
3988
  d1 as summarizeCi,
3986
3989
  summarizeComponent,
3987
3990
  d2 as summarizeSuggestionApprovals,
3988
- c6 as summarizeTokenChange,
3991
+ c9 as summarizeTokenChange,
3989
3992
  switchToPublishedOnGitHub,
3990
3993
  d3 as syncSuggestionStateLabel,
3991
3994
  takeMine,
3992
- c7 as tarballAssetName,
3993
- c8 as tarballUrl,
3994
- c9 as teamKey,
3995
- ca as teamKeyOf,
3996
- cb as teamUnreadableMessage,
3997
- cc as teamsIn,
3995
+ ca as tarballAssetName,
3996
+ cb as tarballUrl,
3997
+ cc as teamKey,
3998
+ cd as teamKeyOf,
3999
+ ce as teamUnreadableMessage,
4000
+ cf as teamsIn,
3998
4001
  threeWayDiff,
3999
4002
  tintedNeutral,
4000
4003
  d4 as titleOf,
4001
4004
  titleWithJiraKey,
4002
- cd as toAlias,
4005
+ cg as toAlias,
4003
4006
  d5 as toChangeSummary,
4004
4007
  toConfigJson,
4005
4008
  toHex,
4006
- ce as toMap,
4009
+ ch as toMap,
4007
4010
  toOklch,
4008
- cf as toPlain,
4009
- cg as tokenBump,
4011
+ ci as toPlain,
4012
+ cj as tokenBump,
4010
4013
  d6 as tokenCssVar,
4011
4014
  tokenFilesOf,
4012
4015
  d7 as tokenHistory,
4013
4016
  t as tokenLabel,
4014
- ch as tokenNode,
4017
+ ck as tokenNode,
4015
4018
  tokenSuggestionPayload,
4016
4019
  tokenUsage,
4017
4020
  tokensPath,
@@ -4019,8 +4022,8 @@ export {
4019
4022
  tryInProductUrl,
4020
4023
  tryTogetherUrl,
4021
4024
  unpicked,
4022
- ci as unreadableShipTeams,
4023
- cj as unreadableTeams,
4025
+ cl as unreadableShipTeams,
4026
+ cm as unreadableTeams,
4024
4027
  d8 as unsafePathProblem,
4025
4028
  updatePendingDrafts,
4026
4029
  upsertToken,
@@ -4034,15 +4037,15 @@ export {
4034
4037
  validatePendingDrafts,
4035
4038
  validateProposal,
4036
4039
  validateSet,
4037
- ck as valueIn,
4038
- cl as valueToCss,
4040
+ cn as valueIn,
4041
+ co as valueToCss,
4039
4042
  valuesEqual,
4040
4043
  variantKeyOf,
4041
4044
  dd as variantName,
4042
4045
  de as versionTimeline,
4043
- cm as visualImpactProblems,
4044
- cn as whoCanShipSentence,
4045
- co as whyItExists,
4046
+ cp as visualImpactProblems,
4047
+ cq as whoCanShipSentence,
4048
+ cr as whyItExists,
4046
4049
  df as withAuthorLine,
4047
4050
  withFigmaOrigin,
4048
4051
  withLink,
@@ -2,10 +2,10 @@ import { execFile } from "node:child_process";
2
2
  import { mkdtemp, rm, mkdir, writeFile, lstat, readFile } from "node:fs/promises";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join, resolve, relative, dirname, sep, posix } from "node:path";
5
- import { aU as assertSafeBranch, c as collectHistory, p as packageDirCandidates, a as parseChangelog, m as mergeReleases, r as releasesFromTags, b as buildReport, cr as prNumberFromSubject, cO as specHash, da as validateComponentSpec, bN as hashSpec, bO as iconComponentName, C as variantKeyOf, d6 as tokenCssVar, aj as COMPONENT_SPECS_VERSION, ai as COLOR_FIELDS, cR as suggestionAppliedComment, X as gitBlobSha, cp as planSuggestionApply } from "../suggestion-apply-DxXRGQrO.js";
6
- import { K as selectTokenFiles, bl as globToRegExp, N as loadConfig, L as LayeredTokenSet, V as CONFIG_FILE, $ as layoutOptions, a0 as buildTokenSet, b3 as defaultContext, B as resolve$1, ae as slugify, bX as protectedBranchesOf, aM as baseBranchOf } from "../prod-branch-BdMPKffE.js";
5
+ import { aU as assertSafeBranch, c as collectHistory, p as packageDirCandidates, a as parseChangelog, m as mergeReleases, r as releasesFromTags, b as buildReport, cr as prNumberFromSubject, cO as specHash, da as validateComponentSpec, bN as hashSpec, bO as iconComponentName, C as variantKeyOf, d6 as tokenCssVar, aj as COMPONENT_SPECS_VERSION, ai as COLOR_FIELDS, cR as suggestionAppliedComment, X as gitBlobSha, cp as planSuggestionApply } from "../suggestion-apply-bH6-gZrE.js";
6
+ import { K as selectTokenFiles, bl as globToRegExp, N as loadConfig, L as LayeredTokenSet, V as CONFIG_FILE, $ as layoutOptions, a0 as buildTokenSet, b3 as defaultContext, B as resolve$1, ae as slugify, bX as protectedBranchesOf, aM as baseBranchOf } from "../prod-branch-6ftQWwdu.js";
7
7
  import { statSync, readFileSync, existsSync, writeFileSync, readdirSync } from "node:fs";
8
- import { i as isAuditable, Q as planCssFixes, O as parseAllowlist, d as DesignSystemIndex, l as buildAuditReport, o as compareWithBaseline, b as AUDIT_IGNORE_DIRS } from "../report-DOnKUw8G.js";
8
+ import { i as isAuditable, Q as planCssFixes, O as parseAllowlist, d as DesignSystemIndex, l as buildAuditReport, o as compareWithBaseline, b as AUDIT_IGNORE_DIRS } from "../report-BeWNSjPk.js";
9
9
  import ts from "typescript";
10
10
  function git(root, args, opts = {}) {
11
11
  return new Promise((resolve2, reject) => {
@@ -1039,6 +1039,19 @@ function approverEntries(owners, rights) {
1039
1039
  if (!rights) return { design: [...owners.design], tech: [...owners.tech] };
1040
1040
  return { design: holdersOf("approveDesign", owners, rights), tech: holdersOf("approveTech", owners, rights) };
1041
1041
  }
1042
+ function soloApprover(owners) {
1043
+ const d = [...new Set(owners.design.map(norm))];
1044
+ const t = [...new Set(owners.tech.map(norm))];
1045
+ if (d.length !== 1 || t.length !== 1 || d[0] !== t[0] || !d[0] || d[0].includes("/")) return null;
1046
+ return d[0];
1047
+ }
1048
+ function soloOwnerOf(gov, teams) {
1049
+ if (!gov.soloOwnerCanApproveBoth) return null;
1050
+ return soloApprover(approverLists(gov.owners, gov.rights ?? null, teams));
1051
+ }
1052
+ function soloOwnerSentence(login, you = false) {
1053
+ return you ? "As the only owner, your approval covers design and code." : `As the only owner, @${norm(login)} approves design and code in one review.`;
1054
+ }
1042
1055
  function shipPolicy(owners, rights, teams) {
1043
1056
  if (!rights) return null;
1044
1057
  const entries = holdersOf("ship", owners, rights);
@@ -1313,7 +1326,8 @@ function defineConfig(input) {
1313
1326
  minReasonLength: g.override.minReasonLength ?? DEFAULT_OVERRIDE.minReasonLength
1314
1327
  }
1315
1328
  } : {},
1316
- ...g.rights ? { rights: normalizeRights(g.rights) } : {}
1329
+ ...g.rights ? { rights: normalizeRights(g.rights) } : {},
1330
+ ...g.soloOwnerCanApproveBoth === true ? { soloOwnerCanApproveBoth: true } : {}
1317
1331
  },
1318
1332
  products: input.products?.length ? input.products.map((p) => ({ ...p })) : DEFAULT_PRODUCTS.map((p) => ({ ...p })),
1319
1333
  changes: input.changes === "direct" ? "direct" : DEFAULT_CHANGES_MODE,
@@ -1437,6 +1451,7 @@ function loadConfig(source) {
1437
1451
  }
1438
1452
  }
1439
1453
  problems.push(...rightsProblems(gov.rights));
1454
+ if (gov.soloOwnerCanApproveBoth !== void 0 && typeof gov.soloOwnerCanApproveBoth !== "boolean") problems.push('"governance.soloOwnerCanApproveBoth" must be true or false');
1440
1455
  }
1441
1456
  }
1442
1457
  problems.push(...visualImpactProblems(d.visualImpact));
@@ -3058,27 +3073,30 @@ export {
3058
3073
  serializeJson as c1,
3059
3074
  shipPolicy as c2,
3060
3075
  snapshotUrl as c3,
3061
- storybookUrl as c4,
3062
- suggestNearestComment as c5,
3063
- summarizeTokenChange as c6,
3064
- tarballAssetName as c7,
3065
- tarballUrl as c8,
3066
- teamKey as c9,
3067
- teamKeyOf as ca,
3068
- teamUnreadableMessage as cb,
3069
- teamsIn as cc,
3070
- toAlias as cd,
3071
- toMap as ce,
3072
- toPlain as cf,
3073
- tokenBump as cg,
3074
- tokenNode as ch,
3075
- unreadableShipTeams as ci,
3076
- unreadableTeams as cj,
3077
- valueIn as ck,
3078
- valueToCss as cl,
3079
- visualImpactProblems as cm,
3080
- whoCanShipSentence as cn,
3081
- whyItExists as co,
3076
+ soloApprover as c4,
3077
+ soloOwnerOf as c5,
3078
+ soloOwnerSentence as c6,
3079
+ storybookUrl as c7,
3080
+ suggestNearestComment as c8,
3081
+ summarizeTokenChange as c9,
3082
+ tarballAssetName as ca,
3083
+ tarballUrl as cb,
3084
+ teamKey as cc,
3085
+ teamKeyOf as cd,
3086
+ teamUnreadableMessage as ce,
3087
+ teamsIn as cf,
3088
+ toAlias as cg,
3089
+ toMap as ch,
3090
+ toPlain as ci,
3091
+ tokenBump as cj,
3092
+ tokenNode as ck,
3093
+ unreadableShipTeams as cl,
3094
+ unreadableTeams as cm,
3095
+ valueIn as cn,
3096
+ valueToCss as co,
3097
+ visualImpactProblems as cp,
3098
+ whoCanShipSentence as cq,
3099
+ whyItExists as cr,
3082
3100
  collectRefs as d,
3083
3101
  evaluatePairs as e,
3084
3102
  findReferenceProblems as f,
@@ -3103,4 +3121,4 @@ export {
3103
3121
  parseColor as y,
3104
3122
  rgbaToHex as z
3105
3123
  };
3106
- //# sourceMappingURL=prod-branch-BdMPKffE.js.map
3124
+ //# sourceMappingURL=prod-branch-6ftQWwdu.js.map