@savvy-web/silk-effects 5.7.1 → 5.8.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 CHANGED
@@ -2771,7 +2771,7 @@ declare class ChangesetConfigError extends ChangesetConfigError_base<{
2771
2771
  //#endregion
2772
2772
  //#region src/schemas/VersioningSchemas.d.ts
2773
2773
  /**
2774
- * Standard changesets configuration matching the `@changesets/config@4.0.0-next.6` spec.
2774
+ * Standard changesets configuration matching the `@changesets/config@4.0.0` spec.
2775
2775
  *
2776
2776
  * @remarks
2777
2777
  * Represents the parsed `.changeset/config.json` file. All fields are optional
@@ -7346,11 +7346,11 @@ type TypeScriptCompiler = "tsgo" | "tsc";
7346
7346
  /**
7347
7347
  * Handler for TypeScript files.
7348
7348
  *
7349
- * Runs type checking with tsgo or tsc.
7349
+ * Runs type checking with tsc or tsgo.
7350
7350
  *
7351
7351
  * @remarks
7352
7352
  * Type checking runs on all staged TypeScript files using the configured
7353
- * compiler (tsgo or tsc). The compiler is auto-detected at runtime using
7353
+ * compiler (tsc or tsgo). The compiler is auto-detected at runtime using
7354
7354
  * `Command.findTool()`, which correctly handles pnpm catalogs, peer
7355
7355
  * dependencies, and hoisted/transitive deps.
7356
7356
  *
@@ -7386,10 +7386,16 @@ declare class TypeScript {
7386
7386
  * Detect which TypeScript compiler to use.
7387
7387
  *
7388
7388
  * Uses `Command.findTool()` to check for available compilers:
7389
- * 1. `tsgo` (native TypeScript) — checked first
7390
- * 2. `tsc` (standard TypeScript) — fallback
7389
+ * 1. `tsc` (standard TypeScript) — checked first
7390
+ * 2. `tsgo` (native TypeScript) — fallback
7391
7391
  *
7392
7392
  * @remarks
7393
+ * `tsc` is preferred so the pre-commit gate runs the same compiler as a
7394
+ * repo's own `types:check` task. Preferring `tsgo` meant any repo with
7395
+ * `\@typescript/native-preview` anywhere in its dependency graph — even as
7396
+ * a hoisted or transitive dep — silently got a different compiler for its
7397
+ * commit gate than for its typecheck task.
7398
+ *
7393
7399
  * Unlike the previous implementation that parsed `package.json` dependencies,
7394
7400
  * this uses runtime tool detection which works correctly with pnpm catalogs,
7395
7401
  * peer dependencies, and hoisted/transitive deps.
@@ -7411,7 +7417,7 @@ declare class TypeScript {
7411
7417
  * Uses the cached `ToolSearchResult` from `detectCompiler()` to build
7412
7418
  * the command string, avoiding a separate package manager detection step.
7413
7419
  *
7414
- * @returns Command string like `pnpm exec tsgo --noEmit` or `tsgo --noEmit`
7420
+ * @returns Command string like `pnpm exec tsc --noEmit` or `tsc --noEmit`
7415
7421
  * @throws Error if no TypeScript compiler is available
7416
7422
  */
7417
7423
  static getDefaultTypecheckCommand(): string;
@@ -8236,6 +8242,541 @@ declare namespace index_d_exports$2 {
8236
8242
  export { BaseHandlerOptions, Biome, BiomeOptions, Command, CreateConfigOptions, DEFAULT_CONFIG_PATH, Filter, HUSKY_HOOK_PATH, Handler, LegacySavvyLintHygieneDef, LintStagedConfig, LintStagedEntry, LintStagedHandler, MARKDOWNLINT_CONFIG, MARKDOWNLINT_CONFIG_PATH, MARKDOWNLINT_SCHEMA, MARKDOWNLINT_TEMPLATE, Markdown, MarkdownOptions, POST_CHECKOUT_HOOK_PATH, POST_COMMIT_HOOK_PATH, POST_MERGE_HOOK_PATH, PackageJson, PackageJsonOptions, PackageManager, PnpmWorkspace, PnpmWorkspaceContent, PnpmWorkspaceOptions, Preset, PresetExtendOptions, PresetType, SavvyLintSectionDef, ShellScripts, ShellScriptsOptions, ToolSearchResult, TypeScript, TypeScriptCompiler, TypeScriptOptions, WorkspacePackageInfo, Yaml, YamlOptions, createConfig, generateManagedContent, getWorkspacePackagePaths, getWorkspacePackages, getWorkspaceRoot, isWorkspacePackagePath, resetWorkspaceCache, savvyLintBlock };
8237
8243
  }
8238
8244
  //#endregion
8245
+ //#region src/pr-body/linked-issue.d.ts
8246
+ declare const LinkedIssueRef_base: Schema.Class<LinkedIssueRef, Schema.Struct<{
8247
+ readonly number: Schema.Number;
8248
+ readonly title: Schema.String;
8249
+ readonly state: Schema.String;
8250
+ }>, {}>;
8251
+ /**
8252
+ * The minimum an issue must carry to appear in a managed PR body.
8253
+ *
8254
+ * @remarks
8255
+ * `state` is deliberately a tolerant `Schema.String` rather than a literal
8256
+ * union: GitHub's REST API reports `"open"`/`"closed"` while GraphQL reports
8257
+ * `"OPEN"`/`"CLOSED"`, and both actions pass their existing issue shapes
8258
+ * through unchanged. **`LinkedIssueRef.isClosed` is the ONLY sanctioned way
8259
+ * to test closedness** — it lowercases before comparing, so both spellings
8260
+ * classify correctly. A hand-written `issue.state === "closed"` comparison
8261
+ * silently misclassifies GraphQL's `"CLOSED"` as open, which re-links (and on
8262
+ * merge auto-closes) an issue the release deliberately dropped.
8263
+ *
8264
+ * The class carries no instance members, so a plain
8265
+ * `{ number, title, state }` literal satisfies the type structurally — both
8266
+ * actions' existing `LinkedIssue` shapes are accepted without mapping.
8267
+ *
8268
+ * @public
8269
+ */
8270
+ declare class LinkedIssueRef extends LinkedIssueRef_base {
8271
+ /**
8272
+ * Whether an issue is closed, case-insensitively.
8273
+ *
8274
+ * @remarks
8275
+ * The only sanctioned closedness test — see the class remarks for why a
8276
+ * bare `state === "closed"` comparison is a silent bug against GraphQL
8277
+ * payloads.
8278
+ *
8279
+ * @public
8280
+ */
8281
+ static isClosed(issue: {
8282
+ readonly state: string;
8283
+ }): boolean;
8284
+ }
8285
+ //#endregion
8286
+ //#region src/pr-body/body.d.ts
8287
+ /**
8288
+ * The inputs to {@link ManagedPrBody.build}.
8289
+ *
8290
+ * @public
8291
+ */
8292
+ interface ManagedPrBodyOptions {
8293
+ /** The proposed squash-commit subject — a conventional-commit header. */
8294
+ readonly subject: string;
8295
+ /**
8296
+ * Every issue this run knows about, open AND closed.
8297
+ *
8298
+ * @remarks
8299
+ * The run decides every issue it knows about: an open issue is emitted, a
8300
+ * closed one is dropped, and a carried line cannot resurrect one it
8301
+ * deliberately dropped. Closedness is tested with
8302
+ * `LinkedIssueRef.isClosed` (case-insensitive), so REST and GraphQL
8303
+ * payloads both classify correctly.
8304
+ */
8305
+ readonly linkedIssues: ReadonlyArray<LinkedIssueRef>;
8306
+ /** The DCO signoff line the squash-commit block carries. */
8307
+ readonly signoff: string;
8308
+ /**
8309
+ * The summary region's current content, from
8310
+ * {@link ManagedPrBody.extractSummary}.
8311
+ *
8312
+ * @remarks
8313
+ * Passed in rather than read from `priorBody` so `build` stays explicit
8314
+ * about it: the summary's owner decides what it says, and this function
8315
+ * must not quietly overrule a caller that passed one. `""` reserves an
8316
+ * empty region.
8317
+ */
8318
+ readonly summary: string;
8319
+ /**
8320
+ * The PR's previous description, verbatim.
8321
+ *
8322
+ * @remarks
8323
+ * The WHOLE prior body rather than an extracted region: merging
8324
+ * references needs both the region's lines and the `owned` attribute on
8325
+ * its opening marker, and two separate parameters would eventually be
8326
+ * passed inconsistently. Optional because a PR being created has no
8327
+ * prior body.
8328
+ */
8329
+ readonly priorBody?: string;
8330
+ }
8331
+ /**
8332
+ * The shared managed-PR-body renderer and its carry-through readers — the
8333
+ * single implementation of the contract `silk-release-action` dogfooded at
8334
+ * `src/utils/pr-body.ts` (savvy-web/systems#419).
8335
+ *
8336
+ * @remarks
8337
+ * Every operation is pure and total: markers absent, regions broken, or
8338
+ * attributes malformed all degrade to the documented fail-safe result
8339
+ * (preserve too much rather than delete someone's work) instead of failing —
8340
+ * a regenerating action must still produce a body when the prior one is
8341
+ * malformed. Use `PrBodyDiagnostic.scan` where a writer wants to be told
8342
+ * about a broken pair instead of tolerating it.
8343
+ *
8344
+ * @public
8345
+ */
8346
+ declare class ManagedPrBody {
8347
+ private constructor();
8348
+ /**
8349
+ * Build the region of the PR description the generating run owns.
8350
+ *
8351
+ * @remarks
8352
+ * Delimited by `Markers.MANAGED_START` / `Markers.MANAGED_END` so
8353
+ * {@link ManagedPrBody.upsert} can regenerate it without touching
8354
+ * anything a human wrote around it. Layout, in order: the reserved
8355
+ * summary region (nothing may sit above it — a reader meets the prose
8356
+ * before the machinery), the proposed-squash-commit fence, and the
8357
+ * bare-reference region. No preamble, no file listing, no linked-issues
8358
+ * list, no run attribution — each said something already on the page.
8359
+ *
8360
+ * @public
8361
+ */
8362
+ static build(options: ManagedPrBodyOptions): string;
8363
+ /**
8364
+ * Put `managed` (a full {@link ManagedPrBody.build} result) into
8365
+ * `existing`, replacing a previous managed region and leaving everything
8366
+ * else alone.
8367
+ *
8368
+ * @remarks
8369
+ * Human edits outside the markers survive; a body with no markers keeps
8370
+ * its content and gains the region below it. See `Region.upsert` for the
8371
+ * splice semantics.
8372
+ *
8373
+ * @public
8374
+ */
8375
+ static upsert(existing: string, managed: string): string;
8376
+ /**
8377
+ * The summary region's current content, or `""` when it is empty or
8378
+ * absent.
8379
+ *
8380
+ * @remarks
8381
+ * Extraction exists because the managed region is REGENERATED on every
8382
+ * run. Re-emitting the region empty would delete a summary the moment
8383
+ * any commit landed — destructive and silent, with no signal back to the
8384
+ * summariser whose work was discarded. Feed the result to
8385
+ * {@link ManagedPrBody.build}'s `summary` option.
8386
+ *
8387
+ * @public
8388
+ */
8389
+ static extractSummary(existing: string): string;
8390
+ /**
8391
+ * The reference region's current content, or `""` when it is empty or
8392
+ * absent.
8393
+ *
8394
+ * @remarks
8395
+ * Symmetric to {@link ManagedPrBody.extractSummary}, and for the same
8396
+ * reason. Located by `Markers.REFERENCES_START_PREFIX` — never the plain
8397
+ * opening constant — because a generating run emits the attributed form.
8398
+ *
8399
+ * @public
8400
+ */
8401
+ static extractReferences(existing: string): string;
8402
+ }
8403
+ //#endregion
8404
+ //#region src/pr-body/diagnostics.d.ts
8405
+ /**
8406
+ * The problems {@link PrBodyDiagnostic.scan} can report about a body's
8407
+ * markers.
8408
+ *
8409
+ * @public
8410
+ */
8411
+ declare const PrBodyDiagnosticCode: Schema.Literals<readonly ["unpairedMarker", "duplicateMarker"]>;
8412
+ /**
8413
+ * The problems {@link PrBodyDiagnostic.scan} can report about a body's
8414
+ * markers.
8415
+ *
8416
+ * @public
8417
+ */
8418
+ type PrBodyDiagnosticCode = typeof PrBodyDiagnosticCode.Type;
8419
+ declare const PrBodyDiagnostic_base: Schema.Class<PrBodyDiagnostic, Schema.Struct<{
8420
+ readonly code: Schema.Literals<readonly ["unpairedMarker", "duplicateMarker"]>;
8421
+ /** The region token the problem is about, e.g. `silk-release:summary`. */
8422
+ readonly token: Schema.String;
8423
+ }>, {}>;
8424
+ /**
8425
+ * One problem with a body's silk-release markers.
8426
+ *
8427
+ * @remarks
8428
+ * Diagnostics are advisory VALUES, not a typed error channel: every parse and
8429
+ * render operation in this namespace is deliberately total (a regenerating
8430
+ * action must still produce a body when the prior one is malformed, and the
8431
+ * fail-safe direction is to preserve too much rather than delete someone's
8432
+ * work). `scan` exists for the writer that wants to be told about a broken
8433
+ * pair before editing — the `pr-body` skill instructs an agent that finds a
8434
+ * region missing its pair to stop and report rather than guess, and this is
8435
+ * the check that instruction points at. A misplaced marker pair is worse than
8436
+ * none: it makes the next regeneration rewrite content it does not own.
8437
+ *
8438
+ * @public
8439
+ */
8440
+ declare class PrBodyDiagnostic extends PrBodyDiagnostic_base {
8441
+ /**
8442
+ * A human-readable description, derived from the structured fields.
8443
+ *
8444
+ * @public
8445
+ */
8446
+ get message(): string;
8447
+ /**
8448
+ * Every marker problem in `body`, or an empty array when the markers are
8449
+ * well-formed (including entirely absent — an unmanaged body is not a
8450
+ * defect).
8451
+ *
8452
+ * @remarks
8453
+ * The references region is located by its attributed opening prefix, so a
8454
+ * marker carrying an `owned="…"` attribute counts as present.
8455
+ *
8456
+ * @public
8457
+ */
8458
+ static scan(body: string): ReadonlyArray<PrBodyDiagnostic>;
8459
+ }
8460
+ //#endregion
8461
+ //#region src/pr-body/markers.d.ts
8462
+ /**
8463
+ * The frozen `silk-release` marker vocabulary — the wire format of the shared
8464
+ * PR-body contract.
8465
+ *
8466
+ * @remarks
8467
+ * **The `silk-release:` token is frozen and names the CONTRACT, not the
8468
+ * emitting action.** `silk-update-action` PRs carry the same markers as
8469
+ * release PRs, deliberately: every live document, the `pr-body` plugin skill,
8470
+ * and every agent that edits a managed PR description key on these exact
8471
+ * byte sequences. Do not parameterize the token per action and do not rename
8472
+ * it — either forks the wire format for zero gain and orphans every open PR
8473
+ * (ruled in savvy-web/systems#419).
8474
+ *
8475
+ * These constants are the single source of truth for the marker grammar.
8476
+ * The agent-facing documentation in the silk plugin (`pr-body` and
8477
+ * `commit-create` skills) duplicates the literals for readability; a drift
8478
+ * lint in this package's test suite asserts the copies stay in sync.
8479
+ */
8480
+ /**
8481
+ * The marker constants of the `silk-release` PR-body contract.
8482
+ *
8483
+ * @public
8484
+ */
8485
+ declare class Markers {
8486
+ private constructor();
8487
+ /**
8488
+ * Opening marker of the whole managed region.
8489
+ *
8490
+ * @remarks
8491
+ * Everything between this and {@link Markers.MANAGED_END} that is not
8492
+ * inside the summary or references region is regenerated wholesale on
8493
+ * every run; everything outside the pair is human territory and survives
8494
+ * every regeneration.
8495
+ *
8496
+ * @public
8497
+ */
8498
+ static readonly MANAGED_START: string;
8499
+ /**
8500
+ * Closing marker of the whole managed region.
8501
+ *
8502
+ * @public
8503
+ */
8504
+ static readonly MANAGED_END: string;
8505
+ /**
8506
+ * Opening marker of the region an AI summariser owns.
8507
+ *
8508
+ * @remarks
8509
+ * The generating action never writes into this region — it only reserves
8510
+ * it and carries its content through on regeneration.
8511
+ *
8512
+ * @public
8513
+ */
8514
+ static readonly SUMMARY_START: string;
8515
+ /**
8516
+ * Closing marker of the summariser's region.
8517
+ *
8518
+ * @public
8519
+ */
8520
+ static readonly SUMMARY_END: string;
8521
+ /**
8522
+ * The PLAIN opening marker of the closing-reference region — the form an
8523
+ * author writes by hand.
8524
+ *
8525
+ * @remarks
8526
+ * A generating run emits the ATTRIBUTED form instead (the plain prefix
8527
+ * plus an `owned="…"` attribute). Never locate the region by matching
8528
+ * this constant — match {@link Markers.REFERENCES_START_PREFIX}, or a
8529
+ * region a run wrote will not be found.
8530
+ *
8531
+ * @public
8532
+ */
8533
+ static readonly REFERENCES_START: string;
8534
+ /**
8535
+ * Closing marker of the closing-reference region.
8536
+ *
8537
+ * @public
8538
+ */
8539
+ static readonly REFERENCES_END: string;
8540
+ /**
8541
+ * The references opening marker up to its attributes, for locating a
8542
+ * region whose `owned` list is unknown.
8543
+ *
8544
+ * @public
8545
+ */
8546
+ static readonly REFERENCES_START_PREFIX = "<!-- silk-release:references:start";
8547
+ /**
8548
+ * The fence language for the proposed squash-commit block.
8549
+ *
8550
+ * @remarks
8551
+ * Not a GFM language and apparently undocumented, but GitHub renders it.
8552
+ * It is a target for AI integrations to read and rewrite into the
8553
+ * eventual squash-commit message. **Do not "correct" it to `text`.**
8554
+ *
8555
+ * @public
8556
+ */
8557
+ static readonly SQUASH_FENCE_LANGUAGE = "proposed-squash-commit";
8558
+ }
8559
+ //#endregion
8560
+ //#region src/pr-body/references.d.ts
8561
+ declare const ClosingReferences_base: Schema.Class<ClosingReferences, Schema.Struct<{
8562
+ readonly ids: Schema.$Array<Schema.Number>;
8563
+ }>, {}>;
8564
+ /**
8565
+ * An ordered list of issue ids destined for closing references, with the two
8566
+ * renderers whose difference is the whole point of this module.
8567
+ *
8568
+ * @remarks
8569
+ * The same issues appear twice in a managed PR body, spelled differently, and
8570
+ * **neither consumer accepts the other's spelling**:
8571
+ *
8572
+ * - commitlint reads ONE comma-joined trailer (`Closes #1, #2`) inside the
8573
+ * proposed-squash-commit fence — {@link ClosingReferences.renderTrailer};
8574
+ * - GitHub's linker reads one bare `Closes #N` line each, OUTSIDE every
8575
+ * fence — {@link ClosingReferences.renderBareLines}. A reference inside a
8576
+ * fenced block is inert to GitHub.
8577
+ *
8578
+ * The duplication is load-bearing. Never "simplify" a body by emitting one
8579
+ * form in both places: comma-joined bare lines link nothing (verified by hand
8580
+ * against live pull requests — `savvy-web/silk-integration` #242/#232 with no
8581
+ * bare line reported `closingIssuesReferences: []`, #243 with one reported
8582
+ * `[168]`), and per-line trailers inside the fence break the commit contract.
8583
+ *
8584
+ * Ids are stored exactly as given — construction neither deduplicates nor
8585
+ * sorts. Call {@link ClosingReferences.dedupe} where uniqueness is wanted;
8586
+ * the split exists because the squash trailer historically renders duplicates
8587
+ * as-given while the references region deduplicates, and byte-compatibility
8588
+ * with live PR bodies pins that behavior.
8589
+ *
8590
+ * @public
8591
+ */
8592
+ declare class ClosingReferences extends ClosingReferences_base {
8593
+ /**
8594
+ * A closing keyword and its issue reference, anchored per line.
8595
+ *
8596
+ * @remarks
8597
+ * Anchored so a number mentioned in passing is not mistaken for a closing
8598
+ * reference — matching what GitHub itself links on. Every keyword GitHub
8599
+ * accepts is matched, not just the present-tense plural this contract
8600
+ * emits: `close`/`closed`, `fix`/`fixed`, `resolve`/`resolved` and an
8601
+ * optional colon are all valid, and a reference the parser fails to
8602
+ * recognise is one the next regeneration silently deletes.
8603
+ */
8604
+ static readonly BARE_LINE_PATTERN: RegExp;
8605
+ /**
8606
+ * The open issues' ids, in input order, duplicates preserved.
8607
+ *
8608
+ * @remarks
8609
+ * Closedness is decided by `LinkedIssueRef.isClosed` — the only
8610
+ * sanctioned test, case-insensitive so REST (`closed`) and GraphQL
8611
+ * (`CLOSED`) payloads classify identically.
8612
+ *
8613
+ * @public
8614
+ */
8615
+ static fromIssues(issues: ReadonlyArray<LinkedIssueRef>): ClosingReferences;
8616
+ /**
8617
+ * Issue ids carried by a region's bare closing lines.
8618
+ *
8619
+ * @public
8620
+ */
8621
+ static parseBare(region: string): ReadonlyArray<number>;
8622
+ /**
8623
+ * A copy with duplicate ids removed, first occurrence winning.
8624
+ *
8625
+ * @public
8626
+ */
8627
+ dedupe(): ClosingReferences;
8628
+ /**
8629
+ * The comma-joined trailer the squash-commit message carries, or `""`
8630
+ * when there is nothing to close.
8631
+ *
8632
+ * @remarks
8633
+ * `Closes #1, #2` on ONE line — the spelling commitlint reads and
8634
+ * GitHub's linker ignores. See the class remarks before changing either
8635
+ * renderer.
8636
+ *
8637
+ * @public
8638
+ */
8639
+ renderTrailer(): string;
8640
+ /**
8641
+ * One bare `Closes #N` line per id, or `""` when empty.
8642
+ *
8643
+ * @remarks
8644
+ * The spelling GitHub's linker reads — each line must sit OUTSIDE every
8645
+ * fenced block to link. See the class remarks before changing either
8646
+ * renderer.
8647
+ *
8648
+ * @public
8649
+ */
8650
+ renderBareLines(): string;
8651
+ }
8652
+ /**
8653
+ * The `owned="…"` attribute on the references region's opening marker.
8654
+ *
8655
+ * @remarks
8656
+ * Records the issue ids a generating run emitted itself, so the next run can
8657
+ * tell its own references from ones an agent or human added. "Not in this
8658
+ * run's linked set" is NOT enough: a reference the previous run emitted also
8659
+ * disappears from the linked set when the release stops tracking that issue,
8660
+ * and treating it as agent-authored would preserve it forever — re-linking,
8661
+ * and on merge auto-closing, an issue the release deliberately dropped.
8662
+ *
8663
+ * **Never hand-edit the attribute.** A wrong value makes the next run delete
8664
+ * a real reference or resurrect a dropped one.
8665
+ *
8666
+ * @public
8667
+ */
8668
+ declare class OwnedAttribute {
8669
+ private constructor();
8670
+ /**
8671
+ * The attribute as emitted on the opening marker.
8672
+ *
8673
+ * @public
8674
+ */
8675
+ static render(ids: ReadonlyArray<number>): string;
8676
+ /**
8677
+ * The ids the prior body's opening marker claims as the previous run's
8678
+ * own.
8679
+ *
8680
+ * @remarks
8681
+ * An absent or malformed attribute reads as "none", which degrades to
8682
+ * treating every reference in the region as agent-authored. That
8683
+ * preserves too much rather than deleting someone's work — the safe
8684
+ * direction to fail. The match is anchored to an attribute boundary: an
8685
+ * unanchored match also finds `data-owned="…"` and `unowned="…"`, which
8686
+ * would let an unrelated attribute claim an agent's reference and get it
8687
+ * dropped on the next run.
8688
+ *
8689
+ * @public
8690
+ */
8691
+ static parse(priorBody: string): ReadonlySet<number>;
8692
+ }
8693
+ //#endregion
8694
+ //#region src/pr-body/region.d.ts
8695
+ /**
8696
+ * The generic marker-delimited region grammar every silk-managed document
8697
+ * uses: `<!-- token:start -->` … `<!-- token:end -->`.
8698
+ *
8699
+ * @remarks
8700
+ * Extracted from `silk-release-action` (its `pr-body.ts` and
8701
+ * `managed-sections.ts` both carried a private copy) so the grammar has one
8702
+ * owner. **Every marker is a pair.** A lone opening marker can only be located
8703
+ * by scanning forward to whatever happens to follow it, which makes the
8704
+ * region's extent a function of its neighbours rather than of itself — moving
8705
+ * anything nearby silently redefines it. The token is free-form; `:start` and
8706
+ * `:end` are the whole contract, so pairs nest and a region can contain
8707
+ * sub-regions without either needing to know about the other.
8708
+ */
8709
+ /**
8710
+ * Pure helpers over the `<!-- token:start -->` / `<!-- token:end -->` region
8711
+ * grammar.
8712
+ *
8713
+ * @remarks
8714
+ * Every operation is total: a body with no region (or a broken pair) degrades
8715
+ * to the documented fail-safe result rather than failing, because the callers
8716
+ * are regenerating actions that must still produce a body when the prior one
8717
+ * is malformed. Use `PrBodyDiagnostic.scan` when a caller wants to be told
8718
+ * about a broken pair instead of silently tolerating it.
8719
+ *
8720
+ * @public
8721
+ */
8722
+ declare class Region {
8723
+ private constructor();
8724
+ /**
8725
+ * The opening delimiter for a named region.
8726
+ *
8727
+ * @public
8728
+ */
8729
+ static start(token: string): string;
8730
+ /**
8731
+ * The closing delimiter for a named region.
8732
+ *
8733
+ * @public
8734
+ */
8735
+ static end(token: string): string;
8736
+ /**
8737
+ * The content between a region's delimiters, or `undefined` when absent.
8738
+ *
8739
+ * @remarks
8740
+ * Finds the FIRST opening marker and the matching close after it, so a
8741
+ * nested region of a different token is returned as part of the content
8742
+ * rather than truncating it.
8743
+ *
8744
+ * @public
8745
+ */
8746
+ static read(body: string, token: string): string | undefined;
8747
+ /**
8748
+ * Everything outside a region, with the region and its delimiters removed.
8749
+ *
8750
+ * @remarks
8751
+ * A body without the region comes back unchanged — removal of an absent
8752
+ * region is a no-op, not an error.
8753
+ *
8754
+ * @public
8755
+ */
8756
+ static strip(body: string, token: string): string;
8757
+ /**
8758
+ * Put `rendered` (a fully rendered region, its own markers included) into
8759
+ * `body`, replacing a previous region of the same token and leaving
8760
+ * everything else alone.
8761
+ *
8762
+ * @remarks
8763
+ * **Human edits outside the markers survive.** A predecessor spliced on a
8764
+ * markdown heading, which silently ate any content a human happened to put
8765
+ * under a heading of that name and could not tell generated text from
8766
+ * theirs. An explicit marker pair can.
8767
+ *
8768
+ * A body with no markers keeps its content and gains the region **below**
8769
+ * it, so an existing hand-written document is not displaced. The result is
8770
+ * trimmed.
8771
+ *
8772
+ * @public
8773
+ */
8774
+ static upsert(body: string, token: string, rendered: string): string;
8775
+ }
8776
+ declare namespace index_d_exports$3 {
8777
+ export { ClosingReferences, LinkedIssueRef, ManagedPrBody, ManagedPrBodyOptions, Markers, OwnedAttribute, PrBodyDiagnostic, PrBodyDiagnosticCode, Region };
8778
+ }
8779
+ //#endregion
8239
8780
  //#region src/repos/constants.d.ts
8240
8781
  /**
8241
8782
  * Directory vendored reference repos live under, relative to the repo root.
@@ -8908,7 +9449,7 @@ declare class ReposManager extends ReposManager_base {
8908
9449
  */
8909
9450
  static readonly layer: Layer.Layer<ReposManager, never, ReposConfigStore | Git | FileSystem.FileSystem | Path.Path | ReposLockdown>;
8910
9451
  }
