@unbrained/pm-cli 2026.5.24 → 2026.5.27

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 (238) hide show
  1. package/CHANGELOG.md +946 -525
  2. package/README.md +2 -10
  3. package/dist/cli/bootstrap-args.d.ts +18 -1
  4. package/dist/cli/bootstrap-args.js +143 -3
  5. package/dist/cli/bootstrap-args.js.map +1 -1
  6. package/dist/cli/commander-usage.js +134 -11
  7. package/dist/cli/commander-usage.js.map +1 -1
  8. package/dist/cli/commands/append.js +4 -3
  9. package/dist/cli/commands/append.js.map +1 -1
  10. package/dist/cli/commands/claim.js +5 -4
  11. package/dist/cli/commands/claim.js.map +1 -1
  12. package/dist/cli/commands/close.js +4 -3
  13. package/dist/cli/commands/close.js.map +1 -1
  14. package/dist/cli/commands/completion.d.ts +2 -2
  15. package/dist/cli/commands/completion.js +109 -56
  16. package/dist/cli/commands/completion.js.map +1 -1
  17. package/dist/cli/commands/config.d.ts +1 -1
  18. package/dist/cli/commands/config.js +82 -4
  19. package/dist/cli/commands/config.js.map +1 -1
  20. package/dist/cli/commands/create.js +7 -272
  21. package/dist/cli/commands/create.js.map +1 -1
  22. package/dist/cli/commands/delete.js +4 -3
  23. package/dist/cli/commands/delete.js.map +1 -1
  24. package/dist/cli/commands/docs.d.ts +1 -12
  25. package/dist/cli/commands/docs.js +8 -312
  26. package/dist/cli/commands/docs.js.map +1 -1
  27. package/dist/cli/commands/extension/bundled-catalog.d.ts +14 -0
  28. package/dist/cli/commands/extension/bundled-catalog.js +268 -0
  29. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -0
  30. package/dist/cli/commands/extension/doctor.d.ts +31 -0
  31. package/dist/cli/commands/extension/doctor.js +345 -0
  32. package/dist/cli/commands/extension/doctor.js.map +1 -0
  33. package/dist/cli/commands/extension/install-sources.d.ts +37 -0
  34. package/dist/cli/commands/extension/install-sources.js +384 -0
  35. package/dist/cli/commands/extension/install-sources.js.map +1 -0
  36. package/dist/cli/commands/extension/managed-state.d.ts +48 -0
  37. package/dist/cli/commands/extension/managed-state.js +172 -0
  38. package/dist/cli/commands/extension/managed-state.js.map +1 -0
  39. package/dist/cli/commands/extension/scaffold.d.ts +14 -0
  40. package/dist/cli/commands/extension/scaffold.js +169 -0
  41. package/dist/cli/commands/extension/scaffold.js.map +1 -0
  42. package/dist/cli/commands/extension/shared.d.ts +14 -0
  43. package/dist/cli/commands/extension/shared.js +106 -0
  44. package/dist/cli/commands/extension/shared.js.map +1 -0
  45. package/dist/cli/commands/extension.d.ts +36 -68
  46. package/dist/cli/commands/extension.js +143 -1422
  47. package/dist/cli/commands/extension.js.map +1 -1
  48. package/dist/cli/commands/files.d.ts +1 -12
  49. package/dist/cli/commands/files.js +11 -308
  50. package/dist/cli/commands/files.js.map +1 -1
  51. package/dist/cli/commands/get.js +4 -3
  52. package/dist/cli/commands/get.js.map +1 -1
  53. package/dist/cli/commands/health.js +17 -3
  54. package/dist/cli/commands/health.js.map +1 -1
  55. package/dist/cli/commands/history-redact.js +23 -18
  56. package/dist/cli/commands/history-redact.js.map +1 -1
  57. package/dist/cli/commands/history-repair.js +24 -18
  58. package/dist/cli/commands/history-repair.js.map +1 -1
  59. package/dist/cli/commands/legacy-none-tokens.d.ts +3 -0
  60. package/dist/cli/commands/legacy-none-tokens.js +39 -0
  61. package/dist/cli/commands/legacy-none-tokens.js.map +1 -0
  62. package/dist/cli/commands/linked-artifacts.d.ts +96 -0
  63. package/dist/cli/commands/linked-artifacts.js +335 -0
  64. package/dist/cli/commands/linked-artifacts.js.map +1 -0
  65. package/dist/cli/commands/linked-test-parsers.d.ts +28 -0
  66. package/dist/cli/commands/linked-test-parsers.js +192 -0
  67. package/dist/cli/commands/linked-test-parsers.js.map +1 -0
  68. package/dist/cli/commands/list.js +19 -4
  69. package/dist/cli/commands/list.js.map +1 -1
  70. package/dist/cli/commands/normalize.js +4 -3
  71. package/dist/cli/commands/normalize.js.map +1 -1
  72. package/dist/cli/commands/recurrence-parsers.d.ts +26 -0
  73. package/dist/cli/commands/recurrence-parsers.js +98 -0
  74. package/dist/cli/commands/recurrence-parsers.js.map +1 -0
  75. package/dist/cli/commands/restore.js +19 -8
  76. package/dist/cli/commands/restore.js.map +1 -1
  77. package/dist/cli/commands/search.js +5 -4
  78. package/dist/cli/commands/search.js.map +1 -1
  79. package/dist/cli/commands/test/linked-command-detection.d.ts +37 -0
  80. package/dist/cli/commands/test/linked-command-detection.js +200 -0
  81. package/dist/cli/commands/test/linked-command-detection.js.map +1 -0
  82. package/dist/cli/commands/test.d.ts +1 -2
  83. package/dist/cli/commands/test.js +7 -349
  84. package/dist/cli/commands/test.js.map +1 -1
  85. package/dist/cli/commands/update-many.js +4 -3
  86. package/dist/cli/commands/update-many.js.map +1 -1
  87. package/dist/cli/commands/update.js +62 -354
  88. package/dist/cli/commands/update.js.map +1 -1
  89. package/dist/cli/error-guidance.d.ts +1 -0
  90. package/dist/cli/error-guidance.js +6 -2
  91. package/dist/cli/error-guidance.js.map +1 -1
  92. package/dist/cli/main.d.ts +11 -0
  93. package/dist/cli/main.js +76 -28
  94. package/dist/cli/main.js.map +1 -1
  95. package/dist/cli/register-list-query.d.ts +4 -1
  96. package/dist/cli/register-list-query.js +242 -203
  97. package/dist/cli/register-list-query.js.map +1 -1
  98. package/dist/cli/register-mutation.js +24 -9
  99. package/dist/cli/register-mutation.js.map +1 -1
  100. package/dist/cli/register-operations.js +3 -3
  101. package/dist/cli/register-operations.js.map +1 -1
  102. package/dist/cli/register-setup.js +12 -7
  103. package/dist/cli/register-setup.js.map +1 -1
  104. package/dist/cli/registration-helpers.js +3 -2
  105. package/dist/cli/registration-helpers.js.map +1 -1
  106. package/dist/cli.js +4 -3
  107. package/dist/cli.js.map +1 -1
  108. package/dist/core/config/positional-value.d.ts +44 -0
  109. package/dist/core/config/positional-value.js +109 -0
  110. package/dist/core/config/positional-value.js.map +1 -0
  111. package/dist/core/extensions/extension-capability-aliases.d.ts +14 -0
  112. package/dist/core/extensions/extension-capability-aliases.js +159 -0
  113. package/dist/core/extensions/extension-capability-aliases.js.map +1 -0
  114. package/dist/core/extensions/extension-hook-runtime.d.ts +13 -0
  115. package/dist/core/extensions/extension-hook-runtime.js +414 -0
  116. package/dist/core/extensions/extension-hook-runtime.js.map +1 -0
  117. package/dist/core/extensions/extension-policy.d.ts +69 -0
  118. package/dist/core/extensions/extension-policy.js +481 -0
  119. package/dist/core/extensions/extension-policy.js.map +1 -0
  120. package/dist/core/extensions/extension-registries.d.ts +8 -0
  121. package/dist/core/extensions/extension-registries.js +52 -0
  122. package/dist/core/extensions/extension-registries.js.map +1 -0
  123. package/dist/core/extensions/extension-runtime-helpers.d.ts +6 -0
  124. package/dist/core/extensions/extension-runtime-helpers.js +29 -0
  125. package/dist/core/extensions/extension-runtime-helpers.js.map +1 -0
  126. package/dist/core/extensions/extension-types.d.ts +13 -39
  127. package/dist/core/extensions/extension-types.js +34 -2
  128. package/dist/core/extensions/extension-types.js.map +1 -1
  129. package/dist/core/extensions/index.d.ts +7 -0
  130. package/dist/core/extensions/index.js +11 -2
  131. package/dist/core/extensions/index.js.map +1 -1
  132. package/dist/core/extensions/loader.d.ts +4 -22
  133. package/dist/core/extensions/loader.js +22 -1139
  134. package/dist/core/extensions/loader.js.map +1 -1
  135. package/dist/core/history/drift-scan.d.ts +11 -0
  136. package/dist/core/history/drift-scan.js +114 -32
  137. package/dist/core/history/drift-scan.js.map +1 -1
  138. package/dist/core/history/history-rewrite.d.ts +43 -0
  139. package/dist/core/history/history-rewrite.js +48 -0
  140. package/dist/core/history/history-rewrite.js.map +1 -0
  141. package/dist/core/history/history.js +5 -4
  142. package/dist/core/history/history.js.map +1 -1
  143. package/dist/core/history/replay.js +4 -3
  144. package/dist/core/history/replay.js.map +1 -1
  145. package/dist/core/item/item-record.d.ts +19 -0
  146. package/dist/core/item/item-record.js +24 -0
  147. package/dist/core/item/item-record.js.map +1 -0
  148. package/dist/core/output/mutation-projection.d.ts +31 -0
  149. package/dist/core/output/mutation-projection.js +103 -0
  150. package/dist/core/output/mutation-projection.js.map +1 -0
  151. package/dist/core/output/output.d.ts +2 -0
  152. package/dist/core/output/output.js +5 -3
  153. package/dist/core/output/output.js.map +1 -1
  154. package/dist/core/schema/runtime-schema.js +8 -38
  155. package/dist/core/schema/runtime-schema.js.map +1 -1
  156. package/dist/core/search/vector-stores.js +46 -9
  157. package/dist/core/search/vector-stores.js.map +1 -1
  158. package/dist/core/sentry/helpers.d.ts +1 -1
  159. package/dist/core/sentry/helpers.js +20 -3
  160. package/dist/core/sentry/helpers.js.map +1 -1
  161. package/dist/core/shared/command-types.d.ts +1 -0
  162. package/dist/core/shared/command-types.js +2 -2
  163. package/dist/core/shared/command-types.js.map +1 -1
  164. package/dist/core/shared/constants.d.ts +10 -1
  165. package/dist/core/shared/constants.js +56 -58
  166. package/dist/core/shared/constants.js.map +1 -1
  167. package/dist/core/shared/primitives.d.ts +23 -0
  168. package/dist/core/shared/primitives.js +39 -2
  169. package/dist/core/shared/primitives.js.map +1 -1
  170. package/dist/core/store/front-matter-cache.d.ts +16 -2
  171. package/dist/core/store/front-matter-cache.js +99 -33
  172. package/dist/core/store/front-matter-cache.js.map +1 -1
  173. package/dist/core/store/item-store.js +8 -73
  174. package/dist/core/store/item-store.js.map +1 -1
  175. package/dist/mcp/server.js +76 -28
  176. package/dist/mcp/server.js.map +1 -1
  177. package/dist/sdk/cli-contracts/enum-contracts.d.ts +20 -0
  178. package/dist/sdk/cli-contracts/enum-contracts.js +156 -0
  179. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -0
  180. package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +14 -0
  181. package/dist/sdk/cli-contracts/tool-option-contracts.js +243 -0
  182. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -0
  183. package/dist/sdk/cli-contracts/tool-parameter-tables.d.ts +11 -0
  184. package/dist/sdk/cli-contracts/tool-parameter-tables.js +901 -0
  185. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -0
  186. package/dist/sdk/cli-contracts.d.ts +11 -33
  187. package/dist/sdk/cli-contracts.js +23 -1356
  188. package/dist/sdk/cli-contracts.js.map +1 -1
  189. package/dist/sdk/package-import-adapters.d.ts +74 -0
  190. package/dist/sdk/package-import-adapters.js +186 -0
  191. package/dist/sdk/package-import-adapters.js.map +1 -0
  192. package/dist/sdk/package-runtime-options.d.ts +26 -0
  193. package/dist/sdk/package-runtime-options.js +71 -0
  194. package/dist/sdk/package-runtime-options.js.map +1 -0
  195. package/dist/sdk/runtime.d.ts +2 -0
  196. package/dist/sdk/runtime.js +4 -2
  197. package/dist/sdk/runtime.js.map +1 -1
  198. package/docs/AGENT_GUIDE.md +6 -10
  199. package/docs/CLAUDE_CODE_PLUGIN.md +5 -28
  200. package/docs/CODEX_PLUGIN.md +5 -5
  201. package/docs/COMMANDS.md +19 -3
  202. package/docs/CONFIGURATION.md +15 -0
  203. package/docs/EXTENSIONS.md +4 -63
  204. package/docs/RELEASING.md +4 -4
  205. package/marketplace.json +7 -3
  206. package/package.json +9 -6
  207. package/packages/pm-beads/extensions/beads/index.js +2 -49
  208. package/packages/pm-beads/extensions/beads/index.ts +2 -54
  209. package/packages/pm-beads/extensions/beads/runtime-loader.js +86 -0
  210. package/packages/pm-beads/extensions/beads/runtime-loader.ts +88 -0
  211. package/packages/pm-beads/extensions/beads/runtime.js +26 -115
  212. package/packages/pm-beads/extensions/beads/runtime.ts +33 -132
  213. package/packages/pm-calendar/extensions/calendar/index.js +47 -2
  214. package/packages/pm-calendar/extensions/calendar/index.ts +52 -2
  215. package/packages/pm-calendar/extensions/calendar/runtime.js +1 -0
  216. package/packages/pm-calendar/extensions/calendar/runtime.ts +1 -0
  217. package/packages/pm-governance-audit/extensions/governance-audit/runtime.js +14 -41
  218. package/packages/pm-governance-audit/extensions/governance-audit/runtime.ts +25 -41
  219. package/packages/pm-guide-shell/extensions/guide-shell/runtime.js +10 -50
  220. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +17 -50
  221. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.js +8 -40
  222. package/packages/pm-linked-test-adapters/extensions/linked-test-adapters/runtime.ts +10 -40
  223. package/packages/pm-search-advanced/extensions/search-advanced/index.js +1 -1
  224. package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +4 -37
  225. package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +6 -37
  226. package/packages/pm-todos/extensions/todos/index.js +3 -50
  227. package/packages/pm-todos/extensions/todos/index.ts +3 -55
  228. package/packages/pm-todos/extensions/todos/runtime-loader.js +86 -0
  229. package/packages/pm-todos/extensions/todos/runtime-loader.ts +88 -0
  230. package/packages/pm-todos/extensions/todos/runtime.js +24 -117
  231. package/packages/pm-todos/extensions/todos/runtime.ts +32 -129
  232. package/plugins/pm-claude/README.md +2 -2
  233. package/plugins/pm-claude/commands/pm-planner.md +1 -15
  234. package/plugins/pm-claude/scripts/pm-mcp-server.mjs +5 -2
  235. package/plugins/pm-claude/skills/pm-planner/SKILL.md +3 -21
  236. package/plugins/pm-codex/scripts/pm-mcp-server.mjs +15 -6
  237. package/plugins/pm-codex/skills/pm-native/SKILL.md +1 -13
  238. package/PRD.md +0 -1734
