@williamthorsen/release-kit 12.0.0 → 13.0.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 (168) hide show
  1. package/.meta/changelog.json +212 -0
  2. package/.readyup/kits/default.js +18 -17
  3. package/.readyup/kits/npm-auto-publish.js +24 -23
  4. package/.readyup/manifest.json +16 -11
  5. package/CHANGELOG.md +58 -0
  6. package/README.md +55 -48
  7. package/bin/release-kit.js +1 -1
  8. package/dist/esm/assertCleanWorkingTree.d.ts +1 -5
  9. package/dist/esm/assertTaggedBaseline.d.ts +29 -0
  10. package/dist/esm/assertTaggedBaseline.js +41 -0
  11. package/dist/esm/attachChangelogDiagnostics.d.ts +1 -1
  12. package/dist/esm/attachChangelogDiagnostics.js +3 -0
  13. package/dist/esm/bin/release-kit.js +85 -22
  14. package/dist/esm/buildChangelogEntries.d.ts +23 -13
  15. package/dist/esm/buildChangelogEntries.js +36 -17
  16. package/dist/esm/buildDependencyGraph.d.ts +6 -6
  17. package/dist/esm/buildEmptyReleaseEntry.d.ts +1 -8
  18. package/dist/esm/buildReleaseSummary.d.ts +2 -8
  19. package/dist/esm/buildSyntheticChangelogEntry.d.ts +3 -5
  20. package/dist/esm/buildSyntheticChangelogEntry.js +2 -2
  21. package/dist/esm/bumpVersion.d.ts +1 -8
  22. package/dist/esm/changelogJsonFile.d.ts +5 -7
  23. package/dist/esm/changelogJsonFile.js +2 -17
  24. package/dist/esm/changelogJsonUtils.d.ts +7 -10
  25. package/dist/esm/changelogOverrides.d.ts +59 -98
  26. package/dist/esm/classifyChangelogCommit.d.ts +7 -9
  27. package/dist/esm/classifyChangelogCommit.js +3 -2
  28. package/dist/esm/commitCommand.d.ts +2 -4
  29. package/dist/esm/compareVersions.d.ts +10 -4
  30. package/dist/esm/compareVersions.js +16 -0
  31. package/dist/esm/configFlagSchema.d.ts +1 -1
  32. package/dist/esm/createGithubRelease.d.ts +7 -19
  33. package/dist/esm/createGithubReleaseCommand.d.ts +5 -5
  34. package/dist/esm/createGithubReleaseCommand.js +9 -9
  35. package/dist/esm/createTags.d.ts +2 -3
  36. package/dist/esm/decideRelease.d.ts +2 -6
  37. package/dist/esm/defaults.d.ts +5 -24
  38. package/dist/esm/defaults.js +4 -5
  39. package/dist/esm/defineConfig.d.ts +1 -1
  40. package/dist/esm/deleteFileIfExists.d.ts +1 -1
  41. package/dist/esm/deriveReleaseNotesConfig.d.ts +20 -0
  42. package/dist/esm/deriveReleaseNotesConfig.js +21 -0
  43. package/dist/esm/deriveWorkspaceConfig.d.ts +3 -5
  44. package/dist/esm/detectPackageManager.d.ts +2 -4
  45. package/dist/esm/detectUndeclaredTagPrefixes.d.ts +4 -6
  46. package/dist/esm/detectUndeclaredTagPrefixes.js +1 -1
  47. package/dist/esm/determineBumpType.d.ts +1 -1
  48. package/dist/esm/discoverWorkspaces.d.ts +14 -15
  49. package/dist/esm/discoverWorkspaces.js +12 -12
  50. package/dist/esm/enterRepoRoot.d.ts +12 -0
  51. package/dist/esm/enterRepoRoot.js +16 -0
  52. package/dist/esm/enumerateReleaseWindows.d.ts +8 -8
  53. package/dist/esm/extractMigration.d.ts +6 -8
  54. package/dist/esm/findUnroutedEntryScopes.d.ts +16 -0
  55. package/dist/esm/findUnroutedEntryScopes.js +57 -0
  56. package/dist/esm/formatExcludedSkip.d.ts +3 -0
  57. package/dist/esm/formatExcludedSkip.js +3 -0
  58. package/dist/esm/formatPrivateSkip.d.ts +1 -6
  59. package/dist/esm/generateChangelogs.d.ts +10 -5
  60. package/dist/esm/glyphs.d.ts +1 -1
  61. package/dist/esm/help/prepareHelp.d.ts +3 -4
  62. package/dist/esm/help/prepareHelp.js +4 -3
  63. package/dist/esm/init/checks.d.ts +3 -3
  64. package/dist/esm/init/checks.js +4 -1
  65. package/dist/esm/init/detectRepoType.d.ts +2 -3
  66. package/dist/esm/init/hasProvenance.d.ts +2 -0
  67. package/dist/esm/init/hasProvenance.js +3 -0
  68. package/dist/esm/init/initCommand.d.ts +3 -6
  69. package/dist/esm/init/initCommand.js +10 -10
  70. package/dist/esm/init/parseJsonRecord.d.ts +1 -4
  71. package/dist/esm/init/scaffold.d.ts +1 -1
  72. package/dist/esm/init/templates.d.ts +9 -11
  73. package/dist/esm/init/templates.js +12 -11
  74. package/dist/esm/init/updateTemplatesCommand.d.ts +13 -0
  75. package/dist/esm/init/updateTemplatesCommand.js +64 -0
  76. package/dist/esm/injectReleaseNotesIntoReadme.d.ts +12 -17
  77. package/dist/esm/injectSection.d.ts +3 -3
  78. package/dist/esm/loadConfig.d.ts +16 -14
  79. package/dist/esm/loadConfig.js +2 -2
  80. package/dist/esm/loadValidatedConfig.d.ts +16 -19
  81. package/dist/esm/loadValidatedConfig.js +6 -1
  82. package/dist/esm/packsPath.d.ts +9 -9
  83. package/dist/esm/parseChangeRecordBlock.d.ts +2 -2
  84. package/dist/esm/parseCommitMessage.d.ts +17 -32
  85. package/dist/esm/parseCommitMessage.js +28 -37
  86. package/dist/esm/parseRequestedTags.d.ts +3 -3
  87. package/dist/esm/planReleaseNotesPreviews.d.ts +6 -6
  88. package/dist/esm/planVersionBump.d.ts +5 -3
  89. package/dist/esm/planVersionBump.js +3 -0
  90. package/dist/esm/prepareCommand.d.ts +4 -7
  91. package/dist/esm/prepareCommand.js +13 -6
  92. package/dist/esm/previewTagPrefixes.d.ts +8 -10
  93. package/dist/esm/propagateBumps.d.ts +6 -7
  94. package/dist/esm/publish.d.ts +1 -1
  95. package/dist/esm/publishCommand.d.ts +4 -3
  96. package/dist/esm/publishCommand.js +8 -8
  97. package/dist/esm/pushCommand.d.ts +4 -3
  98. package/dist/esm/pushCommand.js +8 -2
  99. package/dist/esm/pushRelease.d.ts +2 -2
  100. package/dist/esm/readChangelogSections.d.ts +33 -0
  101. package/dist/esm/readChangelogSections.js +80 -0
  102. package/dist/esm/releaseFiles.d.ts +5 -7
  103. package/dist/esm/releasePlan.d.ts +11 -13
  104. package/dist/esm/releasePrepare.d.ts +23 -22
  105. package/dist/esm/releasePrepare.js +31 -11
  106. package/dist/esm/releasePrepareMono.d.ts +9 -7
  107. package/dist/esm/releasePrepareMono.js +85 -33
  108. package/dist/esm/releasePrepareProject.d.ts +19 -29
  109. package/dist/esm/releasePrepareProject.js +31 -12
  110. package/dist/esm/renderChangelogMarkdown.d.ts +10 -4
  111. package/dist/esm/renderChangelogMarkdown.js +27 -2
  112. package/dist/esm/renderReleaseNotes.d.ts +3 -11
  113. package/dist/esm/renderReleaseNotes.js +2 -6
  114. package/dist/esm/reportPrepare.d.ts +4 -5
  115. package/dist/esm/reportPrepare.js +33 -19
  116. package/dist/esm/resolveCommandTags.d.ts +15 -11
  117. package/dist/esm/resolveCommandTags.js +35 -5
  118. package/dist/esm/resolveConfigFlag.d.ts +7 -0
  119. package/dist/esm/resolveConfigFlag.js +4 -0
  120. package/dist/esm/resolveReleaseTags.d.ts +6 -8
  121. package/dist/esm/resolveReleaseTags.js +1 -1
  122. package/dist/esm/resolveStylesOrExit.d.ts +2 -2
  123. package/dist/esm/showTagPrefixesCommand.d.ts +7 -10
  124. package/dist/esm/showTagPrefixesCommand.js +4 -4
  125. package/dist/esm/stripEmojiPrefix.d.ts +1 -0
  126. package/dist/esm/stripScope.d.ts +2 -2
  127. package/dist/esm/stripScope.js +3 -3
  128. package/dist/esm/sync-labels/generateCommand.d.ts +11 -10
  129. package/dist/esm/sync-labels/generateCommand.js +11 -8
  130. package/dist/esm/sync-labels/initCommand.d.ts +6 -7
  131. package/dist/esm/sync-labels/initCommand.js +2 -2
  132. package/dist/esm/sync-labels/presets.d.ts +5 -4
  133. package/dist/esm/sync-labels/presets.js +9 -9
  134. package/dist/esm/sync-labels/resolveLabels.d.ts +7 -7
  135. package/dist/esm/sync-labels/resolveLabels.js +1 -1
  136. package/dist/esm/sync-labels/retiredConfig.d.ts +4 -5
  137. package/dist/esm/sync-labels/syncCommand.d.ts +1 -4
  138. package/dist/esm/sync-labels/templates.d.ts +3 -3
  139. package/dist/esm/sync-labels/templates.js +3 -3
  140. package/dist/esm/sync-labels/typeLabels.d.ts +14 -0
  141. package/dist/esm/sync-labels/typeLabels.js +38 -0
  142. package/dist/esm/sync-labels/types.d.ts +1 -1
  143. package/dist/esm/tagCommand.d.ts +1 -1
  144. package/dist/esm/typeGuards.d.ts +2 -2
  145. package/dist/esm/types.d.ts +116 -91
  146. package/dist/esm/types.js +1 -1
  147. package/dist/esm/validateConfig.d.ts +2 -11
  148. package/dist/esm/validateConfig.js +2 -2
  149. package/dist/esm/validateOnlyExcludesStrandedDependents.d.ts +14 -12
  150. package/dist/esm/validateOverridesCommand.d.ts +17 -20
  151. package/dist/esm/validateOverridesCommand.js +1 -1
  152. package/docs/api.md +6 -6
  153. package/docs/changelogs.md +63 -40
  154. package/docs/configuration.md +29 -27
  155. package/docs/editorial-overrides.md +23 -23
  156. package/docs/labels.md +21 -19
  157. package/docs/project-releases.md +13 -13
  158. package/docs/publishing.md +5 -5
  159. package/docs/readiness-checks.md +3 -3
  160. package/docs/releasing.md +50 -25
  161. package/docs/work-types.md +41 -57
  162. package/package.json +7 -6
  163. package/presets/labels/common.yaml +1 -41
  164. package/dist/esm/resolveReleaseNotesConfig.d.ts +0 -26
  165. package/dist/esm/resolveReleaseNotesConfig.js +0 -29
  166. package/dist/esm/workTypesData.d.ts +0 -50
  167. package/dist/esm/workTypesData.js +0 -145
  168. package/schemas/label-map.json +0 -24