8911
- declare namespace index_d_exports$3 {
9452
+ declare namespace index_d_exports$4 {
8912
9453
  export { DriftKind, GitSubmoduleError, GitSubmoduleErrorBase, MANIFEST_PATH, NOTE_LIMIT, NoteNotFoundError, NoteNotFoundErrorBase, REPOS_DIR, RepoDrift, RepoEntry, RepoName, RepoNotFoundError, RepoNotFoundErrorBase, RepoNote, RepoOrientation, RepoStatusEntry, ReposAddResult, ReposConfigError, ReposConfigErrorBase, ReposConfigStore, ReposConfigStoreShape, ReposDrift, ReposDriftReport, ReposDriftShape, ReposLockdown, ReposLockdownError, ReposLockdownErrorBase, ReposLockdownShape, ReposManager, ReposManagerShape, ReposManifestFile, ReposNoteResult, ReposPinResult, ReposRemoveResult, ReposRenameResult, ReposRestoreResult, ReposStatusReport, ReposSyncReport, STALE_LOCK_MAX_AGE_MS, resolveModuleDir };
8913
9454
  }
8914
9455
  //#endregion
@@ -10023,9 +10564,9 @@ declare class TurboInspector extends TurboInspector_base {
10023
10564
  */
10024
10565
  static readonly layer: Layer.Layer<TurboInspector, never, ToolDiscovery | ChildProcessSpawner.ChildProcessSpawner | FileSystem.FileSystem | Git>;
10025
10566
  }
10026
- declare namespace index_d_exports$4 {
10567
+ declare namespace index_d_exports$5 {
10027
10568
  export { AffectedResult, AffectedResultType, CacheDiagnosis, CacheDiagnosisType, DryRunParseError, GlobalHashSummary, GraphNode, MissExplanation, NotATurboRepoError, PackageCacheStatus, TaskGraphResult, TaskGraphResultType, TurboCache, TurboDigest, TurboDryRun, TurboDryRunType, TurboDryTask, TurboDryTaskType, TurboEnvVars, TurboError, TurboExecError, TurboGlobalCacheInputs, TurboInspector, TurboInspectorShape, TurboNotInstalledError };
10028
10569
  }
10029
10570
  //#endregion
10030
- export { AnalyzedWorkspace, BiomeSchemaSync, type BiomeSchemaSyncShape, BiomeSyncError, type BiomeSyncOptions, type BiomeSyncResult, ChangesetConfig, ChangesetConfigError, type ChangesetConfigFile, ChangesetConfigReader, type ChangesetConfigReaderShape, type ChangesetConfigShape, type ChangesetMode, index_d_exports as Changesets, index_d_exports$1 as Commitlint, type CommitlintPlugin, type CommitlintUserConfig, ConfigDiscovery, type ConfigDiscoveryOptions, type ConfigDiscoveryShape, type ConfigLocation, ConfigNotFoundError, type ConfigSource, index_d_exports$2 as Lint, type PromptConfig, type PromptSettings, PublishTargetBindingError, type PublishablePackage, type RawPackageJson, type RawPublishConfig, type RawPublishTargets, type RawTargetObject, type RawTargetValue, index_d_exports$3 as Repos, type RuleApplicability, type RuleConfigTuple, type RuleSeverity, type RulesConfig, SavvyBaseSection, SavvyHooksSection, type SilkChangesetConfigFile, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, type SilkWorkspaceAnalyzerShape, type TargetBinding, type TargetGroupBinding, type TargetsBinding, index_d_exports$4 as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
10571
+ export { AnalyzedWorkspace, BiomeSchemaSync, type BiomeSchemaSyncShape, BiomeSyncError, type BiomeSyncOptions, type BiomeSyncResult, ChangesetConfig, ChangesetConfigError, type ChangesetConfigFile, ChangesetConfigReader, type ChangesetConfigReaderShape, type ChangesetConfigShape, type ChangesetMode, index_d_exports as Changesets, index_d_exports$1 as Commitlint, type CommitlintPlugin, type CommitlintUserConfig, ConfigDiscovery, type ConfigDiscoveryOptions, type ConfigDiscoveryShape, type ConfigLocation, ConfigNotFoundError, type ConfigSource, index_d_exports$2 as Lint, index_d_exports$3 as PrBody, type PromptConfig, type PromptSettings, PublishTargetBindingError, type PublishablePackage, type RawPackageJson, type RawPublishConfig, type RawPublishTargets, type RawTargetObject, type RawTargetValue, index_d_exports$4 as Repos, type RuleApplicability, type RuleConfigTuple, type RuleSeverity, type RulesConfig, SavvyBaseSection, SavvyHooksSection, type SilkChangesetConfigFile, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, type SilkWorkspaceAnalyzerShape, type TargetBinding, type TargetGroupBinding, type TargetsBinding, index_d_exports$5 as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
10031
10572
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -10,6 +10,7 @@ import { ConfigNotFoundError } from "./errors/ConfigNotFoundError.js";
10
10
  import { WorkspaceAnalysisError } from "./errors/WorkspaceAnalysisError.js";
11
11
  import { SavvyBaseSection, SavvyHooksSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection } from "./schemas/SavvySections.js";
12
12
  import { lint_exports } from "./lint/index.js";
13
+ import { pr_body_exports } from "./pr-body/index.js";
13
14
  import { repos_exports } from "./repos/index.js";
14
15
  import { AnalyzedWorkspace, SilkPublishConfig, WorkspaceAnalysis } from "./schemas/WorkspaceAnalysisSchemas.js";
15
16
  import { BiomeSchemaSync, buildSchemaUrl, extractSemver } from "./services/BiomeSchemaSync.js";
@@ -17,4 +18,4 @@ import { ConfigDiscovery } from "./services/ConfigDiscovery.js";
17
18
  import { SilkWorkspaceAnalyzer } from "./services/SilkWorkspaceAnalyzer.js";
18
19
  import { turbo_exports } from "./turbo/index.js";
19
20
 
20
- export { AnalyzedWorkspace, BiomeSchemaSync, BiomeSyncError, ChangesetConfig, ChangesetConfigError, ChangesetConfigReader, changesets_exports as Changesets, commitlint_exports as Commitlint, ConfigDiscovery, ConfigNotFoundError, lint_exports as Lint, PublishTargetBindingError, repos_exports as Repos, SavvyBaseSection, SavvyHooksSection, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, turbo_exports as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
21
+ export { AnalyzedWorkspace, BiomeSchemaSync, BiomeSyncError, ChangesetConfig, ChangesetConfigError, ChangesetConfigReader, changesets_exports as Changesets, commitlint_exports as Commitlint, ConfigDiscovery, ConfigNotFoundError, lint_exports as Lint, pr_body_exports as PrBody, PublishTargetBindingError, repos_exports as Repos, SavvyBaseSection, SavvyHooksSection, SilkPublishConfig, SilkPublishability, SilkWorkspaceAnalyzer, turbo_exports as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };