@williamthorsen/release-kit 10.4.4 → 10.6.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 (105) hide show
  1. package/.meta/changelog.json +1502 -0
  2. package/.readyup/kits/default.js +120 -4
  3. package/.readyup/kits/npm-auto-publish.js +11 -3
  4. package/.readyup/manifest.json +16 -11
  5. package/CHANGELOG.md +57 -0
  6. package/README.md +64 -4
  7. package/dist/esm/assertCleanWorkingTree.d.ts +5 -0
  8. package/dist/esm/buildChangelogEntries.d.ts +22 -0
  9. package/dist/esm/buildChangelogEntries.js +5 -0
  10. package/dist/esm/buildDependencyGraph.d.ts +16 -0
  11. package/dist/esm/buildEmptyReleaseEntry.d.ts +8 -0
  12. package/dist/esm/buildReleaseSummary.d.ts +10 -0
  13. package/dist/esm/buildSyntheticChangelogEntry.d.ts +6 -0
  14. package/dist/esm/bumpVersion.d.ts +8 -0
  15. package/dist/esm/changelogJsonFile.d.ts +11 -0
  16. package/dist/esm/changelogJsonUtils.d.ts +16 -2
  17. package/dist/esm/changelogJsonUtils.js +0 -13
  18. package/dist/esm/changelogOverrides.d.ts +143 -0
  19. package/dist/esm/changelogOverrides.js +8 -0
  20. package/dist/esm/checkWorkTypesDrift.d.ts +25 -0
  21. package/dist/esm/collectPolicyViolations.d.ts +9 -0
  22. package/dist/esm/commitCommand.d.ts +6 -0
  23. package/dist/esm/compareVersions.d.ts +7 -0
  24. package/dist/esm/createGithubRelease.d.ts +30 -0
  25. package/dist/esm/createGithubReleaseCommand.d.ts +7 -0
  26. package/dist/esm/createTags.d.ts +5 -0
  27. package/dist/esm/decideRelease.d.ts +37 -0
  28. package/dist/esm/defaults.d.ts +25 -0
  29. package/dist/esm/defineConfig.d.ts +9 -0
  30. package/dist/esm/deleteFileIfExists.d.ts +1 -0
  31. package/dist/esm/deriveWorkspaceConfig.d.ts +9 -0
  32. package/dist/esm/detectPackageManager.d.ts +6 -0
  33. package/dist/esm/detectUndeclaredTagPrefixes.d.ts +18 -0
  34. package/dist/esm/determineBumpFromCommits.d.ts +5 -0
  35. package/dist/esm/determineBumpType.d.ts +12 -0
  36. package/dist/esm/discoverWorkspaces.d.ts +12 -0
  37. package/dist/esm/extractMigration.d.ts +14 -0
  38. package/dist/esm/extractMigration.js +18 -0
  39. package/dist/esm/format.d.ts +3 -0
  40. package/dist/esm/formatPrivateSkip.d.ts +6 -0
  41. package/dist/esm/generateChangelogs.d.ts +25 -0
  42. package/dist/esm/getCommitsSinceTarget.d.ts +16 -0
  43. package/dist/esm/hasPrettierConfig.d.ts +6 -0
  44. package/dist/esm/help/prepareHelp.d.ts +6 -0
  45. package/dist/esm/init/checks.d.ts +4 -0
  46. package/dist/esm/init/detectRepoType.d.ts +7 -0
  47. package/dist/esm/init/initCommand.d.ts +6 -0
  48. package/dist/esm/init/parseJsonRecord.d.ts +4 -0
  49. package/dist/esm/init/scaffold.d.ts +3 -1
  50. package/dist/esm/init/templates.d.ts +13 -0
  51. package/dist/esm/injectReleaseNotesIntoReadme.d.ts +39 -0
  52. package/dist/esm/injectSection.d.ts +6 -0
  53. package/dist/esm/loadConfig.d.ts +46 -0
  54. package/dist/esm/loadValidatedConfig.d.ts +8 -0
  55. package/dist/esm/packsPath.d.ts +15 -0
  56. package/dist/esm/packsPath.js +47 -0
  57. package/dist/esm/parseCommitMessage.d.ts +42 -0
  58. package/dist/esm/parseRequestedTags.d.ts +7 -0
  59. package/dist/esm/planReleaseNotesPreviews.d.ts +20 -0
  60. package/dist/esm/planVersionBump.d.ts +12 -0
  61. package/dist/esm/prepareCommand.d.ts +10 -0
  62. package/dist/esm/previewTagPrefixes.d.ts +21 -1
  63. package/dist/esm/propagateBumps.d.ts +15 -0
  64. package/dist/esm/publish.d.ts +1 -0
  65. package/dist/esm/publishCommand.d.ts +4 -0
  66. package/dist/esm/pushCommand.d.ts +4 -0
  67. package/dist/esm/pushRelease.d.ts +6 -0
  68. package/dist/esm/readCurrentVersion.d.ts +1 -0
  69. package/dist/esm/releaseFiles.d.ts +22 -0
  70. package/dist/esm/releasePlan.d.ts +23 -0
  71. package/dist/esm/releasePrepare.d.ts +40 -0
  72. package/dist/esm/releasePrepare.js +0 -3
  73. package/dist/esm/releasePrepareMono.d.ts +8 -0
  74. package/dist/esm/releasePrepareMono.js +0 -4
  75. package/dist/esm/releasePrepareProject.d.ts +42 -0
  76. package/dist/esm/renderChangelogMarkdown.d.ts +17 -0
  77. package/dist/esm/renderReleaseNotes.d.ts +25 -0
  78. package/dist/esm/reportPrepare.d.ts +14 -0
  79. package/dist/esm/reportPrepare.js +4 -2
  80. package/dist/esm/resolveCliffConfigPath.d.ts +10 -0
  81. package/dist/esm/resolveCommandTags.d.ts +13 -1
  82. package/dist/esm/resolveReleaseNotesConfig.d.ts +14 -0
  83. package/dist/esm/resolveReleaseTags.d.ts +22 -0
  84. package/dist/esm/runGitCliff.d.ts +37 -1
  85. package/dist/esm/runGitCliff.js +4 -10
  86. package/dist/esm/showTagPrefixesCommand.d.ts +11 -0
  87. package/dist/esm/stripScope.d.ts +7 -0
  88. package/dist/esm/sync-labels/generateCommand.d.ts +17 -0
  89. package/dist/esm/sync-labels/initCommand.d.ts +9 -0
  90. package/dist/esm/sync-labels/presets.d.ts +6 -0
  91. package/dist/esm/sync-labels/resolveLabels.d.ts +10 -0
  92. package/dist/esm/sync-labels/retiredConfig.d.ts +8 -0
  93. package/dist/esm/sync-labels/syncCommand.d.ts +6 -0
  94. package/dist/esm/sync-labels/templates.d.ts +14 -0
  95. package/dist/esm/sync-labels/types.d.ts +4 -0
  96. package/dist/esm/syncWorkTypes.d.ts +18 -0
  97. package/dist/esm/tagCommand.d.ts +1 -0
  98. package/dist/esm/typeGuards.d.ts +2 -0
  99. package/dist/esm/types.d.ts +302 -0
  100. package/dist/esm/validateConfig.d.ts +14 -1
  101. package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +21 -0
  102. package/dist/esm/validateOverridesCommand.d.ts +30 -0
  103. package/dist/esm/workTypesData.d.ts +27 -0
  104. package/dist/esm/workTypesUtils.d.ts +17 -0
  105. package/package.json +12 -11