@@ -1,3 +1,4 @@
1
+ import type { BreakingPolicy } from '@williamthorsen/change-grammar';
1
2
  import { z } from 'zod';
2
3
  /** Semver release type for version bumping. */
3
4
  export type ReleaseType = 'major' | 'minor' | 'patch';
@@ -11,30 +12,27 @@ export interface ChangelogItem {
11
12
  /**
12
13
  * Whether this item represents a breaking change.
13
14
  *
14
- * `true` when the commit subject carries the `!` prefix (e.g. `feat!:` or `drop(scope)!:`), or the
15
+ * `true` when the commit subject has the `!` marker (e.g. `feat!:` or `drop(scope)!:`), or the
15
16
  * change-record entry from which the item derives sets `breaking: true`, and the work-type policy
16
- * permits it, so the item agrees with the version bump.
17
- * The `BREAKING CHANGE:` body footer is intentionally NOT considered here. Renderers prefix
18
- * breaking-item bullets with the marker constructed from `WORK_TYPES_DATA.markers.breaking`
19
- * (rendered as `🚨 **Breaking:** ` with the canonical SSOT values) to surface them prominently
20
- * in release notes.
17
+ * permits it, so that the item agrees with the version bump. The `BREAKING CHANGE:` body footer
18
+ * does not set it.
21
19
  */
22
20
  breaking?: boolean;
23
21
  /**
24
22
  * Migration instruction for a consumer, taken from the `Migration:` paragraph of `body`, or from
25
23
  * the `migration` of the change-record entry from which the item derives.
26
24
  *
27
- * On a title-derived item, derived from `body` wherever `body` is set, and absent where the body
28
- * carries no labeled paragraph. Independent of `breaking`: a `deprecate` commit cannot carry `!` under the default
29
- * breaking policy and still calls for a migration. `body` keeps the paragraph, so
30
- * `CHANGELOG.md` goes on rendering it in place.
25
+ * On a title-derived item, derived from `body` whenever `body` is set, and absent when the body
26
+ * does not contain any labeled paragraph. Independent of `breaking`: A `deprecate` commit cannot
27
+ * take `!` under the default breaking policy and still calls for a migration. `body` keeps the
28
+ * paragraph, so `CHANGELOG.md` goes on rendering it in place.
31
29
  */
32
30
  migration?: string;
33
31
  /**
34
32
  * Full git commit SHA when known. Captured from the commit's release window and
35
33
  * persisted in `changelog.json` so that override files can target items by hash. Synthetic
36
34
  * propagation entries (`buildSyntheticChangelogEntry`, `buildEmptyReleaseEntry`) leave
37
- * this field absent — they have no underlying commit.
35
+ * this field absent, because they do not have any underlying commit.
38
36
  */
39
37
  hash?: string;
40
38
  /**
@@ -47,8 +45,8 @@ export interface ChangelogItem {
47
45
  export interface ChangelogSection {
48
46
  /**
49
47
  * Section title, read from the work type of the commit or of its change-record entry. A default
50
- * title carries the type's emoji prefix (e.g. `"🐛 Bug fixes"`), so callers that match against
51
- * `title` (e.g. `sectionOrder` configs) include that prefix.
48
+ * title begins with the type's emoji (e.g. `"🐛 Bug fixes"`), which an exact match against
49
+ * `title`, such as a `sectionOrder` list, must include.
52
50
  */
53
51
  title: string;
54
52
  audience: ChangelogAudience;
@@ -69,12 +67,10 @@ export interface ChangelogJsonConfig {
69
67
  /**
70
68
  * Editorial override for changelog items, keyed in the override file by `<hash>` (every item of the commit) or
71
69
  * `<hash>:<n>` (the item derived from the commit's `n`th change-record entry), where the hash is lowercase hex
72
- * matched as a prefix. All fields are optional; an entry with no fields is a validation error.
70
+ * matched as a prefix. All fields are optional; an entry without any fields is a validation error.
73
71
  *
74
- * `audience` declares the full forward-compatible vocabulary, but only `'skip'` is currently
75
- * supported at runtime. `'all'` and `'dev'` reclassification is reserved for a v2 follow-up
76
- * and rejected by the validator with an explicit "not yet supported" error so the on-disk
77
- * format remains stable through the v1→v2 transition.
72
+ * `audience` admits `'all'` and `'dev'`, but the validator rejects both with a "not yet supported"
73
+ * error; only `'skip'` takes effect.
78
74
  */
79
75
  export interface ChangelogOverride {
80
76
  audience?: 'all' | 'dev' | 'skip';
@@ -91,16 +87,11 @@ export type ChangelogOverridesFile = Record<string, ChangelogOverride>;
91
87
  export interface ReleaseNotesConfig {
92
88
  shouldInjectIntoReadme: boolean;
93
89
  }
94
- /**
95
- * Project-release config after merging defaults. Mirrors the `ReleaseNotesConfig`/
96
- * `ResolvedReleaseNotesConfig`-style split: optional fields in `ProjectConfig` become
97
- * required in `ResolvedProjectConfig`.
98
- */
90
+ /** Project-release config after merging defaults: `ProjectConfig` with every field required. */
99
91
  export interface ResolvedProjectConfig {
100
92
  /**
101
93
  * Resolved commit window for the project release: the git pathspecs that select which commits
102
- * the stage considers. Defaults to the union of every contributing
103
- * workspace's `paths`.
94
+ * the stage considers. Defaults to the union of every contributing workspace's `paths`.
104
95
  */
105
96
  paths: string[];
106
97
  /** Resolved tag prefix for project-level tags. */
@@ -112,11 +103,8 @@ export interface PropagationSource {
112
103
  newVersion: string;
113
104
  }
114
105
  /**
115
- * A `!`-policy violation detected while reading the unreleased window during release preparation.
116
- *
117
- * Surfaces from `releasePrepare`, `releasePrepareMono`, and `releasePrepareProject` via the
118
- * `policyViolations` field on each per-workspace/project result. The policy itself is enforced
119
- * tolerantly at release time — violations are collected and reported, never fail the release.
106
+ * A `!`-policy violation detected while reading the unreleased window during release preparation. Violations are
107
+ * reported and never fail the release.
120
108
  */
121
109
  export interface PolicyViolation {
122
110
  /** Full hash of the offending commit. */
@@ -142,7 +130,10 @@ export interface MalformedChangeRecordBlock {
142
130
  /** The defect that stopped the read. */
143
131
  reason: string;
144
132
  }
145
- /** A change-record entry whose type the work-type taxonomy does not declare, so that it yielded no changelog item. */
133
+ /**
134
+ * A change-record entry whose type the work-type taxonomy does not declare, so that it did not yield any changelog
135
+ * item.
136
+ */
146
137
  export interface UndeclaredEntryType {
147
138
  /** Full hash of the commit. */
148
139
  commitHash: string;
@@ -153,13 +144,32 @@ export interface UndeclaredEntryType {
153
144
  /** The type as the entry declares it. */
154
145
  type: string;
155
146
  }
147
+ /** A change-record entry scope that does not name any workspace whose unreleased window contains its commit. */
148
+ export interface UnroutedEntryScope {
149
+ /** Full hash of the commit. */
150
+ commitHash: string;
151
+ /** First line of the commit message. */
152
+ commitSubject: string;
153
+ /** 1-based position of the entry in its block. */
154
+ entryPosition: number;
155
+ /** The scope as the entry declares it. */
156
+ scope: string;
157
+ }
156
158
  /**
157
- * Result of preparing a single workspace (package) for release when a release was produced.
158
- *
159
- * `currentVersion`, `newVersion`, `tag`, `bumpedFiles`, and `changelogFiles` are always
160
- * populated. `releaseType` and `parsedCommitCount` stay optional because they are left
161
- * undefined for `--set-version` and propagation-only workspaces. `commits` stays optional
162
- * because propagation-only releases have no direct commits.
159
+ * What `prepare` did with the existing `##` sections of one `CHANGELOG.md` that the regenerated file does not render
160
+ * from entries.
161
+ */
162
+ export interface ChangelogPreservation {
163
+ /** The `CHANGELOG.md` path. */
164
+ file: string;
165
+ /** Versions whose sections were kept verbatim, because neither the built entries nor `changelog.json` contain them. */
166
+ preservedVersions: string[];
167
+ /** Headings of the sections that do not name any version, which the regenerated file does not contain. */
168
+ droppedUnversionedHeadings: string[];
169
+ }
170
+ /**
171
+ * Result of preparing a single workspace (package) for release when a release was produced. `releaseType` is absent
172
+ * for `--set-version`.
163
173
  */
164
174
  export interface ReleasedWorkspaceResult {
165
175
  status: 'released';
@@ -168,12 +178,12 @@ export interface ReleasedWorkspaceResult {
168
178
  previousTag?: string;
169
179
  commitCount: number;
170
180
  /**
171
- * Count of commits that yield at least one changelog item — `0` when there are no commits or
172
- * when none does. Absent for `--set-version` and propagation-only workspaces. Use
173
- * `bumpOverride` as the signal for "the user supplied --bump=X".
181
+ * Count of commits that yield at least one changelog item; `0` when the unreleased window does
182
+ * not contain any commits or when none does. Absent for `--set-version` and propagation-only
183
+ * workspaces. `bumpOverride`, not this count, signals that the user supplied `--bump=X`.
174
184
  */
175
185
  parsedCommitCount?: number;
176
- /** Commits that yield no changelog item and that no exclusion or diagnostic accounts for. */
186
+ /** Commits that do not yield any changelog item and are not accounted for by any exclusion or diagnostic. */
177
187
  unparseableCommits?: Commit[];
178
188
  /** Policy violations of the unreleased window's titles and change-record entries; omitted when none. */
179
189
  policyViolations?: PolicyViolation[];
@@ -181,6 +191,8 @@ export interface ReleasedWorkspaceResult {
181
191
  malformedBlocks?: MalformedChangeRecordBlock[];
182
192
  /** Change-record entries of the unreleased window whose type is undeclared; omitted when none. */
183
193
  undeclaredEntryTypes?: UndeclaredEntryType[];
194
+ /** Change-record entry scopes of the unreleased window that route their entry nowhere; omitted when none. */
195
+ unroutedEntryScopes?: UnroutedEntryScope[];
184
196
  releaseType?: ReleaseType;
185
197
  currentVersion: string;
186
198
  newVersion: string;
@@ -189,24 +201,28 @@ export interface ReleasedWorkspaceResult {
189
201
  changelogFiles: string[];
190
202
  /** Release-notes preview files; present only under `--with-release-notes`. */
191
203
  previewFiles?: string[];
192
- /** Raw commits associated with this workspace (present for direct releases, absent for propagation-only). */
204
+ /**
205
+ * Per `CHANGELOG.md`, the existing sections that were kept or dropped; omitted when `prepare` did not keep or drop
206
+ * any.
207
+ */
208
+ changelogPreservation?: ChangelogPreservation[];
209
+ /** Raw commits of the workspace's unreleased window. */
193
210
  commits?: Commit[];
194
211
  /**
195
- * Present when `--bump=X` was supplied and selected the release level for this workspace.
196
- * Distinguishes a bump-override release from a `--force` fallback or a natural-bump release;
197
- * consumed by the renderer to label the release accurately.
212
+ * Present when `--bump=X` was supplied and selected the release level for this workspace, which
213
+ * distinguishes a bump-override release from a `--force` fallback or a natural-bump release.
198
214
  */
199
215
  bumpOverride?: ReleaseType;
200
216
  /** Dependencies that triggered a propagated bump (present for propagated or mixed workspaces). */
201
217
  propagatedFrom?: PropagationSource[];
218
+ /** Present when propagation alone set the bump, the workspace's own commits having called for none. */
219
+ propagatedOnly?: true;
202
220
  /** Present when this workspace was written via `--set-version`; the explicit version that was applied. */
203
221
  setVersion?: string;
204
222
  }
205
223
  /**
206
- * Result of preparing a single workspace (package) for release when the release was skipped.
207
- *
208
- * Carries diagnostic data (`commitCount`, `parsedCommitCount`, `unparseableCommits`,
209
- * `previousTag`) plus the human-readable `skipReason`. Release-only fields are absent.
224
+ * Result of preparing a single workspace (package) for release when the release was skipped: the diagnostic fields
225
+ * and a human-readable `skipReason`, without the release-only fields.
210
226
  */
211
227
  export interface SkippedWorkspaceResult {
212
228
  status: 'skipped';
@@ -214,9 +230,12 @@ export interface SkippedWorkspaceResult {
214
230
  name?: string;
215
231
  previousTag?: string;
216
232
  commitCount: number;
217
- /** Count of commits that yield at least one changelog item — `0` when there are no commits or when none does. */
233
+ /**
234
+ * Count of commits that yield at least one changelog item; `0` when the unreleased window does not contain any
235
+ * commits or when none does.
236
+ */
218
237
  parsedCommitCount: number;
219
- /** Commits that yield no changelog item and that no exclusion or diagnostic accounts for. */
238
+ /** Commits that do not yield any changelog item and are not accounted for by any exclusion or diagnostic. */
220
239
  unparseableCommits?: Commit[];
221
240
  /** Policy violations of the unreleased window's titles and change-record entries; omitted when none. */
222
241
  policyViolations?: PolicyViolation[];
@@ -224,6 +243,8 @@ export interface SkippedWorkspaceResult {
224
243
  malformedBlocks?: MalformedChangeRecordBlock[];
225
244
  /** Change-record entries of the unreleased window whose type is undeclared; omitted when none. */
226
245
  undeclaredEntryTypes?: UndeclaredEntryType[];
246
+ /** Change-record entry scopes of the unreleased window that route their entry nowhere; omitted when none. */
247
+ unroutedEntryScopes?: UnroutedEntryScope[];
227
248
  skipReason: string;
228
249
  }
229
250
  /**
@@ -236,22 +257,20 @@ export type WorkspacePrepareResult = ReleasedWorkspaceResult | SkippedWorkspaceR
236
257
  /**
237
258
  * Result of preparing a project-level release when a release was produced.
238
259
  *
239
- * Mirrors `ReleasedWorkspaceResult` minus the workspace-only fields (`name`,
240
- * `propagatedFrom`, `setVersion`). Project releases never propagate and never use
241
- * `--set-version`, so `releaseType`, `currentVersion`, `newVersion`, `tag`, and
242
- * `commits` are all required.
260
+ * Mirrors `ReleasedWorkspaceResult` without the workspace-only fields. Project releases never propagate and never
261
+ * use `--set-version`, so `releaseType`, `parsedCommitCount`, and `commits` are required.
243
262
  */
244
263
  export interface ReleasedProjectResult {
245
264
  status: 'released';
246
265
  previousTag?: string;
247
266
  commitCount: number;
248
267
  /**
249
- * Count of commits that yield at least one changelog item — `0` when there are no commits or
250
- * when none does. Use `bumpOverride` (not `parsedCommitCount === 0`) as the signal for "the
251
- * user supplied --bump=X".
268
+ * Count of commits that yield at least one changelog item; `0` when the unreleased window does
269
+ * not contain any commits or when none does. `bumpOverride`, not a zero count, signals that the
270
+ * user supplied `--bump=X`.
252
271
  */
253
272
  parsedCommitCount: number;
254
- /** Commits that yield no changelog item and that no exclusion or diagnostic accounts for. */
273
+ /** Commits that do not yield any changelog item and are not accounted for by any exclusion or diagnostic. */
255
274
  unparseableCommits?: Commit[];
256
275
  /** Policy violations of the unreleased window's titles and change-record entries; omitted when none. */
257
276
  policyViolations?: PolicyViolation[];
@@ -267,28 +286,33 @@ export interface ReleasedProjectResult {
267
286
  changelogFiles: string[];
268
287
  /** Release-notes preview files; present only under `--with-release-notes`. */
269
288
  previewFiles?: string[];
289
+ /**
290
+ * Per `CHANGELOG.md`, the existing sections that were kept or dropped; omitted when `prepare` did not keep or drop
291
+ * any.
292
+ */
293
+ changelogPreservation?: ChangelogPreservation[];
270
294
  /** Raw commits in the project's contributing-paths window since the last project tag. */
271
295
  commits: Commit[];
272
296
  /**
273
- * Present when `--bump=X` was supplied and selected the release level for the project.
274
- * Distinguishes a bump-override release from a `--force` fallback or a natural-bump release;
275
- * consumed by the renderer to label the release accurately.
297
+ * Present when `--bump=X` was supplied and selected the release level for the project, which
298
+ * distinguishes a bump-override release from a `--force` fallback or a natural-bump release.
276
299
  */
277
300
  bumpOverride?: ReleaseType;
278
301
  }
279
302
  /**
280
- * Result of preparing a project-level release when the release was skipped.
281
- *
282
- * Carries diagnostic data (`commitCount`, `parsedCommitCount`, `unparseableCommits`,
283
- * `previousTag`) plus the human-readable `skipReason`. Release-only fields are absent.
303
+ * Result of preparing a project-level release when the release was skipped: the diagnostic fields and a
304
+ * human-readable `skipReason`, without the release-only fields.
284
305
  */
285
306
  export interface SkippedProjectResult {
286
307
  status: 'skipped';
287
308
  previousTag?: string;
288
309
  commitCount: number;
289
- /** Count of commits that yield at least one changelog item — `0` when there are no commits or when none does. */
310
+ /**
311
+ * Count of commits that yield at least one changelog item; `0` when the unreleased window does not contain any
312
+ * commits or when none does.
313
+ */
290
314
  parsedCommitCount: number;
291
- /** Commits that yield no changelog item and that no exclusion or diagnostic accounts for. */
315
+ /** Commits that do not yield any changelog item and are not accounted for by any exclusion or diagnostic. */
292
316
  unparseableCommits?: Commit[];
293
317
  /** Policy violations of the unreleased window's titles and change-record entries; omitted when none. */
294
318
  policyViolations?: PolicyViolation[];
@@ -303,8 +327,8 @@ export interface SkippedProjectResult {
303
327
  *
304
328
  * Discriminated by `status`: `ReleasedProjectResult` for produced releases,
305
329
  * `SkippedProjectResult` for skips. `PrepareResult.project === undefined` means either that
306
- * no project block is configured or that `--only` narrowed the run, which skips the stage
307
- * before it can produce a result; the skip is surfaced as a run warning instead.
330
+ * the config does not declare a `project` block or that `--only` narrowed the run, which skips
331
+ * the stage before it can produce a result; `prepare` reports the skip as a run warning instead.
308
332
  */
309
333
  export type ProjectPrepareResult = ReleasedProjectResult | SkippedProjectResult;
310
334
  /** Aggregate result of the prepare workflow for both single-package and monorepo modes. */
@@ -315,7 +339,7 @@ export interface PrepareResult {
315
339
  command: string;
316
340
  files: string[];
317
341
  } | undefined;
318
- /** Warnings surfaced during preparation (e.g., circular dependency detection). */
342
+ /** Warnings reported during preparation (e.g., circular dependency detection). */
319
343
  warnings?: string[] | undefined;
320
344
  /** Result of the project-level release stage (present only when `config.project` is configured and the stage ran). */
321
345
  project?: ProjectPrepareResult | undefined;
@@ -327,9 +351,9 @@ export interface WorkTypeConfig {
327
351
  /** Optional aliases that map to this work type (e.g., 'feature' -> 'feat'). */
328
352
  aliases?: string[] | undefined;
329
353
  /**
330
- * Keeps commits and change-record entries of this type out of every changelog. They yield no
331
- * item, so they contribute nothing to the version bump, and the release report does not list
332
- * them as unparseable.
354
+ * Keeps commits and change-record entries of this type out of every changelog. They do not yield
355
+ * any item, so they contribute nothing to the version bump, and the release report does not
356
+ * list them as unparseable.
333
357
  */
334
358
  excludedFromChangelog?: boolean | undefined;
335
359
  }
@@ -356,15 +380,15 @@ export declare const legacyIdentitySchema: z.ZodObject<{
356
380
  tagPrefix: z.ZodString;
357
381
  }, z.core.$strict>;
358
382
  /**
359
- * A single historical identity snapshot for a workspace. Both fields are required — a full
360
- * tuple stays unambiguous across any number of future renames.
383
+ * A single historical identity snapshot for a workspace. Both fields are required, because a full
384
+ * tuple stays unambiguous across any number of renames.
361
385
  */
362
386
  export type LegacyIdentity = z.infer<typeof legacyIdentitySchema>;
363
387
  /**
364
388
  * Schema for a package that once lived in this repo but has since been extracted or removed.
365
389
  *
366
390
  * Unlike `legacyIdentitySchema`, retired packages are never consulted for baseline lookup
367
- * or changelog attribution — they acknowledge historical tag prefixes and suppress
391
+ * or changelog attribution; they acknowledge historical tag prefixes and suppress
368
392
  * undeclared-candidate warnings.
369
393
  */
370
394
  export declare const retiredPackageSchema: z.ZodObject<{
@@ -415,9 +439,8 @@ export declare const versionPatternsSchema: z.ZodObject<{
415
439
  }, z.core.$strict>;
416
440
  /** Schema for a single `breakingPolicies` value. */
417
441
  export declare const breakingPolicyValueSchema: z.ZodEnum<{
418
- forbidden: "forbidden";
419
442
  optional: "optional";
420
- required: "required";
443
+ forbidden: "forbidden";
421
444
  }>;
422
445
  /** Schema for a single label's spec in the `repoLabels.labels` record. */
423
446
  export declare const labelSpecSchema: z.ZodObject<{
@@ -427,7 +450,7 @@ export declare const labelSpecSchema: z.ZodObject<{
427
450
  /**
428
451
  * A label's color and optional description; the name is the record key in `repoLabels.labels`.
429
452
  * An omitted description resolves to empty, which the generated labels file declares explicitly so that a sync
430
- * clears whatever description the label carries today.
453
+ * clears whatever description the label has on the repo.
431
454
  */
432
455
  export type LabelSpec = z.infer<typeof labelSpecSchema>;
433
456
  /**
@@ -435,10 +458,10 @@ export type LabelSpec = z.infer<typeof labelSpecSchema>;
435
458
  * the GitHub repo, distinct from labels applied to PRs and issues).
436
459
  *
437
460
  * Resolution is an ordered fold with last-writer-wins: presets in `extends` order, then the `labels` record,
438
- * where an entry adds a label, replaces one an earlier layer defined, or removes it (`null`). Names match
461
+ * in which an entry adds a label, replaces one that an earlier layer defined, or removes it (`null`). Names match
439
462
  * case-insensitively, as GitHub matches them, and the replacing layer's spelling wins.
440
463
  * Two misstatements are resolve-time errors (`resolveLabels`), not schema errors: `labels` keys that differ only in
441
- * case, and a `null` naming a label that no earlier layer defined.
464
+ * case, and a `null` naming a label not defined by any earlier layer.
442
465
  */
443
466
  export declare const repoLabelsSchema: z.ZodObject<{
444
467
  extends: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -452,9 +475,8 @@ export type RepoLabelsConfig = z.infer<typeof repoLabelsSchema>;
452
475
  /** Schema for the consumer-facing config file shape (`.config/release-kit.config.ts`). */
453
476
  export declare const releaseKitConfigSchema: z.ZodObject<{
454
477
  breakingPolicies: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<{
455
- forbidden: "forbidden";
456
478
  optional: "optional";
457
- required: "required";
479
+ forbidden: "forbidden";
458
480
  }>>>;
459
481
  changelogJson: z.ZodOptional<z.ZodObject<{
460
482
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -537,12 +559,11 @@ export interface WorkspaceConfig {
537
559
  name: string;
538
560
  /** The git tag prefix for this workspace (e.g., 'nmr-core-v'), derived from the unscoped `package.json` name. */
539
561
  tagPrefix: string;
540
- /** Workspace-relative path to the package root (e.g., `packages/core`). */
562
+ /** Repo-relative path to the package root (e.g., `packages/core`). */
541
563
  workspacePath: string;
542
564
  /**
543
565
  * Whether this workspace can be published to a registry. `true` when `package.json#private`
544
- * is absent or `false`; `false` only when `private === true`. Consumed by `release-kit publish`
545
- * to filter unpublishable workspaces; other commands ignore this field.
566
+ * is absent or `false`; `false` only when `private === true`.
546
567
  */
547
568
  isPublishable: boolean;
548
569
  /** Paths to package.json files to bump. */
@@ -571,7 +592,7 @@ export interface MonorepoReleaseConfig {
571
592
  * When provided, replaces the default entirely.
572
593
  * Pass `{}` to disable enforcement (parser falls back to `'optional'` for missing types).
573
594
  */
574
- breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
595
+ breakingPolicies?: Record<string, BreakingPolicy>;
575
596
  /**
576
597
  * Shell command to run after all changelogs are generated (e.g., 'pnpm run fmt').
577
598
  * Modified file paths (package.json files and CHANGELOGs) are appended as space-separated
@@ -589,11 +610,13 @@ export interface MonorepoReleaseConfig {
589
610
  /** Controls release notes consumption (README injection). */
590
611
  releaseNotes: ReleaseNotesConfig;
591
612
  /**
592
- * Project-level release config. Present iff the consumer declared `project: {}`.
593
- * When present, `releasePrepareMono` runs an additional project-release stage after the per-workspace loop.
613
+ * Project-level release config. Present when the config declares a `project` block, in which case
614
+ * `prepare` runs a project-release stage after the per-workspace loop.
594
615
  */
595
616
  project?: ResolvedProjectConfig;
596
617
  }
618
+ /** Monorepo config as seen by the prepare workflow, which does not read release-notes configuration. */
619
+ export type MonorepoPrepareConfig = Omit<MonorepoReleaseConfig, 'releaseNotes'>;
597
620
  /** Configuration for the release workflow. */
598
621
  export interface ReleaseConfig {
599
622
  /** The git tag prefix used to identify version tags (e.g., 'v'). */
@@ -611,7 +634,7 @@ export interface ReleaseConfig {
611
634
  * provided, replaces the default entirely. Pass `{}` to disable enforcement (parser falls
612
635
  * back to `'optional'` for missing types).
613
636
  */
614
- breakingPolicies?: Record<string, 'forbidden' | 'optional' | 'required'>;
637
+ breakingPolicies?: Record<string, BreakingPolicy>;
615
638
  /**
616
639
  * Shell command to run after changelog generation (e.g., 'pnpm run fmt').
617
640
  * Modified file paths (package.json files and CHANGELOGs) are appended as space-separated arguments.
@@ -629,3 +652,5 @@ export interface ReleaseConfig {
629
652
  /** Controls release notes consumption (README injection). */
630
653
  releaseNotes: ReleaseNotesConfig;
631
654
  }
655
+ /** Single-package config as seen by the prepare workflow, which does not read release-notes configuration. */
656
+ export type PrepareConfig = Omit<ReleaseConfig, 'releaseNotes'>;
package/dist/esm/types.js CHANGED
@@ -50,7 +50,7 @@ export const versionPatternsSchema = z
50
50
  minor: z.array(z.string()),
51
51
  })
52
52
  .strict();
53
- export const breakingPolicyValueSchema = z.enum(['forbidden', 'optional', 'required']);
53
+ export const breakingPolicyValueSchema = z.enum(['forbidden', 'optional']);
54
54
  export const labelSpecSchema = z
55
55
  .object({
56
56
  color: z.string().min(1),
@@ -1,16 +1,7 @@
1
1
  import { type ReleaseKitConfig } from './types.js';
2
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.
3
+ * Validates a raw config object loaded from `.config/release-kit.config.ts`. Returns `{}` with the errors for a config
4
+ * that fails the schema parse, and runs the cross-field checks on one that passes.
14
5
  */
15
6
  export declare function validateConfig(raw: unknown): {
16
7
  config: ReleaseKitConfig;
@@ -31,11 +31,11 @@ function preprocessDeprecatedKeys(raw) {
31
31
  const errors = [];
32
32
  const cleaned = { ...raw };
33
33
  if (Object.hasOwn(cleaned, 'cliffConfigPath')) {
34
- errors.push('cliffConfigPath is no longer supported. release-kit reads changelog history from git directly and uses no external config file. Remove this field from your config, and delete the file it names.');
34
+ errors.push('cliffConfigPath is no longer supported. release-kit reads changelog history from git directly and does not use any external config file. Remove this field from the config, and delete the file that it names.');
35
35
  delete cleaned['cliffConfigPath'];
36
36
  }
37
37
  if (isRecord(cleaned['releaseNotes']) && Object.hasOwn(cleaned['releaseNotes'], 'shouldCreateGithubRelease')) {
38
- errors.push('releaseNotes.shouldCreateGithubRelease is no longer supported. Adoption is now signaled by installing the create-github-release workflow, which `release-kit init` scaffolds. Remove this field from your config.');
38
+ errors.push('releaseNotes.shouldCreateGithubRelease is no longer supported. Adoption is now signaled by installing the create-github-release workflow, which `release-kit init` scaffolds. Remove this field from the config.');
39
39
  const releaseNotesCopy = { ...cleaned['releaseNotes'] };
40
40
  delete releaseNotesCopy['shouldCreateGithubRelease'];
41
41
  cleaned['releaseNotes'] = releaseNotesCopy;
@@ -4,32 +4,34 @@ import type { WorkspaceConfig } from './types.js';
4
4
  export interface CommitsProbeResult {
5
5
  /** Whether the workspace has any commits since its last tag (excluding `release:` commits). */
6
6
  has: boolean;
7
- /** The baseline tag the commits were measured from; `undefined` when no prior tag exists. */
7
+ /**
8
+ * The baseline tag from which the commits were measured; `undefined` when the workspace does not have a prior tag.
9
+ */
8
10
  tag: string | undefined;
9
11
  }
10
12
  /** A single excluded workspace whose changes would be stranded by the `--only` invocation. */
11
13
  export interface StrandedDependentViolation {
12
14
  /** The excluded workspace's `dir`. */
13
15
  dir: string;
14
- /** The released workspace's `dir` whose release would have triggered D's republication. */
16
+ /** The `dir` of the released (or anticipated-release) dependency whose release republishes this workspace. */
15
17
  downstreamOf: string;
16
- /** The baseline tag from which D's commits were counted; `undefined` if no prior tag. */
18
+ /**
19
+ * The baseline tag from which this workspace's commits were counted; `undefined` if the workspace does not have a
20
+ * prior tag.
21
+ */
17
22
  tag: string | undefined;
18
23
  }
19
24
  /** Probe callback that returns whether a workspace has commits since its last tag. */
20
25
  type CommitsProbe = (workspace: WorkspaceConfig) => CommitsProbeResult;
21
26
  /**
22
- * Detect `--only` invocations that would silently strand changes in excluded internal dependents.
27
+ * Detects `--only` invocations that would silently strand changes in excluded internal dependents.
23
28
  *
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).
29
+ * First computes R, the `--only` workspaces that will release, then walks the reverse-dependency graph breadth-first
30
+ * from R and records each excluded workspace with its own commits as a violation. The walk continues through a
31
+ * violation, as though the user had added it to `--only`, which reports deeper violations in the same pass. It stops
32
+ * at an excluded workspace without commits, which does not republish, so its dependents are unaffected by R.
31
33
  *
32
- * Returns `undefined` when no violations are found, or a sorted list otherwise.
34
+ * Returns `undefined` when the walk does not find any violation, or the violations sorted by `dir`.
33
35
  */
34
36
  export declare function validateOnlyExcludesStrandedDependents(workspaces: readonly WorkspaceConfig[], only: readonly string[], graph: DependencyGraph, hasCommits: CommitsProbe): StrandedDependentViolation[] | undefined;
35
37
  export {};
@@ -1,17 +1,18 @@
1
1
  import { type OutputStyle, type StreamStyles } from '@williamthorsen/nmr-core';
2
+ import { type ReleaseHistoryConfig } from './buildChangelogEntries.js';
2
3
  import { type ValidateAllChangelogOverridesInputs, type ValidateAllChangelogOverridesResult } from './changelogOverrides.js';
3
4
  import { type WorkspaceDiscovery } from './discoverWorkspaces.js';
4
5
  import { type GenerateChangelogOptions } from './generateChangelogs.js';
5
6
  import { type LoadValidatedConfigResult } from './loadValidatedConfig.js';
6
- import type { ChangelogEntry, ReleaseConfig } from './types.js';
7
+ import type { ChangelogEntry } from './types.js';
7
8
  /**
8
- * Result of {@link validateOverridesCommand}: tiered exit code paired with a human-readable
9
- * message, which keeps the CLI dispatch layer thin.
9
+ * Result of {@link validateOverridesCommand}: a tiered exit code paired with a human-readable message.
10
10
  *
11
11
  * Exit codes:
12
- * - `0` — clean: no errors, no warnings.
13
- * - `1` — only stale-key warnings.
14
- * - `2` — schema/parse errors or keys that fail to match (ambiguous prefix, overlapping keys, a bare key setting fields on several items) (errors dominate when both classes exist).
12
+ * - `0`: clean, with no errors and no warnings.
13
+ * - `1`: only stale-key warnings.
14
+ * - `2`: schema or parse errors, or keys that fail to match (an ambiguous prefix, overlapping keys, or a bare key
15
+ * that sets fields on several items). Errors take precedence when both classes exist.
15
16
  */
16
17
  export interface ValidateOverridesCommandResult {
17
18
  exitCode: 0 | 1 | 2;
@@ -22,30 +23,26 @@ export interface ValidateOverridesCommandDependencies {
22
23
  discoverWorkspaces?: () => WorkspaceDiscovery;
23
24
  loadValidatedConfig?: () => Promise<LoadValidatedConfigResult>;
24
25
  /**
25
- * Build changelog entries for a scope. Defaults to `buildChangelogEntries`, the same path
26
- * `release-kit prepare` uses — anchoring `validate`'s item universe to `prepare`'s by
27
- * construction.
26
+ * Builds changelog entries for a scope. Defaults to `buildChangelogEntries`, which `release-kit prepare` also
27
+ * uses, so that `validate` sees the same items as `prepare`.
28
28
  */
29
- buildEntries?: (config: Pick<ReleaseConfig, 'breakingPolicies' | 'changelogJson' | 'workTypes'>, options: GenerateChangelogOptions) => ChangelogEntry[];
30
- /** Pluggable validator (default: the production library function). Tests use this to drive specific result shapes through the formatter. */
29
+ buildEntries?: (config: ReleaseHistoryConfig, options: GenerateChangelogOptions) => ChangelogEntry[];
30
+ /** Validator; defaults to `validateAllChangelogOverrides`. Tests use it to feed specific results to the formatter. */
31
31
  validate?: (inputs: ValidateAllChangelogOverridesInputs) => ValidateAllChangelogOverridesResult;
32
32
  }
33
33
  /**
34
- * Validate every changelog override file across the project and per-workspace scopes, and
35
- * return a tiered exit-code-plus-message result. Performs workspace discovery, config load,
34
+ * Validates every changelog override file across the project and per-workspace scopes, and
35
+ * returns a tiered exit-code-plus-message result. Performs workspace discovery, config load,
36
36
  * and per-scope item collection, then delegates the actual validation to
37
37
  * {@link validateAllChangelogOverrides}.
38
38
  *
39
- * Single-package and monorepo modes are handled uniformly: single-package collapses to one
40
- * project scope; monorepo expands to a project scope plus one scope per workspace. A workspace declaring
41
- * patterns that resolve to no package is neither, and exits `2`.
39
+ * Single-package and monorepo modes are handled uniformly: Single-package collapses to one
40
+ * project scope; monorepo expands to a project scope plus one scope per workspace. A workspace that doesn't resolve
41
+ * to any package is neither, and the command returns exit code `2` for it.
42
42
  *
43
43
  * `configPath` names the config file to read, relative to the working directory; it defaults to
44
44
  * `CONFIG_FILE_PATH`.
45
45
  */
46
46
  export declare function validateOverridesCommand(styles: StreamStyles, configPath?: string, dependencies?: ValidateOverridesCommandDependencies): Promise<ValidateOverridesCommandResult>;
47
- /**
48
- * Pure formatter — take an aggregated validation result, return the tiered exit code and a
49
- * rendered message. Exported for unit testing without going through the full discovery path.
50
- */
47
+ /** Returns the tiered exit code and rendered message for an aggregated validation result. */
51
48
  export declare function formatValidateOverridesResult(result: ValidateAllChangelogOverridesResult, style: OutputStyle): ValidateOverridesCommandResult;
@@ -100,7 +100,7 @@ function buildMonorepoInputs(discoveredPaths, userConfig, buildEntries) {
100
100
  const rootPackage = readRootPackageVersion();
101
101
  const config = mergeMonorepoConfig(discoveredPaths, userConfig, rootPackage);
102
102
  const workspaces = config.workspaces.map((workspace) => {
103
- const options = { tagPrefixes: getAllTagPrefixes(workspace), paths: workspace.paths };
103
+ const options = { tagPrefixes: getAllTagPrefixes(workspace), paths: workspace.paths, workspaceDir: workspace.dir };
104
104
  return {
105
105
  filePath: resolveOverridePath(workspace.workspacePath),
106
106
  items: flattenEntriesToItems(buildEntries(config, options)),