@bridge-ds/core 0.17.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.
Files changed (64) hide show
  1. package/bridge.config.schema.json +16 -0
  2. package/dist/activity.d.ts +207 -0
  3. package/dist/audit/index.js +3 -3
  4. package/dist/audit/report.d.ts +17 -2
  5. package/dist/branch-actions.d.ts +7 -1
  6. package/dist/build-requests-github.d.ts +25 -0
  7. package/dist/build-requests.d.ts +403 -0
  8. package/dist/changelog-model.d.ts +102 -0
  9. package/dist/component-spec.d.ts +3 -1
  10. package/dist/config.d.ts +21 -0
  11. package/dist/css-color.d.ts +25 -0
  12. package/dist/docs-proposal.d.ts +1 -0
  13. package/dist/explorations.d.ts +1 -0
  14. package/dist/fidelity-references.d.ts +12 -0
  15. package/dist/figma-fix-loop.d.ts +153 -0
  16. package/dist/figma-fixes.d.ts +169 -0
  17. package/dist/figma-push-github.d.ts +7 -2
  18. package/dist/figma-push.d.ts +15 -2
  19. package/dist/gap-case.d.ts +144 -0
  20. package/dist/github-client.d.ts +31 -0
  21. package/dist/id-map.d.ts +10 -0
  22. package/dist/index.d.ts +14 -0
  23. package/dist/index.js +3944 -774
  24. package/dist/index.js.map +1 -1
  25. package/dist/layered-review.d.ts +2 -0
  26. package/dist/measure-status.d.ts +127 -0
  27. package/dist/measured-only.d.ts +28 -0
  28. package/dist/measured-spec.d.ts +349 -0
  29. package/dist/measured-tokens.d.ts +25 -0
  30. package/dist/motion-docs.d.ts +51 -0
  31. package/dist/node/audit.d.ts +11 -3
  32. package/dist/node/index.d.ts +1 -0
  33. package/dist/node/index.js +1637 -24
  34. package/dist/node/index.js.map +1 -1
  35. package/dist/node/measure-script.d.ts +1 -0
  36. package/dist/node/measure.d.ts +212 -0
  37. package/dist/node/spec-css.d.ts +9 -1
  38. package/dist/node/tokens-script.d.ts +3 -0
  39. package/dist/pr-composer.d.ts +5 -0
  40. package/dist/previews.d.ts +4 -1
  41. package/dist/{prod-branch-DenQkr_e.js → prod-branch-Bdx_2bRQ.js} +197 -159
  42. package/dist/prod-branch-Bdx_2bRQ.js.map +1 -0
  43. package/dist/prod-branch.d.ts +1 -1
  44. package/dist/repo-model.d.ts +5 -1
  45. package/dist/repo-source-github.d.ts +8 -0
  46. package/dist/{repo-source-B4jNZhyC.js → repo-source-m0Tc603o.js} +1406 -629
  47. package/dist/repo-source-m0Tc603o.js.map +1 -0
  48. package/dist/repo-source.d.ts +6 -0
  49. package/dist/{report-DVEmUr0p.js → report-DFPKygfk.js} +17 -6
  50. package/dist/{report-DVEmUr0p.js.map → report-DFPKygfk.js.map} +1 -1
  51. package/dist/requester.d.ts +14 -0
  52. package/dist/requests.d.ts +2 -0
  53. package/dist/review-gate.d.ts +183 -2
  54. package/dist/risk.d.ts +12 -0
  55. package/dist/share-branch.d.ts +1 -1
  56. package/dist/snapshot.d.ts +34 -0
  57. package/dist/suggestion-review.d.ts +2 -0
  58. package/dist/suggestions-github.d.ts +21 -0
  59. package/dist/suggestions.d.ts +6 -0
  60. package/dist/token-proposal.d.ts +7 -0
  61. package/dist/try-in-product.d.ts +9 -0
  62. package/package.json +1 -1
  63. package/dist/prod-branch-DenQkr_e.js.map +0 -1
  64. package/dist/repo-source-B4jNZhyC.js.map +0 -1
