@bridge-ds/core 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bridge.config.schema.json +16 -0
- package/dist/audit/index.js +3 -3
- package/dist/audit/report.d.ts +17 -2
- package/dist/branch-actions.d.ts +7 -1
- package/dist/build-requests-github.d.ts +25 -0
- package/dist/build-requests.d.ts +403 -0
- package/dist/changelog-model.d.ts +102 -0
- package/dist/component-spec.d.ts +3 -1
- package/dist/config.d.ts +21 -0
- package/dist/css-color.d.ts +25 -0
- package/dist/docs-proposal.d.ts +1 -0
- package/dist/explorations.d.ts +1 -0
- package/dist/fidelity-references.d.ts +12 -0
- package/dist/figma-fix-loop.d.ts +153 -0
- package/dist/figma-fixes.d.ts +169 -0
- package/dist/figma-push-github.d.ts +7 -2
- package/dist/figma-push.d.ts +15 -2
- package/dist/gap-case.d.ts +144 -0
- package/dist/github-client.d.ts +31 -0
- package/dist/id-map.d.ts +10 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +3412 -658
- package/dist/index.js.map +1 -1
- package/dist/layered-review.d.ts +2 -0
- package/dist/measure-status.d.ts +127 -0
- package/dist/measured-only.d.ts +28 -0
- package/dist/measured-spec.d.ts +349 -0
- package/dist/measured-tokens.d.ts +25 -0
- package/dist/motion-docs.d.ts +51 -0
- package/dist/node/audit.d.ts +11 -3
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1637 -24
- package/dist/node/index.js.map +1 -1
- package/dist/node/measure-script.d.ts +1 -0
- package/dist/node/measure.d.ts +212 -0
- package/dist/node/spec-css.d.ts +9 -1
- package/dist/node/tokens-script.d.ts +3 -0
- package/dist/pr-composer.d.ts +5 -0
- package/dist/previews.d.ts +4 -1
- package/dist/{prod-branch-DenQkr_e.js → prod-branch-Bdx_2bRQ.js} +197 -159
- package/dist/prod-branch-Bdx_2bRQ.js.map +1 -0
- package/dist/prod-branch.d.ts +1 -1
- package/dist/repo-model.d.ts +5 -1
- package/dist/repo-source-github.d.ts +8 -0
- package/dist/{repo-source-CRfhLO87.js → repo-source-m0Tc603o.js} +1406 -629
- package/dist/repo-source-m0Tc603o.js.map +1 -0
- package/dist/repo-source.d.ts +6 -0
- package/dist/{report-DVEmUr0p.js → report-DFPKygfk.js} +17 -6
- package/dist/{report-DVEmUr0p.js.map → report-DFPKygfk.js.map} +1 -1
- package/dist/requester.d.ts +14 -0
- package/dist/requests.d.ts +2 -0
- package/dist/review-gate.d.ts +183 -2
- package/dist/risk.d.ts +12 -0
- package/dist/share-branch.d.ts +1 -1
- package/dist/snapshot.d.ts +34 -0
- package/dist/suggestion-review.d.ts +2 -0
- package/dist/suggestions-github.d.ts +21 -0
- package/dist/suggestions.d.ts +6 -0
- package/dist/token-proposal.d.ts +7 -0
- package/dist/try-in-product.d.ts +9 -0
- package/package.json +1 -1
- package/dist/prod-branch-DenQkr_e.js.map +0 -1
- package/dist/repo-source-CRfhLO87.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface Requester {
|
|
2
|
+
/** The display name, when the line gives one. */
|
|
3
|
+
name: string | null;
|
|
4
|
+
/** The GitHub login, without "@", when the line gives one. */
|
|
5
|
+
login: string | null;
|
|
6
|
+
}
|
|
7
|
+
/** The neutral author of a change whose requester deleted their Bridge account (api/account rewrites the line). */
|
|
8
|
+
export declare const FORMER_MEMBER = "A former member";
|
|
9
|
+
/** How a sentence names a requester by first name ("Waiting for Priya"): the former member stays whole. */
|
|
10
|
+
export declare const requesterFirstName: (name: string) => string;
|
|
11
|
+
/** The requester a body names, null when it names none (or names it in a form Bridge does not write). */
|
|
12
|
+
export declare function requesterOf(body: string | null | undefined): Requester | null;
|
|
13
|
+
/** The line Bridge writes for a requester: "Requested by Ann Leroy (@annleroy)." */
|
|
14
|
+
export declare function requesterLine(r: Requester): string;
|
package/dist/requests.d.ts
CHANGED
|
@@ -45,6 +45,8 @@ export interface ComponentChangeRequest {
|
|
|
45
45
|
* `exploration` label and the brief says to work on that branch (docs/EXPLORATIONS.md).
|
|
46
46
|
*/
|
|
47
47
|
exploration?: string | undefined;
|
|
48
|
+
/** Build request details (before and after images, props needed, spec path): build-requests.ts. */
|
|
49
|
+
build?: import('./build-requests').BuildRequestExtra | undefined;
|
|
48
50
|
}
|
|
49
51
|
export interface RequestIssue {
|
|
50
52
|
title: string;
|
package/dist/review-gate.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FigmaPush } from './build-requests';
|
|
1
2
|
import type { OverridePolicy } from './config';
|
|
2
3
|
import { type ShipPolicy } from './rights';
|
|
3
4
|
import { type RiskTier } from './risk';
|
|
@@ -12,8 +13,22 @@ export interface PullStateLike {
|
|
|
12
13
|
draft?: boolean;
|
|
13
14
|
merged?: boolean;
|
|
14
15
|
merged_at?: string | null;
|
|
16
|
+
/** GitHub labels (objects or names): `drafted-by-claude` makes a draft ready for review (isDraft). */
|
|
17
|
+
labels?: readonly ({
|
|
18
|
+
name?: string;
|
|
19
|
+
} | string)[] | null | undefined;
|
|
15
20
|
}
|
|
16
21
|
export type PullState = 'merged' | 'closed' | 'draft' | 'open';
|
|
22
|
+
/**
|
|
23
|
+
* Where Claude stands on a library branch opened from Figma (figma-push labels): `waiting` while it carries the spec
|
|
24
|
+
* only (a developer builds it with Claude), `drafted` once the code is written. Null on any other branch.
|
|
25
|
+
*/
|
|
26
|
+
export declare function claudeStage(labels: PullStateLike['labels']): 'waiting' | 'drafted' | null;
|
|
27
|
+
/**
|
|
28
|
+
* A draft on GitHub that still reads as one. Decision RT-1: once Claude drafted the code (`drafted-by-claude`), the
|
|
29
|
+
* branch is ready for review even while GitHub still calls it a draft; the merge marks it ready first (branch-actions).
|
|
30
|
+
*/
|
|
31
|
+
export declare const isDraft: (p: Pick<PullStateLike, "draft" | "labels">) => boolean;
|
|
17
32
|
/** Merged wins over closed (GitHub reports merged pull requests as closed), closed over draft, draft over open. */
|
|
18
33
|
export declare function pullState(p: PullStateLike): PullState;
|
|
19
34
|
/** Label and pill tone of each state, for list and detail views. */
|
|
@@ -33,7 +48,13 @@ export interface CiStatusLike {
|
|
|
33
48
|
context: string;
|
|
34
49
|
state: 'success' | 'failure' | 'error' | 'pending' | string;
|
|
35
50
|
target_url?: string | null;
|
|
51
|
+
description?: string | null;
|
|
36
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* A status the hosting platform posts when it refused to run at all (Vercel "Deployment rate limited"): it says nothing
|
|
55
|
+
* about the change, and GitHub does not require it, so it never counts as a failed check.
|
|
56
|
+
*/
|
|
57
|
+
export declare function isPlatformRefusal(s: Pick<CiStatusLike, 'state' | 'description'>): boolean;
|
|
37
58
|
export type CiState = 'pass' | 'fail' | 'pending' | 'none';
|
|
38
59
|
export interface CiSummary {
|
|
39
60
|
state: CiState;
|
|
@@ -56,13 +77,29 @@ export interface ReviewLike {
|
|
|
56
77
|
} | null;
|
|
57
78
|
state: 'APPROVED' | 'CHANGES_REQUESTED' | 'COMMENTED' | 'DISMISSED' | 'PENDING' | string;
|
|
58
79
|
submitted_at?: string | null;
|
|
80
|
+
/** The commit the review was given on (GitHub `commit_id`): tells whether the branch moved on since. */
|
|
81
|
+
commit_id?: string | null;
|
|
59
82
|
}
|
|
60
83
|
export interface ApprovalSummary {
|
|
61
84
|
approvers: string[];
|
|
62
85
|
changesRequested: string[];
|
|
63
86
|
design: boolean;
|
|
64
87
|
tech: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* One owner approved (design or tech list, teams expanded): the Tier 1 rule of docs/GOVERNANCE.md, "1 code owner",
|
|
90
|
+
* the same as Settings says ("one owner"). With no owner configured, any approval counts. Absent (a summary built by
|
|
91
|
+
* hand): any approval counts.
|
|
92
|
+
*/
|
|
93
|
+
owner?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* A token value change (withTokenValueApprovals, decision TV-1 in docs/BUILD-REQUESTS.md): token values changed or
|
|
96
|
+
* tokens added, nothing renamed or removed, no code. The design approval is all it needs: once it is in, `tech` counts
|
|
97
|
+
* as given and the change ships after the automatic checks. mergeGate never asks for the tech approval then.
|
|
98
|
+
*/
|
|
99
|
+
valuesOnly?: boolean;
|
|
65
100
|
}
|
|
101
|
+
/** Whether the Tier 1 approval is in: one owner approved (GOVERNANCE.md "1 code owner"), else any approval without owners. */
|
|
102
|
+
export declare const hasOwnerApproval: (a: ApprovalSummary) => boolean;
|
|
66
103
|
export interface ApprovalRules {
|
|
67
104
|
/**
|
|
68
105
|
* `governance.soloOwnerCanApproveBoth`: when the owners resolve to one person holding both roles, that person's
|
|
@@ -75,6 +112,41 @@ export declare function summarizeApprovals(reviews: ReviewLike[], owners: {
|
|
|
75
112
|
design: string[];
|
|
76
113
|
tech: string[];
|
|
77
114
|
}, author?: string, rules?: ApprovalRules): ApprovalSummary;
|
|
115
|
+
/**
|
|
116
|
+
* The reviewers to look again: the author updated the branch after every changes request that still counts (the
|
|
117
|
+
* latest decisive review of each of those reviewers was given on a commit other than `headSha`). Then it is the
|
|
118
|
+
* reviewers' turn, not the author's, like GitHub's re-request but read from what happened (an email member cannot
|
|
119
|
+
* request reviewers). Empty while one request was given on the current head, or a review does not say its commit.
|
|
120
|
+
* The merge gate is unchanged: the changes request still blocks until that reviewer approves.
|
|
121
|
+
*/
|
|
122
|
+
export declare function lookAgainReviewers(reviews: ReviewLike[], headSha: string | null | undefined, author?: string): string[];
|
|
123
|
+
/**
|
|
124
|
+
* The approvals a pull request carries from the Bridge suggestion it applies (its body says "Closes #n"): the owners
|
|
125
|
+
* approved that exact change on the suggestion, so the pull request that applies it is not gated a second time for the
|
|
126
|
+
* same approval (docs/GOVERNANCE.md, Suggestions). Only when the suggestion is approved (every approval its tier needs,
|
|
127
|
+
* no changes requested) and the pull request's tier is not higher than the tier it was approved at. Changes requested
|
|
128
|
+
* on the pull request itself still block, and CI, conflicts and the ship right gate the merge as before.
|
|
129
|
+
*/
|
|
130
|
+
export declare function withSuggestionApprovals(pr: ApprovalSummary, suggestion: {
|
|
131
|
+
approvals: ApprovalSummary;
|
|
132
|
+
tier: RiskTier;
|
|
133
|
+
} | null | undefined, prTier: RiskTier | null | undefined): ApprovalSummary;
|
|
134
|
+
/**
|
|
135
|
+
* The approvals a push from the Figma plugin carries (docs/BUILD-REQUESTS.md): a push counts as design-approved, since
|
|
136
|
+
* keeping unvalidated work out of Figma main is the team's discipline. Token values only (scope `token-values`) also
|
|
137
|
+
* count as tech-approved: they ship after the automatic checks. A rename or removal, code, or unread token changes still
|
|
138
|
+
* need the tech approval. A guardrail file (`outside`) gets no credit. Changes requested on the pull request, CI, a
|
|
139
|
+
* conflict and the ship right gate the merge as before.
|
|
140
|
+
*/
|
|
141
|
+
export declare function withFigmaPushApprovals(pr: ApprovalSummary, push: FigmaPush | null | undefined): ApprovalSummary;
|
|
142
|
+
/**
|
|
143
|
+
* Decision TV-1 (docs/BUILD-REQUESTS.md, "Token values from Studio"): a token value change follows the rule of a push
|
|
144
|
+
* from Figma, whoever opened it (Studio, the CLI, the MCP server, an agent). Once the design approval is given, it
|
|
145
|
+
* ships after the automatic checks with no developer code OK: the tech approval counts as given. A rename or removal,
|
|
146
|
+
* unread token changes, code or a guardrail file is not a value change (isTokenValueChange) and still needs it. Changes
|
|
147
|
+
* requested, CI, a conflict and the ship right gate the merge as before.
|
|
148
|
+
*/
|
|
149
|
+
export declare function withTokenValueApprovals(pr: ApprovalSummary, valuesOnly: boolean | null | undefined): ApprovalSummary;
|
|
78
150
|
export type MissingApproval = 'design approval' | 'tech approval' | 'approval';
|
|
79
151
|
export interface MergeGate {
|
|
80
152
|
allowed: boolean;
|
|
@@ -88,6 +160,21 @@ export interface MergeGate {
|
|
|
88
160
|
}
|
|
89
161
|
/** Whether `login` may use the owner override. Case-insensitive, a leading @ is ignored. */
|
|
90
162
|
export declare function canOverride(login: string | null | undefined, policy: OverridePolicy | null | undefined): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Who may use the owner override: the logins `governance.override.allowed` names that are also owners (design or
|
|
165
|
+
* tech lists, teams expanded). docs/GOVERNANCE.md: "A listed owner may merge past missing approvals only". Settings,
|
|
166
|
+
* the Home and the branch page read this one list, so the override is never offered to someone who is not an owner.
|
|
167
|
+
* When an owner entry is a team whose members are not known (a "/" entry), the allowed list stands as it is.
|
|
168
|
+
*/
|
|
169
|
+
export declare function overrideHolders(policy: OverridePolicy | null | undefined, owners: {
|
|
170
|
+
design: string[];
|
|
171
|
+
tech: string[];
|
|
172
|
+
}): string[];
|
|
173
|
+
/** The override policy limited to its holders (overrideHolders): what the gate and the who-acts rules read. */
|
|
174
|
+
export declare const ownerOverridePolicy: (policy: OverridePolicy | null | undefined, owners: {
|
|
175
|
+
design: string[];
|
|
176
|
+
tech: string[];
|
|
177
|
+
}) => OverridePolicy | null;
|
|
91
178
|
/**
|
|
92
179
|
* Whether the Merge button is enabled, and why not. Mirrors docs/GOVERNANCE.md.
|
|
93
180
|
* The owner override only ever covers missing approvals: CI failing or running, changes requested, a draft,
|
|
@@ -110,8 +197,90 @@ export declare function mergeGate(input: {
|
|
|
110
197
|
ship?: ShipPolicy | null;
|
|
111
198
|
}): MergeGate;
|
|
112
199
|
/** The gate reason of a conflict, in the words a designer reads. Detected by identity, never by regex. */
|
|
200
|
+
/**
|
|
201
|
+
* The verdict on one pull request, assembled once for every surface: Studio's branch page and row status, the MCP
|
|
202
|
+
* tools (bridge_branch_status, bridge_merge_branch, bridge_what_needs_me) and the CLI (`bridge branch status`,
|
|
203
|
+
* `bridge branch merge`). One composition of the rules of docs/GOVERNANCE.md, so a branch never reads ready in one
|
|
204
|
+
* place and blocked in another:
|
|
205
|
+
* - the pull request that applies an approved suggestion ("Closes #n") carries its approvals (withSuggestionApprovals);
|
|
206
|
+
* - the owner override is limited to the owners `governance.override.allowed` names (ownerOverridePolicy);
|
|
207
|
+
* - Tier 1 needs one owner approval (hasOwnerApproval, inside mergeGate and reviewStatusKind).
|
|
208
|
+
* `gate` is null while the tests or the reviews could not be read: an unknown read never reads as mergeable.
|
|
209
|
+
*/
|
|
210
|
+
export interface BranchVerdictInput {
|
|
211
|
+
tier: RiskTier | null;
|
|
212
|
+
ci: CiSummary | null;
|
|
213
|
+
/** The pull request's own approvals (summarizeApprovals); null when its reviews could not be read. */
|
|
214
|
+
approvals: ApprovalSummary | null;
|
|
215
|
+
/** The approved Bridge suggestion the pull request applies (approvedSuggestionOnGitHub), or null. */
|
|
216
|
+
suggestion?: {
|
|
217
|
+
approvals: ApprovalSummary;
|
|
218
|
+
tier: RiskTier;
|
|
219
|
+
} | null | undefined;
|
|
220
|
+
/** The approver lists (approverLists: rights applied, teams expanded). */
|
|
221
|
+
owners: {
|
|
222
|
+
design: string[];
|
|
223
|
+
tech: string[];
|
|
224
|
+
};
|
|
225
|
+
/** `governance.override` as configured; the verdict limits it to its owner holders. */
|
|
226
|
+
override?: OverridePolicy | null | undefined;
|
|
227
|
+
draft?: boolean | undefined;
|
|
228
|
+
/** The pull request's labels: `drafted-by-claude` reads a draft as ready for review (isDraft). */
|
|
229
|
+
labels?: PullStateLike['labels'];
|
|
230
|
+
mergeable?: boolean | null | undefined;
|
|
231
|
+
state?: string | undefined;
|
|
232
|
+
merged_at?: string | null | undefined;
|
|
233
|
+
/** Login of the viewer; null or absent leaves out who may ship and the override (signed out, no token). */
|
|
234
|
+
viewer?: string | null | undefined;
|
|
235
|
+
exploration?: boolean | undefined;
|
|
236
|
+
ship?: ShipPolicy | null | undefined;
|
|
237
|
+
/** Pushed from the Figma plugin (figmaPushOf): design approved by the push, tech too for token values only. */
|
|
238
|
+
figmaPush?: FigmaPush | null | undefined;
|
|
239
|
+
/**
|
|
240
|
+
* The pull request only changes token values (isTokenValueChange over its real files and token changes), whoever
|
|
241
|
+
* opened it: the design approval is all it needs (withTokenValueApprovals, decision TV-1). Absent: not known, the
|
|
242
|
+
* tech approval is still asked.
|
|
243
|
+
*/
|
|
244
|
+
tokenValues?: boolean | null | undefined;
|
|
245
|
+
/**
|
|
246
|
+
* Auto-merge is armed on the pull request (GitHub `auto_merge` set): Bridge armed a token value change once its design
|
|
247
|
+
* approval was in (/api/ship, decision TV-1). With `tokenValues` and the design approval, it reads `autoShip`.
|
|
248
|
+
*/
|
|
249
|
+
autoMerge?: boolean | null | undefined;
|
|
250
|
+
/**
|
|
251
|
+
* The reviewers to look again (lookAgainReviewers over the reviews and the head sha): the author updated the branch
|
|
252
|
+
* after every changes request. The status stays `changes-requested` and the merge stays blocked; only its words say
|
|
253
|
+
* "Updated, look again".
|
|
254
|
+
*/
|
|
255
|
+
lookAgain?: readonly string[] | null | undefined;
|
|
256
|
+
}
|
|
257
|
+
export interface BranchVerdict {
|
|
258
|
+
/** The approvals the gate counts: the pull request's own plus the ones carried from its approved suggestion. */
|
|
259
|
+
approvals: ApprovalSummary | null;
|
|
260
|
+
/** The owner override as the gate reads it: its holders only. Null when none is configured. */
|
|
261
|
+
override: OverridePolicy | null;
|
|
262
|
+
gate: MergeGate | null;
|
|
263
|
+
status: ReviewStatusKind;
|
|
264
|
+
/** The words of the status, the same in Studio, the MCP server and the CLI (reviewStatusLabel). */
|
|
265
|
+
label: string;
|
|
266
|
+
/** Reviewers to look again (the input's lookAgain while changes are requested), else empty. */
|
|
267
|
+
lookAgain: string[];
|
|
268
|
+
/**
|
|
269
|
+
* A token push from Figma with values only, still open: Bridge merges it once the automatic checks pass, nobody
|
|
270
|
+
* reviews it. Also a token value change whose design approval is in and whose merge Bridge armed (`autoMerge`,
|
|
271
|
+
* decision TV-1). Review queues and "Needs you" leave it out; Studio shows "On its way to the library".
|
|
272
|
+
*/
|
|
273
|
+
autoShip: boolean;
|
|
274
|
+
}
|
|
275
|
+
export declare function branchVerdict(input: BranchVerdictInput): BranchVerdict;
|
|
113
276
|
export declare const CONFLICT_REASON = "It conflicts with main: resolve it with Update from main on the branch.";
|
|
114
277
|
export declare const OVERRIDE_HEADING = "**Bridge owner override**";
|
|
278
|
+
/**
|
|
279
|
+
* The shortest override reason accepted. docs/GOVERNANCE.md: the reason is always required, at least
|
|
280
|
+
* `minReasonLength` characters (20 by default). `requireReason: false` no longer waives it: an override without a
|
|
281
|
+
* reason would leave the audit trail empty.
|
|
282
|
+
*/
|
|
283
|
+
export declare function overrideReasonMin(policy: Pick<OverridePolicy, 'minReasonLength'>): number;
|
|
115
284
|
/** Problem with an override reason, or null when it is accepted. */
|
|
116
285
|
export declare function overrideReasonProblem(reason: string, policy: OverridePolicy): string | null;
|
|
117
286
|
/**
|
|
@@ -163,6 +332,7 @@ export declare const REVIEW_STATUS_ORDER: Record<ReviewStatusKind, number>;
|
|
|
163
332
|
export declare function reviewStatusKind(input: {
|
|
164
333
|
state?: string;
|
|
165
334
|
draft?: boolean;
|
|
335
|
+
labels?: PullStateLike['labels'];
|
|
166
336
|
merged_at?: string | null;
|
|
167
337
|
ci: CiSummary | null;
|
|
168
338
|
approvals: ApprovalSummary | null;
|
|
@@ -174,6 +344,14 @@ export declare function reviewStatusKind(input: {
|
|
|
174
344
|
* working out whether an approved branch merges cleanly; it never stands for missing tests.
|
|
175
345
|
*/
|
|
176
346
|
export declare const REVIEW_STATUS_LABEL: Record<ReviewStatusKind, string>;
|
|
347
|
+
/** The words of a branch the author updated after every changes request: the reviewers who asked look again. */
|
|
348
|
+
export declare const LOOK_AGAIN_STATUS_LABEL = "Updated, look again";
|
|
349
|
+
/**
|
|
350
|
+
* The words of a status. Changes requested on a branch the author updated since (lookAgainReviewers not empty) reads
|
|
351
|
+
* "Updated, look again", never the stale "Changes requested": the merge gate is the same, the next step is the
|
|
352
|
+
* reviewers'.
|
|
353
|
+
*/
|
|
354
|
+
export declare function reviewStatusLabel(kind: ReviewStatusKind, lookAgain?: readonly string[] | null): string;
|
|
177
355
|
/** The words of a CI summary. A repo without automated checks reads as that, calmly, never as pending or unknown. */
|
|
178
356
|
export declare const CI_STATE_LABEL: Record<CiState, string>;
|
|
179
357
|
export interface QueuePull extends PullStateLike {
|
|
@@ -233,8 +411,11 @@ export declare function reopenEligibility(x: {
|
|
|
233
411
|
branch: 'exists' | 'gone' | 'unknown';
|
|
234
412
|
}): ReopenEligibility;
|
|
235
413
|
export type ApprovalRole = 'design' | 'tech' | 'approval';
|
|
236
|
-
/**
|
|
237
|
-
|
|
414
|
+
/**
|
|
415
|
+
* The approvals a tier needs, as mergeGate counts them (Tier 2 and 3: design and tech; Tier 1: one approval). A token
|
|
416
|
+
* value change (`valuesOnly`, withTokenValueApprovals) needs the design approval only.
|
|
417
|
+
*/
|
|
418
|
+
export declare function requiredApprovals(tier: RiskTier | null, valuesOnly?: boolean | null): ApprovalRole[];
|
|
238
419
|
/** The approvals still missing on a branch, from its tier and the reviews read (empty when either is unknown). */
|
|
239
420
|
export declare function pendingApprovals(tier: RiskTier | null | undefined, approvals: ApprovalSummary | null | undefined): ApprovalRole[];
|
|
240
421
|
/**
|
package/dist/risk.d.ts
CHANGED
|
@@ -32,6 +32,18 @@ export interface RiskResult {
|
|
|
32
32
|
bump?: SemverBump | undefined;
|
|
33
33
|
}
|
|
34
34
|
export declare const RISK_LABELS: Record<RiskTier, string>;
|
|
35
|
+
/**
|
|
36
|
+
* The tier line of a token change pushed from the Figma plugin (docs/BUILD-REQUESTS.md): a push is design-approved, so
|
|
37
|
+
* the approvals part of RISK_LABELS would mislead. Token values ship once the checks pass; a rename or a removal waits for
|
|
38
|
+
* a developer OK. Keeps "Tier N" first so parseTier reads it. Same rule as branchVerdict `autoShip`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function figmaPushTierLabel(tier: RiskTier, changes: readonly {
|
|
41
|
+
kind: TokenChangeKind | string;
|
|
42
|
+
}[]): string;
|
|
43
|
+
/** The sentence after it: what happens next to a token change pushed from Figma. */
|
|
44
|
+
export declare const figmaPushNextLine: (changes: readonly {
|
|
45
|
+
kind: TokenChangeKind | string;
|
|
46
|
+
}[]) => string;
|
|
35
47
|
/** Kind and description-only flag of any token change. */
|
|
36
48
|
export declare function summarizeTokenChange(c: AcceptedChange | TokenChangeSummary): TokenChangeSummary;
|
|
37
49
|
/** Semver bump of a set of token changes: renames and removals major, other changes minor, descriptions patch. */
|
package/dist/share-branch.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The dialog's explanation, in designer words. */
|
|
2
|
-
export declare const SHARE_EXPLAIN = "Product teams can install this
|
|
2
|
+
export declare const SHARE_EXPLAIN = "Product teams can install this change in their app before it is in the library, and remove it any time.";
|
|
3
3
|
export type ChangeLifecycle = 'open' | 'draft' | 'merged' | 'closed';
|
|
4
4
|
type Source = 'pkg.pr.new' | 'release' | 'other';
|
|
5
5
|
export type ShareState =
|
package/dist/snapshot.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { AuditMetrics, AuditReport } from './audit/types';
|
|
2
|
+
import type { ChangelogReleaseRow } from './changelog-model';
|
|
2
3
|
import type { ContrastPairResult } from './contrast-model';
|
|
3
4
|
import type { SpecCoverage } from './component-spec';
|
|
5
|
+
import { type MotionDocs } from './motion-docs';
|
|
4
6
|
import { type RepoSource } from './repo-source';
|
|
5
7
|
import type { RepoModel } from './repo-model';
|
|
6
8
|
export declare const SNAPSHOT_SCHEMA_VERSION = 1;
|
|
@@ -10,6 +12,17 @@ export declare const SNAPSHOT_FILE = "snapshot.json";
|
|
|
10
12
|
export declare const SNAPSHOT_AUDITS_DIR = "audits";
|
|
11
13
|
/** Above this, a snapshot is refused (a published file the browser downloads whole). */
|
|
12
14
|
export declare const SNAPSHOT_MAX_BYTES = 5000000;
|
|
15
|
+
/** Releases a snapshot keeps, newest first (the pending one counts); older ones stay in the CHANGELOG.md files. */
|
|
16
|
+
export declare const SNAPSHOT_MAX_RELEASES = 60;
|
|
17
|
+
/** A workspace package of the repository, for the Library's Install page. */
|
|
18
|
+
export interface SnapshotPackage {
|
|
19
|
+
name: string;
|
|
20
|
+
version: string;
|
|
21
|
+
/** Not published to npm. */
|
|
22
|
+
private: boolean;
|
|
23
|
+
/** Repo-relative folder ("." for the root package). */
|
|
24
|
+
dir: string;
|
|
25
|
+
}
|
|
13
26
|
/** One adoption audit: the summary lives in snapshot.json, the full report in audits/<id>.json next to it. */
|
|
14
27
|
export interface SnapshotAudit {
|
|
15
28
|
id: string;
|
|
@@ -85,6 +98,19 @@ export interface RepoSnapshot {
|
|
|
85
98
|
* written before Bridge read global stylesheets: a reader then reads those files from the repository.
|
|
86
99
|
*/
|
|
87
100
|
styles?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* Releases from the packages' CHANGELOG.md files and the pending changesets, newest first, at most
|
|
103
|
+
* SNAPSHOT_MAX_RELEASES. Dates come from release tags or git history, absent when the clone has neither. Absent from
|
|
104
|
+
* a snapshot written before Bridge read releases, or when the repository has no changelog.
|
|
105
|
+
*/
|
|
106
|
+
releases?: ChangelogReleaseRow[];
|
|
107
|
+
/** Workspace packages (name, version, private, folder). Absent from a snapshot written before Bridge read them. */
|
|
108
|
+
packages?: SnapshotPackage[];
|
|
109
|
+
/**
|
|
110
|
+
* Motion and interaction docs per component (motionDocs), keyed by component name, computed from the specs file the
|
|
111
|
+
* snapshot does not carry. Absent without a readable specs file or a component scan.
|
|
112
|
+
*/
|
|
113
|
+
motion?: Record<string, MotionDocs>;
|
|
88
114
|
}
|
|
89
115
|
export declare class SnapshotError extends Error {
|
|
90
116
|
}
|
|
@@ -120,7 +146,15 @@ export interface BuildSnapshotInput {
|
|
|
120
146
|
committedAt?: string;
|
|
121
147
|
generatedAt?: string;
|
|
122
148
|
audits?: SnapshotAudit[];
|
|
149
|
+
/** collectReleases() of the repository; kept to the newest SNAPSHOT_MAX_RELEASES. */
|
|
150
|
+
releases?: ChangelogReleaseRow[];
|
|
151
|
+
packages?: SnapshotPackage[];
|
|
123
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Motion docs of every scanned component, from the parsed specs file: what the Library's motion section shows. Null
|
|
155
|
+
* without a specs file or a component scan.
|
|
156
|
+
*/
|
|
157
|
+
export declare function snapshotMotion(model: Pick<RepoModel, 'components' | 'specs'>): Record<string, MotionDocs> | null;
|
|
124
158
|
/** Counts of a model for the snapshot summary. */
|
|
125
159
|
export declare function snapshotSummary(model: RepoModel): SnapshotSummary;
|
|
126
160
|
/** Assembles the snapshot from a model and the files it was read from. The specs file becomes the coverage list. */
|
|
@@ -68,6 +68,8 @@ export interface SuggestionApprovals extends ApprovalSummary {
|
|
|
68
68
|
export declare function summarizeSuggestionApprovals(comments: readonly SuggestionCommentLike[], gov: SuggestionGovernance, opts: {
|
|
69
69
|
payloadSha: string;
|
|
70
70
|
author?: string | null | undefined;
|
|
71
|
+
/** A token value suggestion (suggestionIsTokenValues): the design approval is all it needs (decision TV-1). */
|
|
72
|
+
valuesOnly?: boolean | undefined;
|
|
71
73
|
}): SuggestionApprovals;
|
|
72
74
|
/** The review state for the status machine: changes requested beats approved; approved when no approval is missing. */
|
|
73
75
|
export declare function suggestionReviewState(tier: RiskTier, approvals: ApprovalSummary): 'needs-review' | 'changes-requested' | 'approved';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GitHubClient, type IssueSummary, type PullRequestSummary } from './github-client';
|
|
2
|
+
import { type Requester } from './requester';
|
|
2
3
|
import { type SuggestionAppliedRecord, type SuggestionApprovals, type SuggestionCommentLike, type SuggestionGovernance, type SuggestionReviewEvent } from './suggestion-review';
|
|
3
4
|
import { type ComposeSuggestionOptions, type ParsedSuggestion, type SuggestionKind, type SuggestionPayloadV1, type SuggestionStatus } from './suggestions';
|
|
4
5
|
import type { ApprovalRole } from './review-gate';
|
|
@@ -32,6 +33,11 @@ export interface SuggestionListItem {
|
|
|
32
33
|
title: string;
|
|
33
34
|
url: string;
|
|
34
35
|
author: string;
|
|
36
|
+
/**
|
|
37
|
+
* Who asked for it, as Bridge records it in the body ("Requested by Ann Leroy."): the person to show, since the
|
|
38
|
+
* GitHub author is often a lead or an agent acting for them. Null when the body names nobody.
|
|
39
|
+
*/
|
|
40
|
+
requester: Requester | null;
|
|
35
41
|
createdAt: string;
|
|
36
42
|
state: 'open' | 'closed';
|
|
37
43
|
stateReason: string | null;
|
|
@@ -86,6 +92,21 @@ export declare function getSuggestionOnGitHub(gh: GitHubClient, n: number, gov:
|
|
|
86
92
|
pulls?: PullRequestSummary[] | undefined;
|
|
87
93
|
outdated?: boolean | undefined;
|
|
88
94
|
}): Promise<SuggestionDetail>;
|
|
95
|
+
/** An approved Bridge suggestion a pull request applies: its number, approvals and the tier they were given at. */
|
|
96
|
+
export interface ApprovedSuggestion {
|
|
97
|
+
number: number;
|
|
98
|
+
approvals: SuggestionApprovals;
|
|
99
|
+
tier: 1 | 2 | 3;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The approved Bridge suggestion a pull request applies, from the issues its body closes ("Closes #n", the first three):
|
|
103
|
+
* its approvals and the tier they were given at, for branchVerdict (withSuggestionApprovals). Null when it closes
|
|
104
|
+
* none, or none is an approved suggestion. Studio, the MCP server and the CLI read it through this one call. A read
|
|
105
|
+
* that fails counts as no suggestion: the pull request then needs its own approvals, never fewer.
|
|
106
|
+
*/
|
|
107
|
+
export declare function approvedSuggestionOnGitHub(gh: GitHubClient, body: string | null | undefined, gov: SuggestionGovernance): Promise<ApprovedSuggestion | null>;
|
|
108
|
+
/** One issue: the approved suggestion it holds, or null (not a suggestion, not approved). Throws when it cannot be read. */
|
|
109
|
+
export declare function approvedSuggestionNumber(gh: GitHubClient, n: number, gov: SuggestionGovernance): Promise<ApprovedSuggestion | null>;
|
|
89
110
|
/**
|
|
90
111
|
* Keeps exactly one status label on the issue, the one the status calls for (suggestionLabelChanges): an open state
|
|
91
112
|
* label while open, the final label ("suggestion: applied", "suggestion: declined") once closed, the old ones removed.
|
package/dist/suggestions.d.ts
CHANGED
|
@@ -173,6 +173,12 @@ export interface SuggestionStatusInput {
|
|
|
173
173
|
/** The dry-run apply found a conflict with the current default branch. */
|
|
174
174
|
outdated?: boolean | undefined;
|
|
175
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Decision TV-1 (docs/BUILD-REQUESTS.md, "Token values from Studio"): a token suggestion that only changes values or
|
|
178
|
+
* adds tokens (every edit a `set` or an `add`, no file beside its changeset) needs the design approval only, the same
|
|
179
|
+
* rule as a pull request (isTokenValueChange). A rename, a removal or any other kind still needs the tech approval.
|
|
180
|
+
*/
|
|
181
|
+
export declare function suggestionIsTokenValues(p: Pick<SuggestionPayloadV1, 'kind' | 'tokens' | 'files' | 'docs' | 'componentSpec'>): boolean;
|
|
176
182
|
/**
|
|
177
183
|
* Where a suggestion stands. Closed: applied when a linked pull request merged or the issue was closed as completed,
|
|
178
184
|
* declined otherwise. Open: applying when a linked pull request is open or an applied marker exists; outdated when the
|
package/dist/token-proposal.d.ts
CHANGED
|
@@ -52,6 +52,8 @@ export declare function planTokenProposal(input: {
|
|
|
52
52
|
tool?: string | undefined;
|
|
53
53
|
/** More body paragraphs, after the generated body (the product line, "Needed by"). */
|
|
54
54
|
bodyExtra?: string[] | undefined;
|
|
55
|
+
/** Pushed from the Figma plugin: the body says design-approved and what happens next (docs/BUILD-REQUESTS.md). */
|
|
56
|
+
fromFigma?: boolean | undefined;
|
|
55
57
|
}): TokenProposalPlan | null;
|
|
56
58
|
export interface OpenedTokenProposal {
|
|
57
59
|
branch: string;
|
|
@@ -74,6 +76,11 @@ export declare function writeTokenProposalOnGitHub(gh: GitHubClient, plan: Token
|
|
|
74
76
|
labelsAfter?: string[] | undefined;
|
|
75
77
|
/** Who proposes it, in the commit message: "Bridge MCP (source: mcp)". */
|
|
76
78
|
tool?: string | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Open it as a draft or not. Default: a draft from tier 2, until design review. A token push from Figma with values
|
|
81
|
+
* only opens ready (false): it ships after the automatic checks (docs/BUILD-REQUESTS.md).
|
|
82
|
+
*/
|
|
83
|
+
draft?: boolean | undefined;
|
|
77
84
|
}): Promise<OpenedTokenProposal>;
|
|
78
85
|
export interface SuggestedTokenProposal {
|
|
79
86
|
status: 'suggested';
|
package/dist/try-in-product.d.ts
CHANGED
|
@@ -17,3 +17,12 @@ export declare function productPreview(apps: PreviewApps, ctx: {
|
|
|
17
17
|
* Only http(s) previews: anything else (a javascript: or data: URL in a hostile comment) gives ''.
|
|
18
18
|
*/
|
|
19
19
|
export declare function tryInProductUrl(preview: string, pr: number, screen: ProductScreen | null): string;
|
|
20
|
+
/**
|
|
21
|
+
* True when nothing reported an online preview of the branch (no Vercel status, deployment or comment, only config
|
|
22
|
+
* templates): explorations and library branches are not deployed, a developer tries them on their machine.
|
|
23
|
+
*/
|
|
24
|
+
export declare function noOnlinePreview(previews: readonly {
|
|
25
|
+
source: string | null;
|
|
26
|
+
}[]): boolean;
|
|
27
|
+
/** The command that puts a branch on a developer's machine, quoted when the name has shell characters. */
|
|
28
|
+
export declare function localTryCommand(branch: string): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bridge-ds/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Bridge core: bridge.config.json, DTCG token loading (tiers and layered modes), alias resolution, WCAG contrast, diffs, minimal-diff edits, PR body, the shared risk tier classifier, changesets and a fetch-based GitHub client. No Figma API, no DOM; Node-only helpers (git, reading a product folder) under @bridge-ds/core/node; the adoption audit under @bridge-ds/core/audit.",
|
|
6
6
|
"license": "MIT",
|