@@ -1,8 +1,9 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="689e9580-d7f6-5b07-be3d-28c381d20260")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="94e19c77-3288-5a43-a8b2-6b9f15d4f234")}catch(e){}}();
3
3
  import { pathExists } from "../../core/fs/fs-utils.js";
4
4
  import { canonicalizeCommandOptionKey, commandOptionFlagLabel, resolveItemTypeRegistry, resolveCommandOptionPolicyState, resolveTypeDefinition, resolveTypeName, validateTypeOptions, } from "../../core/item/type-registry.js";
5
5
  import { normalizeItemId } from "../../core/item/id.js";
6
+ import { toItemRecord } from "../../core/item/item-record.js";
6
7
  import { buildInvalidTypeError } from "../../core/schema/item-types-file.js";
7
8
  import { normalizeParentReferenceValue, validateMissingParentReference, } from "../../core/item/parent-reference-policy.js";
8
9
  import { validateSprintOrReleaseValue } from "../../core/item/sprint-release-format.js";
@@ -22,9 +23,10 @@ import { readSettings } from "../../core/store/settings.js";
22
23
  import { runClose } from "./close.js";
23
24
  import { normalizeRiskInput, normalizeSeverityInput, parseConfidenceInput, parseRegressionInput, } from "./metadata-normalizers.js";