@@ -0,0 +1,403 @@
1
+ import { type BridgeConfig } from './config';
2
+ import { type ComponentChangeRequest, type RequestIssue, type RequestKind } from './requests';
3
+ import { type ChangedFile, type TokenChangeKind, type TokenChangeSummary } from './risk';
4
+ import { type CiSummary } from './review-gate';
5
+ /** Every build request issue carries this label (with component-change, which the Jira Action mirrors). */
6
+ export declare const BUILD_REQUEST_LABEL = "bridge-build";
7
+ /** The label the plugin puts on what it pushes (token pull requests, suggestions and requests). */
8
+ export declare const SOURCE_FIGMA_LABEL = "source: figma";
9
+ /** A build request waits this many days before it reads as stale. */
10
+ export declare const BUILD_STALE_DAYS = 7;
11
+ /**
12
+ * What the two images of a build request are called on designer screens (Studio): the component as it is in code
13
+ * now, and the design in Figma. The data keeps its field names, `before` and `after`; the GitHub issue table, read by
14
+ * developers, keeps Before and After.
15
+ */
16
+ export declare const BUILD_IMAGE_LABEL: {
17
+ readonly before: "In code now";
18
+ readonly after: "In Figma";
19
+ };
20
+ /**
21
+ * Whether a pull request (or issue) was pushed from the Figma plugin: the `source: figma` or `from-figma` label, or the
22
+ * hidden "From Figma" origin block of a component branch.
23
+ */
24
+ export declare function isFigmaPush(p: {
25
+ labels?: readonly ({
26
+ name?: string;
27
+ } | string)[] | null | undefined;
28
+ body?: string | null | undefined;
29
+ }): boolean;
30
+ /**
31
+ * What a push from Figma changes, from the pull request's real files and token changes (never from what its body says):
32
+ * - `token-values`: token files only (values changed or tokens added), plus changesets, docs and Bridge's own files;
33
+ * - `token-structure`: a token renamed or removed;
34
+ * - `token-unknown`: token files changed but the token changes were not read (counts like token-structure);
35
+ * - `component`: component or other source code (a Claude draft branch, the pull request of a build request);
36
+ * - `outside`: a guardrail file (CI, AGENTS.md, bridge.config.json, contrast checks): no Figma credit at all.
37
+ */
38
+ export type FigmaPushScope = 'token-values' | 'token-structure' | 'token-unknown' | 'component' | 'outside';
39
+ /** A token file: `*.tokens.json`, or a JSON file under `tokens.root`. */
40
+ export declare function isTokenPath(path: string, config?: BridgeConfig | undefined): boolean;
41
+ export declare function figmaPushScope(input: {
42
+ files: readonly ChangedFile[];
43
+ tokenChanges: readonly {
44
+ kind: TokenChangeKind | string;
45
+ }[] | null | undefined;
46
+ config?: BridgeConfig | undefined;
47
+ }): FigmaPushScope;
48
+ /**
49
+ * Whether the token files of a pull request are worth reading to tell a token value change (isTokenValueChange): it
50
+ * changes token files, and nothing beside them but changesets, docs and Bridge's own files. Every other pull request
51
+ * (code, a guardrail file, no token file) is not one, with no read.
52
+ */
53
+ export declare function mayBeTokenValueChange(files: readonly ChangedFile[], config?: BridgeConfig | undefined): boolean;
54
+ /**
55
+ * Decision TV-1 (docs/BUILD-REQUESTS.md, "Token values from Studio"): a pull request that only changes token values
56
+ * (values changed or tokens added, from its real files and token changes, never from its body), whoever opened it.
57
+ * Once the design approval is given it ships after the automatic checks, with no developer code OK (review-gate
58
+ * withTokenValueApprovals, branchVerdict `tokenValues`). A rename or removal, unread token changes (null), code, a
59
+ * guardrail file or a running exploration is not one: those still need the tech approval.
60
+ */
61
+ export declare function isTokenValueChange(input: {
62
+ files: readonly ChangedFile[];
63
+ tokenChanges: readonly {
64
+ kind: TokenChangeKind | string;
65
+ }[] | null | undefined;
66
+ config?: BridgeConfig | undefined;
67
+ labels?: readonly ({
68
+ name?: string;
69
+ } | string)[] | null | undefined;
70
+ }): boolean;
71
+ /**
72
+ * The token changes between two versions of token files, by kind, from their text alone (DTCG: a node with `$value` is a
73
+ * token, its path the keys joined by "."). For callers that only have the files of a pull request (the server arming a
74
+ * merge, Studio's branch page): a path gone is `removed` (a rename reads as removed plus added, which gates the same),
75
+ * a new path `added`, a different `$value`, `$type` or extension `changed`, a different `$description` only
76
+ * `changed` with descriptionOnly. Unreadable JSON throws, so the caller treats the changes as unknown.
77
+ */
78
+ export declare function tokenFileChanges(files: readonly {
79
+ before: string | null | undefined;
80
+ after: string | null | undefined;
81
+ }[]): TokenChangeSummary[];
82
+ /** The Figma push facts the gate reads (branchVerdict `figmaPush`). Null when the pull request is not one. */
83
+ export interface FigmaPush {
84
+ scope: FigmaPushScope;
85
+ }
86
+ /**
87
+ * The Figma push facts of a pull request: pushed from the plugin (isFigmaPush), or the pull request of a build request
88
+ * sent from Figma (`closesFigmaBuildRequest`: its body closes one). Null otherwise, and for a running exploration.
89
+ */
90
+ export declare function figmaPushOf(pr: {
91
+ labels?: readonly ({
92
+ name?: string;
93
+ } | string)[] | null | undefined;
94
+ body?: string | null | undefined;
95
+ }, facts: {
96
+ files: readonly ChangedFile[];
97
+ tokenChanges: readonly {
98
+ kind: TokenChangeKind | string;
99
+ }[] | null | undefined;
100
+ config?: BridgeConfig | undefined;
101
+ closesFigmaBuildRequest?: boolean | undefined;
102
+ }): FigmaPush | null;
103
+ /** Whether a scope ships with no person in the loop: design approved by the push, tech approved by being values only. */
104
+ export declare const shipsByItself: (scope: FigmaPushScope | null | undefined) => boolean;
105
+ /**
106
+ * Where one published thing went:
107
+ * - `shipped`: a token pull request with values only. Bridge merges it once the automatic checks pass (auto-merge
108
+ * armed); poll libraryArrival until it reads "In the library".
109
+ * - `waiting-for-developer`: a pull request a developer approves first (a token renamed or removed).
110
+ * - `build-request`: an issue developers build from (a structure change).
111
+ */
112
+ export type PublishRoute = 'shipped' | 'waiting-for-developer' | 'build-request';
113
+ export interface PublishOutcome {
114
+ /** What was published: a token path, or a component name. */
115
+ subject: {
116
+ type: 'token' | 'component';
117
+ name: string;
118
+ };
119
+ route: PublishRoute;
120
+ /** The pull request (shipped, waiting-for-developer) or the issue (build-request). */
121
+ ref: {
122
+ kind: 'pull' | 'issue';
123
+ number: number;
124
+ url: string;
125
+ };
126
+ /**
127
+ * `shipped` only: whether Bridge armed the merge (auto-merge on GitHub, or the Bridge app merging on green checks).
128
+ * False when it could not (no Bridge app on the repository, auto-merge off): the route is then reported as
129
+ * `waiting-for-developer` instead, so this is true on every `shipped` outcome.
130
+ */
131
+ armed?: boolean | undefined;
132
+ }
133
+ export interface PublishResult {
134
+ outcomes: PublishOutcome[];
135
+ }
136
+ export declare const PUBLISH_ROUTE_COPY: Record<PublishRoute, {
137
+ label: string;
138
+ sentence: string;
139
+ }>;
140
+ /**
141
+ * The route of a token push, from its token changes: values changed or tokens added ship; a rename or a removal waits
142
+ * for a developer. `armed` false (Bridge could not arm the merge) also waits for a developer.
143
+ */
144
+ export declare function tokenPublishRoute(changes: readonly {
145
+ kind: TokenChangeKind | string;
146
+ }[], armed?: boolean): Exclude<PublishRoute, 'build-request'>;
147
+ /** One sentence for the end of a publish: "2 on their way to the library, 1 waiting for a developer, 1 build request sent." */
148
+ export declare function publishSummary(r: PublishResult): string;
149
+ export type LibraryArrivalKey = 'on-its-way' | 'in-the-library' | 'held' | 'not-shipped';
150
+ export interface LibraryArrival {
151
+ key: LibraryArrivalKey;
152
+ label: string;
153
+ sentence: string;
154
+ /** Stop polling: it is in the library, or it will not get there by itself. */
155
+ final: boolean;
156
+ }
157
+ /**
158
+ * Where a published pull request stands, for the plugin to poll after `shipped` (every 20 to 30 seconds is plenty)
159
+ * and for Studio. Never names a technical blocker: a failing check, a conflict or a change request all read "Held for a
160
+ * developer". `held` is final for polling on a conflict or a change request (a person picks it up from there), not on a
161
+ * failed check, which a re-run can clear.
162
+ */
163
+ export declare function libraryArrival(p: {
164
+ state: string;
165
+ merged_at?: string | null | undefined;
166
+ merged?: boolean | undefined;
167
+ mergeable?: boolean | null | undefined;
168
+ ci?: CiSummary | null | undefined;
169
+ changesRequested?: number | undefined;
170
+ }): LibraryArrival;
171
+ /** The review Bridge's app leaves on a token push it ships (the merge rule's record on GitHub). */
172
+ export declare const FIGMA_SHIP_HEADING = "**Bridge: shipped from Figma**";
173
+ export declare function figmaShipReviewBody(by?: string | null): string;
174
+ /** A prop (option) the build needs. */
175
+ export interface BuildProp {
176
+ name: string;
177
+ /** "variant", "boolean", "text", "instance swap", or a TypeScript type. */
178
+ type?: string | undefined;
179
+ values?: string[] | undefined;
180
+ default?: string | undefined;
181
+ /** "new", "changed" or "removed"; default new. */
182
+ change?: 'new' | 'changed' | 'removed' | undefined;
183
+ note?: string | undefined;
184
+ }
185
+ /** What a build request adds to a component change request (kept in the request's hidden block, under `build`). */
186
+ export interface BuildRequestExtra {
187
+ v: 1;
188
+ /** Image URLs of the design before and after the change. */
189
+ before?: string[] | undefined;
190
+ after?: string[] | undefined;
191
+ props?: BuildProp[] | undefined;
192
+ /** Where the full spec lives, when it is not in the issue (too large): a path on a branch, or a URL. */
193
+ specPath?: string | undefined;
194
+ }
195
+ /** The input of the build request issue builder (the Figma plugin, Studio, the CLI and the MCP server). */
196
+ export interface BuildRequestInput {
197
+ /** Coded name ("Button"), or the proposed name of a new component. */
198
+ component: string;
199
+ kind: RequestKind;
200
+ /** One line, sentence case: "Add a lg size". */
201
+ title: string;
202
+ /** What and why, in the designer's words. */
203
+ summary: string;
204
+ /** What changes for developers in one sentence. */
205
+ line?: string | undefined;
206
+ changes?: ComponentChangeRequest['changes'] | undefined;
207
+ figma: {
208
+ fileKey?: string | undefined;
209
+ nodeId?: string | undefined;
210
+ nodeName?: string | undefined;
211
+ url?: string | undefined;
212
+ };
213
+ images?: {
214
+ before?: string[] | undefined;
215
+ after?: string[] | undefined;
216
+ } | undefined;
217
+ props?: BuildProp[] | undefined;
218
+ /** The structured spec (the plugin's ComponentPushDiff, with its token edits), shown collapsed. Omitted when too large. */
219
+ spec?: unknown;
220
+ specPath?: string | undefined;
221
+ /** A brief for Claude written by the caller; default buildRequestBrief. */
222
+ brief?: string | undefined;
223
+ source: ComponentChangeRequest['source'];
224
+ /** GitHub login of who pushed, when known (the "Requested by" record). */
225
+ requestedBy?: string | undefined;
226
+ }
227
+ /** Kinds that are structure changes, so a push from Figma becomes a build request. */
228
+ export declare const BUILD_KINDS: readonly RequestKind[];
229
+ /** The largest spec JSON kept in the issue body (GitHub caps a body at 65,536 characters). */
230
+ export declare const BUILD_SPEC_MAX = 30000;
231
+ /** The request a build request input stands for (what parseRequestIssue reads back, with `build`). */
232
+ export declare function buildRequestOf(input: BuildRequestInput): ComponentChangeRequest & {
233
+ build: BuildRequestExtra;
234
+ };
235
+ /**
236
+ * The brief Claude gets to build it ("Copy brief for Claude" in Studio, `bridge build show` in the CLI,
237
+ * `bridge_get_build_request` in the MCP server). Without an issue number (inside the issue body), it says "this issue".
238
+ */
239
+ export declare function buildRequestBrief(r: ComponentChangeRequest & {
240
+ build?: BuildRequestExtra | undefined;
241
+ }, ctx?: {
242
+ issue?: number | undefined;
243
+ issueUrl?: string | undefined;
244
+ componentsDir?: string | undefined;
245
+ agentsFile?: string | undefined;
246
+ files?: string[] | undefined;
247
+ }): string;
248
+ /**
249
+ * The GitHub issue of a build request: a component change request issue (component-change, so the bridge-jira Action
250
+ * mirrors it to Jira) with the bridge-build label, before and after images side by side, the props needed, the spec
251
+ * collapsed and the brief for Claude collapsed. parseBuildRequestIssue reads it back.
252
+ */
253
+ export declare function composeBuildRequestIssue(input: BuildRequestInput, opts?: {
254
+ labels?: string[] | undefined;
255
+ assignees?: string[] | undefined;
256
+ componentUrl?: string | undefined;
257
+ }): RequestIssue;
258
+ /** The build request in an issue body, or undefined when it has no Bridge request block. `build` is empty for a plain request. */
259
+ export declare function parseBuildRequestIssue(body: string | null | undefined): (ComponentChangeRequest & {
260
+ build: BuildRequestExtra;
261
+ }) | undefined;
262
+ /** The spec kept collapsed in a build request issue, or undefined. */
263
+ export declare function parseBuildSpec(body: string | null | undefined): unknown;
264
+ /** Whether an issue is a build request: every component change request is one (bridge-build marks the new ones). Explorations are not. */
265
+ export declare function isBuildRequestIssue(labels: readonly ({
266
+ name?: string;
267
+ } | string)[] | null | undefined): boolean;
268
+ /**
269
+ * Requested (nobody assigned) -> Picked up (assigned: "Ana is on it") -> In progress (a linked draft pull request, or a
270
+ * linked branch with commits) -> In review (a linked pull request ready for review) -> Shipped (merged, or the issue
271
+ * closed as completed). `not-planned`: closed as not planned.
272
+ */
273
+ export type BuildStatus = 'requested' | 'picked-up' | 'in-progress' | 'in-review' | 'shipped' | 'not-planned';
274
+ export declare const BUILD_STATUS_LABEL: Record<BuildStatus, string>;
275
+ /** Steps of the status timeline, in order (not-planned is off the line). */
276
+ export declare const BUILD_STEPS: readonly BuildStatus[];
277
+ /** A pull request linked to a build request (closes it, or the build request is that branch). */
278
+ export interface BuildPullLike {
279
+ number: number;
280
+ url?: string | undefined;
281
+ /** "open", "closed" or "merged" (PullRequestSummary), or GitHub's open/closed with merged_at. */
282
+ state: string;
283
+ draft?: boolean | undefined;
284
+ mergedAt?: string | null | undefined;
285
+ merged_at?: string | null | undefined;
286
+ labels?: readonly ({
287
+ name?: string;
288
+ } | string)[] | undefined;
289
+ author?: string | undefined;
290
+ assignees?: string[] | undefined;
291
+ createdAt?: string | undefined;
292
+ updatedAt?: string | undefined;
293
+ body?: string | undefined;
294
+ /** Commits on the branch, when known (a branch with only the spec commit is not work in progress). */
295
+ commits?: number | null | undefined;
296
+ headRef?: string | undefined;
297
+ title?: string | undefined;
298
+ }
299
+ export interface BuildIssueLike {
300
+ number: number;
301
+ url: string;
302
+ title: string;
303
+ body: string;
304
+ state: 'open' | 'closed';
305
+ stateReason?: string | null | undefined;
306
+ labels: readonly ({
307
+ name?: string;
308
+ } | string)[];
309
+ author?: string | undefined;
310
+ assignees?: string[] | undefined;
311
+ createdAt: string;
312
+ closedAt?: string | null | undefined;
313
+ }
314
+ export interface BuildStatusEvent {
315
+ status: BuildStatus;
316
+ /** ISO date, when GitHub says. */
317
+ at?: string | undefined;
318
+ /** Who, when it is a person ("ana"). */
319
+ who?: string | undefined;
320
+ }
321
+ export interface BuildRequestView {
322
+ /** "issue-12" or "pull-34". */
323
+ id: string;
324
+ /** Where it lives: an issue, or (direct mode, no issue) the library branch from Figma waiting for a developer. */
325
+ kind: 'issue' | 'pull';
326
+ number: number;
327
+ url: string;
328
+ component: string;
329
+ /** "Add a lg size": the request's title, without the component prefix. */
330
+ title: string;
331
+ requestKind: RequestKind | null;
332
+ status: BuildStatus;
333
+ label: string;
334
+ /** One designer sentence: "Ana is on it.", "Waiting for a developer for 9 days." */
335
+ sentence: string;
336
+ /** Who works on it: the assignees, else the author of the linked pull request in progress. */
337
+ builders: string[];
338
+ requestedBy: string | null;
339
+ createdAt: string;
340
+ ageDays: number;
341
+ /** Requested for more than BUILD_STALE_DAYS days. */
342
+ stale: boolean;
343
+ shippedAt: string | null;
344
+ /** The linked pull request that moves it furthest. */
345
+ pull: {
346
+ number: number;
347
+ url?: string | undefined;
348
+ state: string;
349
+ } | null;
350
+ /** Jira key from the bridge-jira Action's `jira: DS-12` label. */
351
+ jira: string | null;
352
+ figmaUrl: string | null;
353
+ /** The status timeline: each step reached, with when and who when GitHub says. */
354
+ timeline: BuildStatusEvent[];
355
+ }
356
+ /** The issue numbers a pull request links: "Closes #n" in its body, plus GitHub's linked issues when the caller read them. */
357
+ export declare function linkedIssueNumbers(p: Pick<BuildPullLike, 'body'>, extra?: readonly number[]): number[];
358
+ /** The Jira key the bridge-jira Action labelled an issue with ("jira: DS-12"), or null. */
359
+ export declare function jiraKeyOfLabels(labels: readonly ({
360
+ name?: string;
361
+ } | string)[] | null | undefined): string | null;
362
+ /**
363
+ * The status of one build request, from GitHub only: the issue (state, reason, assignees) and the pull requests linked
364
+ * to it. `nameOf` turns a login into the name a designer knows (team members), default the login.
365
+ */
366
+ export declare function buildRequestStatus(x: {
367
+ issue?: BuildIssueLike | null | undefined;
368
+ pull?: BuildPullLike | null | undefined;
369
+ linked?: readonly BuildPullLike[] | undefined;
370
+ }, now?: Date | number, nameOf?: (login: string) => string): Pick<BuildRequestView, 'status' | 'label' | 'sentence' | 'builders' | 'ageDays' | 'stale' | 'shippedAt' | 'pull' | 'timeline' | 'createdAt'>;
371
+ /**
372
+ * Every build request, from the issues and pull requests read on GitHub: issues that are build requests
373
+ * (isBuildRequestIssue) with the pull requests that close them, plus library branches from Figma waiting for a
374
+ * developer that no issue covers (direct mode). `linkedByIssue`: GitHub's linked pull requests per issue number, when the
375
+ * caller read the timeline (Development links), on top of "Closes #n".
376
+ */
377
+ export declare function assembleBuildRequests(input: {
378
+ issues: readonly BuildIssueLike[];
379
+ pulls: readonly BuildPullLike[];
380
+ now?: Date | number | undefined;
381
+ nameOf?: ((login: string) => string) | undefined;
382
+ linkedByIssue?: ReadonlyMap<number, readonly number[]> | undefined;
383
+ }): BuildRequestView[];
384
+ /** The filters of the Being built page. */
385
+ export type BuildFilter = 'all' | 'waiting' | 'in-progress' | 'shipped-this-week';
386
+ export declare const BUILD_FILTER_LABEL: Record<BuildFilter, string>;
387
+ /** Whether a build request shows under a filter. "All" leaves out what was closed as not planned more than a week ago. */
388
+ export declare function matchesBuildFilter(v: Pick<BuildRequestView, 'status' | 'shippedAt' | 'timeline'>, f: BuildFilter, now?: Date | number): boolean;
389
+ /** Build requests still open (not shipped, not closed). */
390
+ export declare const openBuildRequests: <V extends Pick<BuildRequestView, "status">>(views: readonly V[]) => V[];
391
+ /** The calm summary line of the home: "3 being built, 1 waiting to be picked up." Null when nothing is open. */
392
+ export declare function buildSummaryLine(views: readonly Pick<BuildRequestView, 'status' | 'stale'>[]): string | null;
393
+ /**
394
+ * The Library component page line while build requests for a component are open: "Figma is ahead: 2 changes being
395
+ * built (Ana)." Null when none is open (it disappears once shipped).
396
+ */
397
+ export declare function figmaAheadLine(views: readonly Pick<BuildRequestView, 'component' | 'status' | 'builders'>[], component: string, nameOf?: (login: string) => string): {
398
+ count: number;
399
+ builders: string[];
400
+ sentence: string;
401
+ } | null;
402
+ /** "Button: add a lg size", the issue title of a build request (same rule as every request). */
403
+ export declare const buildRequestTitle: (r: Pick<BuildRequestInput, "component" | "title">) => string;
@@ -0,0 +1,102 @@
1
+ export type ChangelogBump = 'major' | 'minor' | 'patch';
2
+ export interface ChangelogEntry {
3
+ source: 'changeset' | 'release';
4
+ /** First sentence of the note, the row title. */
5
+ title: string;
6
+ /** Rest of the note's first paragraph, may be empty. */
7
+ detail: string;
8
+ kind: string;
9
+ bump: ChangelogBump | null;
10
+ packages: string[];
11
+ forYou: string;
12
+ /** The author wrote the "For you:" line (forYou is not the default for the bump). */
13
+ forYouAuthored?: boolean;
14
+ date?: string;
15
+ /** Changeset id: the commit sha prefix in a CHANGELOG.md, or the .changeset file path for pending ones. */
16
+ ref?: string;
17
+ }
18
+ export interface ChangelogReleasePackage {
19
+ name: string;
20
+ version: string;
21
+ /** Published to npm (not a private app). */
22
+ published: boolean;
23
+ }
24
+ export interface ChangelogRelease {
25
+ /** "v1.1.0" (the Library version, from @bridge-ds/react) or "core 0.3.1" when react is not in the release. */
26
+ name: string;
27
+ date?: string;
28
+ pending: boolean;
29
+ packages: ChangelogReleasePackage[];
30
+ entries: ChangelogEntry[];
31
+ announcement: string;
32
+ }
33
+ /** One "## x.y.z" section of a package CHANGELOG.md. */
34
+ export interface ChangelogSection {
35
+ pkg: string;
36
+ version: string;
37
+ published: boolean;
38
+ notes: {
39
+ id: string;
40
+ bump: ChangelogBump;
41
+ text: string;
42
+ }[];
43
+ }
44
+ export declare const shortPackage: (name: string) => string;
45
+ /** Splits a paragraph into sentences: ". ", "! " or "? " before a capital, a quote or a backtick, never inside `code`. */
46
+ export declare function noteSentences(para: string): string[];
47
+ /** Longest second sentence shown under a title; a longer one stays in the full notes rather than being cut. */
48
+ export declare const CHANGELOG_DETAIL_MAX = 240;
49
+ /**
50
+ * A note as a row: its first sentence is the title (no trailing period), the second one the description when it is
51
+ * short enough to read in a list, and the author's "For you:" line when there is one.
52
+ */
53
+ export declare function splitNote(text: string): {
54
+ title: string;
55
+ detail: string;
56
+ forYou?: string;
57
+ };
58
+ /** Parses a package CHANGELOG.md into its version sections. "Updated dependencies" lines are not changes. */
59
+ export declare function parseChangelogSections(md: string, pkg: string, published: boolean): ChangelogSection[];
60
+ /** One pending .changeset/*.md file, or null when it is not a changeset. */
61
+ export declare function parseChangeset(src: string, ref: string): ChangelogEntry | null;
62
+ /**
63
+ * Groups version sections into releases. Sections released together share a date, or, when no date is known
64
+ * (shallow clone, no tags), share a changeset: the release action writes one changeset into every package it
65
+ * bumps. Each changeset shows once per release, with every package it touched. Newest first.
66
+ * `dateOf(pkg, version)` returns the release date (YYYY-MM-DD) or undefined; it never guesses.
67
+ */
68
+ export declare function groupReleases(sections: ChangelogSection[], dateOf: (pkg: string, version: string) => string | undefined, libraryPackage?: string): Omit<ChangelogRelease, 'announcement'>[];
69
+ /** Breaking first, then New, Fix, Internal; the notes' own order inside a kind. */
70
+ export declare function sortChangelogEntries<T extends {
71
+ kind: string;
72
+ }>(entries: T[]): T[];
73
+ export declare function releaseAnnouncement(r: Omit<ChangelogRelease, 'announcement'>): string;
74
+ /** Meta line of an entry: the bump in words, then the packages (short names). Over `max`, only a count. */
75
+ export declare function releasePackagesLabel(packages: string[], max?: number): {
76
+ tags: string[];
77
+ count: string | null;
78
+ };
79
+ /** A release as the snapshot carries it: the announcement is left out (releaseAnnouncement(r) rebuilds it). */
80
+ export type ChangelogReleaseRow = Omit<ChangelogRelease, 'announcement'>;
81
+ export interface CollectReleasesInput {
82
+ /** Each package's CHANGELOG.md text, with its npm name and whether it is published (not private). */
83
+ changelogs: {
84
+ pkg: string;
85
+ published: boolean;
86
+ text: string;
87
+ }[];
88
+ /** Pending .changeset/*.md files: `ref` is the file path. README.md is not a changeset and is skipped by the caller. */
89
+ changesets?: {
90
+ ref: string;
91
+ text: string;
92
+ }[];
93
+ /** Release date (YYYY-MM-DD) of a package version, or undefined; never guessed. */
94
+ dateOf?: (pkg: string, version: string) => string | undefined;
95
+ /** Package whose version names a release ("v1.1.0"). */
96
+ libraryPackage?: string;
97
+ }
98
+ /**
99
+ * Every release of a repository, newest first: the pending changesets as "Coming in the next release" when there are
100
+ * any, then the published versions grouped by groupReleases. What the Changelog shows and the team snapshot carries.
101
+ */
102
+ export declare function collectReleases(input: CollectReleasesInput): ChangelogReleaseRow[];
@@ -8,7 +8,9 @@ export declare const DEFAULT_COMPONENT_SPECS_FILE = "packages/react/component-sp
8
8
  * (gap), sizes. Text: textFill (color), font family, size, weight, line height, letter spacing, and textDecoration (a
9
9
  * keyword, "UNDERLINE" or "STRIKETHROUGH", not a token).
10
10
  */
11
- export type SpecField = 'fill' | 'stroke' | 'strokeWeight' | 'strokeTopWeight' | 'strokeRightWeight' | 'strokeBottomWeight' | 'strokeLeftWeight' | 'cornerRadius' | 'paddingTop' | 'paddingRight' | 'paddingBottom' | 'paddingLeft' | 'itemSpacing' | 'counterAxisSpacing' | 'width' | 'height' | 'minWidth' | 'minHeight' | 'opacity' | 'textFill' | 'fontFamily' | 'fontSize' | 'fontWeight' | 'lineHeight' | 'letterSpacing' | 'textDecoration';
11
+ export type SpecField = 'fill' | 'stroke' | 'strokeWeight' | 'strokeTopWeight' | 'strokeRightWeight' | 'strokeBottomWeight' | 'strokeLeftWeight' | 'cornerRadius' | 'paddingTop' | 'paddingRight' | 'paddingBottom' | 'paddingLeft' | 'itemSpacing' | 'counterAxisSpacing' | 'width' | 'height' | 'minWidth' | 'minHeight' | 'opacity'
12
+ /** A CSS box-shadow list (drop and inner shadows), as the page computes it. */
13
+ | 'shadow' | 'textFill' | 'fontFamily' | 'fontSize' | 'fontWeight' | 'lineHeight' | 'letterSpacing' | 'textDecoration';
12
14
  export declare const SPEC_FIELDS: readonly SpecField[];
