pm-changelog 2026.6.2 → 2026.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.6.4 - 2026-06-04
4
+
5
+ ### Added
6
+
7
+ - Add opt-in breaking-changes, suggest-semver, body-preview, and emoji-prefix flags ([pmc-se5c](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/features/pmc-se5c.toon))
8
+
9
+ ### Fixed
10
+
11
+ - Deduplicate label grouping tags in changelog sections ([pmc-an10](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/issues/pmc-an10.toon))
12
+
13
+ ## 2026.6.3 - 2026-06-03
14
+
15
+ ### Added
16
+
17
+ - Opt-in changelog enhancements ([pmc-emx6](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/features/pmc-emx6.toon))
18
+ - Add --changelog-json structured document output ([pmc-gl6b](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/tasks/pmc-gl6b.toon))
19
+ - Add --limit and --since-version release windowing ([pmc-xtwa](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/tasks/pmc-xtwa.toon))
20
+ - Add --contributors per-release contributor list ([pmc-imsu](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/tasks/pmc-imsu.toon))
21
+ - Add --conventional Conventional-Commits heading mapping ([pmc-91hn](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/tasks/pmc-91hn.toon))
22
+ - Add --section-by type\|status\|label within-release grouping ([pmc-qro6](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/tasks/pmc-qro6.toon))
23
+
24
+ ### Fixed
25
+
26
+ - Zero-regression guarantee for pm-changelog enhancements ([pmc-1w1r](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/decisions/pmc-1w1r.toon))
27
+ - Fix changelog export format validation and metadata ([pmc-55cp](https://github.com/unbraind/pm-changelog/blob/main/.agents/pm/issues/pmc-55cp.toon))
28
+
3
29
  ## 2026.6.1 - 2026-06-01
4
30
 
5
31
  ### Fixed
package/README.md CHANGED
@@ -25,6 +25,25 @@ npm install --save-dev pm-changelog @unbrained/pm-cli
25
25
  npx pm-changelog --mode prepend --output CHANGELOG.md
26
26
  ```
27
27
 
28
+ ## Opt-in extras
29
+
30
+ These flags are strictly additive — omitting them keeps output byte-for-byte identical to the default:
31
+
32
+ ```bash
33
+ npx pm-changelog --stdout --section-by type # group by type/status/label instead of categories
34
+ npx pm-changelog --stdout --conventional # Features / Bug Fixes / ... headings
35
+ npx pm-changelog --stdout --contributors # per-release contributor list
36
+ npx pm-changelog --all-release-tags --limit 10 # keep only the newest N releases
37
+ npx pm-changelog --all-release-tags --since-version 2.0.0
38
+ npx pm-changelog --all-release-tags --changelog-json > changelog.json
39
+ npx pm-changelog --stdout --breaking-changes # add a Breaking Changes section
40
+ npx pm-changelog --suggest-semver # print a suggested semver bump as JSON
41
+ npx pm-changelog --stdout --body-preview 80 # append first 80 chars of each item body
42
+ npx pm-changelog --stdout --emoji-prefix # prefix headings with emoji (Added 🎉, Fixed 🐛, ...)
43
+ ```
44
+
45
+ See [Usage](docs/usage.md#opt-in-enhancements) for details.
46
+
28
47
  ## Docs
29
48
 
30
49
  - [Docs index](docs/README.md)
package/dist/cli.js CHANGED
@@ -2,28 +2,32 @@
2
2
  import { appendFileSync, existsSync, readFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
4
  import { stdin } from "node:process";
5
- import { createChangelog, mergeChangelog, parsePmItemsJson, readPmItems, writeChangelog, } from "./generator.js";
5
+ import { buildChangelogDocument, createChangelog, mergeChangelog, parsePmItemsJson, readPmItems, suggestSemver, writeChangelog, } from "./generator.js";
6
6
  import { resolveReleaseContext, resolveReleaseTagWindows } from "./release-context.js";
7
7
  async function main() {
8
8
  const options = parseArgs(process.argv.slice(2));
9
9
  applyReleaseContext(options);
10
10
  const items = await loadItems(options);
11
11
  const outputPath = resolve(options.output);
12
+ // OPT-IN (`--changelog-json`): emit the full structured changelog document to
13
+ // stdout and exit, leaving every other mode and CHANGELOG.md untouched.
14
+ if (options.changelogJson) {
15
+ const document = buildChangelogDocument(buildGenerationOptions(options, items));
16
+ process.stdout.write(JSON.stringify(document, null, 2) + "\n");
17
+ return;
18
+ }
19
+ // OPT-IN (`--suggest-semver`) without `--changelog-json`: emit only the
20
+ // semver analysis as JSON to stdout and exit. Never writes CHANGELOG.md and
21
+ // never touches default markdown.
22
+ if (options.suggestSemver) {
23
+ const suggestion = suggestSemver(buildGenerationOptions(options, items));
24
+ process.stdout.write(JSON.stringify(suggestion, null, 2) + "\n");
25
+ return;
26
+ }
12
27
  if (!options.stdout) {
13
28
  const result = writeChangelog({
14
- items,
29
+ ...buildGenerationOptions(options, items),
15
30
  output: outputPath,
16
- title: options.title,
17
- version: options.version,
18
- date: options.date,
19
- since: options.since,
20
- until: options.until,
21
- releaseWindows: options.releaseWindows,
22
- includeStatuses: options.statuses,
23
- groupBy: options.groupBy,
24
- includeEmpty: options.includeEmpty,
25
- includeLinks: options.includeLinks,
26
- itemUrlBase: options.itemUrlBase,
27
31
  mode: options.mode,
28
32
  check: options.check,
29
33
  });
@@ -45,20 +49,7 @@ async function main() {
45
49
  process.exit(1);
46
50
  return;
47
51
  }
48
- const generated = createChangelog({
49
- items,
50
- title: options.title,
51
- version: options.version,
52
- date: options.date,
53
- since: options.since,
54
- until: options.until,
55
- releaseWindows: options.releaseWindows,
56
- includeStatuses: options.statuses,
57
- groupBy: options.groupBy,
58
- includeEmpty: options.includeEmpty,
59
- includeLinks: options.includeLinks,
60
- itemUrlBase: options.itemUrlBase,
61
- });
52
+ const generated = createChangelog(buildGenerationOptions(options, items));
62
53
  const existing = options.mode === "prepend" && existsSync(outputPath)
63
54
  ? readFileSync(outputPath, "utf-8")
64
55
  : undefined;
@@ -96,6 +87,13 @@ function parseArgs(args) {
96
87
  stdin: false,
97
88
  pmArgs: [],
98
89
  groupBy: "version",
90
+ sectionBy: "category",
91
+ conventional: false,
92
+ contributors: false,
93
+ breakingChanges: false,
94
+ suggestSemver: false,
95
+ emojiPrefix: false,
96
+ changelogJson: false,
99
97
  includeEmpty: false,
100
98
  includeLinks: false,
101
99
  mode: "replace",
@@ -194,6 +192,36 @@ function parseArgs(args) {
194
192
  case "--group-by":
195
193
  options.groupBy = parseGroupBy(requireValue(args, ++i, arg));
196
194
  break;
195
+ case "--section-by":
196
+ options.sectionBy = parseSectionBy(requireValue(args, ++i, arg));
197
+ break;
198
+ case "--conventional":
199
+ options.conventional = true;
200
+ break;
201
+ case "--contributors":
202
+ options.contributors = true;
203
+ break;
204
+ case "--breaking-changes":
205
+ options.breakingChanges = true;
206
+ break;
207
+ case "--suggest-semver":
208
+ options.suggestSemver = true;
209
+ break;
210
+ case "--body-preview":
211
+ options.bodyPreview = parseBodyPreview(requireValue(args, ++i, arg));
212
+ break;
213
+ case "--emoji-prefix":
214
+ options.emojiPrefix = true;
215
+ break;
216
+ case "--changelog-json":
217
+ options.changelogJson = true;
218
+ break;
219
+ case "--limit":
220
+ options.limit = parseLimit(requireValue(args, ++i, arg));
221
+ break;
222
+ case "--since-version":
223
+ options.sinceVersion = requireValue(args, ++i, arg);
224
+ break;
197
225
  case "--mode":
198
226
  options.mode = parseMode(requireValue(args, ++i, arg));
199
227
  break;
@@ -279,11 +307,55 @@ function parseGroupBy(value) {
279
307
  return value;
280
308
  throw new Error("--group-by must be 'version', 'release', or 'milestone'");
281
309
  }
310
+ function parseSectionBy(value) {
311
+ if (value === "category" || value === "type" || value === "status" || value === "label")
312
+ return value;
313
+ throw new Error("--section-by must be 'category', 'type', 'status', or 'label'");
314
+ }
315
+ function parseLimit(value) {
316
+ const parsed = Number.parseInt(value, 10);
317
+ if (!Number.isInteger(parsed) || parsed < 1) {
318
+ throw new Error("--limit must be a positive integer");
319
+ }
320
+ return parsed;
321
+ }
322
+ function parseBodyPreview(value) {
323
+ const parsed = Number.parseInt(value, 10);
324
+ if (!Number.isInteger(parsed) || parsed < 1) {
325
+ throw new Error("--body-preview must be a positive integer");
326
+ }
327
+ return parsed;
328
+ }
282
329
  function parseMode(value) {
283
330
  if (value === "replace" || value === "prepend")
284
331
  return value;
285
332
  throw new Error("--mode must be 'replace' or 'prepend'");
286
333
  }
334
+ function buildGenerationOptions(options, items) {
335
+ return {
336
+ items,
337
+ title: options.title,
338
+ version: options.version,
339
+ date: options.date,
340
+ since: options.since,
341
+ until: options.until,
342
+ releaseWindows: options.releaseWindows,
343
+ includeStatuses: options.statuses,
344
+ groupBy: options.groupBy,
345
+ sectionBy: options.sectionBy,
346
+ conventional: options.conventional,
347
+ contributors: options.contributors,
348
+ limit: options.limit,
349
+ sinceVersion: options.sinceVersion,
350
+ breakingChanges: options.breakingChanges,
351
+ bodyPreview: options.bodyPreview,
352
+ emojiPrefix: options.emojiPrefix,
353
+ suggestSemver: options.suggestSemver,
354
+ includeEmpty: options.includeEmpty,
355
+ includeLinks: options.includeLinks,
356
+ itemUrlBase: options.itemUrlBase,
357
+ };
358
+ }
287
359
  function buildSummary(options, result, output = result.output) {
288
360
  return {
289
361
  output,
@@ -367,6 +439,16 @@ Options:
367
439
  Git tag glob for --all-release-tags (default: v*)
368
440
  --status <list> Comma-separated statuses (default: closed)
369
441
  --group-by <mode> version, release, or milestone (default: version)
442
+ --section-by <mode> Within-release grouping: category, type, status, or label (default: category)
443
+ --conventional Use Conventional-Commits headings (Features/Bug Fixes/...) for category grouping
444
+ --contributors Append a Contributors list per release from item assignee/author
445
+ --limit <n> Keep only the most recent N release sections (history modes only)
446
+ --since-version <v> Keep only releases at or newer than version <v> (history modes only)
447
+ --breaking-changes Emit a Breaking Changes section listing items detected as breaking
448
+ --suggest-semver Print a suggested semver bump (major/minor/patch) as JSON; never writes the changelog
449
+ --body-preview <n> Append the first N chars of each item body to its entry
450
+ --emoji-prefix Prefix section headings with conventional emoji (Added 🎉, Fixed 🐛, ...)
451
+ --changelog-json Print the full structured changelog document (releases->sections->items) to stdout
370
452
  --mode <mode> replace or prepend existing changelog (default: replace)
371
453
  --include-empty Emit an empty release section when no items match
372
454
  --include-links Include item URLs in generated entries (default: false)
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { appendFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { stdin } from \"node:process\";\n\nimport {\n createChangelog,\n mergeChangelog,\n parsePmItemsJson,\n readPmItems,\n writeChangelog,\n} from \"./generator.js\";\nimport { resolveReleaseContext, resolveReleaseTagWindows } from \"./release-context.js\";\nimport type { ChangelogGroupBy, ChangelogReleaseWindow, PmItem } from \"./types.js\";\n\ninterface CliOptions {\n output: string;\n stdout: boolean;\n json: boolean;\n input?: string;\n stdin: boolean;\n pmRoot?: string;\n pmBin?: string;\n pmArgs: string[];\n pmCwd?: string;\n title?: string;\n version?: string;\n versionFromPackage: boolean;\n date?: string;\n since?: string;\n sincePreviousTag: boolean;\n until?: string;\n untilReleaseTag: boolean;\n allReleaseTags: boolean;\n releaseTagPattern: string;\n statuses?: string[];\n groupBy: ChangelogGroupBy;\n releaseWindows?: ChangelogReleaseWindow[];\n includeEmpty: boolean;\n includeLinks: boolean;\n itemUrlBase?: string;\n mode: \"replace\" | \"prepend\";\n check: boolean;\n githubOutput: boolean;\n githubStepSummary: boolean;\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2));\n applyReleaseContext(options);\n const items = await loadItems(options);\n const outputPath = resolve(options.output);\n\n if (!options.stdout) {\n const result = writeChangelog({\n items,\n output: outputPath,\n title: options.title,\n version: options.version,\n date: options.date,\n since: options.since,\n until: options.until,\n releaseWindows: options.releaseWindows,\n includeStatuses: options.statuses,\n groupBy: options.groupBy,\n includeEmpty: options.includeEmpty,\n includeLinks: options.includeLinks,\n itemUrlBase: options.itemUrlBase,\n mode: options.mode,\n check: options.check,\n });\n const summary = buildSummary(options, result, outputPath);\n\n if (options.githubOutput) writeGitHubOutput(summary);\n if (options.githubStepSummary) writeGitHubStepSummary(result.markdown);\n if (options.json) {\n process.stdout.write(JSON.stringify(summary) + \"\\n\");\n } else if (options.check) {\n console.error(result.changed ? `Changelog is out of date: ${outputPath}` : `Changelog is up to date: ${outputPath}`);\n } else {\n console.error(`Wrote ${outputPath}`);\n }\n\n if (options.check && result.changed) process.exit(1);\n return;\n }\n\n const generated = createChangelog({\n items,\n title: options.title,\n version: options.version,\n date: options.date,\n since: options.since,\n until: options.until,\n releaseWindows: options.releaseWindows,\n includeStatuses: options.statuses,\n groupBy: options.groupBy,\n includeEmpty: options.includeEmpty,\n includeLinks: options.includeLinks,\n itemUrlBase: options.itemUrlBase,\n });\n const existing = options.mode === \"prepend\" && existsSync(outputPath)\n ? readFileSync(outputPath, \"utf-8\")\n : undefined;\n const merged = options.mode === \"prepend\"\n ? mergeChangelog(existing, generated.markdown, { title: options.title })\n : { markdown: generated.markdown, action: \"replaced\" as const, changed: true };\n\n if (options.stdout) {\n if (options.json) {\n const summary = buildSummary(options, {\n output: outputPath,\n markdown: merged.markdown,\n action: merged.action,\n changed: merged.changed,\n itemCount: generated.itemCount,\n bytes: Buffer.byteLength(merged.markdown, \"utf-8\"),\n });\n if (options.githubOutput) writeGitHubOutput(summary);\n if (options.githubStepSummary) writeGitHubStepSummary(merged.markdown);\n process.stdout.write(JSON.stringify(summary) + \"\\n\");\n return;\n }\n if (options.githubStepSummary) writeGitHubStepSummary(merged.markdown);\n process.stdout.write(merged.markdown);\n return;\n }\n\n}\n\nfunction parseArgs(args: string[]): CliOptions {\n const options: CliOptions = {\n output: \"CHANGELOG.md\",\n stdout: false,\n json: false,\n stdin: false,\n pmArgs: [],\n groupBy: \"version\",\n includeEmpty: false,\n includeLinks: false,\n mode: \"replace\",\n check: false,\n githubOutput: false,\n githubStepSummary: false,\n versionFromPackage: false,\n sincePreviousTag: false,\n untilReleaseTag: false,\n allReleaseTags: false,\n releaseTagPattern: \"v*\",\n };\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n switch (arg) {\n case \"--help\":\n case \"-h\":\n printHelp();\n process.exit(0);\n case \"--output\":\n case \"-o\":\n options.output = requireValue(args, ++i, arg);\n break;\n case \"--stdout\":\n options.stdout = true;\n break;\n case \"--json\":\n options.json = true;\n break;\n case \"--check\":\n options.check = true;\n break;\n case \"--github-output\":\n case \"--set-output\":\n options.githubOutput = true;\n break;\n case \"--github-step-summary\":\n options.githubStepSummary = true;\n break;\n case \"--input\":\n case \"-i\":\n options.input = requireValue(args, ++i, arg);\n break;\n case \"--stdin\":\n options.stdin = true;\n break;\n case \"--pm-root\":\n options.pmRoot = requireValue(args, ++i, arg);\n break;\n case \"--pm-bin\":\n options.pmBin = requireValue(args, ++i, arg);\n break;\n case \"--pm-arg\":\n options.pmArgs.push(requireAnyValue(args, ++i, arg));\n break;\n case \"--pm-cwd\":\n options.pmCwd = requireValue(args, ++i, arg);\n break;\n case \"--title\":\n options.title = requireValue(args, ++i, arg);\n break;\n case \"--version\":\n options.version = requireValue(args, ++i, arg);\n break;\n case \"--release-version-from-package\":\n options.versionFromPackage = true;\n break;\n case \"--date\":\n options.date = requireValue(args, ++i, arg);\n break;\n case \"--since\":\n options.since = requireValue(args, ++i, arg);\n break;\n case \"--since-previous-tag\":\n options.sincePreviousTag = true;\n break;\n case \"--until\":\n options.until = requireValue(args, ++i, arg);\n break;\n case \"--until-release-tag\":\n options.untilReleaseTag = true;\n break;\n case \"--all-release-tags\":\n options.allReleaseTags = true;\n break;\n case \"--release-tag-pattern\":\n options.releaseTagPattern = requireValue(args, ++i, arg);\n break;\n case \"--status\":\n case \"--statuses\":\n options.statuses = requireValue(args, ++i, arg)\n .split(\",\")\n .map((status) => status.trim())\n .filter(Boolean);\n break;\n case \"--group-by\":\n options.groupBy = parseGroupBy(requireValue(args, ++i, arg));\n break;\n case \"--mode\":\n options.mode = parseMode(requireValue(args, ++i, arg));\n break;\n case \"--include-empty\":\n options.includeEmpty = true;\n break;\n case \"--include-links\":\n options.includeLinks = true;\n break;\n case \"--no-links\":\n options.includeLinks = false;\n break;\n case \"--item-url-base\":\n options.itemUrlBase = requireValue(args, ++i, arg);\n break;\n default:\n throw new Error(`Unknown option: ${arg}`);\n }\n }\n\n return options;\n}\n\nfunction applyReleaseContext(options: CliOptions): void {\n if (options.allReleaseTags) {\n const cwd = options.pmCwd ? resolve(options.pmCwd) : process.cwd();\n if (options.versionFromPackage && !options.version) {\n const context = resolveReleaseContext({\n cwd,\n versionFromPackage: true,\n });\n options.version = context.version;\n }\n options.releaseWindows = resolveReleaseTagWindows({\n cwd,\n tagPattern: options.releaseTagPattern,\n pendingVersion: options.version,\n pendingTimestamp: options.until ?? options.date,\n });\n return;\n }\n\n if (!options.version && !options.versionFromPackage && !options.sincePreviousTag && !options.untilReleaseTag) return;\n const context = resolveReleaseContext({\n cwd: options.pmCwd ? resolve(options.pmCwd) : process.cwd(),\n version: options.version,\n versionFromPackage: options.versionFromPackage,\n since: options.since,\n sincePreviousTag: options.sincePreviousTag,\n until: options.until,\n untilReleaseTag: options.untilReleaseTag,\n });\n options.version = context.version;\n options.date = options.date ?? context.date;\n options.since = context.since;\n options.until = context.until;\n}\n\nasync function loadItems(options: CliOptions): Promise<PmItem[]> {\n if (options.stdin) {\n return parsePmItemsJson(await readStdin());\n }\n\n if (options.input) {\n return parsePmItemsJson(readFileSync(resolve(options.input), \"utf-8\"));\n }\n\n return readPmItems({\n pmRoot: options.pmRoot,\n pmBin: options.pmBin,\n pmArgs: options.pmArgs,\n cwd: options.pmCwd ? resolve(options.pmCwd) : undefined,\n });\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolvePromise, reject) => {\n let data = \"\";\n stdin.setEncoding(\"utf-8\");\n stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n stdin.on(\"end\", () => resolvePromise(data));\n stdin.on(\"error\", reject);\n });\n}\n\nfunction parseGroupBy(value: string): ChangelogGroupBy {\n if (value === \"version\" || value === \"release\" || value === \"milestone\") return value;\n throw new Error(\"--group-by must be 'version', 'release', or 'milestone'\");\n}\n\nfunction parseMode(value: string): \"replace\" | \"prepend\" {\n if (value === \"replace\" || value === \"prepend\") return value;\n throw new Error(\"--mode must be 'replace' or 'prepend'\");\n}\n\nfunction buildSummary(\n options: CliOptions,\n result: {\n output?: string;\n action: string;\n changed: boolean;\n markdown: string;\n itemCount: number;\n bytes: number;\n },\n output = result.output\n): Record<string, unknown> {\n return {\n output,\n mode: options.mode,\n action: result.action,\n changed: result.changed,\n itemCount: result.itemCount,\n bytes: result.bytes,\n check: options.check,\n markdown: options.stdout ? result.markdown : undefined,\n };\n}\n\nfunction writeGitHubOutput(summary: Record<string, unknown>): void {\n const githubOutput = process.env.GITHUB_OUTPUT;\n if (!githubOutput) {\n throw new Error(\"--github-output requires the GITHUB_OUTPUT environment variable\");\n }\n\n const lines = [\n `output=${String(summary.output ?? \"\")}`,\n `mode=${String(summary.mode ?? \"\")}`,\n `action=${String(summary.action ?? \"\")}`,\n `changed=${String(summary.changed ?? \"\")}`,\n `item_count=${String(summary.itemCount ?? \"\")}`,\n `bytes=${String(summary.bytes ?? \"\")}`,\n ];\n appendFileSync(githubOutput, `${lines.join(\"\\n\")}\\n`, \"utf-8\");\n}\n\nfunction writeGitHubStepSummary(markdown: string): void {\n const githubStepSummary = process.env.GITHUB_STEP_SUMMARY;\n if (!githubStepSummary) {\n throw new Error(\"--github-step-summary requires the GITHUB_STEP_SUMMARY environment variable\");\n }\n\n appendFileSync(githubStepSummary, `${markdown.trimEnd()}\\n`, \"utf-8\");\n}\n\nfunction requireValue(args: string[], index: number, flag: string): string {\n const value = args[index];\n if (!value || value.startsWith(\"--\")) {\n throw new Error(`${flag} requires a value`);\n }\n return value;\n}\n\nfunction requireAnyValue(args: string[], index: number, flag: string): string {\n const value = args[index];\n if (!value) {\n throw new Error(`${flag} requires a value`);\n }\n return value;\n}\n\nfunction printHelp(): void {\n process.stdout.write(`pm-changelog\n\nGenerate CHANGELOG.md from pm-cli items.\n\nUsage:\n pm-changelog [options]\n\nOptions:\n -o, --output <file> Write changelog to a file (default: CHANGELOG.md)\n --stdout Print markdown instead of writing a file\n --json Print a JSON summary for CI/runners\n --check Do not write; exit 1 when output would change\n --github-output Write summary fields to $GITHUB_OUTPUT\n --github-step-summary Append generated markdown to $GITHUB_STEP_SUMMARY\n -i, --input <file> Read pm JSON from a file instead of running pm\n --stdin Read pm JSON from stdin\n --pm-root <dir> pm project root for \"pm --path <dir> list-all --json\"\n --pm-bin <file> pm executable to run (default: pm)\n --pm-arg <arg> Extra argument passed before \"list-all --json\" (repeatable)\n --pm-cwd <dir> Working directory for running pm\n --title <text> Changelog title (default: Changelog)\n --version <version> Version heading (default: Unreleased)\n --release-version-from-package\n Read version heading from nearest package.json\n --date <date> Release date (default: resolved tag date when available, otherwise today)\n --since <date> Include items changed on or after this date\n --since-previous-tag Derive --since from the previous git tag\n --until <date> Include items changed on or before this date\n --until-release-tag Derive --until from the current release tag when it exists\n --all-release-tags Rebuild full history from git release tag windows\n --release-tag-pattern <glob>\n Git tag glob for --all-release-tags (default: v*)\n --status <list> Comma-separated statuses (default: closed)\n --group-by <mode> version, release, or milestone (default: version)\n --mode <mode> replace or prepend existing changelog (default: replace)\n --include-empty Emit an empty release section when no items match\n --include-links Include item URLs in generated entries (default: false)\n --item-url-base <url> Make item IDs clickable links: [pmc-abc]({url}/pmc-abc.toon)\n`);\n}\n\nmain().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { appendFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { stdin } from \"node:process\";\n\nimport {\n buildChangelogDocument,\n createChangelog,\n mergeChangelog,\n parsePmItemsJson,\n readPmItems,\n suggestSemver,\n writeChangelog,\n} from \"./generator.js\";\nimport { resolveReleaseContext, resolveReleaseTagWindows } from \"./release-context.js\";\nimport type {\n ChangelogGroupBy,\n ChangelogReleaseWindow,\n ChangelogSectionBy,\n PmItem,\n} from \"./types.js\";\n\ninterface CliOptions {\n output: string;\n stdout: boolean;\n json: boolean;\n input?: string;\n stdin: boolean;\n pmRoot?: string;\n pmBin?: string;\n pmArgs: string[];\n pmCwd?: string;\n title?: string;\n version?: string;\n versionFromPackage: boolean;\n date?: string;\n since?: string;\n sincePreviousTag: boolean;\n until?: string;\n untilReleaseTag: boolean;\n allReleaseTags: boolean;\n releaseTagPattern: string;\n statuses?: string[];\n groupBy: ChangelogGroupBy;\n sectionBy: ChangelogSectionBy;\n conventional: boolean;\n contributors: boolean;\n limit?: number;\n sinceVersion?: string;\n breakingChanges: boolean;\n suggestSemver: boolean;\n bodyPreview?: number;\n emojiPrefix: boolean;\n changelogJson: boolean;\n releaseWindows?: ChangelogReleaseWindow[];\n includeEmpty: boolean;\n includeLinks: boolean;\n itemUrlBase?: string;\n mode: \"replace\" | \"prepend\";\n check: boolean;\n githubOutput: boolean;\n githubStepSummary: boolean;\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2));\n applyReleaseContext(options);\n const items = await loadItems(options);\n const outputPath = resolve(options.output);\n\n // OPT-IN (`--changelog-json`): emit the full structured changelog document to\n // stdout and exit, leaving every other mode and CHANGELOG.md untouched.\n if (options.changelogJson) {\n const document = buildChangelogDocument(buildGenerationOptions(options, items));\n process.stdout.write(JSON.stringify(document, null, 2) + \"\\n\");\n return;\n }\n\n // OPT-IN (`--suggest-semver`) without `--changelog-json`: emit only the\n // semver analysis as JSON to stdout and exit. Never writes CHANGELOG.md and\n // never touches default markdown.\n if (options.suggestSemver) {\n const suggestion = suggestSemver(buildGenerationOptions(options, items));\n process.stdout.write(JSON.stringify(suggestion, null, 2) + \"\\n\");\n return;\n }\n\n if (!options.stdout) {\n const result = writeChangelog({\n ...buildGenerationOptions(options, items),\n output: outputPath,\n mode: options.mode,\n check: options.check,\n });\n const summary = buildSummary(options, result, outputPath);\n\n if (options.githubOutput) writeGitHubOutput(summary);\n if (options.githubStepSummary) writeGitHubStepSummary(result.markdown);\n if (options.json) {\n process.stdout.write(JSON.stringify(summary) + \"\\n\");\n } else if (options.check) {\n console.error(result.changed ? `Changelog is out of date: ${outputPath}` : `Changelog is up to date: ${outputPath}`);\n } else {\n console.error(`Wrote ${outputPath}`);\n }\n\n if (options.check && result.changed) process.exit(1);\n return;\n }\n\n const generated = createChangelog(buildGenerationOptions(options, items));\n const existing = options.mode === \"prepend\" && existsSync(outputPath)\n ? readFileSync(outputPath, \"utf-8\")\n : undefined;\n const merged = options.mode === \"prepend\"\n ? mergeChangelog(existing, generated.markdown, { title: options.title })\n : { markdown: generated.markdown, action: \"replaced\" as const, changed: true };\n\n if (options.stdout) {\n if (options.json) {\n const summary = buildSummary(options, {\n output: outputPath,\n markdown: merged.markdown,\n action: merged.action,\n changed: merged.changed,\n itemCount: generated.itemCount,\n bytes: Buffer.byteLength(merged.markdown, \"utf-8\"),\n });\n if (options.githubOutput) writeGitHubOutput(summary);\n if (options.githubStepSummary) writeGitHubStepSummary(merged.markdown);\n process.stdout.write(JSON.stringify(summary) + \"\\n\");\n return;\n }\n if (options.githubStepSummary) writeGitHubStepSummary(merged.markdown);\n process.stdout.write(merged.markdown);\n return;\n }\n\n}\n\nfunction parseArgs(args: string[]): CliOptions {\n const options: CliOptions = {\n output: \"CHANGELOG.md\",\n stdout: false,\n json: false,\n stdin: false,\n pmArgs: [],\n groupBy: \"version\",\n sectionBy: \"category\",\n conventional: false,\n contributors: false,\n breakingChanges: false,\n suggestSemver: false,\n emojiPrefix: false,\n changelogJson: false,\n includeEmpty: false,\n includeLinks: false,\n mode: \"replace\",\n check: false,\n githubOutput: false,\n githubStepSummary: false,\n versionFromPackage: false,\n sincePreviousTag: false,\n untilReleaseTag: false,\n allReleaseTags: false,\n releaseTagPattern: \"v*\",\n };\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n switch (arg) {\n case \"--help\":\n case \"-h\":\n printHelp();\n process.exit(0);\n case \"--output\":\n case \"-o\":\n options.output = requireValue(args, ++i, arg);\n break;\n case \"--stdout\":\n options.stdout = true;\n break;\n case \"--json\":\n options.json = true;\n break;\n case \"--check\":\n options.check = true;\n break;\n case \"--github-output\":\n case \"--set-output\":\n options.githubOutput = true;\n break;\n case \"--github-step-summary\":\n options.githubStepSummary = true;\n break;\n case \"--input\":\n case \"-i\":\n options.input = requireValue(args, ++i, arg);\n break;\n case \"--stdin\":\n options.stdin = true;\n break;\n case \"--pm-root\":\n options.pmRoot = requireValue(args, ++i, arg);\n break;\n case \"--pm-bin\":\n options.pmBin = requireValue(args, ++i, arg);\n break;\n case \"--pm-arg\":\n options.pmArgs.push(requireAnyValue(args, ++i, arg));\n break;\n case \"--pm-cwd\":\n options.pmCwd = requireValue(args, ++i, arg);\n break;\n case \"--title\":\n options.title = requireValue(args, ++i, arg);\n break;\n case \"--version\":\n options.version = requireValue(args, ++i, arg);\n break;\n case \"--release-version-from-package\":\n options.versionFromPackage = true;\n break;\n case \"--date\":\n options.date = requireValue(args, ++i, arg);\n break;\n case \"--since\":\n options.since = requireValue(args, ++i, arg);\n break;\n case \"--since-previous-tag\":\n options.sincePreviousTag = true;\n break;\n case \"--until\":\n options.until = requireValue(args, ++i, arg);\n break;\n case \"--until-release-tag\":\n options.untilReleaseTag = true;\n break;\n case \"--all-release-tags\":\n options.allReleaseTags = true;\n break;\n case \"--release-tag-pattern\":\n options.releaseTagPattern = requireValue(args, ++i, arg);\n break;\n case \"--status\":\n case \"--statuses\":\n options.statuses = requireValue(args, ++i, arg)\n .split(\",\")\n .map((status) => status.trim())\n .filter(Boolean);\n break;\n case \"--group-by\":\n options.groupBy = parseGroupBy(requireValue(args, ++i, arg));\n break;\n case \"--section-by\":\n options.sectionBy = parseSectionBy(requireValue(args, ++i, arg));\n break;\n case \"--conventional\":\n options.conventional = true;\n break;\n case \"--contributors\":\n options.contributors = true;\n break;\n case \"--breaking-changes\":\n options.breakingChanges = true;\n break;\n case \"--suggest-semver\":\n options.suggestSemver = true;\n break;\n case \"--body-preview\":\n options.bodyPreview = parseBodyPreview(requireValue(args, ++i, arg));\n break;\n case \"--emoji-prefix\":\n options.emojiPrefix = true;\n break;\n case \"--changelog-json\":\n options.changelogJson = true;\n break;\n case \"--limit\":\n options.limit = parseLimit(requireValue(args, ++i, arg));\n break;\n case \"--since-version\":\n options.sinceVersion = requireValue(args, ++i, arg);\n break;\n case \"--mode\":\n options.mode = parseMode(requireValue(args, ++i, arg));\n break;\n case \"--include-empty\":\n options.includeEmpty = true;\n break;\n case \"--include-links\":\n options.includeLinks = true;\n break;\n case \"--no-links\":\n options.includeLinks = false;\n break;\n case \"--item-url-base\":\n options.itemUrlBase = requireValue(args, ++i, arg);\n break;\n default:\n throw new Error(`Unknown option: ${arg}`);\n }\n }\n\n return options;\n}\n\nfunction applyReleaseContext(options: CliOptions): void {\n if (options.allReleaseTags) {\n const cwd = options.pmCwd ? resolve(options.pmCwd) : process.cwd();\n if (options.versionFromPackage && !options.version) {\n const context = resolveReleaseContext({\n cwd,\n versionFromPackage: true,\n });\n options.version = context.version;\n }\n options.releaseWindows = resolveReleaseTagWindows({\n cwd,\n tagPattern: options.releaseTagPattern,\n pendingVersion: options.version,\n pendingTimestamp: options.until ?? options.date,\n });\n return;\n }\n\n if (!options.version && !options.versionFromPackage && !options.sincePreviousTag && !options.untilReleaseTag) return;\n const context = resolveReleaseContext({\n cwd: options.pmCwd ? resolve(options.pmCwd) : process.cwd(),\n version: options.version,\n versionFromPackage: options.versionFromPackage,\n since: options.since,\n sincePreviousTag: options.sincePreviousTag,\n until: options.until,\n untilReleaseTag: options.untilReleaseTag,\n });\n options.version = context.version;\n options.date = options.date ?? context.date;\n options.since = context.since;\n options.until = context.until;\n}\n\nasync function loadItems(options: CliOptions): Promise<PmItem[]> {\n if (options.stdin) {\n return parsePmItemsJson(await readStdin());\n }\n\n if (options.input) {\n return parsePmItemsJson(readFileSync(resolve(options.input), \"utf-8\"));\n }\n\n return readPmItems({\n pmRoot: options.pmRoot,\n pmBin: options.pmBin,\n pmArgs: options.pmArgs,\n cwd: options.pmCwd ? resolve(options.pmCwd) : undefined,\n });\n}\n\nfunction readStdin(): Promise<string> {\n return new Promise((resolvePromise, reject) => {\n let data = \"\";\n stdin.setEncoding(\"utf-8\");\n stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n stdin.on(\"end\", () => resolvePromise(data));\n stdin.on(\"error\", reject);\n });\n}\n\nfunction parseGroupBy(value: string): ChangelogGroupBy {\n if (value === \"version\" || value === \"release\" || value === \"milestone\") return value;\n throw new Error(\"--group-by must be 'version', 'release', or 'milestone'\");\n}\n\nfunction parseSectionBy(value: string): ChangelogSectionBy {\n if (value === \"category\" || value === \"type\" || value === \"status\" || value === \"label\") return value;\n throw new Error(\"--section-by must be 'category', 'type', 'status', or 'label'\");\n}\n\nfunction parseLimit(value: string): number {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new Error(\"--limit must be a positive integer\");\n }\n return parsed;\n}\n\nfunction parseBodyPreview(value: string): number {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new Error(\"--body-preview must be a positive integer\");\n }\n return parsed;\n}\n\nfunction parseMode(value: string): \"replace\" | \"prepend\" {\n if (value === \"replace\" || value === \"prepend\") return value;\n throw new Error(\"--mode must be 'replace' or 'prepend'\");\n}\n\nfunction buildGenerationOptions(options: CliOptions, items: PmItem[]) {\n return {\n items,\n title: options.title,\n version: options.version,\n date: options.date,\n since: options.since,\n until: options.until,\n releaseWindows: options.releaseWindows,\n includeStatuses: options.statuses,\n groupBy: options.groupBy,\n sectionBy: options.sectionBy,\n conventional: options.conventional,\n contributors: options.contributors,\n limit: options.limit,\n sinceVersion: options.sinceVersion,\n breakingChanges: options.breakingChanges,\n bodyPreview: options.bodyPreview,\n emojiPrefix: options.emojiPrefix,\n suggestSemver: options.suggestSemver,\n includeEmpty: options.includeEmpty,\n includeLinks: options.includeLinks,\n itemUrlBase: options.itemUrlBase,\n };\n}\n\nfunction buildSummary(\n options: CliOptions,\n result: {\n output?: string;\n action: string;\n changed: boolean;\n markdown: string;\n itemCount: number;\n bytes: number;\n },\n output = result.output\n): Record<string, unknown> {\n return {\n output,\n mode: options.mode,\n action: result.action,\n changed: result.changed,\n itemCount: result.itemCount,\n bytes: result.bytes,\n check: options.check,\n markdown: options.stdout ? result.markdown : undefined,\n };\n}\n\nfunction writeGitHubOutput(summary: Record<string, unknown>): void {\n const githubOutput = process.env.GITHUB_OUTPUT;\n if (!githubOutput) {\n throw new Error(\"--github-output requires the GITHUB_OUTPUT environment variable\");\n }\n\n const lines = [\n `output=${String(summary.output ?? \"\")}`,\n `mode=${String(summary.mode ?? \"\")}`,\n `action=${String(summary.action ?? \"\")}`,\n `changed=${String(summary.changed ?? \"\")}`,\n `item_count=${String(summary.itemCount ?? \"\")}`,\n `bytes=${String(summary.bytes ?? \"\")}`,\n ];\n appendFileSync(githubOutput, `${lines.join(\"\\n\")}\\n`, \"utf-8\");\n}\n\nfunction writeGitHubStepSummary(markdown: string): void {\n const githubStepSummary = process.env.GITHUB_STEP_SUMMARY;\n if (!githubStepSummary) {\n throw new Error(\"--github-step-summary requires the GITHUB_STEP_SUMMARY environment variable\");\n }\n\n appendFileSync(githubStepSummary, `${markdown.trimEnd()}\\n`, \"utf-8\");\n}\n\nfunction requireValue(args: string[], index: number, flag: string): string {\n const value = args[index];\n if (!value || value.startsWith(\"--\")) {\n throw new Error(`${flag} requires a value`);\n }\n return value;\n}\n\nfunction requireAnyValue(args: string[], index: number, flag: string): string {\n const value = args[index];\n if (!value) {\n throw new Error(`${flag} requires a value`);\n }\n return value;\n}\n\nfunction printHelp(): void {\n process.stdout.write(`pm-changelog\n\nGenerate CHANGELOG.md from pm-cli items.\n\nUsage:\n pm-changelog [options]\n\nOptions:\n -o, --output <file> Write changelog to a file (default: CHANGELOG.md)\n --stdout Print markdown instead of writing a file\n --json Print a JSON summary for CI/runners\n --check Do not write; exit 1 when output would change\n --github-output Write summary fields to $GITHUB_OUTPUT\n --github-step-summary Append generated markdown to $GITHUB_STEP_SUMMARY\n -i, --input <file> Read pm JSON from a file instead of running pm\n --stdin Read pm JSON from stdin\n --pm-root <dir> pm project root for \"pm --path <dir> list-all --json\"\n --pm-bin <file> pm executable to run (default: pm)\n --pm-arg <arg> Extra argument passed before \"list-all --json\" (repeatable)\n --pm-cwd <dir> Working directory for running pm\n --title <text> Changelog title (default: Changelog)\n --version <version> Version heading (default: Unreleased)\n --release-version-from-package\n Read version heading from nearest package.json\n --date <date> Release date (default: resolved tag date when available, otherwise today)\n --since <date> Include items changed on or after this date\n --since-previous-tag Derive --since from the previous git tag\n --until <date> Include items changed on or before this date\n --until-release-tag Derive --until from the current release tag when it exists\n --all-release-tags Rebuild full history from git release tag windows\n --release-tag-pattern <glob>\n Git tag glob for --all-release-tags (default: v*)\n --status <list> Comma-separated statuses (default: closed)\n --group-by <mode> version, release, or milestone (default: version)\n --section-by <mode> Within-release grouping: category, type, status, or label (default: category)\n --conventional Use Conventional-Commits headings (Features/Bug Fixes/...) for category grouping\n --contributors Append a Contributors list per release from item assignee/author\n --limit <n> Keep only the most recent N release sections (history modes only)\n --since-version <v> Keep only releases at or newer than version <v> (history modes only)\n --breaking-changes Emit a Breaking Changes section listing items detected as breaking\n --suggest-semver Print a suggested semver bump (major/minor/patch) as JSON; never writes the changelog\n --body-preview <n> Append the first N chars of each item body to its entry\n --emoji-prefix Prefix section headings with conventional emoji (Added 🎉, Fixed 🐛, ...)\n --changelog-json Print the full structured changelog document (releases->sections->items) to stdout\n --mode <mode> replace or prepend existing changelog (default: replace)\n --include-empty Emit an empty release section when no items match\n --include-links Include item URLs in generated entries (default: false)\n --item-url-base <url> Make item IDs clickable links: [pmc-abc]({url}/pmc-abc.toon)\n`);\n}\n\nmain().catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exit(1);\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":";;;;;AASA,wBA8MG"}
1
+ {"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":";;;;;AASA,wBA6RG"}
package/dist/extension.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { writeFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
3
  import { defineExtension, listAllFrontMatter, EXIT_CODE, PmCliError } from "@unbrained/pm-cli/sdk";
4
- import { createChangelog, mergeChangelog, writeChangelog } from "./generator.js";
4
+ import { buildChangelogDocument, createChangelog, mergeChangelog, suggestSemver, writeChangelog } from "./generator.js";
5
5
  import { resolveReleaseContext, resolveReleaseTagWindows } from "./release-context.js";
6
6
  export default defineExtension({
7
7
  name: "pm-changelog",
8
- version: "2026.6.2",
8
+ version: "2026.6.4",
9
9
  activate(api) {
10
10
  api.registerCommand({
11
11
  name: "changelog generate",
@@ -36,6 +36,16 @@ export default defineExtension({
36
36
  { long: "--release-tag-pattern", value_name: "glob", description: "Git tag glob for --all-release-tags (default: v*)" },
37
37
  { long: "--status", value_name: "list", description: "Comma-separated statuses (default: closed)" },
38
38
  { long: "--group-by", value_name: "mode", description: "version, release, or milestone (default: version)" },
39
+ { long: "--section-by", value_name: "mode", description: "Within-release grouping: category, type, status, or label (default: category)" },
40
+ { long: "--conventional", description: "Use Conventional-Commits headings (Features/Bug Fixes/...) for category grouping" },
41
+ { long: "--contributors", description: "Append a Contributors list per release from item assignee/author" },
42
+ { long: "--limit", value_name: "n", description: "Keep only the most recent N release sections (history modes only)" },
43
+ { long: "--since-version", value_name: "version", description: "Keep only releases at or newer than this version (history modes only)" },
44
+ { long: "--breaking-changes", description: "Emit a Breaking Changes section listing items detected as breaking" },
45
+ { long: "--suggest-semver", description: "Return a suggested semver bump (major/minor/patch); never writes the changelog" },
46
+ { long: "--body-preview", value_name: "n", description: "Append the first N chars of each item body to its entry" },
47
+ { long: "--emoji-prefix", description: "Prefix section headings with conventional emoji (Added 🎉, Fixed 🐛, ...)" },
48
+ { long: "--changelog-json", description: "Return the full structured changelog document (releases->sections->items)" },
39
49
  { long: "--mode", value_name: "mode", description: "replace or prepend existing changelog (default: replace)" },
40
50
  { long: "--include-empty", description: "Emit an empty release section when no items match" },
41
51
  { long: "--include-links", description: "Include item URLs in generated entries (default: false)" },
@@ -57,7 +67,13 @@ export default defineExtension({
57
67
  if (modeOption !== "replace" && modeOption !== "prepend") {
58
68
  throw new PmCliError("--mode must be 'replace' or 'prepend'", EXIT_CODE.USAGE);
59
69
  }
70
+ const sectionByOption = stringOption(ctx.options, "section-by", "sectionBy") ?? "category";
71
+ if (sectionByOption !== "category" && sectionByOption !== "type" && sectionByOption !== "status" && sectionByOption !== "label") {
72
+ throw new PmCliError("--section-by must be 'category', 'type', 'status', or 'label'", EXIT_CODE.USAGE);
73
+ }
74
+ const limitValue = parseLimitOption(ctx.options);
60
75
  const groupBy = groupByOption;
76
+ const sectionBy = sectionByOption;
61
77
  const mode = modeOption;
62
78
  const statuses = ctx.options["status"]
63
79
  ?.split(",")
@@ -99,10 +115,30 @@ export default defineExtension({
99
115
  releaseWindows,
100
116
  includeStatuses: statuses,
101
117
  groupBy,
118
+ sectionBy,
119
+ conventional: booleanOption(ctx.options, "conventional", "conventional"),
120
+ contributors: booleanOption(ctx.options, "contributors", "contributors"),
121
+ limit: limitValue,
122
+ sinceVersion: stringOption(ctx.options, "since-version", "sinceVersion"),
123
+ breakingChanges: booleanOption(ctx.options, "breaking-changes", "breakingChanges"),
124
+ bodyPreview: parseBodyPreviewOption(ctx.options),
125
+ emojiPrefix: booleanOption(ctx.options, "emoji-prefix", "emojiPrefix"),
126
+ suggestSemver: booleanOption(ctx.options, "suggest-semver", "suggestSemver"),
102
127
  includeEmpty: booleanOption(ctx.options, "include-empty", "includeEmpty"),
103
128
  includeLinks: booleanOption(ctx.options, "include-links", "includeLinks"),
104
129
  itemUrlBase: stringOption(ctx.options, "item-url-base", "itemUrlBase"),
105
130
  };
131
+ // OPT-IN (`--changelog-json`): structured document; never writes a file.
132
+ if (booleanOption(ctx.options, "changelog-json", "changelogJson")) {
133
+ const document = buildChangelogDocument(generationOptions);
134
+ return { document, format: "json", item_count: document.item_count };
135
+ }
136
+ // OPT-IN (`--suggest-semver`) standalone: emit only the semver analysis;
137
+ // never writes a file and never alters default markdown.
138
+ if (booleanOption(ctx.options, "suggest-semver", "suggestSemver")) {
139
+ const suggestion = suggestSemver(generationOptions);
140
+ return { suggested_semver: suggestion, format: "json" };
141
+ }
106
142
  const generated = createChangelog(generationOptions);
107
143
  if (stdout) {
108
144
  const merged = mode === "prepend"
@@ -141,8 +177,40 @@ export default defineExtension({
141
177
  // --release-notes concise mode. Does NOT write CHANGELOG.md unless --output
142
178
  // is given, so it is side-effect free by default.
143
179
  // -----------------------------------------------------------------------
144
- api.registerExporter("changelog", async (ctx) => {
180
+ const changelogExportMetadata = {
181
+ description: "Export changelog or release notes through the pm import/export pipeline.",
182
+ intent: "export changelog release notes as markdown or json",
183
+ examples: [
184
+ "pm changelog export",
185
+ "pm changelog export --format json",
186
+ "pm changelog export --release-notes --since-previous-tag --until-release-tag",
187
+ "pm changelog export --output RELEASE_NOTES.md --release-version-from-package",
188
+ ],
189
+ flags: [
190
+ { long: "--format", value_name: "md|json", description: "Export format (default: md)" },
191
+ { long: "--output", value_name: "file", description: "Write output to a file instead of stdout" },
192
+ { long: "--release-notes", description: "Use a concise release-notes title and output shape" },
193
+ { long: "--title", value_name: "text", description: "Output title (default: Changelog or Release Notes)" },
194
+ { long: "--release-version", value_name: "version", description: "Release/version heading (default: Unreleased)" },
195
+ { long: "--release-version-from-package", description: "Read release/version heading from nearest package.json" },
196
+ { long: "--date", value_name: "date", description: "Release date (default: resolved tag date when available, otherwise today)" },
197
+ { long: "--since", value_name: "date", description: "Include items changed on or after this date" },
198
+ { long: "--since-previous-tag", description: "Derive --since from the previous git tag" },
199
+ { long: "--until", value_name: "date", description: "Include items changed on or before this date" },
200
+ { long: "--until-release-tag", description: "Derive --until from the current release tag when it exists" },
201
+ { long: "--status", value_name: "list", description: "Comma-separated statuses (default: closed)" },
202
+ { long: "--group-by", value_name: "mode", description: "version, release, or milestone (default: version)" },
203
+ { long: "--include-empty", description: "Emit an empty release section when no items match" },
204
+ { long: "--include-links", description: "Include item URLs in generated entries (default: false)" },
205
+ { long: "--item-url-base", value_name: "url", description: "Make item IDs clickable links to .toon files under the base URL" },
206
+ ],
207
+ };
208
+ const registerExporterWithMetadata = api.registerExporter;
209
+ registerExporterWithMetadata("changelog", async (ctx) => {
145
210
  const format = (stringOption(ctx.options, "format", "format") ?? "md").toLowerCase();
211
+ if (format !== "md" && format !== "json") {
212
+ throw new PmCliError("--format must be 'md' or 'json'", EXIT_CODE.USAGE);
213
+ }
146
214
  const groupByOption = stringOption(ctx.options, "group-by", "groupBy") ?? "version";
147
215
  if (groupByOption !== "version" && groupByOption !== "release" && groupByOption !== "milestone") {
148
216
  throw new PmCliError("--group-by must be 'version', 'release', or 'milestone'", EXIT_CODE.USAGE);
@@ -195,7 +263,10 @@ export default defineExtension({
195
263
  return { file: outputPath, format: "markdown", item_count: generated.itemCount };
196
264
  }
197
265
  return { changelog: generated.markdown, format: "markdown", item_count: generated.itemCount };
198
- });
266
+ }, changelogExportMetadata);
267
+ if (api.registerExporter.length < 3 && typeof api.registerFlags === "function") {
268
+ api.registerFlags("changelog export", changelogExportMetadata.flags);
269
+ }
199
270
  },
200
271
  });
201
272
  function stringOption(options, kebabKey, camelKey) {
@@ -205,4 +276,24 @@ function stringOption(options, kebabKey, camelKey) {
205
276
  function booleanOption(options, kebabKey, camelKey) {
206
277
  return Boolean(options[kebabKey] ?? options[camelKey]);
207
278
  }
279
+ function parseLimitOption(options) {
280
+ const raw = options["limit"];
281
+ if (raw === undefined || raw === null || raw === "")
282
+ return undefined;
283
+ const parsed = typeof raw === "number" ? raw : Number.parseInt(String(raw), 10);
284
+ if (!Number.isInteger(parsed) || parsed < 1) {
285
+ throw new PmCliError("--limit must be a positive integer", EXIT_CODE.USAGE);
286
+ }
287
+ return parsed;
288
+ }
289
+ function parseBodyPreviewOption(options) {
290
+ const raw = options["body-preview"] ?? options["bodyPreview"];
291
+ if (raw === undefined || raw === null || raw === "")
292
+ return undefined;
293
+ const parsed = typeof raw === "number" ? raw : Number.parseInt(String(raw), 10);
294
+ if (!Number.isInteger(parsed) || parsed < 1) {
295
+ throw new PmCliError("--body-preview must be a positive integer", EXIT_CODE.USAGE);
296
+ }
297
+ return parsed;
298
+ }
208
299
  //# sourceMappingURL=extension.js.map