24
25
  import { resolveEventEndAt } from "./event-validation-messages.js";
25
- import { DEPENDENCY_KIND_VALUES, ISSUE_SEVERITY_VALUES, RECURRENCE_FREQUENCY_VALUES, RECURRENCE_WEEKDAY_VALUES, RISK_VALUES, weekdayOrderIndex, } from "../../types/index.js";
26
+ import { assertNoLegacyNoneToken, assertNoLegacyNoneTokens, isLegacyNoneToken } from "./legacy-none-tokens.js";
27
+ import { ensureEnumValue as ensureEnum, parseEventBoolean, parseRecurrenceRule } from "./recurrence-parsers.js";
28
+ import { DEPENDENCY_KIND_VALUES, ISSUE_SEVERITY_VALUES, RISK_VALUES, } from "../../types/index.js";
26
29
  import { parseDocs, parseFiles, parseLogSeed, parseTests } from "./create.js";
27
- const LEGACY_NONE_TOKENS = new Set(["none", "null"]);
28
30
  const UPDATE_UNSET_FIELD_DEFINITIONS = [
29
31
  { canonical: "tags", aliases: ["tags"], optionKey: "tags", frontMatterKey: "tags" },
30
32
  { canonical: "close-reason", aliases: ["close_reason", "close-reason"], optionKey: "closeReason", frontMatterKey: "close_reason" },
@@ -170,30 +172,6 @@ function toAuthor(candidate, defaultAuthor) {
170
172
  const trimmed = resolved.trim();
171
173
  return trimmed || "unknown";
172
174
  }
173
- function isLegacyNoneToken(value) {
174
- if (value === undefined) {
175
- return false;
176
- }
177
- return LEGACY_NONE_TOKENS.has(value.trim().toLowerCase());
178
- }
179
- function assertNoLegacyNoneToken(value, flag, replacementHint) {
180
- if (!isLegacyNoneToken(value)) {
181
- return;
182
- }
183
- const suffix = replacementHint ? ` ${replacementHint}` : "";
184
- throw new PmCliError(`${flag} no longer accepts "none" or "null".${suffix}`.trim(), EXIT_CODE.USAGE);
185
- }
186
- function assertNoLegacyNoneTokens(values, flag, replacementHint) {
187
- if (!values || values.length === 0) {
188
- return;
189
- }
190
- const hasLegacyToken = values.some((value) => isLegacyNoneToken(value));
191
- if (!hasLegacyToken) {
192
- return;
193
- }
194
- const suffix = replacementHint ? ` ${replacementHint}` : "";
195
- throw new PmCliError(`${flag} no longer accepts "none" or "null".${suffix}`.trim(), EXIT_CODE.USAGE);
196
- }
197
175
  const UPDATE_LEGACY_NONE_COLLECTION_NORMALIZERS = [
198
176
  { optionKey: "dep", clearFlagKey: "clearDeps", valueFlag: "--dep", clearFlag: "--clear-deps", disableReplaceFlagKey: "replaceDeps" },
199
177
  { optionKey: "comment", clearFlagKey: "clearComments", valueFlag: "--comment", clearFlag: "--clear-comments" },
@@ -481,12 +459,6 @@ function enforceAllowAuditUpdateScope(options, clearFrontMatterKeys) {
481
459
  throw new PmCliError(`--allow-audit-update only supports non-lifecycle metadata fields. Remove restricted options: ${disallowedFlags.join(", ")}`, EXIT_CODE.USAGE);
482
460
  }
483
461
  }
484
- function ensureEnum(value, allowed, label) {
485
- if (!allowed.includes(value)) {
486
- throw new PmCliError(`Invalid ${label} value "${value}". Allowed: ${allowed.join(", ")}`, EXIT_CODE.USAGE);
487
- }
488
- return value;
489
- }
490
462
  function parseStatus(value, statusRegistry) {
491
463
  const normalized = normalizeStatusInput(value, statusRegistry);
492
464
  if (!normalized) {
@@ -509,75 +481,6 @@ function parseReminderEntries(raw, nowValue) {
509
481
  };
510
482
  });
511
483
  }
