@savvy-web/silk-core 0.1.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/index.d.ts ADDED
@@ -0,0 +1,1261 @@
1
+ import { Equal, Hash, Option, Schema } from "effect";
2
+ import { Section, SectionId } from "@effected/templates";
3
+ import { PublishConfig, PublishTarget, VersioningStrategy } from "@effected/workspaces";
4
+ //#endregion
5
+ //#region src/errors/BiomeSyncError.d.ts
6
+ declare const BiomeSyncError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
7
+ readonly _tag: "BiomeSyncError";
8
+ } & Readonly<A>;
9
+ /**
10
+ * Raised when a Biome config file cannot be read or its `$schema` URL cannot be updated.
11
+ *
12
+ * @remarks
13
+ * Returned by `BiomeSchemaSync.sync` and `BiomeSchemaSync.check` when
14
+ * a `biome.json` or `biome.jsonc` file exists but cannot be read, contains invalid JSON,
15
+ * or cannot be written back to disk.
16
+ *
17
+ * @since 0.1.0
18
+ * @public
19
+ */
20
+ export declare class BiomeSyncError extends BiomeSyncError_base<{
21
+ readonly path: string;
22
+ readonly reason: string;
23
+ }> {
24
+ get message(): string;
25
+ }
26
+ //#endregion
27
+ //#region src/errors/ChangesetConfigError.d.ts
28
+ declare const ChangesetConfigError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
29
+ readonly _tag: "ChangesetConfigError";
30
+ } & Readonly<A>;
31
+ /**
32
+ * Raised when the `.changeset/config.json` file cannot be read or decoded.
33
+ *
34
+ * @remarks
35
+ * Returned by `ChangesetConfigReader.read` when the file is missing,
36
+ * contains invalid JSON, or fails Effect Schema validation.
37
+ *
38
+ * @since 0.1.0
39
+ * @public
40
+ */
41
+ export declare class ChangesetConfigError extends ChangesetConfigError_base<{
42
+ readonly path: string;
43
+ readonly reason: string;
44
+ }> {
45
+ get message(): string;
46
+ }
47
+ //#endregion
48
+ //#region src/errors/ConfigNotFoundError.d.ts
49
+ declare const ConfigNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
50
+ readonly _tag: "ConfigNotFoundError";
51
+ } & Readonly<A>;
52
+ /**
53
+ * Raised when a config file cannot be located in any of the expected locations.
54
+ *
55
+ * @remarks
56
+ * Returned by consumers that require a config file to exist. `ConfigDiscovery.find`
57
+ * itself returns `null` instead of failing — callers that need a hard failure should
58
+ * map `null` to this error.
59
+ *
60
+ * @since 0.1.0
61
+ * @public
62
+ */
63
+ export declare class ConfigNotFoundError extends ConfigNotFoundError_base<{
64
+ readonly name: string;
65
+ readonly searchedPaths: ReadonlyArray<string>;
66
+ }> {
67
+ get message(): string;
68
+ }
69
+ //#endregion
70
+ //#region src/errors/PublishTargetBindingError.d.ts
71
+ declare const PublishTargetBindingError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
72
+ readonly _tag: "PublishTargetBindingError";
73
+ } & Readonly<A>;
74
+ /**
75
+ * Raised when publishability detection selects a directory that the package's
76
+ * `dist/prod/targets.json` binding does not describe.
77
+ *
78
+ * @remarks
79
+ * The bundler's prod build writes `targets.json` naming every byte-group
80
+ * directory it produced. Once that binding exists it is authoritative: the only
81
+ * directories whose bytes may be published are the ones it lists. A detector
82
+ * that returns anything else — most often `publishConfig.directory` pointing at
83
+ * a **dev** build, because silk mode was misdetected — is about to pack an
84
+ * unresolved workspace manifest and ship it to a registry.
85
+ *
86
+ * That is the `yaml-effect@0.7.1` failure: detection picked `dist/dev/pkg`, the
87
+ * dev manifest still carried `catalog:` specifiers, and the published package
88
+ * was uninstallable (`EUNSUPPORTEDPROTOCOL`).
89
+ *
90
+ * @since 3.1.0
91
+ * @public
92
+ */
93
+ export declare class PublishTargetBindingError extends PublishTargetBindingError_base<{
94
+ /** The package whose targets were being resolved. */
95
+ readonly pkg: string;
96
+ /** The directory detection selected, relative to the package root. */
97
+ readonly directory: string;
98
+ /** The group directories the prod binding actually describes. */
99
+ readonly boundDirectories: ReadonlyArray<string>;
100
+ }> {
101
+ get message(): string;
102
+ }
103
+ //#endregion
104
+ //#region src/errors/WorkspaceAnalysisError.d.ts
105
+ declare const WorkspaceAnalysisError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
106
+ readonly _tag: "WorkspaceAnalysisError";
107
+ } & Readonly<A>;
108
+ /**
109
+ * Raised when workspace analysis fails for a given root directory.
110
+ *
111
+ * @remarks
112
+ * Returned by `SilkWorkspaceAnalyzer.analyze` when the analysis pipeline
113
+ * encounters an unrecoverable error — e.g. workspace discovery failure,
114
+ * package manager detection failure, or publishability detection errors.
115
+ *
116
+ * @since 0.2.0
117
+ * @public
118
+ */
119
+ export declare class WorkspaceAnalysisError extends WorkspaceAnalysisError_base<{
120
+ readonly root: string;
121
+ readonly reason: string;
122
+ }> {
123
+ get message(): string;
124
+ }
125
+ //#endregion
126
+ //#region src/pr-body/linked-issue.d.ts
127
+ declare const LinkedIssueRef_base: Schema.Class<LinkedIssueRef, Schema.Struct<{
128
+ readonly number: Schema.Number;
129
+ readonly title: Schema.String;
130
+ readonly state: Schema.String;
131
+ }>, {}>;
132
+ /**
133
+ * The minimum an issue must carry to appear in a managed PR body.
134
+ *
135
+ * @remarks
136
+ * `state` is deliberately a tolerant `Schema.String` rather than a literal
137
+ * union: GitHub's REST API reports `"open"`/`"closed"` while GraphQL reports
138
+ * `"OPEN"`/`"CLOSED"`, and both actions pass their existing issue shapes
139
+ * through unchanged. **`LinkedIssueRef.isClosed` is the ONLY sanctioned way
140
+ * to test closedness** — it lowercases before comparing, so both spellings
141
+ * classify correctly. A hand-written `issue.state === "closed"` comparison
142
+ * silently misclassifies GraphQL's `"CLOSED"` as open, which re-links (and on
143
+ * merge auto-closes) an issue the release deliberately dropped.
144
+ *
145
+ * The class carries no instance members, so a plain
146
+ * `{ number, title, state }` literal satisfies the type structurally — both
147
+ * actions' existing `LinkedIssue` shapes are accepted without mapping.
148
+ *
149
+ * @public
150
+ */
151
+ declare class LinkedIssueRef extends LinkedIssueRef_base {
152
+ /**
153
+ * Whether an issue is closed, case-insensitively.
154
+ *
155
+ * @remarks
156
+ * The only sanctioned closedness test — see the class remarks for why a
157
+ * bare `state === "closed"` comparison is a silent bug against GraphQL
158
+ * payloads.
159
+ *
160
+ * @public
161
+ */
162
+ static isClosed(issue: {
163
+ readonly state: string;
164
+ }): boolean;
165
+ }
166
+ //#endregion
167
+ //#region src/pr-body/body.d.ts
168
+ /**
169
+ * The inputs to {@link ManagedPrBody.build}.
170
+ *
171
+ * @public
172
+ */
173
+ interface ManagedPrBodyOptions {
174
+ /** The proposed squash-commit subject — a conventional-commit header. */
175
+ readonly subject: string;
176
+ /**
177
+ * Every issue this run knows about, open AND closed.
178
+ *
179
+ * @remarks
180
+ * The run decides every issue it knows about: an open issue is emitted, a
181
+ * closed one is dropped, and a carried line cannot resurrect one it
182
+ * deliberately dropped. Closedness is tested with
183
+ * `LinkedIssueRef.isClosed` (case-insensitive), so REST and GraphQL
184
+ * payloads both classify correctly.
185
+ */
186
+ readonly linkedIssues: ReadonlyArray<LinkedIssueRef>;
187
+ /** The DCO signoff line the squash-commit block carries. */
188
+ readonly signoff: string;
189
+ /**
190
+ * The summary region's current content, from
191
+ * {@link ManagedPrBody.extractSummary}.
192
+ *
193
+ * @remarks
194
+ * Passed in rather than read from `priorBody` so `build` stays explicit
195
+ * about it: the summary's owner decides what it says, and this function
196
+ * must not quietly overrule a caller that passed one. `""` reserves an
197
+ * empty region.
198
+ */
199
+ readonly summary: string;
200
+ /**
201
+ * The PR's previous description, verbatim.
202
+ *
203
+ * @remarks
204
+ * The WHOLE prior body rather than an extracted region: merging
205
+ * references needs both the region's lines and the `owned` attribute on
206
+ * its opening marker, and two separate parameters would eventually be
207
+ * passed inconsistently. Optional because a PR being created has no
208
+ * prior body.
209
+ */
210
+ readonly priorBody?: string;
211
+ }
212
+ /**
213
+ * The shared managed-PR-body renderer and its carry-through readers — the
214
+ * single implementation of the contract `silk-release-action` dogfooded at
215
+ * `src/utils/pr-body.ts` (savvy-web/systems#419).
216
+ *
217
+ * @remarks
218
+ * Every operation is pure and total: markers absent, regions broken, or
219
+ * attributes malformed all degrade to the documented fail-safe result
220
+ * (preserve too much rather than delete someone's work) instead of failing —
221
+ * a regenerating action must still produce a body when the prior one is
222
+ * malformed. Use `PrBodyDiagnostic.scan` where a writer wants to be told
223
+ * about a broken pair instead of tolerating it.
224
+ *
225
+ * @public
226
+ */
227
+ declare class ManagedPrBody {
228
+ private constructor();
229
+ /**
230
+ * Build the region of the PR description the generating run owns.
231
+ *
232
+ * @remarks
233
+ * Delimited by `Markers.MANAGED_START` / `Markers.MANAGED_END` so
234
+ * {@link ManagedPrBody.upsert} can regenerate it without touching
235
+ * anything a human wrote around it. Layout, in order: the reserved
236
+ * summary region (nothing may sit above it — a reader meets the prose
237
+ * before the machinery), the proposed-squash-commit fence, and the
238
+ * bare-reference region. No preamble, no file listing, no linked-issues
239
+ * list, no run attribution — each said something already on the page.
240
+ *
241
+ * @public
242
+ */
243
+ static build(options: ManagedPrBodyOptions): string;
244
+ /**
245
+ * Put `managed` (a full {@link ManagedPrBody.build} result) into
246
+ * `existing`, replacing a previous managed region and leaving everything
247
+ * else alone.
248
+ *
249
+ * @remarks
250
+ * Human edits outside the markers survive; a body with no markers keeps
251
+ * its content and gains the region below it. See `Region.upsert` for the
252
+ * splice semantics.
253
+ *
254
+ * @public
255
+ */
256
+ static upsert(existing: string, managed: string): string;
257
+ /**
258
+ * The summary region's current content, or `""` when it is empty or
259
+ * absent.
260
+ *
261
+ * @remarks
262
+ * Extraction exists because the managed region is REGENERATED on every
263
+ * run. Re-emitting the region empty would delete a summary the moment
264
+ * any commit landed — destructive and silent, with no signal back to the
265
+ * summariser whose work was discarded. Feed the result to
266
+ * {@link ManagedPrBody.build}'s `summary` option.
267
+ *
268
+ * @public
269
+ */
270
+ static extractSummary(existing: string): string;
271
+ /**
272
+ * The reference region's current content, or `""` when it is empty or
273
+ * absent.
274
+ *
275
+ * @remarks
276
+ * Symmetric to {@link ManagedPrBody.extractSummary}, and for the same
277
+ * reason. Located by `Markers.REFERENCES_START_PREFIX` — never the plain
278
+ * opening constant — because a generating run emits the attributed form.
279
+ *
280
+ * @public
281
+ */
282
+ static extractReferences(existing: string): string;
283
+ }
284
+ //#endregion
285
+ //#region src/pr-body/diagnostics.d.ts
286
+ /**
287
+ * The problems {@link PrBodyDiagnostic.scan} can report about a body's
288
+ * markers.
289
+ *
290
+ * @public
291
+ */
292
+ declare const PrBodyDiagnosticCode: Schema.Literals<readonly ["unpairedMarker", "duplicateMarker"]>;
293
+ /**
294
+ * The problems {@link PrBodyDiagnostic.scan} can report about a body's
295
+ * markers.
296
+ *
297
+ * @public
298
+ */
299
+ type PrBodyDiagnosticCode = typeof PrBodyDiagnosticCode.Type;
300
+ declare const PrBodyDiagnostic_base: Schema.Class<PrBodyDiagnostic, Schema.Struct<{
301
+ readonly code: Schema.Literals<readonly ["unpairedMarker", "duplicateMarker"]>;
302
+ /** The region token the problem is about, e.g. `silk-release:summary`. */
303
+ readonly token: Schema.String;
304
+ }>, {}>;
305
+ /**
306
+ * One problem with a body's silk-release markers.
307
+ *
308
+ * @remarks
309
+ * Diagnostics are advisory VALUES, not a typed error channel: every parse and
310
+ * render operation in this namespace is deliberately total (a regenerating
311
+ * action must still produce a body when the prior one is malformed, and the
312
+ * fail-safe direction is to preserve too much rather than delete someone's
313
+ * work). `scan` exists for the writer that wants to be told about a broken
314
+ * pair before editing — the `pr-body` skill instructs an agent that finds a
315
+ * region missing its pair to stop and report rather than guess, and this is
316
+ * the check that instruction points at. A misplaced marker pair is worse than
317
+ * none: it makes the next regeneration rewrite content it does not own.
318
+ *
319
+ * @public
320
+ */
321
+ declare class PrBodyDiagnostic extends PrBodyDiagnostic_base {
322
+ /**
323
+ * A human-readable description, derived from the structured fields.
324
+ *
325
+ * @public
326
+ */
327
+ get message(): string;
328
+ /**
329
+ * Every marker problem in `body`, or an empty array when the markers are
330
+ * well-formed (including entirely absent — an unmanaged body is not a
331
+ * defect).
332
+ *
333
+ * @remarks
334
+ * The references region is located by its attributed opening prefix, so a
335
+ * marker carrying an `owned="…"` attribute counts as present.
336
+ *
337
+ * @public
338
+ */
339
+ static scan(body: string): ReadonlyArray<PrBodyDiagnostic>;
340
+ }
341
+ //#endregion
342
+ //#region src/pr-body/markers.d.ts
343
+ /**
344
+ * The frozen `silk-release` marker vocabulary — the wire format of the shared
345
+ * PR-body contract.
346
+ *
347
+ * @remarks
348
+ * **The `silk-release:` token is frozen and names the CONTRACT, not the
349
+ * emitting action.** `silk-update-action` PRs carry the same markers as
350
+ * release PRs, deliberately: every live document, the `pr-body` plugin skill,
351
+ * and every agent that edits a managed PR description key on these exact
352
+ * byte sequences. Do not parameterize the token per action and do not rename
353
+ * it — either forks the wire format for zero gain and orphans every open PR
354
+ * (ruled in savvy-web/systems#419).
355
+ *
356
+ * These constants are the single source of truth for the marker grammar.
357
+ * The agent-facing documentation in the silk plugin (`pr-body` and
358
+ * `commit-create` skills) duplicates the literals for readability; a drift
359
+ * lint in this package's test suite asserts the copies stay in sync.
360
+ */
361
+ /**
362
+ * The marker constants of the `silk-release` PR-body contract.
363
+ *
364
+ * @public
365
+ */
366
+ declare class Markers {
367
+ private constructor();
368
+ /**
369
+ * Opening marker of the whole managed region.
370
+ *
371
+ * @remarks
372
+ * Everything between this and {@link Markers.MANAGED_END} that is not
373
+ * inside the summary or references region is regenerated wholesale on
374
+ * every run; everything outside the pair is human territory and survives
375
+ * every regeneration.
376
+ *
377
+ * @public
378
+ */
379
+ static readonly MANAGED_START: string;
380
+ /**
381
+ * Closing marker of the whole managed region.
382
+ *
383
+ * @public
384
+ */
385
+ static readonly MANAGED_END: string;
386
+ /**
387
+ * Opening marker of the region an AI summariser owns.
388
+ *
389
+ * @remarks
390
+ * The generating action never writes into this region — it only reserves
391
+ * it and carries its content through on regeneration.
392
+ *
393
+ * @public
394
+ */
395
+ static readonly SUMMARY_START: string;
396
+ /**
397
+ * Closing marker of the summariser's region.
398
+ *
399
+ * @public
400
+ */
401
+ static readonly SUMMARY_END: string;
402
+ /**
403
+ * The PLAIN opening marker of the closing-reference region — the form an
404
+ * author writes by hand.
405
+ *
406
+ * @remarks
407
+ * A generating run emits the ATTRIBUTED form instead (the plain prefix
408
+ * plus an `owned="…"` attribute). Never locate the region by matching
409
+ * this constant — match {@link Markers.REFERENCES_START_PREFIX}, or a
410
+ * region a run wrote will not be found.
411
+ *
412
+ * @public
413
+ */
414
+ static readonly REFERENCES_START: string;
415
+ /**
416
+ * Closing marker of the closing-reference region.
417
+ *
418
+ * @public
419
+ */
420
+ static readonly REFERENCES_END: string;
421
+ /**
422
+ * The references opening marker up to its attributes, for locating a
423
+ * region whose `owned` list is unknown.
424
+ *
425
+ * @public
426
+ */
427
+ static readonly REFERENCES_START_PREFIX = "<!-- silk-release:references:start";
428
+ /**
429
+ * The fence language for the proposed squash-commit block.
430
+ *
431
+ * @remarks
432
+ * Not a GFM language and apparently undocumented, but GitHub renders it.
433
+ * It is a target for AI integrations to read and rewrite into the
434
+ * eventual squash-commit message. **Do not "correct" it to `text`.**
435
+ *
436
+ * @public
437
+ */
438
+ static readonly SQUASH_FENCE_LANGUAGE = "proposed-squash-commit";
439
+ }
440
+ //#endregion
441
+ //#region src/pr-body/references.d.ts
442
+ declare const ClosingReferences_base: Schema.Class<ClosingReferences, Schema.Struct<{
443
+ readonly ids: Schema.$Array<Schema.Number>;
444
+ }>, {}>;
445
+ /**
446
+ * An ordered list of issue ids destined for closing references, with the two
447
+ * renderers whose difference is the whole point of this module.
448
+ *
449
+ * @remarks
450
+ * The same issues appear twice in a managed PR body, spelled differently, and
451
+ * **neither consumer accepts the other's spelling**:
452
+ *
453
+ * - commitlint reads ONE comma-joined trailer (`Closes #1, #2`) inside the
454
+ * proposed-squash-commit fence — {@link ClosingReferences.renderTrailer};
455
+ * - GitHub's linker reads one bare `Closes #N` line each, OUTSIDE every
456
+ * fence — {@link ClosingReferences.renderBareLines}. A reference inside a
457
+ * fenced block is inert to GitHub.
458
+ *
459
+ * The duplication is load-bearing. Never "simplify" a body by emitting one
460
+ * form in both places: comma-joined bare lines link nothing (verified by hand
461
+ * against live pull requests — `savvy-web/silk-integration` #242/#232 with no
462
+ * bare line reported `closingIssuesReferences: []`, #243 with one reported
463
+ * `[168]`), and per-line trailers inside the fence break the commit contract.
464
+ *
465
+ * Ids are stored exactly as given — construction neither deduplicates nor
466
+ * sorts. Call {@link ClosingReferences.dedupe} where uniqueness is wanted;
467
+ * the split exists because the squash trailer historically renders duplicates
468
+ * as-given while the references region deduplicates, and byte-compatibility
469
+ * with live PR bodies pins that behavior.
470
+ *
471
+ * @public
472
+ */
473
+ declare class ClosingReferences extends ClosingReferences_base {
474
+ /**
475
+ * The open issues' ids, in input order, duplicates preserved.
476
+ *
477
+ * @remarks
478
+ * Closedness is decided by `LinkedIssueRef.isClosed` — the only
479
+ * sanctioned test, case-insensitive so REST (`closed`) and GraphQL
480
+ * (`CLOSED`) payloads classify identically.
481
+ *
482
+ * @public
483
+ */
484
+ static fromIssues(issues: ReadonlyArray<LinkedIssueRef>): ClosingReferences;
485
+ /**
486
+ * Issue ids carried by a region's bare closing lines.
487
+ *
488
+ * @remarks
489
+ * The region is read with `@effected/github-references`' `parseBareLines`
490
+ * — per line, the whole line, after trimming, must be
491
+ * `<keyword>[:] #<number>`, so a number mentioned in passing is never
492
+ * mistaken for a closing reference. Every keyword GitHub accepts counts,
493
+ * not just the present-tense plural this contract emits, because a
494
+ * reference the parser fails to recognise is one the next regeneration
495
+ * silently deletes.
496
+ *
497
+ * @public
498
+ */
499
+ static parseBare(region: string): ReadonlyArray<number>;
500
+ /**
501
+ * A copy with duplicate ids removed, first occurrence winning.
502
+ *
503
+ * @public
504
+ */
505
+ dedupe(): ClosingReferences;
506
+ /**
507
+ * The comma-joined trailer the squash-commit message carries, or `""`
508
+ * when there is nothing to close.
509
+ *
510
+ * @remarks
511
+ * `Closes #1, #2` on ONE line — the spelling commitlint reads and
512
+ * GitHub's linker ignores. See the class remarks before changing either
513
+ * renderer.
514
+ *
515
+ * @public
516
+ */
517
+ renderTrailer(): string;
518
+ /**
519
+ * One bare `Closes #N` line per id, or `""` when empty.
520
+ *
521
+ * @remarks
522
+ * The spelling GitHub's linker reads — each line must sit OUTSIDE every
523
+ * fenced block to link. See the class remarks before changing either
524
+ * renderer.
525
+ *
526
+ * @public
527
+ */
528
+ renderBareLines(): string;
529
+ }
530
+ /**
531
+ * The `owned="…"` attribute on the references region's opening marker.
532
+ *
533
+ * @remarks
534
+ * Records the issue ids a generating run emitted itself, so the next run can
535
+ * tell its own references from ones an agent or human added. "Not in this
536
+ * run's linked set" is NOT enough: a reference the previous run emitted also
537
+ * disappears from the linked set when the release stops tracking that issue,
538
+ * and treating it as agent-authored would preserve it forever — re-linking,
539
+ * and on merge auto-closing, an issue the release deliberately dropped.
540
+ *
541
+ * **Never hand-edit the attribute.** A wrong value makes the next run delete
542
+ * a real reference or resurrect a dropped one.
543
+ *
544
+ * @public
545
+ */
546
+ declare class OwnedAttribute {
547
+ private constructor();
548
+ /**
549
+ * The attribute as emitted on the opening marker.
550
+ *
551
+ * @public
552
+ */
553
+ static render(ids: ReadonlyArray<number>): string;
554
+ /**
555
+ * The ids the prior body's opening marker claims as the previous run's
556
+ * own.
557
+ *
558
+ * @remarks
559
+ * An absent or malformed attribute reads as "none", which degrades to
560
+ * treating every reference in the region as agent-authored. That
561
+ * preserves too much rather than deleting someone's work — the safe
562
+ * direction to fail. The match is anchored to an attribute boundary: an
563
+ * unanchored match also finds `data-owned="…"` and `unowned="…"`, which
564
+ * would let an unrelated attribute claim an agent's reference and get it
565
+ * dropped on the next run.
566
+ *
567
+ * @public
568
+ */
569
+ static parse(priorBody: string): ReadonlySet<number>;
570
+ }
571
+ //#endregion
572
+ //#region src/pr-body/region.d.ts
573
+ /**
574
+ * The generic marker-delimited region grammar every silk-managed document
575
+ * uses: `<!-- token:start -->` … `<!-- token:end -->`.
576
+ *
577
+ * @remarks
578
+ * Extracted from `silk-release-action` (its `pr-body.ts` and
579
+ * `managed-sections.ts` both carried a private copy) so the grammar has one
580
+ * owner. **Every marker is a pair.** A lone opening marker can only be located
581
+ * by scanning forward to whatever happens to follow it, which makes the
582
+ * region's extent a function of its neighbours rather than of itself — moving
583
+ * anything nearby silently redefines it. The token is free-form; `:start` and
584
+ * `:end` are the whole contract, so pairs nest and a region can contain
585
+ * sub-regions without either needing to know about the other.
586
+ */
587
+ /**
588
+ * Pure helpers over the `<!-- token:start -->` / `<!-- token:end -->` region
589
+ * grammar.
590
+ *
591
+ * @remarks
592
+ * Every operation is total: a body with no region (or a broken pair) degrades
593
+ * to the documented fail-safe result rather than failing, because the callers
594
+ * are regenerating actions that must still produce a body when the prior one
595
+ * is malformed. Use `PrBodyDiagnostic.scan` when a caller wants to be told
596
+ * about a broken pair instead of silently tolerating it.
597
+ *
598
+ * @public
599
+ */
600
+ declare class Region {
601
+ private constructor();
602
+ /**
603
+ * The opening delimiter for a named region.
604
+ *
605
+ * @public
606
+ */
607
+ static start(token: string): string;
608
+ /**
609
+ * The closing delimiter for a named region.
610
+ *
611
+ * @public
612
+ */
613
+ static end(token: string): string;
614
+ /**
615
+ * The content between a region's delimiters, or `undefined` when absent.
616
+ *
617
+ * @remarks
618
+ * Finds the FIRST opening marker and the matching close after it, so a
619
+ * nested region of a different token is returned as part of the content
620
+ * rather than truncating it.
621
+ *
622
+ * @public
623
+ */
624
+ static read(body: string, token: string): string | undefined;
625
+ /**
626
+ * Everything outside a region, with the region and its delimiters removed.
627
+ *
628
+ * @remarks
629
+ * A body without the region comes back unchanged — removal of an absent
630
+ * region is a no-op, not an error.
631
+ *
632
+ * @public
633
+ */
634
+ static strip(body: string, token: string): string;
635
+ /**
636
+ * Put `rendered` (a fully rendered region, its own markers included) into
637
+ * `body`, replacing a previous region of the same token and leaving
638
+ * everything else alone.
639
+ *
640
+ * @remarks
641
+ * **Human edits outside the markers survive.** A predecessor spliced on a
642
+ * markdown heading, which silently ate any content a human happened to put
643
+ * under a heading of that name and could not tell generated text from
644
+ * theirs. An explicit marker pair can.
645
+ *
646
+ * A body with no markers keeps its content and gains the region **below**
647
+ * it, so an existing hand-written document is not displaced. The result is
648
+ * trimmed.
649
+ *
650
+ * @public
651
+ */
652
+ static upsert(body: string, token: string, rendered: string): string;
653
+ }
654
+ declare namespace index_d_exports {
655
+ export { ClosingReferences, LinkedIssueRef, ManagedPrBody, ManagedPrBodyOptions, Markers, OwnedAttribute, PrBodyDiagnostic, PrBodyDiagnosticCode, Region };
656
+ }
657
+ //#endregion
658
+ //#region src/schemas/BiomeConfig.d.ts
659
+ /**
660
+ * Result of a Biome schema URL sync or check operation.
661
+ *
662
+ * @remarks
663
+ * - `updated` — paths of config files whose `$schema` URL was changed (or would be changed on `check`).
664
+ * - `skipped` — paths of config files with no `$schema` field or a non-biomejs.dev URL.
665
+ * - `current` — paths of config files already pointing to the expected schema URL.
666
+ *
667
+ * @since 0.1.0
668
+ * @public
669
+ */
670
+ export declare const BiomeSyncResult: Schema.Struct<{
671
+ readonly updated: Schema.$Array<Schema.String>;
672
+ readonly skipped: Schema.$Array<Schema.String>;
673
+ readonly current: Schema.$Array<Schema.String>;
674
+ }>;
675
+ /**
676
+ * @since 0.1.0
677
+ * @public
678
+ */
679
+ export type BiomeSyncResult = typeof BiomeSyncResult.Type;
680
+ /**
681
+ * Options for `BiomeSchemaSync` operations.
682
+ *
683
+ * @remarks
684
+ * `cwd` overrides the working directory used to locate `biome.json` / `biome.jsonc`.
685
+ * `gitignore` is reserved for future use to skip gitignored config files (defaults to `true`).
686
+ *
687
+ * @since 0.1.0
688
+ * @public
689
+ */
690
+ export declare const BiomeSyncOptions: Schema.Struct<{
691
+ readonly cwd: Schema.optional<Schema.String>;
692
+ readonly gitignore: Schema.withConstructorDefault<Schema.withDecodingDefaultType<Schema.Boolean, never>>;
693
+ }>;
694
+ /**
695
+ * @since 0.1.0
696
+ * @public
697
+ */
698
+ export type BiomeSyncOptions = typeof BiomeSyncOptions.Type;
699
+ //#endregion
700
+ //#region src/schemas/ConfigDiscoverySchemas.d.ts
701
+ /**
702
+ * The discovery strategy used to locate a config file.
703
+ *
704
+ * @remarks
705
+ * - `"lib"` — found under `lib/configs/{name}` relative to the workspace root.
706
+ * - `"root"` — found directly in the workspace root as `{name}`.
707
+ * - `"cosmiconfig"` — reserved for future cosmiconfig-based discovery.
708
+ *
709
+ * @since 0.1.0
710
+ * @public
711
+ */
712
+ export declare const ConfigSource: Schema.Literals<readonly ["lib", "root", "cosmiconfig"]>;
713
+ /**
714
+ * @since 0.1.0
715
+ * @public
716
+ */
717
+ export type ConfigSource = typeof ConfigSource.Type;
718
+ /**
719
+ * The resolved location of a discovered config file.
720
+ *
721
+ * @remarks
722
+ * Produced by `ConfigDiscovery.find` and `ConfigDiscovery.findAll`.
723
+ * `path` is the absolute file path; `source` indicates how it was discovered.
724
+ *
725
+ * @since 0.1.0
726
+ * @public
727
+ */
728
+ export declare const ConfigLocation: Schema.Struct<{
729
+ readonly path: Schema.String;
730
+ readonly source: Schema.Literals<readonly ["lib", "root", "cosmiconfig"]>;
731
+ }>;
732
+ /**
733
+ * @since 0.1.0
734
+ * @public
735
+ */
736
+ export type ConfigLocation = typeof ConfigLocation.Type;
737
+ /**
738
+ * Options passed to config discovery methods.
739
+ *
740
+ * @remarks
741
+ * `cwd` overrides the working directory for path resolution (defaults to the current working directory).
742
+ * `tool` is reserved for future use as a tool-specific discovery hint.
743
+ *
744
+ * @since 0.1.0
745
+ * @public
746
+ */
747
+ export declare const ConfigDiscoveryOptions: Schema.Struct<{
748
+ readonly cwd: Schema.optional<Schema.String>;
749
+ readonly tool: Schema.optional<Schema.String>;
750
+ }>;
751
+ /**
752
+ * @since 0.1.0
753
+ * @public
754
+ */
755
+ export type ConfigDiscoveryOptions = typeof ConfigDiscoveryOptions.Type;
756
+ //#endregion
757
+ //#region src/schemas/SavvyInstallSection.d.ts
758
+ /**
759
+ * The hooks {@link savvyInstallDeps} can be generated for.
760
+ *
761
+ * @remarks
762
+ * Both are needed, and `post-merge` is the one that matters most in practice:
763
+ * a fast-forward `git pull` — the batch-alignment case this exists for — fires
764
+ * `post-merge` and never `post-checkout`. They are separate spellings rather
765
+ * than one argument-sniffing block because the two hooks disagree on both
766
+ * halves of the decision: `post-checkout` is handed `<prev> <new> <flag>` and
767
+ * must ignore a file checkout, while `post-merge` is handed only a squash flag
768
+ * and has to recover its own range from `ORIG_HEAD`.
769
+ *
770
+ * @since 7.5.0
771
+ * @public
772
+ */
773
+ type SavvyInstallHook = "post-checkout" | "post-merge";
774
+ /**
775
+ * Section identity for the dependency auto-install block.
776
+ *
777
+ * `toolName` is `"savvy-install"`; pair with {@link savvyInstallDeps}.
778
+ *
779
+ * @since 7.5.0
780
+ * @public
781
+ */
782
+ export declare const SavvyInstallSection: SectionId;
783
+ /**
784
+ * Dependency auto-install shared across Silk Suite hook files.
785
+ *
786
+ * @remarks
787
+ * Brings `node_modules` back in line after a branch switch or a pull, so a batch
788
+ * of repos pulled to align their dependencies does not each need a manual
789
+ * install. Installs with lifecycle scripts skipped — `--ignore-scripts`, or
790
+ * `--mode=skip-build` for Yarn Berry, which dropped the former — because the goal
791
+ * is to get the dependency tree on disk, not to run a full postinstall.
792
+ *
793
+ * **That flag has a cost, and one shape of repo cannot pay it.** Where a package
794
+ * publishes through a built link directory — `publishConfig.directory` with
795
+ * `linkDirectory: true`, which is how this monorepo wires `dist/dev/pkg` — the
796
+ * workspace resolves its own dependencies through a directory that a `prepare`
797
+ * script has to build, and skipping scripts yields a populated `node_modules`
798
+ * pointing at nothing.
799
+ *
800
+ * Those repos ask for a full install through the LOCAL git config key
801
+ * `savvy.installLifecycleScripts`, which `savvy init` sets when it finds the
802
+ * shape. The decision deliberately does NOT read the checked-out tree. Doing so
803
+ * failed in both directions at once: a branch that merely declared the shape
804
+ * could turn lifecycle scripts back on just by being checked out, making
805
+ * `git checkout` of an untrusted revision a code-execution path; and the `jq`
806
+ * the scan needed is absent on stock macOS and Ubuntu, where the missing answer
807
+ * silently skipped scripts in precisely the repos that cannot survive it.
808
+ * `.git/config` is neither checked out nor parsed with `jq`, so it has neither
809
+ * failure mode.
810
+ *
811
+ * The package managers gate dependency scripts themselves on top of this —
812
+ * pnpm's `strictDepBuilds` with an `allowBuilds` allowlist being the case in
813
+ * point — but workspace and root lifecycle scripts still run, which is why the
814
+ * opt-in is local rather than inferred. With the flag on, the hook says on the
815
+ * way out that scripts were skipped rather than leaving it to be discovered.
816
+ *
817
+ * Deliberately self-contained, like `savvyToolchainCheck`: its homes carry
818
+ * `SavvyHooksSection` but no `SavvyBaseSection`, so it defines its own root, CI
819
+ * and package-manager lookups rather than depending on `ROOT`, `in_ci` or `PM`.
820
+ *
821
+ * Four guards keep it from firing on the many checkouts that are not dependency
822
+ * events, each a silent no-op:
823
+ *
824
+ * - CI, where the runtime action owns installation by construction.
825
+ * - `SAVVY_SKIP_INSTALL`, the escape hatch for a bisect or a scripted sweep that
826
+ * does not want an install between steps.
827
+ * - `post-checkout` only: a branch-flag of `0`, which is `git checkout -- <file>`
828
+ * and not a move between commits.
829
+ * - **The gate that makes this affordable:** nothing dependency-related actually
830
+ * changed across the move. Without it every branch switch would pay for a full
831
+ * install. A missing `node_modules` overrides it, since there is nothing to be
832
+ * stale.
833
+ *
834
+ * A fresh clone is not among the cases it handles, and cannot be: husky sets
835
+ * `core.hooksPath` from its own `prepare` script, so until the first manual
836
+ * install has run there is no hook installed to fire.
837
+ *
838
+ * The install's exit status is swallowed and its output goes to stderr. Git
839
+ * ignores what `post-checkout` and `post-merge` return, so a failure here must
840
+ * not look like a failed checkout; the hint names the escape hatch instead.
841
+ *
842
+ * Every probe that can legitimately fail — no `ORIG_HEAD` to compare against, an
843
+ * unresolvable range — is neutralised with `|| true` rather than left to its own
844
+ * status. These blocks are co-owned and consumer content can sit below them, so
845
+ * under a hook running `set -e` a bare failing substitution would abort the whole
846
+ * file and take those later sections with it.
847
+ *
848
+ * @param hook - Which hook the block is being generated for; decides the
849
+ * argument guard and how the comparison range is recovered.
850
+ * @returns The install shell, with no surrounding markers or trailing newline.
851
+ *
852
+ * @since 7.5.0
853
+ * @public
854
+ */
855
+ export declare function savvyInstallDeps(hook: SavvyInstallHook): string;
856
+ /**
857
+ * The local git config key that authorizes lifecycle scripts during a hook install.
858
+ *
859
+ * @remarks
860
+ * Local scope only. It lives in `.git/config`, which is never checked out, so no
861
+ * incoming revision can set it — that is the whole point of reading the decision
862
+ * from here rather than from a manifest in the tree.
863
+ *
864
+ * @since 7.5.0
865
+ * @public
866
+ */
867
+ export declare const LIFECYCLE_SCRIPTS_CONFIG_KEY = "savvy.installLifecycleScripts";
868
+ /**
869
+ * Whether `manifest` publishes through a built link directory.
870
+ *
871
+ * @remarks
872
+ * `publishConfig.directory` with `linkDirectory: true` means consumers of this
873
+ * package resolve it through a directory that a `prepare` script has to produce,
874
+ * so an install that skips lifecycle scripts leaves the link pointing at nothing.
875
+ * A workspace containing any such package is one whose owner probably wants
876
+ * {@link LIFECYCLE_SCRIPTS_CONFIG_KEY} set.
877
+ *
878
+ * Reporting the shape is deliberately separate from acting on it: this answers
879
+ * "does this repo need scripts", and a human still decides whether hook-time
880
+ * installs may run them.
881
+ *
882
+ * @param manifest - A parsed `package.json`; any non-object reads as `false`.
883
+ *
884
+ * @since 7.5.0
885
+ * @public
886
+ */
887
+ export declare function publishesBuiltLinkDirectory(manifest: unknown): boolean;
888
+ /**
889
+ * Build the dependency auto-install block for `hook`.
890
+ *
891
+ * @param hook - Which hook the section is destined for.
892
+ * @returns A shell `Section` (`commentStyle: hash`) keyed `SAVVY-INSTALL`.
893
+ *
894
+ * @since 7.5.0
895
+ * @public
896
+ */
897
+ export declare function savvyInstallBlock(hook: SavvyInstallHook): Section;
898
+ //#endregion
899
+ //#region src/schemas/SavvySections.d.ts
900
+ /**
901
+ * Section identity for the shared package-manager preamble.
902
+ *
903
+ * `toolName` is `"savvy-base"`; pair with {@link savvyBasePreamble} to build the block:
904
+ *
905
+ * @example
906
+ * ```ts
907
+ * const section = SavvyBaseSection.section(savvyBasePreamble());
908
+ * ```
909
+ *
910
+ * @since 0.5.0
911
+ * @public
912
+ */
913
+ export declare const SavvyBaseSection: SectionId;
914
+ /**
915
+ * Section identity for the shared repo-hygiene block.
916
+ *
917
+ * `toolName` is `"savvy-hooks"`; pair with {@link savvyHooksHygiene}.
918
+ *
919
+ * @since 0.5.0
920
+ * @public
921
+ */
922
+ export declare const SavvyHooksSection: SectionId;
923
+ /**
924
+ * Package-manager detection preamble shared across Silk Suite hook files.
925
+ *
926
+ * @remarks
927
+ * Side-effect-free definitions meant to run unconditionally — no markers, no outer CI
928
+ * guard. Defines `ROOT`, the `in_ci` predicate, `PM` (via `detect_pm`), and `pm_exec`.
929
+ * `pm_exec` uses local/exec semantics for every package manager and `bun x` (space form),
930
+ * which works regardless of how bun was installed (the `bunx` shim is not always on PATH).
931
+ *
932
+ * @returns The preamble shell, with no surrounding markers or trailing newline.
933
+ *
934
+ * @since 0.5.0
935
+ * @public
936
+ */
937
+ export declare function savvyBasePreamble(): string;
938
+ /**
939
+ * Repo-hygiene block shared across Silk Suite hook files.
940
+ *
941
+ * @remarks
942
+ * Self-guarded against CI and needs no package manager: disables Git's `core.fileMode`
943
+ * tracking and marks tracked shell scripts executable.
944
+ *
945
+ * @returns The hygiene shell, with no surrounding markers or trailing newline.
946
+ *
947
+ * @since 0.5.0
948
+ * @public
949
+ */
950
+ export declare function savvyHooksHygiene(): string;
951
+ /**
952
+ * Build a consumer's one-line tool section so every consumer calls the shared base
953
+ * helpers identically.
954
+ *
955
+ * @remarks
956
+ * The returned block's content is exactly `in_ci || pm_exec <command>` with `command`
957
+ * appended verbatim — it is not parsed, quoted, or interpolated, so shell tokens like
958
+ * `$ROOT` and `$1` survive into the generated literal.
959
+ *
960
+ * **Precondition:** a {@link SavvyBaseSection} block must precede this section in the same
961
+ * hook file so `in_ci` and `pm_exec` are defined. Consumers guarantee this by passing both
962
+ * to `ManagedSection.syncAll` in order:
963
+ *
964
+ * @example
965
+ * ```ts
966
+ * yield* sections.syncAll(".husky/commit-msg", [
967
+ * SavvyBaseSection.section(savvyBasePreamble()),
968
+ * savvyToolSection("savvy-commit", 'commitlint --config "$ROOT/lib/configs/commitlint.config.ts" --edit "$1"'),
969
+ * ]);
970
+ * ```
971
+ *
972
+ * @param toolName - Section identity; also drives the marker names (uppercased).
973
+ * @param command - The command passed verbatim to `pm_exec`, run only outside CI.
974
+ * @returns A shell `Section` (`commentStyle: hash`) for `toolName`.
975
+ *
976
+ * @since 0.5.0
977
+ * @public
978
+ */
979
+ export declare function savvyToolSection(toolName: string, command: string): Section;
980
+ /**
981
+ * Section identity for the package-manager toolchain drift check.
982
+ *
983
+ * `toolName` is `"savvy-toolchain"`; pair with {@link savvyToolchainCheck}.
984
+ *
985
+ * @since 7.3.0
986
+ * @public
987
+ */
988
+ export declare const SavvyToolchainSection: SectionId;
989
+ /**
990
+ * Package-manager drift check shared across Silk Suite hook files.
991
+ *
992
+ * @remarks
993
+ * Compares the running package manager's version against the repo's
994
+ * `devEngines.packageManager` pin and prints a warning on mismatch. **Warn only** —
995
+ * it never blocks the hook and never installs anything, so nobody mid-bisect or
996
+ * mid-rebase on an older pin is stranded.
997
+ *
998
+ * Deliberately self-contained: its homes are `.husky/post-checkout` and
999
+ * `.husky/post-merge`, which carry {@link SavvyHooksSection} but no
1000
+ * {@link SavvyBaseSection}, so it defines its own root/CI/pin lookups rather than
1001
+ * depending on `ROOT`, `in_ci` or `PM`. It honours the `name` recorded in the pin
1002
+ * rather than assuming pnpm.
1003
+ *
1004
+ * Every input is treated as optional: no `git` root, no `jq`, no `devEngines` block,
1005
+ * or a package manager that is not on `PATH` all mean "say nothing". Only an exact
1006
+ * pin is comparable, so ranges (`^1.2.3`, `>=1 || <2`) and wildcards (`1.x`) are
1007
+ * skipped, and the `+sha512…` integrity tail `devEngines` versions routinely carry is
1008
+ * stripped before comparison. Skipped under CI, where the runtime action installs the
1009
+ * pin by construction.
1010
+ *
1011
+ * @returns The drift-check shell, with no surrounding markers or trailing newline.
1012
+ *
1013
+ * @since 7.3.0
1014
+ * @public
1015
+ */
1016
+ export declare function savvyToolchainCheck(): string;
1017
+ //#endregion
1018
+ //#region src/schemas/VersioningSchemas.d.ts
1019
+ /**
1020
+ * Standard changesets configuration matching the `@changesets/config@4.0.0` spec.
1021
+ *
1022
+ * @remarks
1023
+ * Represents the parsed `.changeset/config.json` file. All fields are optional
1024
+ * to allow partial configs. Use {@link (SilkChangesetConfigFile:type)} when the Silk changelog
1025
+ * adapter is detected.
1026
+ *
1027
+ * @since 0.1.0
1028
+ */
1029
+ /** @public */
1030
+ export declare const ChangesetConfigFile: Schema.Struct<{
1031
+ readonly changelog: Schema.optional<Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Unknown>, Schema.Literal<false>]>>;
1032
+ readonly commit: Schema.optional<Schema.Union<readonly [Schema.Boolean, Schema.String, Schema.$Array<Schema.Unknown>]>>;
1033
+ readonly fixed: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1034
+ readonly linked: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1035
+ readonly access: Schema.optional<Schema.Literals<readonly ["public", "restricted"]>>;
1036
+ readonly baseBranch: Schema.optional<Schema.String>;
1037
+ readonly updateInternalDependencies: Schema.optional<Schema.Literals<readonly ["patch", "minor", "major"]>>;
1038
+ readonly ignore: Schema.optional<Schema.$Array<Schema.String>>;
1039
+ readonly privatePackages: Schema.optional<Schema.Union<readonly [Schema.Struct<{
1040
+ readonly tag: Schema.optional<Schema.Boolean>;
1041
+ readonly version: Schema.optional<Schema.Boolean>;
1042
+ }>, Schema.Literal<false>]>>;
1043
+ readonly prettier: Schema.optional<Schema.Boolean>;
1044
+ readonly changedFilePatterns: Schema.optional<Schema.$Array<Schema.String>>;
1045
+ readonly bumpVersionsWithWorkspaceProtocolOnly: Schema.optional<Schema.Boolean>;
1046
+ readonly snapshot: Schema.optional<Schema.Struct<{
1047
+ readonly useCalculatedVersion: Schema.optional<Schema.Boolean>;
1048
+ readonly prereleaseTemplate: Schema.optional<Schema.String>;
1049
+ }>>;
1050
+ }>;
1051
+ /**
1052
+ * @since 0.1.0
1053
+ * @public
1054
+ */
1055
+ export type ChangesetConfigFile = typeof ChangesetConfigFile.Type;
1056
+ /**
1057
+ * Extended changeset config for repos using the `@savvy-web/changesets` changelog adapter.
1058
+ *
1059
+ * @remarks
1060
+ * Extends {@link (ChangesetConfigFile:type)} with a `_isSilk` marker flag that is automatically
1061
+ * set to `true`. Detected by `ChangesetConfigReader` when the `changelog` field
1062
+ * references `@savvy-web/changesets`.
1063
+ *
1064
+ * @since 0.1.0
1065
+ */
1066
+ /** @public */
1067
+ export declare const SilkChangesetConfigFile: Schema.Struct<{
1068
+ readonly changelog: Schema.optional<Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Unknown>, Schema.Literal<false>]>>;
1069
+ readonly commit: Schema.optional<Schema.Union<readonly [Schema.Boolean, Schema.String, Schema.$Array<Schema.Unknown>]>>;
1070
+ readonly fixed: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1071
+ readonly linked: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1072
+ readonly access: Schema.optional<Schema.Literals<readonly ["public", "restricted"]>>;
1073
+ readonly baseBranch: Schema.optional<Schema.String>;
1074
+ readonly updateInternalDependencies: Schema.optional<Schema.Literals<readonly ["patch", "minor", "major"]>>;
1075
+ readonly ignore: Schema.optional<Schema.$Array<Schema.String>>;
1076
+ readonly privatePackages: Schema.optional<Schema.Union<readonly [Schema.Struct<{
1077
+ readonly tag: Schema.optional<Schema.Boolean>;
1078
+ readonly version: Schema.optional<Schema.Boolean>;
1079
+ }>, Schema.Literal<false>]>>;
1080
+ readonly prettier: Schema.optional<Schema.Boolean>;
1081
+ readonly changedFilePatterns: Schema.optional<Schema.$Array<Schema.String>>;
1082
+ readonly bumpVersionsWithWorkspaceProtocolOnly: Schema.optional<Schema.Boolean>;
1083
+ readonly snapshot: Schema.optional<Schema.Struct<{
1084
+ readonly useCalculatedVersion: Schema.optional<Schema.Boolean>;
1085
+ readonly prereleaseTemplate: Schema.optional<Schema.String>;
1086
+ }>>;
1087
+ readonly _isSilk: Schema.withConstructorDefault<Schema.withDecodingDefaultType<Schema.Boolean, never>>;
1088
+ }>;
1089
+ /**
1090
+ * @since 0.1.0
1091
+ * @public
1092
+ */
1093
+ export type SilkChangesetConfigFile = typeof SilkChangesetConfigFile.Type;
1094
+ //#endregion
1095
+ //#region src/schemas/WorkspaceAnalysisSchemas.d.ts
1096
+ declare const SilkPublishConfig_base: Schema.Class<SilkPublishConfig, Schema.Struct<{
1097
+ readonly access: Schema.optionalKey<Schema.Literals<readonly ["public", "restricted"]>>;
1098
+ readonly registry: Schema.optionalKey<Schema.String>;
1099
+ readonly directory: Schema.optionalKey<Schema.String>;
1100
+ readonly linkDirectory: Schema.optionalKey<Schema.Boolean>;
1101
+ readonly tag: Schema.optionalKey<Schema.String>;
1102
+ targets: Schema.optional<Schema.$Array<Schema.Union<readonly [Schema.Literals<readonly ["npm", "github", "jsr"]>, Schema.Struct<{
1103
+ readonly protocol: Schema.withConstructorDefault<Schema.withDecodingDefaultType<Schema.Literals<readonly ["npm", "jsr"]>, never>>;
1104
+ readonly registry: Schema.optional<Schema.String>;
1105
+ readonly directory: Schema.optional<Schema.String>;
1106
+ readonly access: Schema.optional<Schema.Literals<readonly ["public", "restricted"]>>;
1107
+ readonly provenance: Schema.optional<Schema.Boolean>;
1108
+ readonly tag: Schema.optional<Schema.String>;
1109
+ }>]>>>;
1110
+ }>, PublishConfig> & Pick<{}, never>;
1111
+ /**
1112
+ * Silk-extended publishConfig schema.
1113
+ *
1114
+ * @remarks
1115
+ * Extends the base PublishConfig from `@effected/workspaces` (which covers the
1116
+ * npm standard fields — access, registry, directory, tag — and, as of kit
1117
+ * round 3, `linkDirectory`) with the Silk `targets` extension for
1118
+ * multi-registry publishing.
1119
+ *
1120
+ * @since 0.2.0
1121
+ * @public
1122
+ */
1123
+ export declare class SilkPublishConfig extends SilkPublishConfig_base {}
1124
+ declare const AnalyzedWorkspace_base: Schema.Class<AnalyzedWorkspace, Schema.TaggedStruct<"AnalyzedWorkspace", {
1125
+ readonly name: Schema.String;
1126
+ readonly version: Schema.Struct<{
1127
+ readonly current: Schema.optional<Schema.String>;
1128
+ }>;
1129
+ readonly path: Schema.String;
1130
+ readonly root: Schema.Boolean;
1131
+ readonly publishConfig: Schema.NullOr<typeof SilkPublishConfig>;
1132
+ readonly publishable: Schema.Boolean;
1133
+ readonly targets: Schema.$Array<typeof PublishTarget>;
1134
+ readonly versioned: Schema.Boolean;
1135
+ readonly tagged: Schema.Boolean;
1136
+ readonly released: Schema.Boolean;
1137
+ readonly linked: Schema.$Array<Schema.suspend<any>>;
1138
+ readonly fixed: Schema.$Array<Schema.suspend<any>>;
1139
+ }>, {}>;
1140
+ /**
1141
+ * A fully analyzed workspace with publish targets, versioning status,
1142
+ * and release group membership.
1143
+ *
1144
+ * @since 0.2.0
1145
+ * @public
1146
+ */
1147
+ export declare class AnalyzedWorkspace extends AnalyzedWorkspace_base {
1148
+ get isRoot(): boolean;
1149
+ get isPublishable(): boolean;
1150
+ get isReleasable(): boolean;
1151
+ get isFixed(): boolean;
1152
+ get isLinked(): boolean;
1153
+ publishesTo(registry: string): boolean;
1154
+ hasTarget(shorthand: "npm" | "github" | "jsr"): boolean;
1155
+ targetFor(registry: string): Option.Option<PublishTarget>;
1156
+ [Equal.symbol](that: Equal.Equal): boolean;
1157
+ [Hash.symbol](): number;
1158
+ toString(): string;
1159
+ toJSON(): unknown;
1160
+ static publishable(workspaces: ReadonlyArray<AnalyzedWorkspace>): ReadonlyArray<AnalyzedWorkspace>;
1161
+ static releasable(workspaces: ReadonlyArray<AnalyzedWorkspace>): ReadonlyArray<AnalyzedWorkspace>;
1162
+ static findByName: {
1163
+ (name: string): (workspaces: ReadonlyArray<AnalyzedWorkspace>) => Option.Option<AnalyzedWorkspace>;
1164
+ (workspaces: ReadonlyArray<AnalyzedWorkspace>, name: string): Option.Option<AnalyzedWorkspace>;
1165
+ };
1166
+ /** Pretty-print an AnalyzedWorkspace instance. */
1167
+ static pretty: (self: AnalyzedWorkspace) => string;
1168
+ }
1169
+ declare const WorkspaceAnalysis_base: Schema.Class<WorkspaceAnalysis, Schema.TaggedStruct<"WorkspaceAnalysis", {
1170
+ readonly root: Schema.String;
1171
+ readonly runtime: Schema.Literals<readonly ["node", "bun"]>;
1172
+ readonly packageManager: Schema.Struct<{
1173
+ readonly type: Schema.Literals<readonly ["npm", "pnpm", "yarn", "bun"]>;
1174
+ readonly version: Schema.optional<Schema.String>;
1175
+ }>;
1176
+ readonly workspaces: Schema.$Array<typeof AnalyzedWorkspace>;
1177
+ readonly changesetConfig: Schema.NullOr<Schema.Union<readonly [Schema.Struct<{
1178
+ readonly changelog: Schema.optional<Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Unknown>, Schema.Literal<false>]>>;
1179
+ readonly commit: Schema.optional<Schema.Union<readonly [Schema.Boolean, Schema.String, Schema.$Array<Schema.Unknown>]>>;
1180
+ readonly fixed: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1181
+ readonly linked: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1182
+ readonly access: Schema.optional<Schema.Literals<readonly ["public", "restricted"]>>;
1183
+ readonly baseBranch: Schema.optional<Schema.String>;
1184
+ readonly updateInternalDependencies: Schema.optional<Schema.Literals<readonly ["patch", "minor", "major"]>>;
1185
+ readonly ignore: Schema.optional<Schema.$Array<Schema.String>>;
1186
+ readonly privatePackages: Schema.optional<Schema.Union<readonly [Schema.Struct<{
1187
+ readonly tag: Schema.optional<Schema.Boolean>;
1188
+ readonly version: Schema.optional<Schema.Boolean>;
1189
+ }>, Schema.Literal<false>]>>;
1190
+ readonly prettier: Schema.optional<Schema.Boolean>;
1191
+ readonly changedFilePatterns: Schema.optional<Schema.$Array<Schema.String>>;
1192
+ readonly bumpVersionsWithWorkspaceProtocolOnly: Schema.optional<Schema.Boolean>;
1193
+ readonly snapshot: Schema.optional<Schema.Struct<{
1194
+ readonly useCalculatedVersion: Schema.optional<Schema.Boolean>;
1195
+ readonly prereleaseTemplate: Schema.optional<Schema.String>;
1196
+ }>>;
1197
+ readonly _isSilk: Schema.withConstructorDefault<Schema.withDecodingDefaultType<Schema.Boolean, never>>;
1198
+ }>, Schema.Struct<{
1199
+ readonly changelog: Schema.optional<Schema.Union<readonly [Schema.String, Schema.$Array<Schema.Unknown>, Schema.Literal<false>]>>;
1200
+ readonly commit: Schema.optional<Schema.Union<readonly [Schema.Boolean, Schema.String, Schema.$Array<Schema.Unknown>]>>;
1201
+ readonly fixed: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1202
+ readonly linked: Schema.optional<Schema.$Array<Schema.$Array<Schema.String>>>;
1203
+ readonly access: Schema.optional<Schema.Literals<readonly ["public", "restricted"]>>;
1204
+ readonly baseBranch: Schema.optional<Schema.String>;
1205
+ readonly updateInternalDependencies: Schema.optional<Schema.Literals<readonly ["patch", "minor", "major"]>>;
1206
+ readonly ignore: Schema.optional<Schema.$Array<Schema.String>>;
1207
+ readonly privatePackages: Schema.optional<Schema.Union<readonly [Schema.Struct<{
1208
+ readonly tag: Schema.optional<Schema.Boolean>;
1209
+ readonly version: Schema.optional<Schema.Boolean>;
1210
+ }>, Schema.Literal<false>]>>;
1211
+ readonly prettier: Schema.optional<Schema.Boolean>;
1212
+ readonly changedFilePatterns: Schema.optional<Schema.$Array<Schema.String>>;
1213
+ readonly bumpVersionsWithWorkspaceProtocolOnly: Schema.optional<Schema.Boolean>;
1214
+ readonly snapshot: Schema.optional<Schema.Struct<{
1215
+ readonly useCalculatedVersion: Schema.optional<Schema.Boolean>;
1216
+ readonly prereleaseTemplate: Schema.optional<Schema.String>;
1217
+ }>>;
1218
+ }>]>>;
1219
+ readonly versioning: Schema.NullOr<typeof VersioningStrategy>;
1220
+ readonly tagStrategy: Schema.NullOr<Schema.Literals<readonly ["single", "scoped"]>>;
1221
+ }>, {}>;
1222
+ /**
1223
+ * Full workspace analysis result containing all analyzed workspaces
1224
+ * and project-level configuration.
1225
+ *
1226
+ * @since 0.2.0
1227
+ * @public
1228
+ */
1229
+ export declare class WorkspaceAnalysis extends WorkspaceAnalysis_base {
1230
+ findWorkspace(name: string): Option.Option<AnalyzedWorkspace>;
1231
+ get rootWorkspace(): Option.Option<AnalyzedWorkspace>;
1232
+ get publishableWorkspaces(): ReadonlyArray<AnalyzedWorkspace>;
1233
+ get versionedWorkspaces(): ReadonlyArray<AnalyzedWorkspace>;
1234
+ get taggedWorkspaces(): ReadonlyArray<AnalyzedWorkspace>;
1235
+ get releasableWorkspaces(): ReadonlyArray<AnalyzedWorkspace>;
1236
+ get isSilk(): boolean;
1237
+ get hasChangesets(): boolean;
1238
+ [Equal.symbol](that: Equal.Equal): boolean;
1239
+ [Hash.symbol](): number;
1240
+ toString(): string;
1241
+ /** Pretty-print a WorkspaceAnalysis instance. */
1242
+ static pretty: (self: WorkspaceAnalysis) => string;
1243
+ }
1244
+ //#endregion
1245
+ //#region src/utils/TrailingSlash.d.ts
1246
+ /**
1247
+ * Trim trailing slashes from a string.
1248
+ *
1249
+ * @remarks
1250
+ * Trims trailing slashes with an index scan rather than `/\/+$/`. That regex is
1251
+ * unanchored at the start, so the engine retries the match from every position
1252
+ * and degrades to O(n²) on a string of many slashes (CodeQL `js/polynomial-redos`).
1253
+ * Only a trailing run of slashes is removed; interior slash runs are untouched.
1254
+ *
1255
+ * @since 0.1.0
1256
+ * @public
1257
+ */
1258
+ export declare const trimTrailingSlashes: (s: string) => string;
1259
+ //#endregion
1260
+ export { index_d_exports as PrBody, type SavvyInstallHook };
1261
+ //# sourceMappingURL=index.d.ts.map