@@ -1,10 +1,28 @@
1
+ /** Outcome of a sync operation. */
1
2
  export interface SyncResult {
3
+ /**
4
+ * Process exit code semantics:
5
+ * - `0` — sync succeeded (file may be unchanged).
6
+ * - `2` — network error or local write failure.
7
+ * - `3` — schema mismatch (upstream JSON does not parse or fails the shape check).
8
+ */
2
9
  exitCode: 0 | 2 | 3;
3
10
  message: string;
4
11
  }
12
+ /** Minimal injection seam so unit tests can substitute a deterministic fetcher. */
5
13
  export interface SyncWorkTypesDependencies {
14
+ /** Absolute path of the local `work-types.json`. Defaults to the bundled file. */
6
15
  localPath?: string;
16
+ /** HTTP fetcher. Defaults to global `fetch`. */
7
17
  fetch?: typeof globalThis.fetch;
18
+ /** Override the upstream URL (used by tests). */
8
19
  upstreamUrl?: string;
9
20
  }
21
+ /**
22
+ * Fetch the upstream `work-types.json`, validate its top-level shape, and overwrite the
23
+ * locally-bundled copy with the formatted upstream contents.
24
+ *
25
+ * Output is reformatted to match the local file's conventions (2-space indent, trailing
26
+ * newline) so subsequent diffs are content-driven, not whitespace-driven.
27
+ */
10
28
  export declare function syncWorkTypes(dependencies?: SyncWorkTypesDependencies): Promise<SyncResult>;
@@ -1 +1,2 @@
1
+ /** Orchestrate the CLI `tag` command: parse flags and delegate to `createTags`. */
1
2
  export declare function tagCommand(argv: string[]): void;
@@ -1,2 +1,4 @@
1
+ /** Check whether a value is a plain object (non-null, non-array). */
1
2
  export declare function isRecord(value: unknown): value is Record<string, unknown>;
3
+ /** Narrow an `unknown` value to `unknown[]` via `Array.isArray`, avoiding `any[]`. */
2
4
  export declare function isUnknownArray(value: unknown): value is unknown[];
@@ -1,58 +1,149 @@
1
1
  import { z } from 'zod';
2
+ /** Semver release type for version bumping. */
2
3
  export type ReleaseType = 'major' | 'minor' | 'patch';
4
+ /** Target audience for a changelog section. */
3
5
  export type ChangelogAudience = 'all' | 'dev';