512
- function parseEventBoolean(value, flag) {
513
- const normalized = value.trim().toLowerCase();
514
- if (normalized === "true" || normalized === "1" || normalized === "yes") {
515
- return true;
516
- }
517
- if (normalized === "false" || normalized === "0" || normalized === "no") {
518
- return false;
519
- }
520
- throw new PmCliError(`${flag} must be one of true|false|1|0|yes|no`, EXIT_CODE.USAGE);
521
- }
522
- function parseDelimitedList(raw) {
523
- if (!raw) {
524
- return [];
525
- }
526
- return raw
527
- .split("|")
528
- .map((value) => value.trim())
529
- .filter((value) => value.length > 0);
530
- }
531
- function parseRecurrenceRule(kv, startAt, nowValue) {
532
- const freqRaw = kv.recur_freq?.trim();
533
- const intervalRaw = kv.recur_interval?.trim();
534
- const countRaw = kv.recur_count?.trim();
535
- const untilRaw = kv.recur_until?.trim();
536
- const byWeekdayRaw = kv.recur_by_weekday?.trim();
537
- const byMonthDayRaw = kv.recur_by_month_day?.trim();
538
- const exdatesRaw = kv.recur_exdates?.trim();
539
- const recurrenceInputsProvided = [freqRaw, intervalRaw, countRaw, untilRaw, byWeekdayRaw, byMonthDayRaw, exdatesRaw].some((value) => value !== undefined);
540
- if (!recurrenceInputsProvided) {
541
- return undefined;
542
- }
543
- if (!freqRaw) {
544
- throw new PmCliError("--event recurrence fields require recur_freq=<daily|weekly|monthly|yearly>", EXIT_CODE.USAGE);
545
- }
546
- const freq = ensureEnum(freqRaw.toLowerCase(), RECURRENCE_FREQUENCY_VALUES, "event recurrence frequency");
547
- const interval = intervalRaw ? parseOptionalNumber(intervalRaw, "event recur_interval") : undefined;
548
- if (interval !== undefined && (!Number.isInteger(interval) || interval < 1)) {
549
- throw new PmCliError("--event recur_interval must be an integer >= 1", EXIT_CODE.USAGE);
550
- }
551
- const count = countRaw ? parseOptionalNumber(countRaw, "event recur_count") : undefined;
552
- if (count !== undefined && (!Number.isInteger(count) || count < 1)) {
553
- throw new PmCliError("--event recur_count must be an integer >= 1", EXIT_CODE.USAGE);
554
- }
555
- const until = untilRaw ? resolveIsoOrRelative(untilRaw, nowValue, "event.recur_until") : undefined;
556
- if (until && until < startAt) {
557
- throw new PmCliError("--event recur_until must be at or after start", EXIT_CODE.USAGE);
558
- }
559
- const byWeekday = Array.from(new Set(parseDelimitedList(byWeekdayRaw)
560
- .map((value) => ensureEnum(value.toLowerCase(), RECURRENCE_WEEKDAY_VALUES, "event weekday")))).sort((left, right) => weekdayOrderIndex(left) -
561
- weekdayOrderIndex(right));
562
- const byMonthDay = Array.from(new Set(parseDelimitedList(byMonthDayRaw)
563
- .map((value) => {
564
- const day = parseOptionalNumber(value, "event recur_by_month_day");
565
- if (!Number.isInteger(day) || day < 1 || day > 31) {
566
- throw new PmCliError("--event recur_by_month_day values must be integers 1..31", EXIT_CODE.USAGE);
567
- }
568
- return day;
569
- }))).sort((left, right) => left - right);
570
- const exdates = Array.from(new Set(parseDelimitedList(exdatesRaw).map((value) => resolveIsoOrRelative(value, nowValue, "event.recur_exdates")))).sort((left, right) => left.localeCompare(right));
571
- return {
572
- freq,
573
- interval,
574
- count,
575
- until,
576
- by_weekday: byWeekday.length > 0 ? byWeekday : undefined,
577
- by_month_day: byMonthDay.length > 0 ? byMonthDay : undefined,
578
- exdates: exdates.length > 0 ? exdates : undefined,
579
- };
580
- }
581
484
  function parseEventEntries(raw, nowValue) {
582
485
  return raw.map((entry) => {
583
486
  const kv = parseCsvKv(entry, "--event");
@@ -610,7 +513,7 @@ function parseEventEntries(raw, nowValue) {
610
513
  throw new PmCliError("--event timezone must not be empty", EXIT_CODE.USAGE);
611
514
  }
612
515
  const allDayRaw = kv.all_day?.trim();
613
- const recurrence = parseRecurrenceRule(kv, startAt, nowValue);
516
+ const recurrence = parseRecurrenceRule(kv, startAt, nowValue, "truthy");
614
517
  return {
615
518
  start_at: startAt,
616
519
  end_at: endAt,
@@ -1268,7 +1171,7 @@ export async function runUpdate(id, options, global) {
1268
1171
  }
1269
1172
  const { document } = await readLocatedItem(located, { schema: settings.schema });
1270
1173
  return {
1271
- item: document.metadata,
1174
+ item: toItemRecord(document.metadata),
1272
1175
  changed_fields: [],
1273
1176
  warnings: ["noop_no_update_fields"],
1274
1177
  };
@@ -1329,6 +1232,27 @@ export async function runUpdate(id, options, global) {
1329
1232
  const changedFields = [];
1330
1233
  const warnings = [];
1331
1234
  let activeTypeName = resolveTypeName(document.metadata.type, typeRegistry) ?? document.metadata.type;
1235
+ // Declarative set-or-clear helpers for the many string scalar fields that
1236
+ // share an identical shape: set from `--flag` (optionally transformed) or
1237
+ // delete when `--unset <field>` was requested, then record the change.
1238
+ // Each call is placed in the same position the inline block occupied so
1239
+ // the order of `changedFields` is preserved exactly (pm-why9).
1240
+ const metadataRecord = toItemRecord(document.metadata);
1241
+ const setOrClearScalar = (optionValue, metadataKey, transform) => {
1242
+ if (optionValue === undefined && !clearFrontMatterKeys.has(metadataKey)) {
1243
+ return;
1244
+ }
1245
+ if (clearFrontMatterKeys.has(metadataKey)) {
1246
+ delete metadataRecord[metadataKey];
1247
+ }
1248
+ else {
1249
+ metadataRecord[metadataKey] = transform(optionValue);
1250
+ }
1251
+ changedFields.push(metadataKey);
1252
+ };
1253
+ const setOrClearTrimScalar = (optionValue, metadataKey) => {
1254
+ setOrClearScalar(optionValue, metadataKey, (value) => value.trim());
1255
+ };
1332
1256
  if (options.title !== undefined) {
1333
1257
  document.metadata.title = options.title;
1334
1258
  changedFields.push("title");
@@ -1538,42 +1462,10 @@ export async function runUpdate(id, options, global) {
1538
1462
  document.metadata.tags = clearFrontMatterKeys.has("tags") ? [] : parseTags(options.tags);
1539
1463
  changedFields.push("tags");
1540
1464
  }
1541
- if (options.deadline !== undefined || clearFrontMatterKeys.has("deadline")) {
1542
- if (clearFrontMatterKeys.has("deadline")) {
1543
- delete document.metadata.deadline;
1544
- }
1545
- else {
1546
- document.metadata.deadline = resolveIsoOrRelative(options.deadline, new Date(), "deadline");
1547
- }
1548
- changedFields.push("deadline");
1549
- }
1550
- if (options.estimatedMinutes !== undefined || clearFrontMatterKeys.has("estimated_minutes")) {
1551
- if (clearFrontMatterKeys.has("estimated_minutes")) {
1552
- delete document.metadata.estimated_minutes;
1553
- }
1554
- else {
1555
- document.metadata.estimated_minutes = parseOptionalNumber(options.estimatedMinutes, "estimated-minutes");
1556
- }
1557
- changedFields.push("estimated_minutes");
1558
- }
1559
- if (options.acceptanceCriteria !== undefined || clearFrontMatterKeys.has("acceptance_criteria")) {
1560
- if (clearFrontMatterKeys.has("acceptance_criteria")) {
1561
- delete document.metadata.acceptance_criteria;
1562
- }
1563
- else {
1564
- document.metadata.acceptance_criteria = options.acceptanceCriteria;
1565
- }
1566
- changedFields.push("acceptance_criteria");
1567
- }
1568
- if (options.definitionOfReady !== undefined || clearFrontMatterKeys.has("definition_of_ready")) {
1569
- if (clearFrontMatterKeys.has("definition_of_ready")) {
1570
- delete document.metadata.definition_of_ready;
1571
- }
1572
- else {
1573
- document.metadata.definition_of_ready = options.definitionOfReady.trim();
1574
- }
1575
- changedFields.push("definition_of_ready");
1576
- }
1465
+ setOrClearScalar(options.deadline, "deadline", (value) => resolveIsoOrRelative(value, nowValue, "deadline"));
1466
+ setOrClearScalar(options.estimatedMinutes, "estimated_minutes", (value) => parseOptionalNumber(value, "estimated-minutes"));
1467
+ setOrClearScalar(options.acceptanceCriteria, "acceptance_criteria", (value) => value);
1468
+ setOrClearTrimScalar(options.definitionOfReady, "definition_of_ready");
1577
1469
  const orderRaw = options.order ?? options.rank;
1578
1470
  if (orderRaw !== undefined || clearFrontMatterKeys.has("order")) {
1579
1471
  if (clearFrontMatterKeys.has("order")) {
@@ -1588,60 +1480,12 @@ export async function runUpdate(id, options, global) {
1588
1480
  }
1589
1481
  changedFields.push("order");
1590
1482
  }
1591
- if (options.goal !== undefined || clearFrontMatterKeys.has("goal")) {
1592
- if (clearFrontMatterKeys.has("goal")) {
1593
- delete document.metadata.goal;
1594
- }
1595
- else {
1596
- document.metadata.goal = options.goal.trim();
1597
- }
1598
- changedFields.push("goal");
1599
- }
1600
- if (options.objective !== undefined || clearFrontMatterKeys.has("objective")) {
1601
- if (clearFrontMatterKeys.has("objective")) {
1602
- delete document.metadata.objective;
1603
- }
1604
- else {
1605
- document.metadata.objective = options.objective.trim();
1606
- }
1607
- changedFields.push("objective");
1608
- }
1609
- if (options.value !== undefined || clearFrontMatterKeys.has("value")) {
1610
- if (clearFrontMatterKeys.has("value")) {
1611
- delete document.metadata.value;
1612
- }
1613
- else {
1614
- document.metadata.value = options.value.trim();
1615
- }
1616
- changedFields.push("value");
1617
- }
1618
- if (options.impact !== undefined || clearFrontMatterKeys.has("impact")) {
1619
- if (clearFrontMatterKeys.has("impact")) {
1620
- delete document.metadata.impact;
1621
- }
1622
- else {
1623
- document.metadata.impact = options.impact.trim();
1624
- }
1625
- changedFields.push("impact");
1626
- }
1627
- if (options.outcome !== undefined || clearFrontMatterKeys.has("outcome")) {
1628
- if (clearFrontMatterKeys.has("outcome")) {
1629
- delete document.metadata.outcome;
1630
- }
1631
- else {
1632
- document.metadata.outcome = options.outcome.trim();
1633
- }
1634
- changedFields.push("outcome");
1635
- }
1636
- if (options.whyNow !== undefined || clearFrontMatterKeys.has("why_now")) {
1637
- if (clearFrontMatterKeys.has("why_now")) {
1638
- delete document.metadata.why_now;
1639
- }
1640
- else {
1641
- document.metadata.why_now = options.whyNow.trim();
1642
- }
1643
- changedFields.push("why_now");
1644
- }
1483
+ setOrClearTrimScalar(options.goal, "goal");
1484
+ setOrClearTrimScalar(options.objective, "objective");
1485
+ setOrClearTrimScalar(options.value, "value");
1486
+ setOrClearTrimScalar(options.impact, "impact");
1487
+ setOrClearTrimScalar(options.outcome, "outcome");
1488
+ setOrClearTrimScalar(options.whyNow, "why_now");
1645
1489
  if (options.assignee !== undefined || clearFrontMatterKeys.has("assignee")) {
1646
1490
  if (clearFrontMatterKeys.has("assignee")) {
1647
1491
  delete document.metadata.assignee;
@@ -1663,33 +1507,9 @@ export async function runUpdate(id, options, global) {
1663
1507
  }
1664
1508
  changedFields.push("parent");
1665
1509
  }
1666
- if (options.reviewer !== undefined || clearFrontMatterKeys.has("reviewer")) {
1667
- if (clearFrontMatterKeys.has("reviewer")) {
1668
- delete document.metadata.reviewer;
1669
- }
1670
- else {
1671
- document.metadata.reviewer = options.reviewer.trim();
1672
- }
1673
- changedFields.push("reviewer");
1674
- }
1675
- if (options.risk !== undefined || clearFrontMatterKeys.has("risk")) {
1676
- if (clearFrontMatterKeys.has("risk")) {
1677
- delete document.metadata.risk;
1678
- }
1679
- else {
1680
- document.metadata.risk = ensureEnum(normalizeRiskInput(options.risk), RISK_VALUES, "risk");
1681
- }
1682
- changedFields.push("risk");
1683
- }
1684
- if (options.confidence !== undefined || clearFrontMatterKeys.has("confidence")) {
1685
- if (clearFrontMatterKeys.has("confidence")) {
1686
- delete document.metadata.confidence;
1687
- }
1688
- else {
1689
- document.metadata.confidence = parseConfidenceInput(options.confidence);
1690
- }
1691
- changedFields.push("confidence");
1692
- }
1510
+ setOrClearTrimScalar(options.reviewer, "reviewer");
1511
+ setOrClearScalar(options.risk, "risk", (value) => ensureEnum(normalizeRiskInput(value), RISK_VALUES, "risk"));
1512
+ setOrClearScalar(options.confidence, "confidence", (value) => parseConfidenceInput(value));
1693
1513
  if (options.sprint !== undefined || clearFrontMatterKeys.has("sprint")) {
1694
1514
  if (clearFrontMatterKeys.has("sprint")) {
1695
1515
  delete document.metadata.sprint;
@@ -1723,132 +1543,20 @@ export async function runUpdate(id, options, global) {
1723
1543
  // pm-kyd6: keep the dependency graph in sync with the blocked_by scalar.
1724
1544
  applyBlockedByDependencyEdge(document.metadata, resolvedBlockedByDependencyId, nowIso, author, changedFields);
1725
1545
  }
1726
- if (options.blockedReason !== undefined || clearFrontMatterKeys.has("blocked_reason")) {
1727
- if (clearFrontMatterKeys.has("blocked_reason")) {
1728
- delete document.metadata.blocked_reason;
1729
- }
1730
- else {
1731
- document.metadata.blocked_reason = options.blockedReason.trim();
1732
- }
1733
- changedFields.push("blocked_reason");
1734
- }
1735
- if (options.unblockNote !== undefined || clearFrontMatterKeys.has("unblock_note")) {
1736
- if (clearFrontMatterKeys.has("unblock_note")) {
1737
- delete document.metadata.unblock_note;
1738
- }
1739
- else {
1740
- document.metadata.unblock_note = options.unblockNote.trim();
1741
- }
1742
- changedFields.push("unblock_note");
1743
- }
1744
- if (options.reporter !== undefined || clearFrontMatterKeys.has("reporter")) {
1745
- if (clearFrontMatterKeys.has("reporter")) {
1746
- delete document.metadata.reporter;
1747
- }
1748
- else {
1749
- document.metadata.reporter = options.reporter.trim();
1750
- }
1751
- changedFields.push("reporter");
1752
- }
1753
- if (options.severity !== undefined || clearFrontMatterKeys.has("severity")) {
1754
- if (clearFrontMatterKeys.has("severity")) {
1755
- delete document.metadata.severity;
1756
- }
1757
- else {
1758
- document.metadata.severity = ensureEnum(normalizeSeverityInput(options.severity), ISSUE_SEVERITY_VALUES, "severity");
1759
- }
1760
- changedFields.push("severity");
1761
- }
1762
- if (options.environment !== undefined || clearFrontMatterKeys.has("environment")) {
1763
- if (clearFrontMatterKeys.has("environment")) {
1764
- delete document.metadata.environment;
1765
- }
1766
- else {
1767
- document.metadata.environment = options.environment.trim();
1768
- }
1769
- changedFields.push("environment");
1770
- }
1771
- if (options.reproSteps !== undefined || clearFrontMatterKeys.has("repro_steps")) {
1772
- if (clearFrontMatterKeys.has("repro_steps")) {
1773
- delete document.metadata.repro_steps;
1774
- }
1775
- else {
1776
- document.metadata.repro_steps = options.reproSteps.trim();
1777
- }
1778
- changedFields.push("repro_steps");
1779
- }
1780
- if (options.resolution !== undefined || clearFrontMatterKeys.has("resolution")) {
1781
- if (clearFrontMatterKeys.has("resolution")) {
1782
- delete document.metadata.resolution;
1783
- }
1784
- else {
1785
- document.metadata.resolution = options.resolution.trim();
1786
- }
1787
- changedFields.push("resolution");
1788
- }
1789
- if (options.expectedResult !== undefined || clearFrontMatterKeys.has("expected_result")) {
1790
- if (clearFrontMatterKeys.has("expected_result")) {
1791
- delete document.metadata.expected_result;
1792
- }
1793
- else {
1794
- document.metadata.expected_result = options.expectedResult.trim();
1795
- }
1796
- changedFields.push("expected_result");
1797
- }
1798
- if (options.actualResult !== undefined || clearFrontMatterKeys.has("actual_result")) {
1799
- if (clearFrontMatterKeys.has("actual_result")) {
1800
- delete document.metadata.actual_result;
1801
- }
1802
- else {
1803
- document.metadata.actual_result = options.actualResult.trim();
1804
- }
1805
- changedFields.push("actual_result");
1806
- }
1807
- if (options.affectedVersion !== undefined || clearFrontMatterKeys.has("affected_version")) {
1808
- if (clearFrontMatterKeys.has("affected_version")) {
1809
- delete document.metadata.affected_version;
1810
- }
1811
- else {
1812
- document.metadata.affected_version = options.affectedVersion.trim();
1813
- }
1814
- changedFields.push("affected_version");
1815
- }
1816
- if (options.fixedVersion !== undefined || clearFrontMatterKeys.has("fixed_version")) {
1817
- if (clearFrontMatterKeys.has("fixed_version")) {
1818
- delete document.metadata.fixed_version;
1819
- }
1820
- else {
1821
- document.metadata.fixed_version = options.fixedVersion.trim();
1822
- }
1823
- changedFields.push("fixed_version");
1824
- }
1825
- if (options.component !== undefined || clearFrontMatterKeys.has("component")) {
1826
- if (clearFrontMatterKeys.has("component")) {
1827
- delete document.metadata.component;
1828
- }
1829
- else {
1830
- document.metadata.component = options.component.trim();
1831
- }
1832
- changedFields.push("component");
1833
- }
1834
- if (options.regression !== undefined || clearFrontMatterKeys.has("regression")) {
1835
- if (clearFrontMatterKeys.has("regression")) {
1836
- delete document.metadata.regression;
1837
- }
1838
- else {
1839
- document.metadata.regression = parseRegressionInput(options.regression);
1840
- }
1841
- changedFields.push("regression");
1842
- }
1843
- if (options.customerImpact !== undefined || clearFrontMatterKeys.has("customer_impact")) {
1844
- if (clearFrontMatterKeys.has("customer_impact")) {
1845
- delete document.metadata.customer_impact;
1846
- }
1847
- else {
1848
- document.metadata.customer_impact = options.customerImpact.trim();
1849
- }
1850
- changedFields.push("customer_impact");
1851
- }
1546
+ setOrClearTrimScalar(options.blockedReason, "blocked_reason");
1547
+ setOrClearTrimScalar(options.unblockNote, "unblock_note");
1548
+ setOrClearTrimScalar(options.reporter, "reporter");
1549
+ setOrClearScalar(options.severity, "severity", (value) => ensureEnum(normalizeSeverityInput(value), ISSUE_SEVERITY_VALUES, "severity"));
1550
+ setOrClearTrimScalar(options.environment, "environment");
1551
+ setOrClearTrimScalar(options.reproSteps, "repro_steps");
1552
+ setOrClearTrimScalar(options.resolution, "resolution");
1553
+ setOrClearTrimScalar(options.expectedResult, "expected_result");
1554
+ setOrClearTrimScalar(options.actualResult, "actual_result");
1555
+ setOrClearTrimScalar(options.affectedVersion, "affected_version");
1556
+ setOrClearTrimScalar(options.fixedVersion, "fixed_version");
1557
+ setOrClearTrimScalar(options.component, "component");
1558
+ setOrClearScalar(options.regression, "regression", (value) => parseRegressionInput(value));
1559
+ setOrClearTrimScalar(options.customerImpact, "customer_impact");
1852
1560
  if (options.reminder !== undefined || clearFrontMatterKeys.has("reminders")) {
1853
1561
  if (clearFrontMatterKeys.has("reminders")) {
1854
1562
  delete document.metadata.reminders;
@@ -1871,10 +1579,10 @@ export async function runUpdate(id, options, global) {
1871
1579
  if (!clearFrontMatterKeys.has(definition.metadata_key)) {
1872
1580
  continue;
1873
1581
  }
1874
- if (document.metadata[definition.metadata_key] === undefined) {
1582
+ if (metadataRecord[definition.metadata_key] === undefined) {
1875
1583
  continue;
1876
1584
  }
1877
- delete document.metadata[definition.metadata_key];
1585
+ delete metadataRecord[definition.metadata_key];
1878
1586
  changedFields.push(definition.metadata_key);
1879
1587
  }
1880
1588
  const runtimeFieldUpdates = collectRuntimeUpdateFieldValues(options, runtimeFieldRegistry);
@@ -1882,14 +1590,14 @@ export async function runUpdate(id, options, global) {
1882
1590
  if (clearFrontMatterKeys.has(fieldKey)) {
1883
1591
  continue;
1884
1592
  }
1885
- if (JSON.stringify(document.metadata[fieldKey]) === JSON.stringify(fieldValue)) {
1593
+ if (JSON.stringify(metadataRecord[fieldKey]) === JSON.stringify(fieldValue)) {
1886
1594
  continue;
1887
1595
  }
1888
- document.metadata[fieldKey] = fieldValue;
1596
+ metadataRecord[fieldKey] = fieldValue;
1889
1597
  changedFields.push(fieldKey);
1890
1598
  }
1891
1599
  try {
1892
- applyRegisteredItemFieldDefaultsAndValidation(document.metadata, getActiveExtensionRegistrations());
1600
+ applyRegisteredItemFieldDefaultsAndValidation(metadataRecord, getActiveExtensionRegistrations());
1893
1601
  }
1894
1602
  catch (error) {
1895
1603
  throw new PmCliError(error instanceof Error ? error.message : "Invalid extension item field values", EXIT_CODE.USAGE);
@@ -1898,11 +1606,11 @@ export async function runUpdate(id, options, global) {
1898
1606
  },
1899
1607
  });
1900
1608
  return {
1901
- item: result.item,
1609
+ item: toItemRecord(result.item),
1902
1610
  changed_fields: result.changedFields,
1903
1611
  warnings: [...parentReferenceWarnings, ...result.warnings],
1904
1612
  ...(options.allowAuditUpdate === true || options.allowAuditDepUpdate === true ? { audit_update: true } : {}),
1905
1613
  };
1906
1614
  }
1907
1615
  //# sourceMappingURL=update.js.map
1908
- //# debugId=689e9580-d7f6-5b07-be3d-28c381d20260
1616
+ //# debugId=94e19c77-3288-5a43-a8b2-6b9f15d4f234