13
15
  /** Fields whose token must be a color. */
14
16
  export declare const COLOR_FIELDS: ReadonlySet<SpecField>;
package/dist/config.d.ts CHANGED
@@ -17,6 +17,16 @@ export interface StorybookConfig {
17
17
  /** Root URL (where index.json and iframe.html are served), https only, no trailing slash. */
18
18
  url: string;
19
19
  }
20
+ /**
21
+ * A public demo's persona (Bridge's own demo repositories only): who a visitor without an account stands in for,
22
+ * so the demo home greets them as that person ("Good morning, Dana.") and names their role. Ignored elsewhere.
23
+ */
24
+ export interface DemoConfig {
25
+ /** The persona's first name: "Dana". */
26
+ viewer: string;
27
+ /** What they do: "DS lead". */
28
+ role?: string;
29
+ }
20
30
  /** The team's hosted Library (/library/<owner>/<repo>/). */
21
31
  export interface LibraryConfig {
22
32
  /** True lets search engines index the hosted Library of a public repository. Default false: noindex. */
@@ -144,6 +154,8 @@ export interface AuditConfig {
144
154
  exclude?: string[] | undefined;
145
155
  }
146
156
  export interface BridgeConfig {
157
+ /** The team's display name ("Bridge", "Acme Design"), 1 to 60 characters. Undefined: Bridge names the team after its repository. */
158
+ name?: string | undefined;
147
159
  /** GitHub repository. Undefined only for a detected config of a repo with no known remote. */
148
160
  repo: RepoRef | undefined;
149
161
  tokens: TokenConfig;
@@ -190,6 +202,8 @@ export interface BridgeConfig {
190
202
  storybook?: StorybookConfig | undefined;
191
203
  /** The hosted Library. Read it through libraryIsPublic(). */
192
204
  library?: LibraryConfig | undefined;
205
+ /** A public demo's persona (see DemoConfig). */
206
+ demo?: DemoConfig | undefined;
193
207
  }
194
208
  type Partialish<T> = {
195
209
  [K in keyof T]?: T[K] | undefined;
@@ -198,6 +212,8 @@ type Partialish<T> = {
198
212
  export interface BridgeConfigInput {
199
213
  $schema?: string;
200
214
  version?: number;
215
+ /** The team's display name, shown on invites instead of owner/repo. */
216
+ name?: string;
201
217
  repo?: (Partial<RepoRef> & {
202
218
  owner: string;
203
219
  name: string;
@@ -256,7 +272,12 @@ export interface BridgeConfigInput {
256
272
  url: string;
257
273
  };
258
274
  library?: LibraryConfig;
275
+ demo?: DemoConfig;
259
276
  }
277
+ /** Longest team display name bridge.config.json accepts. */
278
+ export declare const TEAM_NAME_MAX = 60;
279
+ /** The team's display name from a config value: trimmed, 1 to 60 characters; undefined for anything else. */
280
+ export declare function teamName(value: unknown): string | undefined;
260
281
  export declare const DEFAULT_TOKEN_PATHS: TokenPaths;
261
282
  export declare const DEFAULT_GOVERNANCE: GovernanceConfig;
262
283
  export declare class ConfigError extends Error {
@@ -0,0 +1,25 @@
1
+ /** One CSS color function (`oklch(0.205 0 0)`, `color(display-p3 1 0 0 / 0.5)`) as `rgb(r, g, b)` / `rgba(...)`. */
2
+ export declare function cssColorToRgb(fn: string, inner: string): string | undefined;
3
+ /** Every oklch/oklab/lab/lch/color() in a CSS value (a color, a shadow, SVG markup) as sRGB; the rest unchanged. */
4
+ export declare function cssColorsToRgb(text: string): string;
5
+ /** The same on every string inside a value (a measure result, a token harvest). */
6
+ export declare function withSrgbColors<T>(value: T): T;
7
+ export interface CssShadow {
8
+ inset: boolean;
9
+ x: number;
10
+ y: number;
11
+ blur: number;
12
+ spread: number;
13
+ /** 0..1 sRGB and alpha. */
14
+ color: {
15
+ r: number;
16
+ g: number;
17
+ b: number;
18
+ a: number;
19
+ };
20
+ }
21
+ /**
22
+ * A computed `box-shadow` (`rgba(0, 0, 0, 0.1) 0px 1px 3px 0px, inset ...`) as shadows, transparent ones left out (the
23
+ * zero rings utility CSS stacks under every shadow). Colors in any notation the page kept are read as sRGB.
24
+ */
25
+ export declare function parseBoxShadow(css: string | undefined): CssShadow[];
@@ -21,6 +21,7 @@ export interface DocsOrigin {
21
21
  }
22
22
  export declare const DOCS_EDITOR_ORIGIN: DocsOrigin;
23
23
  export declare const DOCS_MCP_ORIGIN: DocsOrigin;
24
+ export declare const DOCS_CLI_ORIGIN: DocsOrigin;
24
25
  export interface DocsIssue {
25
26
  field: string;
26
27
  message: string;
@@ -162,6 +162,7 @@ export declare function explorationShareMessage(input: {
162
162
  label: string;
163
163
  url: string;
164
164
  }[] | undefined;
165
+ local?: string | undefined;
165
166
  }): string;
166
167
  /**
167
168
  * The rules Claude follows on an exploration branch (request briefs, docs drafts, token edits with a target branch):
@@ -31,6 +31,18 @@ export interface ReferenceRender {
31
31
  * elements with their props, icons by name. Replaces `text` and `parts`.
32
32
  */
33
33
  children?: (string | SpecExample)[] | undefined;
34
+ /**
35
+ * Export name of the compound component this set is a part of (AccordionItem in Accordion, Radio in RadioGroup,
36
+ * MenuItem in Menu): the part needs its parent around it to render, and the image shows the part alone.
37
+ */
38
+ within?: string | undefined;
39
+ /**
40
+ * A popup drawn open (Dialog/Popup): the root renders open (`defaultOpen`), and the image is the popup Base UI
41
+ * portals, found by the class of the spec's root part ("popup", "tooltip"), not the trigger.
42
+ */
43
+ popup?: {
44
+ className: string;
45
+ } | undefined;
34
46
  }
35
47
  export type ReferencePlan = {
36
48
  ok: true;