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