6
+ /** A single item in a changelog section (typically one commit). */
4
7
  export interface ChangelogItem {
5
8
  description: string;
9
+ /** Optional commit body text, with trailing trailer metadata stripped. */
6
10
  body?: string;
11
+ /**
12
+ * Whether this item represents a breaking change.
13
+ *
14
+ * `true` when the commit subject carries the `!` prefix (e.g. `feat!:` or `drop(scope)!:`).
15
+ * The `BREAKING CHANGE:` body footer is intentionally NOT considered here — only the prefix
16
+ * `!` marks a changelog item as breaking. Renderers prefix breaking-item bullets with the
17
+ * marker constructed from `WORK_TYPES_DATA.markers.breaking` (rendered as `🚨 **Breaking:** `
18
+ * with the canonical SSOT values) to surface them prominently in release notes.
19
+ */
7
20
  breaking?: boolean;
21
+ /**
22
+ * Migration instruction for a consumer, taken from the `Migration:` paragraph of `body`.
23
+ *
24
+ * Derived from `body` wherever `body` is set, and absent where the body carries no labeled
25
+ * paragraph. Independent of `breaking`: a `fix` that tightens validation cannot carry `!` under
26
+ * the default breaking policy and still imposes a migration. `body` keeps the paragraph, so
27
+ * `CHANGELOG.md` goes on rendering it in place.
28
+ */
29
+ migration?: string;
30
+ /**
31
+ * Full git commit SHA when known. Captured from git-cliff's `--context` output and
32
+ * persisted in `changelog.json` so that override files can target items by hash. Synthetic
33
+ * propagation entries (`buildSyntheticChangelogEntry`, `buildEmptyReleaseEntry`) leave
34
+ * this field absent — they have no underlying commit.
35
+ */
8
36
  hash?: string;
9
37
  }
38
+ /** A grouped section within a changelog entry (e.g., "Features", "Bug fixes"). */
10
39
  export interface ChangelogSection {
40
+ /**
41
+ * Section title carrying the leading emoji prefix used by `cliff.toml.template` group
42
+ * definitions (e.g. `"🐛 Bug fixes"`). The `<!-- NN -->` canonical-order HTML comment
43
+ * is stripped during transform; the emoji remains. Callers that match against `title`
44
+ * (e.g. `sectionOrder` configs) must include the emoji prefix.
45
+ */
11
46
  title: string;
12
47
  audience: ChangelogAudience;
13
48
  items: ChangelogItem[];
14
49
  }
50
+ /** A single version's changelog data. */
15
51
  export interface ChangelogEntry {
16
52
  version: string;
17
53
  date: string;
18
54
  sections: ChangelogSection[];
19
55
  }
56
+ /** Configuration for structured changelog JSON generation. */
20
57
  export interface ChangelogJsonConfig {
21
58
  enabled: boolean;
22
59
  outputPath: string;
23
60
  devOnlySections: string[];
24
61
  }
62
+ /**
63
+ * Editorial override for a single changelog item, keyed by commit hash (or hash prefix) in
64
+ * the override file. All fields are optional; an entry with no fields is a validation error.
65
+ *
66
+ * `audience` declares the full forward-compatible vocabulary, but only `'skip'` is currently
67
+ * supported at runtime. `'all'` and `'dev'` reclassification is reserved for a v2 follow-up
68
+ * and rejected by the validator with an explicit "not yet supported" error so the on-disk
69
+ * format remains stable through the v1→v2 transition.
70
+ */
25
71
  export interface ChangelogOverride {
26
72
  audience?: 'all' | 'dev' | 'skip';
27
73
  description?: string;
28
74
  body?: string;
29
75
  breaking?: boolean;
30
76
  }
77
+ /** On-disk shape of `.meta/changelog-overrides.json`: a flat record keyed by commit hash or prefix. */
31
78
  export type ChangelogOverridesFile = Record<string, ChangelogOverride>;
79
+ /** Configuration for release notes consumption (README injection). */
32
80
  export interface ReleaseNotesConfig {
33
81
  shouldInjectIntoReadme: boolean;
34
82
  }
83
+ /**
84
+ * Project-release config after merging defaults. Mirrors the `ReleaseNotesConfig`/
85
+ * `ResolvedReleaseNotesConfig`-style split: optional fields in `ProjectConfig` become
86
+ * required in `ResolvedProjectConfig`.
87
+ */
35
88
  export interface ResolvedProjectConfig {
89
+ /**
90
+ * Resolved commit window for the project release: the git pathspecs and git-cliff include-paths
91
+ * that select which commits the stage considers. Defaults to the union of every contributing
92
+ * workspace's `paths`.
93
+ */
36
94
  paths: string[];
95
+ /** Resolved tag prefix for project-level tags. */
37
96
  tagPrefix: string;
38
97
  }
98
+ /** Identifies a dependency whose version bump triggered a propagated release. */
39
99
  export interface PropagationSource {
40
100
  packageName: string;
41
101
  newVersion: string;
42
102
  }
103
+ /**
104
+ * A `!`-policy violation detected while parsing commits during release preparation.
105
+ *
106
+ * Surfaces from `releasePrepare`, `releasePrepareMono`, and `releasePrepareProject` via the
107
+ * `policyViolations` field on each per-workspace/project result. The policy itself is enforced
108
+ * tolerantly at release time — violations are collected and reported, never fail the release.
109
+ */
43
110
  export interface PolicyViolation {
111
+ /** Full hash of the offending commit. */
44
112
  commitHash: string;
113
+ /** First line of the commit message (raw, including any ticket prefix). */
45
114
  commitSubject: string;
115
+ /** Resolved canonical work type whose policy was violated. */
46
116
  type: string;
117
+ /** Where the violation was detected: `'prefix'` for `!`, `'body'` for `BREAKING CHANGE:` footer. */
47
118
  surface: 'prefix' | 'body';
48
119
  }
120
+ /**
121
+ * Result of preparing a single workspace (package) for release when a release was produced.
122
+ *
123
+ * `currentVersion`, `newVersion`, `tag`, `bumpedFiles`, and `changelogFiles` are always
124
+ * populated. `releaseType` stays optional because it is left undefined for
125
+ * `--set-version` workspaces. `parsedCommitCount` stays optional because the legacy
126
+ * single-package bump-override path does not populate it. `commits` stays optional
127
+ * because propagation-only releases have no direct commits.
128
+ */
49
129
  export interface ReleasedWorkspaceResult {
50
130
  status: 'released';
131
+ /** Workspace name; absent in single-package mode, present in monorepo mode. */
51
132
  name?: string;
52
133
  previousTag?: string;
53
134
  commitCount: number;
135
+ /**
136
+ * Count of commits that parsed into a recognized work type. Always populated for
137
+ * results produced by the unified `decideRelease` algorithm (the monorepo path),
138
+ * including the no-commits case where it is `0`. May be absent for results
139
+ * produced by the legacy single-package executor's bump-override path. Use
140
+ * `bumpOverride` (not `parsedCommitCount === undefined`) as the signal for "the
141
+ * user supplied --bump=X".
142
+ */
54
143
  parsedCommitCount?: number;
144
+ /** Commits that could not be parsed into a recognized work type. */
55
145
  unparseableCommits?: Commit[];
146
+ /** Policy violations detected while parsing this workspace's commits; omitted when none. */
56
147
  policyViolations?: PolicyViolation[];
57
148
  releaseType?: ReleaseType;
58
149
  currentVersion: string;
@@ -60,29 +151,73 @@ export interface ReleasedWorkspaceResult {
60
151
  tag: string;
61
152
  bumpedFiles: string[];
62
153
  changelogFiles: string[];
154
+ /** Release-notes preview files; present only under `--with-release-notes`. */
63
155
  previewFiles?: string[];
156
+ /** Raw commits associated with this workspace (present for direct releases, absent for propagation-only). */
64
157
  commits?: Commit[];
158
+ /**
159
+ * Present when `--bump=X` was supplied and selected the release level for this workspace.
160
+ * Distinguishes a bump-override release from a `--force` fallback or a natural-bump release;
161
+ * consumed by the renderer to label the release accurately.
162
+ */
65
163
  bumpOverride?: ReleaseType;
164
+ /** Dependencies that triggered a propagated bump (present for propagated or mixed workspaces). */
66
165
  propagatedFrom?: PropagationSource[];
166
+ /** Present when this workspace was written via `--set-version`; the explicit version that was applied. */
67
167
  setVersion?: string;
68
168
  }
169
+ /**
170
+ * Result of preparing a single workspace (package) for release when the release was skipped.
171
+ *
172
+ * Carries diagnostic data (`commitCount`, `parsedCommitCount`, `unparseableCommits`,
173
+ * `previousTag`) plus the human-readable `skipReason`. Release-only fields are absent.
174
+ */
69
175
  export interface SkippedWorkspaceResult {
70
176
  status: 'skipped';
177
+ /** Workspace name; absent in single-package mode, present in monorepo mode. */
71
178
  name?: string;
72
179
  previousTag?: string;
73
180
  commitCount: number;
181
+ /**
182
+ * Count of commits that parsed into a recognized work type. May be absent for results
183
+ * produced by the legacy single-package executor's bump-override path.
184
+ */
74
185
  parsedCommitCount?: number;
186
+ /** Commits that could not be parsed into a recognized work type. */
75
187
  unparseableCommits?: Commit[];
188
+ /** Policy violations detected while parsing this workspace's commits; omitted when none. */
76
189
  policyViolations?: PolicyViolation[];
77
190
  skipReason: string;
78
191
  }
192
+ /**
193
+ * Result of preparing a single workspace (package) for release.
194
+ *
195
+ * Discriminated by `status`: `ReleasedWorkspaceResult` for produced releases,
196
+ * `SkippedWorkspaceResult` for skips.
197
+ */
79
198
  export type WorkspacePrepareResult = ReleasedWorkspaceResult | SkippedWorkspaceResult;
199
+ /**
200
+ * Result of preparing a project-level release when a release was produced.
201
+ *
202
+ * Mirrors `ReleasedWorkspaceResult` minus the workspace-only fields (`name`,
203
+ * `propagatedFrom`, `setVersion`). Project releases never propagate and never use
204
+ * `--set-version`, so `releaseType`, `currentVersion`, `newVersion`, `tag`, and
205
+ * `commits` are all required.
206
+ */
80
207
  export interface ReleasedProjectResult {
81
208
  status: 'released';
82
209
  previousTag?: string;
83
210
  commitCount: number;
211
+ /**
212
+ * Count of commits that parsed into a recognized work type. Always populated by the
213
+ * unified `decideRelease` algorithm — `0` when there are no commits or when none
214
+ * parse. Use `bumpOverride` (not `parsedCommitCount === 0`) as the signal for "the
215
+ * user supplied --bump=X".
216
+ */
84
217
  parsedCommitCount: number;
218
+ /** Commits that could not be parsed into a recognized work type. */
85
219
  unparseableCommits?: Commit[];
220
+ /** Policy violations detected while parsing the project's commits; omitted when none. */
86
221
  policyViolations?: PolicyViolation[];
87
222
  releaseType: ReleaseType;
88
223
  currentVersion: string;
@@ -90,20 +225,49 @@ export interface ReleasedProjectResult {
90
225
  tag: string;
91
226
  bumpedFiles: string[];
92
227
  changelogFiles: string[];
228
+ /** Release-notes preview files; present only under `--with-release-notes`. */
93
229
  previewFiles?: string[];
230
+ /** Raw commits in the project's contributing-paths window since the last project tag. */
94
231
  commits: Commit[];
232
+ /**
233
+ * Present when `--bump=X` was supplied and selected the release level for the project.
234
+ * Distinguishes a bump-override release from a `--force` fallback or a natural-bump release;
235
+ * consumed by the renderer to label the release accurately.
236
+ */
95
237
  bumpOverride?: ReleaseType;
96
238
  }
239
+ /**
240
+ * Result of preparing a project-level release when the release was skipped.
241
+ *
242
+ * Carries diagnostic data (`commitCount`, `parsedCommitCount`, `unparseableCommits`,
243
+ * `previousTag`) plus the human-readable `skipReason`. Release-only fields are absent.
244
+ */
97
245
  export interface SkippedProjectResult {
98
246
  status: 'skipped';
99
247
  previousTag?: string;
100
248
  commitCount: number;
249
+ /**
250
+ * Count of commits that parsed into a recognized work type. Always populated by the
251
+ * unified `decideRelease` algorithm — `0` when there are no commits or when none
252
+ * parse.
253
+ */
101
254
  parsedCommitCount: number;
255
+ /** Commits that could not be parsed into a recognized work type. */
102
256
  unparseableCommits?: Commit[];
257
+ /** Policy violations detected while parsing the project's commits; omitted when none. */
103
258
  policyViolations?: PolicyViolation[];
104
259
  skipReason: string;
105
260
  }
261
+ /**
262
+ * Result of preparing a project-level release.
263
+ *
264
+ * Discriminated by `status`: `ReleasedProjectResult` for produced releases,
265
+ * `SkippedProjectResult` for skips. `PrepareResult.project === undefined` means either that
266
+ * no project block is configured or that `--only` narrowed the run, which skips the stage
267
+ * before it can produce a result; the skip is surfaced as a run warning instead.
268
+ */
106
269
  export type ProjectPrepareResult = ReleasedProjectResult | SkippedProjectResult;
270
+ /** Aggregate result of the prepare workflow for both single-package and monorepo modes. */
107
271
  export interface PrepareResult {
108
272
  workspaces: WorkspacePrepareResult[];
109
273
  tags: string[];
@@ -111,28 +275,60 @@ export interface PrepareResult {
111
275
  command: string;
112
276
  files: string[];
113
277
  } | undefined;
278
+ /** Warnings surfaced during preparation (e.g., circular dependency detection). */
114
279
  warnings?: string[] | undefined;
280
+ /** Result of the project-level release stage (present only when `config.project` is configured and the stage ran). */
115
281
  project?: ProjectPrepareResult | undefined;
116
282
  }
283
+ /** Configuration for a single work type used in commit categorization. */
117
284
  export interface WorkTypeConfig {
285
+ /** Human-readable label for the section heading in changelogs. */
118
286
  header: string;
287
+ /** Optional aliases that map to this work type (e.g., 'feature' -> 'feat'). */
119
288
  aliases?: string[] | undefined;
120
289
  }
290
+ /**
291
+ * Defines which commit types trigger major or minor version bumps.
292
+ * Any recognized commit type not listed defaults to a patch bump.
293
+ * The sentinel `'!'` in `major` means "any breaking commit triggers a major bump".
294
+ */
121
295
  export interface VersionPatterns {
296
+ /** Patterns that trigger a major bump. Use `'!'` for any breaking change. */
122
297
  major: string[];
298
+ /** Commit types that trigger a minor bump. */
123
299
  minor: string[];
124
300
  }
301
+ /**
302
+ * Schema for a single historical identity snapshot for a workspace.
303
+ *
304
+ * Captures what the package looked like at some earlier point: the full npm `name`
305
+ * (e.g., `'@williamthorsen/nmr-core'`) and the `tagPrefix` under which tags were
306
+ * published (e.g., `'core-v'`).
307
+ */
125
308
  export declare const legacyIdentitySchema: z.ZodObject<{
126
309
  name: z.ZodString;
127
310
  tagPrefix: z.ZodString;
128
311
  }, z.core.$strict>;
312
+ /**
313
+ * A single historical identity snapshot for a workspace. Both fields are required — a full
314
+ * tuple stays unambiguous across any number of future renames.
315
+ */
129
316
  export type LegacyIdentity = z.infer<typeof legacyIdentitySchema>;
317
+ /**
318
+ * Schema for a package that once lived in this repo but has since been extracted or removed.
319
+ *
320
+ * Unlike `legacyIdentitySchema`, retired packages are never consulted for baseline lookup
321
+ * or changelog attribution — they acknowledge historical tag prefixes and suppress
322
+ * undeclared-candidate warnings.
323
+ */
130
324
  export declare const retiredPackageSchema: z.ZodObject<{
131
325
  name: z.ZodString;
132
326
  tagPrefix: z.ZodString;
133
327
  successor: z.ZodOptional<z.ZodString>;
134
328
  }, z.core.$strict>;
329
+ /** A package that once lived in this repo but has since been extracted or removed. */
135
330
  export type RetiredPackage = z.infer<typeof retiredPackageSchema>;
331
+ /** Schema for a single workspace override entry in the config file. */
136
332
  export declare const workspaceOverrideSchema: z.ZodObject<{
137
333
  dir: z.ZodString;
138
334
  shouldExclude: z.ZodOptional<z.ZodBoolean>;
@@ -141,38 +337,60 @@ export declare const workspaceOverrideSchema: z.ZodObject<{
141
337
  tagPrefix: z.ZodString;
142
338
  }, z.core.$strict>>>;
143
339
  }, z.core.$strict>;
340
+ /** Override for a single workspace in the config file. Matches a discovered workspace by `dir`. */
144
341
  export type WorkspaceOverride = z.infer<typeof workspaceOverrideSchema>;
342
+ /** Schema for the optional `project` block. */
145
343
  export declare const projectConfigSchema: z.ZodObject<{
146
344
  paths: z.ZodOptional<z.ZodArray<z.ZodString>>;
147
345
  tagPrefix: z.ZodOptional<z.ZodString>;
148
346
  }, z.core.$strict>;
347
+ /** Consumer-facing project-release config (`project` block). Empty object opts in to project releases. */
149
348
  export type ProjectConfig = z.infer<typeof projectConfigSchema>;
349
+ /** Schema for the optional `changelogJson` block (input shape, all fields optional). */
150
350
  export declare const changelogJsonInputSchema: z.ZodObject<{
151
351
  enabled: z.ZodOptional<z.ZodBoolean>;
152
352
  outputPath: z.ZodOptional<z.ZodString>;
153
353
  devOnlySections: z.ZodOptional<z.ZodArray<z.ZodString>>;
154
354
  }, z.core.$strict>;
355
+ /** Schema for the optional `releaseNotes` block (input shape, all fields optional). */
155
356
  export declare const releaseNotesInputSchema: z.ZodObject<{
156
357
  shouldInjectIntoReadme: z.ZodOptional<z.ZodBoolean>;
157
358
  }, z.core.$strict>;
359
+ /** Schema for a single `workTypes` entry. */
158
360
  export declare const workTypeConfigSchema: z.ZodObject<{
159
361
  header: z.ZodString;
160
362
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
161
363
  }, z.core.$strict>;
364
+ /** Schema for the `versionPatterns` block. Both arrays are required when the field is provided. */
162
365
  export declare const versionPatternsSchema: z.ZodObject<{
163
366
  major: z.ZodArray<z.ZodString>;
164
367
  minor: z.ZodArray<z.ZodString>;
165
368
  }, z.core.$strict>;
369
+ /** Schema for a single `breakingPolicies` value. */
166
370
  export declare const breakingPolicyValueSchema: z.ZodEnum<{
167
371
  forbidden: "forbidden";
168
372
  optional: "optional";
169
373
  required: "required";
170
374
  }>;
375
+ /** Schema for a single label's spec in the `repoLabels.labels` record. */
171
376
  export declare const labelSpecSchema: z.ZodObject<{
172
377
  color: z.ZodString;
173
378
  description: z.ZodOptional<z.ZodString>;
174
379
  }, z.core.$strict>;
380
+ /**
381
+ * A label's color and optional description; the name is the record key in `repoLabels.labels`.
382
+ * An omitted description resolves to empty, which the generated labels file declares explicitly so that a sync
383
+ * clears whatever description the label carries today.
384
+ */
175
385
  export type LabelSpec = z.infer<typeof labelSpecSchema>;
386
+ /**
387
+ * Schema for the optional `repoLabels` block, which declares the repository's label registry (the labels defined on
388
+ * the GitHub repo, distinct from labels applied to PRs and issues).
389
+ *
390
+ * Resolution is an ordered fold with last-writer-wins: presets in `extends` order, then the `labels` record,
391
+ * where an entry adds a label, replaces one an earlier layer defined, or removes it (`null`).
392
+ * A `null` naming a label no earlier layer defined is a resolve-time error (`resolveLabels`), not a schema error.
393
+ */
176
394
  export declare const repoLabelsSchema: z.ZodObject<{
177
395
  extends: z.ZodOptional<z.ZodArray<z.ZodString>>;
178
396
  labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodObject<{
@@ -180,7 +398,9 @@ export declare const repoLabelsSchema: z.ZodObject<{
180
398
  description: z.ZodOptional<z.ZodString>;
181
399
  }, z.core.$strict>>>>;
182
400
  }, z.core.$strict>;
401
+ /** Consumer-facing `repoLabels` block: bundled presets to extend plus per-name adjustments. */
183
402
  export type RepoLabelsConfig = z.infer<typeof repoLabelsSchema>;
403
+ /** Schema for the consumer-facing config file shape (`.config/release-kit.config.ts`). */
184
404
  export declare const releaseKitConfigSchema: z.ZodObject<{
185
405
  breakingPolicies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
186
406
  forbidden: "forbidden";
@@ -231,52 +451,134 @@ export declare const releaseKitConfigSchema: z.ZodObject<{
231
451
  aliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
232
452
  }, z.core.$strict>>>;
233
453
  }, z.core.$strict>;
454
+ /**
455
+ * Consumer-facing config file shape (`.config/release-kit.config.ts`).
456
+ * All fields are optional; defaults are applied during config merging.
457
+ */
234
458
  export type ReleaseKitConfig = z.infer<typeof releaseKitConfigSchema>;
459
+ /** A raw commit from the git log. */
235
460
  export interface Commit {
461
+ /** The full commit message (first line). */
236
462
  message: string;
463
+ /** The commit hash. */
237
464
  hash: string;
238
465
  }
466
+ /** A commit that has been parsed to extract structured metadata. */
239
467
  export interface ParsedCommit {
468
+ /** The original commit message. */
240
469
  message: string;
470
+ /** The commit hash. */
241
471
  hash: string;
472
+ /** The resolved work type (e.g., 'feat', 'fix'). */
242
473
  type: string;
474
+ /** The commit description after the type prefix. */
243
475
  description: string;
476
+ /** The scope extracted from `scope|type:` or `type(scope):` format. */
244
477
  scope?: string;
478
+ /** Whether this is a breaking change. */
245
479
  breaking: boolean;
246
480
  }
481
+ /** Per-workspace configuration for monorepo releases. */
247
482
  export interface WorkspaceConfig {
483
+ /** The package directory name (e.g., 'arrays'). Used for display and `--only` matching. */
248
484
  dir: string;
485
+ /** The full scoped npm name from `package.json` (e.g., `'@williamthorsen/nmr-core'`). */
249
486
  name: string;
487
+ /** The git tag prefix for this workspace (e.g., 'nmr-core-v'), derived from the unscoped `package.json` name. */
250
488
  tagPrefix: string;
489
+ /** Workspace-relative path to the package root (e.g., `packages/core`). */
251
490
  workspacePath: string;
491
+ /**
492
+ * Whether this workspace can be published to a registry. `true` when `package.json#private`
493
+ * is absent or `false`; `false` only when `private === true`. Consumed by `release-kit publish`
494
+ * to filter unpublishable workspaces; other commands ignore this field.
495
+ */
252
496
  isPublishable: boolean;
497
+ /** Paths to package.json files to bump. */
253
498
  packageFiles: string[];
499
+ /** Directories in which to generate changelogs. */
254
500
  changelogPaths: string[];
501
+ /** Glob patterns passed to `git log -- <paths>` for commit filtering. */
255
502
  paths: string[];
503
+ /**
504
+ * Prior identities of this workspace.
505
+ * Each identity's `tagPrefix` is consulted in addition to the current `tagPrefix` when searching for baseline
506
+ * tags and generating changelogs. `undefined` is equivalent to the empty array.
507
+ */
256
508
  legacyIdentities?: LegacyIdentity[];
257
509
  }
510
+ /** Configuration for a monorepo release workflow with multiple workspaces. */
258
511
  export interface MonorepoReleaseConfig {
512
+ /** Ordered list of workspace configurations. */
259
513
  workspaces: WorkspaceConfig[];
514
+ /** Work type configurations shared across all workspaces. Defaults to `DEFAULT_WORK_TYPES`. */
260
515
  workTypes?: Record<string, WorkTypeConfig>;
516
+ /** Version bump patterns. Defaults to `DEFAULT_VERSION_PATTERNS`. */
261
517
  versionPatterns?: VersionPatterns;
518
+ /**
519
+ * Per-canonical-type breaking-policy lookup. Defaults to `DEFAULT_BREAKING_POLICIES`.
520
+ * When provided, replaces the default entirely.
521
+ * Pass `{}` to disable enforcement (parser falls back to `'optional'` for missing types).
522
+ */
262
523
  breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
524
+ /**
525
+ * Shell command to run after all changelogs are generated (e.g., 'pnpm run fmt').
526
+ * Modified file paths (package.json files and CHANGELOGs) are appended as space-separated
527
+ * arguments. Paths are repo-relative; file paths containing spaces are not supported.
528
+ */
263
529
  formatCommand?: string;
530
+ /** Path to the cliff.toml file; defaults to 'cliff.toml' when absent. */
264
531
  cliffConfigPath?: string;
532
+ /**
533
+ * Maps scope shorthand names to their canonical names.
534
+ * When a commit uses `shorthand|type: description` or `type(shorthand): description`,
535
+ * the shorthand is resolved to the canonical scope name before the parsed commit is returned.
536
+ */
265
537
  scopeAliases?: Record<string, string>;
538
+ /** Controls structured changelog JSON generation. */
266
539
  changelogJson: ChangelogJsonConfig;
540
+ /** Controls release notes consumption (README injection). */
267
541
  releaseNotes: ReleaseNotesConfig;
542
+ /**
543
+ * Project-level release config. Present iff the consumer declared `project: {}`.
544
+ * When present, `releasePrepareMono` runs an additional project-release stage after the per-workspace loop.
545
+ */
268
546
  project?: ResolvedProjectConfig;
269
547
  }
548
+ /** Configuration for the release workflow. */
270
549
  export interface ReleaseConfig {
550
+ /** The git tag prefix used to identify version tags (e.g., 'v'). */
271
551
  tagPrefix: string;
552
+ /** Paths to package.json files to bump. */
272
553
  packageFiles: string[];
554
+ /** Paths to directories in which to generate changelogs. */
273
555
  changelogPaths: string[];
556
+ /** Work type configurations. Defaults to `DEFAULT_WORK_TYPES`. */
274
557
  workTypes?: Record<string, WorkTypeConfig>;
558
+ /** Version bump patterns. Defaults to `DEFAULT_VERSION_PATTERNS`. */
275
559
  versionPatterns?: VersionPatterns;
560
+ /**
561
+ * Per-canonical-type breaking-policy lookup. Defaults to `DEFAULT_BREAKING_POLICIES`. When
562
+ * provided, replaces the default entirely. Pass `{}` to disable enforcement (parser falls
563
+ * back to `'optional'` for missing types).
564
+ */
276
565
  breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
566
+ /**
567
+ * Shell command to run after changelog generation (e.g., 'pnpm run fmt').
568
+ * Modified file paths (package.json files and CHANGELOGs) are appended as space-separated arguments.
569
+ * Paths are repo-relative; file paths containing spaces are not supported.
570
+ */
277
571
  formatCommand?: string;
572
+ /** Path to the cliff.toml file; defaults to 'cliff.toml' when absent. */
278
573
  cliffConfigPath?: string;
574
+ /**
575
+ * Maps scope shorthand names to their canonical names.
576
+ * When a commit uses `shorthand|type: description` or `type(shorthand): description`,
577
+ * the shorthand is resolved to the canonical scope name before the parsed commit is returned.
578
+ */
279
579
  scopeAliases?: Record<string, string>;
580
+ /** Controls structured changelog JSON generation. */
280
581
  changelogJson: ChangelogJsonConfig;
582
+ /** Controls release notes consumption (README injection). */
281
583
  releaseNotes: ReleaseNotesConfig;
282
584
  }
@@ -1,4 +1,17 @@
1
- import type { ReleaseKitConfig } from './types.js';
1
+ import { type ReleaseKitConfig } from './types.js';
2
+ /**
3
+ * Validate a raw config object loaded from `.config/release-kit.config.ts`.
4
+ *
5
+ * Single source of truth: `releaseKitConfigSchema` in `types.ts`, with
6
+ * `ReleaseKitConfig = z.infer<typeof releaseKitConfigSchema>`. Adding a field to the type
7
+ * without updating the schema is impossible because the type *is* derived from the
8
+ * schema.
9
+ *
10
+ * Pipeline: (1) preprocess strips deprecated keys and emits migration-guidance errors;
11
+ * (2) `releaseKitConfigSchema.safeParse` does shape validation; (3) post-parse cross-field
12
+ * checks (full-tuple duplicates, retired-vs-legacy collisions) operate on the typed
13
+ * result.
14
+ */
2
15
  export declare function validateConfig(raw: unknown): {
3
16
  config: ReleaseKitConfig;
4
17
  errors: string[];
@@ -1,14 +1,35 @@
1
1
  import type { DependencyGraph } from './buildDependencyGraph.js';
2
2
  import type { WorkspaceConfig } from './types.js';
3
+ /** Result of probing a workspace's commits since its last tag. */
3
4
  export interface CommitsProbeResult {
5
+ /** Whether the workspace has any commits since its last tag (excluding `release:` commits). */
4
6
  has: boolean;
7
+ /** The baseline tag the commits were measured from; `undefined` when no prior tag exists. */
5
8
  tag: string | undefined;
6
9
  }
10
+ /** A single excluded workspace whose changes would be stranded by the `--only` invocation. */
7
11
  export interface StrandedDependentViolation {
12
+ /** The excluded workspace's `dir`. */
8
13
  dir: string;
14
+ /** The released workspace's `dir` whose release would have triggered D's republication. */
9
15
  downstreamOf: string;
16
+ /** The baseline tag from which D's commits were counted; `undefined` if no prior tag. */
10
17
  tag: string | undefined;
11
18
  }
19
+ /** Probe callback that returns whether a workspace has commits since its last tag. */
12
20
  type CommitsProbe = (workspace: WorkspaceConfig) => CommitsProbeResult;
21
+ /**
22
+ * Detect `--only` invocations that would silently strand changes in excluded internal dependents.
23
+ *
24
+ * Runs in two steps. First, compute the released `--only` set R via fixpoint: start with `--only`
25
+ * workspaces that have own commits, then iteratively add `--only` workspaces whose `workspace:`
26
+ * deps land in R (those will release via propagation). Second, BFS through the reverse-dep graph
27
+ * starting from R, recording each excluded workspace with own commits as a violation. The walk
28
+ * continues *through* such workspaces (anticipating that the user will add them to `--only`,
29
+ * surfacing deeper footguns in one pass), but stops at excluded workspaces with no commits
30
+ * (case-3 barriers — they don't republish, so their downstream dependents aren't affected by R).
31
+ *
32
+ * Returns `undefined` when no violations are found, or a sorted list otherwise.
33
+ */
13
34
  export declare function validateOnlyExcludesStrandedDependents(workspaces: readonly WorkspaceConfig[], only: readonly string[], graph: DependencyGraph, hasCommits: CommitsProbe): StrandedDependentViolation[] | undefined;
14
35
  export {};