@unbrained/pm-cli 2026.9.7 → 2026.9.9

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 (746) hide show
  1. package/.agents/skills/pm-developer/SKILL.md +12 -4
  2. package/.agents/skills/pm-developer/references/MULTI_AGENT_MERGE.md +19 -10
  3. package/.agents/skills/pm-extensions/SKILL.md +6 -0
  4. package/.agents/skills/pm-sdk/SKILL.md +11 -2
  5. package/.agents/skills/pm-user/SKILL.md +7 -2
  6. package/.agents/skills/pm-user/references/ECOSYSTEM_PLANNING.md +95 -0
  7. package/.claude-plugin/marketplace.json +2 -2
  8. package/CHANGELOG.md +231 -182
  9. package/dist/cli/after-command-context-usage.js +1 -48
  10. package/dist/cli/argv-utils.js +1 -40
  11. package/dist/cli/bootstrap-args.js +1 -9
  12. package/dist/cli/bundle-integrity.js +2 -110
  13. package/dist/cli/commander-usage.js +11 -771
  14. package/dist/cli/commands/activity.js +1 -9
  15. package/dist/cli/commands/aggregate.js +1 -5
  16. package/dist/cli/commands/append.js +1 -5
  17. package/dist/cli/commands/claim.js +1 -5
  18. package/dist/cli/commands/close-many.js +1 -5
  19. package/dist/cli/commands/close.js +1 -9
  20. package/dist/cli/commands/comments.js +1 -5
  21. package/dist/cli/commands/config.js +1 -9
  22. package/dist/cli/commands/context.js +1 -9
  23. package/dist/cli/commands/contracts.js +1 -5
  24. package/dist/cli/commands/copy.js +1 -9
  25. package/dist/cli/commands/create.js +1 -9
  26. package/dist/cli/commands/delete.js +1 -9
  27. package/dist/cli/commands/deps.js +1 -9
  28. package/dist/cli/commands/docs.js +1 -9
  29. package/dist/cli/commands/duplicates.js +1 -9
  30. package/dist/cli/commands/eval.js +1 -9
  31. package/dist/cli/commands/extension/describe.js +1 -5
  32. package/dist/cli/commands/extension/scaffold.js +1 -5
  33. package/dist/cli/commands/extension/shared.js +1 -5
  34. package/dist/cli/commands/extension.js +1 -9
  35. package/dist/cli/commands/files.js +1 -9
  36. package/dist/cli/commands/focus.js +1 -9
  37. package/dist/cli/commands/gc.js +1 -9
  38. package/dist/cli/commands/get.js +1 -9
  39. package/dist/cli/commands/graph.js +1 -10
  40. package/dist/cli/commands/health.js +1 -9
  41. package/dist/cli/commands/history-compact.js +1 -10
  42. package/dist/cli/commands/history-redact.js +1 -11
  43. package/dist/cli/commands/history-repair.js +1 -10
  44. package/dist/cli/commands/history.js +1 -5
  45. package/dist/cli/commands/index.js +1 -58
  46. package/dist/cli/commands/init-agent-guidance.js +1 -9
  47. package/dist/cli/commands/init.js +1 -9
  48. package/dist/cli/commands/learnings.js +1 -5
  49. package/dist/cli/commands/lifecycle-transitions.js +1 -5
  50. package/dist/cli/commands/list.js +1 -9
  51. package/dist/cli/commands/merge.js +1 -11
  52. package/dist/cli/commands/next.js +1 -9
  53. package/dist/cli/commands/notes.js +1 -5
  54. package/dist/cli/commands/plan.js +1 -9
  55. package/dist/cli/commands/profile.js +1 -9
  56. package/dist/cli/commands/restore.js +1 -9
  57. package/dist/cli/commands/scheduling-shortcuts.js +1 -9
  58. package/dist/cli/commands/schema.js +1 -10
  59. package/dist/cli/commands/search.js +1 -9
  60. package/dist/cli/commands/stats.js +1 -9
  61. package/dist/cli/commands/telemetry.js +1 -9
  62. package/dist/cli/commands/test-all.js +1 -9
  63. package/dist/cli/commands/test-runs.js +1 -9
  64. package/dist/cli/commands/test.js +1 -9
  65. package/dist/cli/commands/update-many.js +1 -5
  66. package/dist/cli/commands/update.js +1 -9
  67. package/dist/cli/commands/upgrade.js +1 -5
  68. package/dist/cli/commands/validate.js +1 -15
  69. package/dist/cli/context-intent-invocation.js +1 -20
  70. package/dist/cli/description-stdin.js +1 -17
  71. package/dist/cli/error-guidance.js +1 -1353
  72. package/dist/cli/extension-command-help.js +5 -636
  73. package/dist/cli/extension-command-options.js +1 -427
  74. package/dist/cli/extension-recovery.js +1 -126
  75. package/dist/cli/help-content.js +2 -1001
  76. package/dist/cli/help-json-payload.js +4 -570
  77. package/dist/cli/main.d.ts +4 -0
  78. package/dist/cli/main.js +5 -2573
  79. package/dist/cli/migration-gates.js +1 -289
  80. package/dist/cli/public.js +1 -20
  81. package/dist/cli/register-annotations.js +1 -270
  82. package/dist/cli/register-assurance.js +1 -62
  83. package/dist/cli/register-files-lookup.js +1 -56
  84. package/dist/cli/register-history-activity.d.ts +8 -0
  85. package/dist/cli/register-history-activity.js +2 -0
  86. package/dist/cli/register-history-author.js +1 -38
  87. package/dist/cli/register-history-maintenance.d.ts +9 -0
  88. package/dist/cli/register-history-maintenance.js +2 -0
  89. package/dist/cli/register-list-query.js +10 -943
  90. package/dist/cli/register-mutation-options.js +1 -9
  91. package/dist/cli/register-mutation.d.ts +0 -5
  92. package/dist/cli/register-mutation.js +19 -1893
  93. package/dist/cli/register-operations.js +1 -920
  94. package/dist/cli/register-setup.js +1 -716
  95. package/dist/cli/register-structured-mutation.js +1 -196
  96. package/dist/cli/registration-helpers.js +1 -5
  97. package/dist/cli/runtime-compatibility-boundary.js +4 -42
  98. package/dist/cli/schema-registration-helpers.js +1 -73
  99. package/dist/cli/search-refresh.js +1 -13
  100. package/dist/cli/stats-analytics-json.js +1 -68
  101. package/dist/cli/telemetry-flush.js +1 -10
  102. package/dist/cli-bundle/bundle-manifest.json +164 -156
  103. package/dist/cli-bundle/chunks/{chunk-NPN5I67J.js → chunk-3IPRM75M.js} +3 -3
  104. package/dist/cli-bundle/chunks/chunk-4VL5P22L.js +2 -0
  105. package/dist/cli-bundle/chunks/chunk-AAFBV3U3.js +29 -0
  106. package/dist/cli-bundle/chunks/chunk-D3YVILJJ.js +20 -0
  107. package/dist/cli-bundle/chunks/{chunk-WYRZZ5ZE.js → chunk-DEZPZOQ7.js} +2 -2
  108. package/dist/cli-bundle/chunks/chunk-ECBLPN7B.js +3 -0
  109. package/dist/cli-bundle/chunks/chunk-J6ERHBV2.js +235 -0
  110. package/dist/cli-bundle/chunks/chunk-JUNJ5EKI.js +2 -0
  111. package/dist/cli-bundle/chunks/chunk-L5RCDKQ2.js +2 -0
  112. package/dist/cli-bundle/chunks/chunk-NSAPNEYH.js +2 -0
  113. package/dist/cli-bundle/chunks/chunk-OHNLSGGV.js +79 -0
  114. package/dist/cli-bundle/chunks/chunk-WQKMSFBV.js +5 -0
  115. package/dist/cli-bundle/chunks/{chunk-BAX2BYUW.js → chunk-XZ6T7YPP.js} +256 -150
  116. package/dist/cli-bundle/chunks/{chunk-JT6XF6GE.js → chunk-Z3XVXUVF.js} +4 -4
  117. package/dist/cli-bundle/chunks/register-list-query-UIHRCS6D.js +11 -0
  118. package/dist/cli-bundle/chunks/register-mutation-WHWMGRVX.js +20 -0
  119. package/dist/cli-bundle/chunks/register-operations-64YZYTC5.js +2 -0
  120. package/dist/cli-bundle/chunks/register-setup-PERI45EM.js +2 -0
  121. package/dist/cli-bundle/focused-chunks/chunk-2W4XIYOB.js +2 -0
  122. package/dist/cli-bundle/focused-chunks/chunk-2WSBXIGF.js +12 -0
  123. package/dist/cli-bundle/focused-chunks/chunk-5FHTCOHS.js +3 -0
  124. package/dist/cli-bundle/focused-chunks/chunk-7N6DOREF.js +26 -0
  125. package/dist/cli-bundle/focused-chunks/{chunk-3BZEOXLT.js → chunk-7PC4R5QB.js} +2 -2
  126. package/dist/cli-bundle/focused-chunks/chunk-BUCJUZVG.js +6 -0
  127. package/dist/cli-bundle/focused-chunks/chunk-FE3BABLJ.js +2 -0
  128. package/dist/cli-bundle/focused-chunks/chunk-IWITF53W.js +2 -0
  129. package/dist/cli-bundle/focused-chunks/chunk-OQUGRHKV.js +10 -0
  130. package/dist/cli-bundle/focused-chunks/{chunk-M6PBRFSH.js → chunk-PNKIANFZ.js} +2 -2
  131. package/dist/cli-bundle/focused-chunks/{chunk-LIJIA4TY.js → chunk-QQQ4SAUO.js} +3 -3
  132. package/dist/cli-bundle/focused-chunks/chunk-TTYXF5YD.js +177 -0
  133. package/dist/cli-bundle/focused-chunks/chunk-XNR3DM6J.js +2 -0
  134. package/dist/cli-bundle/focused-chunks/chunk-XSS3APUF.js +9 -0
  135. package/dist/cli-bundle/focused-chunks/chunk-YCDQ2N23.js +8 -0
  136. package/dist/cli-bundle/focused-chunks/chunk-YJUXGS57.js +20 -0
  137. package/dist/cli-bundle/focused-chunks/chunk-ZTCE4UO6.js +58 -0
  138. package/dist/cli-bundle/main.js +20 -20
  139. package/dist/cli-bundle/sdk-authoring.js +1 -1
  140. package/dist/cli-bundle/sdk-contracts.js +2 -2
  141. package/dist/cli-bundle/sdk-core.js +37 -37
  142. package/dist/cli-bundle/sdk-governance.js +1 -1
  143. package/dist/cli-bundle/sdk-graph.js +1 -1
  144. package/dist/cli-bundle/sdk-merge.js +42 -42
  145. package/dist/cli-bundle/sdk-query.js +1 -1
  146. package/dist/cli-bundle/sdk-runtime.js +1 -1
  147. package/dist/cli-bundle/sdk-testing.js +1 -1
  148. package/dist/cli-bundle/sdk.js +11 -11
  149. package/dist/cli.js +1 -104
  150. package/dist/core/checkpoint/checkpoint-gc.js +1 -169
  151. package/dist/core/checkpoint/mutation-checkpoint.js +2 -133
  152. package/dist/core/config/nested-settings.js +1 -534
  153. package/dist/core/config/positional-value.js +1 -109
  154. package/dist/core/diagnostics/remediation.js +1 -506
  155. package/dist/core/extensions/activation-summary-markdown.js +2 -145
  156. package/dist/core/extensions/activation-summary.js +1 -92
  157. package/dist/core/extensions/activation-transaction.js +1 -46
  158. package/dist/core/extensions/capability-usage.js +1 -173
  159. package/dist/core/extensions/command-hook-context.js +1 -13
  160. package/dist/core/extensions/command-metadata-contract.js +1 -22
  161. package/dist/core/extensions/command-visibility-tier.js +1 -29
  162. package/dist/core/extensions/contribution-inventory.js +1 -173
  163. package/dist/core/extensions/exporter-output-contract.js +1 -66
  164. package/dist/core/extensions/extension-candidate.js +1 -18
  165. package/dist/core/extensions/extension-capability-aliases.js +1 -158
  166. package/dist/core/extensions/extension-hook-runtime.js +1 -699
  167. package/dist/core/extensions/extension-policy.js +1 -599
  168. package/dist/core/extensions/extension-registries.js +1 -62
  169. package/dist/core/extensions/extension-runtime-helpers.js +1 -33
  170. package/dist/core/extensions/extension-types.js +1 -102
  171. package/dist/core/extensions/flag-definition-validation.js +1 -52
  172. package/dist/core/extensions/flag-value-types.js +1 -64
  173. package/dist/core/extensions/index.js +1 -526
  174. package/dist/core/extensions/item-field-types.js +1 -39
  175. package/dist/core/extensions/item-fields.js +1 -261
  176. package/dist/core/extensions/loader.js +1 -2223
  177. package/dist/core/extensions/manifest-schema.js +1 -69
  178. package/dist/core/extensions/module-graph-snapshot.js +1 -33
  179. package/dist/core/extensions/preflight-ownership.js +1 -41
  180. package/dist/core/extensions/registration-validation.js +1 -82
  181. package/dist/core/extensions/registration-values.js +1 -209
  182. package/dist/core/extensions/reserved-host-flags.js +1 -36
  183. package/dist/core/extensions/runtime-registrations.js +1 -67
  184. package/dist/core/extensions/service-ownership.js +1 -19
  185. package/dist/core/extensions/version-compat.js +1 -216
  186. package/dist/core/fs/fs-utils.js +2 -158
  187. package/dist/core/fs/host-environment-errors.js +1 -141
  188. package/dist/core/fs/index.js +1 -9
  189. package/dist/core/fs/path-utils.js +1 -17
  190. package/dist/core/governance/content-fields.js +1 -160
  191. package/dist/core/governance/issue-codes.js +1 -151
  192. package/dist/core/governance/metadata-coverage.js +1 -358
  193. package/dist/core/history/drift-cache.js +3 -72
  194. package/dist/core/history/drift-scan.js +1 -342
  195. package/dist/core/history/event-classification.js +1 -109
  196. package/dist/core/history/event-index.js +8 -784
  197. package/dist/core/history/history-compact-bulk.js +1 -104
  198. package/dist/core/history/history-diff.js +1 -158
  199. package/dist/core/history/history-rewrite.d.ts +6 -1
  200. package/dist/core/history/history-rewrite.js +1 -107
  201. package/dist/core/history/history-storage-stats.js +1 -102
  202. package/dist/core/history/history-stream-policy.js +1 -62
  203. package/dist/core/history/history.js +2 -617
  204. package/dist/core/history/identity.js +1 -30
  205. package/dist/core/history/index.js +1 -9
  206. package/dist/core/history/projection.js +1 -196
  207. package/dist/core/history/read.d.ts +9 -0
  208. package/dist/core/history/read.js +1 -57
  209. package/dist/core/history/replay.js +2 -439
  210. package/dist/core/history/version-address.js +1 -32
  211. package/dist/core/history/workspace-history.js +2 -433
  212. package/dist/core/io/body-file.js +1 -62
  213. package/dist/core/io/bulk-ids-input.js +1 -112
  214. package/dist/core/item/actionability.js +1 -327
  215. package/dist/core/item/dependency-reference.js +1 -20
  216. package/dist/core/item/id.js +1 -112
  217. package/dist/core/item/index.js +1 -12
  218. package/dist/core/item/item-format-version.js +1 -78
  219. package/dist/core/item/item-format.js +5 -1473
  220. package/dist/core/item/item-record.js +1 -23
  221. package/dist/core/item/item-type-definition.js +1 -133
  222. package/dist/core/item/parent-reference-policy.js +1 -57
  223. package/dist/core/item/parse.js +2 -603
  224. package/dist/core/item/plan-lifecycle.js +1 -19
  225. package/dist/core/item/priority.js +1 -61
  226. package/dist/core/item/sprint-release-format.js +1 -38
  227. package/dist/core/item/status-filter.js +1 -115
  228. package/dist/core/item/status.js +1 -43
  229. package/dist/core/item/toon-decode.js +1 -29
  230. package/dist/core/item/type-registry.js +1 -715
  231. package/dist/core/item/type-synonyms.js +1 -38
  232. package/dist/core/lock/index.js +1 -9
  233. package/dist/core/lock/lock-gc.js +1 -240
  234. package/dist/core/lock/lock.js +3 -590
  235. package/dist/core/output/mutation-projection.js +1 -217
  236. package/dist/core/output/output-control.js +1 -25
  237. package/dist/core/output/output.js +11 -494
  238. package/dist/core/output/query-summary.js +1 -58
  239. package/dist/core/output/tabular.js +1 -77
  240. package/dist/core/packages/manifest.js +1 -244
  241. package/dist/core/packages/root.js +1 -84
  242. package/dist/core/policy/workflow-policy-schema.d.ts +312 -0
  243. package/dist/core/policy/workflow-policy-schema.js +2 -0
  244. package/dist/core/policy/workflow-policy-store.d.ts +24 -0
  245. package/dist/core/policy/workflow-policy-store.js +2 -0
  246. package/dist/core/policy/workflow-policy.d.ts +139 -0
  247. package/dist/core/policy/workflow-policy.js +2 -0
  248. package/dist/core/profile/profile-describe.js +1 -83
  249. package/dist/core/profile/profile-lint.js +1 -415
  250. package/dist/core/profile/profile-plan.js +0 -0
  251. package/dist/core/profile/profile-presets.js +1 -370
  252. package/dist/core/reproducibility/context.js +1 -82
  253. package/dist/core/schema/fields-file.js +2 -288
  254. package/dist/core/schema/item-types-file.js +2 -296
  255. package/dist/core/schema/runtime-field-filters.js +1 -49
  256. package/dist/core/schema/runtime-field-values.js +1 -313
  257. package/dist/core/schema/runtime-schema.js +2 -826
  258. package/dist/core/schema/status-defs-file.js +2 -227
  259. package/dist/core/schema/status-token.js +1 -31
  260. package/dist/core/schema/type-inference.js +1 -95
  261. package/dist/core/schema/type-presets.js +1 -87
  262. package/dist/core/schema/type-workflows.js +1 -104
  263. package/dist/core/search/background-refresh.js +2 -286
  264. package/dist/core/search/bm25.js +1 -146
  265. package/dist/core/search/cache.js +2 -534
  266. package/dist/core/search/corpus.js +1 -311
  267. package/dist/core/search/embedding-batches.js +1 -163
  268. package/dist/core/search/eval.js +1 -225
  269. package/dist/core/search/http-client.js +1 -75
  270. package/dist/core/search/providers.js +1 -242
  271. package/dist/core/search/relevance.js +1 -244
  272. package/dist/core/search/semantic-defaults.js +1 -199
  273. package/dist/core/search/staleness.js +1 -30
  274. package/dist/core/search/vector-stores.js +2 -664
  275. package/dist/core/search/vectorization-metadata.js +1 -81
  276. package/dist/core/sentry/helpers.js +1 -272
  277. package/dist/core/sentry/instrument.js +1 -387
  278. package/dist/core/session/session-state.js +1 -260
  279. package/dist/core/shared/agent-session-context.js +1 -133
  280. package/dist/core/shared/author.js +1 -1172
  281. package/dist/core/shared/command-types.js +1 -4
  282. package/dist/core/shared/conflict-markers.js +1 -31
  283. package/dist/core/shared/constants.js +1 -405
  284. package/dist/core/shared/errors.js +1 -20
  285. package/dist/core/shared/html-entity-decode.js +1 -131
  286. package/dist/core/shared/index.js +1 -12
  287. package/dist/core/shared/item-metadata-contract.js +1 -89
  288. package/dist/core/shared/lazy-module.js +1 -16
  289. package/dist/core/shared/levenshtein.js +1 -61
  290. package/dist/core/shared/memo.js +1 -19
  291. package/dist/core/shared/numeric-parsers.js +1 -20
  292. package/dist/core/shared/option-alias-visibility.js +1 -67
  293. package/dist/core/shared/primitives.js +1 -127
  294. package/dist/core/shared/serial-queue.js +1 -79
  295. package/dist/core/shared/serialization.js +1 -210
  296. package/dist/core/shared/split-comma-list.js +1 -30
  297. package/dist/core/shared/text-normalization.js +1 -38
  298. package/dist/core/shared/time.js +1 -306
  299. package/dist/core/store/index.js +1 -12
  300. package/dist/core/store/item-format-migration.js +1 -125
  301. package/dist/core/store/item-metadata-cache.js +1 -1116
  302. package/dist/core/store/item-metadata-query-index.js +9 -394
  303. package/dist/core/store/item-metadata-read-work.js +1 -43
  304. package/dist/core/store/item-store.js +1 -693
  305. package/dist/core/store/paths.d.ts +1 -1
  306. package/dist/core/store/paths.js +1 -214
  307. package/dist/core/store/settings-read-cache.js +1 -85
  308. package/dist/core/store/settings-validator.d.ts +1 -0
  309. package/dist/core/store/settings-validator.js +1 -421
  310. package/dist/core/store/settings.js +3 -1309
  311. package/dist/core/store/tracker-preflight.js +1 -141
  312. package/dist/core/telemetry/consent.js +5 -108
  313. package/dist/core/telemetry/observability.js +1 -246
  314. package/dist/core/telemetry/runtime.js +4 -1988
  315. package/dist/core/test/background-runs.js +4 -945
  316. package/dist/core/test/item-test-run-tracking.js +1 -63
  317. package/dist/core/test/run-selectors.js +1 -120
  318. package/dist/core/validate/estimate-defaults.js +1 -89
  319. package/dist/core/validate/fix-planning.js +1 -189
  320. package/dist/core/validate/linked-artifact-reference.js +1 -36
  321. package/dist/core/validate/missing-by-type.js +1 -34
  322. package/dist/core/validate/missing-link-owners.js +1 -95
  323. package/dist/core/validate/stale-file-classification.js +1 -82
  324. package/dist/mcp/http-server.js +5 -448
  325. package/dist/mcp/legacy-adapter.js +1 -77
  326. package/dist/mcp/runtime-capabilities.js +1 -200
  327. package/dist/mcp/server.js +4 -1233
  328. package/dist/mcp/tool-definitions.js +1 -804
  329. package/dist/sdk/actionability.js +1 -13
  330. package/dist/sdk/agent/closed-domain-contracts.js +1 -161
  331. package/dist/sdk/agent/command-recovery.js +1 -59
  332. package/dist/sdk/agent/command-suggestions.js +1 -66
  333. package/dist/sdk/agent/create-option-policy.js +1 -31
  334. package/dist/sdk/agent/identity-config.js +1 -106
  335. package/dist/sdk/agent/item-addressing.js +1 -207
  336. package/dist/sdk/agent/refusal-closure-census.js +1 -151
  337. package/dist/sdk/agent/refusal-closure.js +1 -133
  338. package/dist/sdk/agent/refusal-corpus-contracts.js +1 -193
  339. package/dist/sdk/agent/refusal-reachability.js +1 -593
  340. package/dist/sdk/agent/subcommand-recovery.js +1 -83
  341. package/dist/sdk/agent/task-transcript-contracts.js +1 -197
  342. package/dist/sdk/agent/tracker-preflight-contracts.js +1 -126
  343. package/dist/sdk/agent-capability-contracts.js +1 -428
  344. package/dist/sdk/agent-session-context.js +1 -9
  345. package/dist/sdk/annotations.js +1 -448
  346. package/dist/sdk/author-attribution.js +1 -468
  347. package/dist/sdk/authoring.js +1 -20
  348. package/dist/sdk/cli-bootstrap.js +1 -838
  349. package/dist/sdk/cli-contracts/agent-output-contracts.d.ts +1 -1
  350. package/dist/sdk/cli-contracts/agent-output-contracts.js +4 -476
  351. package/dist/sdk/cli-contracts/bootstrap-command-scanner.js +1 -79
  352. package/dist/sdk/cli-contracts/command-aliases.d.ts +4 -0
  353. package/dist/sdk/cli-contracts/command-aliases.js +1 -107
  354. package/dist/sdk/cli-contracts/command-exit-contracts.js +1 -151
  355. package/dist/sdk/cli-contracts/commander-mutation-options.js +1 -1081
  356. package/dist/sdk/cli-contracts/commander-types.js +1 -159
  357. package/dist/sdk/cli-contracts/completeness.js +1 -393
  358. package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
  359. package/dist/sdk/cli-contracts/enum-contracts.js +1 -222
  360. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1947
  361. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -347
  362. package/dist/sdk/cli-contracts/grammar-contracts.js +1 -986
  363. package/dist/sdk/cli-contracts/registration-helpers.js +7 -990
  364. package/dist/sdk/cli-contracts/runtime-contracts.d.ts +5 -0
  365. package/dist/sdk/cli-contracts/runtime-contracts.js +1 -2090
  366. package/dist/sdk/cli-contracts/schemas/assurance-definition.js +1 -324
  367. package/dist/sdk/cli-contracts/string-lists.js +1 -16
  368. package/dist/sdk/cli-contracts/tool-option-contracts.js +1 -461
  369. package/dist/sdk/cli-contracts/tool-parameter-tables.js +1 -2167
  370. package/dist/sdk/cli-contracts/tool-schema.d.ts +3 -1
  371. package/dist/sdk/cli-contracts/tool-schema.js +1 -1664
  372. package/dist/sdk/cli-contracts/typed-action-inputs.js +1 -4
  373. package/dist/sdk/cli-contracts.d.ts +1 -1
  374. package/dist/sdk/cli-contracts.js +1 -17
  375. package/dist/sdk/cli-program.js +1 -49
  376. package/dist/sdk/command-line.d.ts +2 -5
  377. package/dist/sdk/command-line.js +1 -78
  378. package/dist/sdk/comments.js +1 -133
  379. package/dist/sdk/compile-cache.js +1 -73
  380. package/dist/sdk/completion.js +174 -839
  381. package/dist/sdk/compose.js +1 -1090
  382. package/dist/sdk/config.js +1 -1204
  383. package/dist/sdk/context/recency.js +1 -33
  384. package/dist/sdk/context/semantic-session-attribution.js +1 -82
  385. package/dist/sdk/context/usage-egress.js +1 -29
  386. package/dist/sdk/context/usage-ledger.js +3 -185
  387. package/dist/sdk/context-intent-contracts.js +1 -709
  388. package/dist/sdk/context-intent-runtime.js +1 -115
  389. package/dist/sdk/context-packing.js +1 -218
  390. package/dist/sdk/context-relevance.js +1 -503
  391. package/dist/sdk/context-signal-store.js +2 -426
  392. package/dist/sdk/context-usage.js +1 -367
  393. package/dist/sdk/contracts.js +1 -23
  394. package/dist/sdk/core-governance.js +1 -14
  395. package/dist/sdk/core.js +1 -14
  396. package/dist/sdk/corpus-shape.js +1 -401
  397. package/dist/sdk/define.js +1 -220
  398. package/dist/sdk/dependencies.js +1 -718
  399. package/dist/sdk/dependency-flag-validation.js +1 -156
  400. package/dist/sdk/dependency-provenance.js +1 -135
  401. package/dist/sdk/docs.js +1 -14
  402. package/dist/sdk/duplicates.js +1 -40
  403. package/dist/sdk/environment/agent-environment.js +1 -466
  404. package/dist/sdk/environment/host-environment-errors.js +1 -8
  405. package/dist/sdk/environment/project-runtime-compatibility.js +1 -481
  406. package/dist/sdk/environment/source-context.js +1 -28
  407. package/dist/sdk/environment/tracker-preflight.js +1 -9
  408. package/dist/sdk/error-code-catalog.js +1 -153
  409. package/dist/sdk/error-runtime.js +1 -58
  410. package/dist/sdk/errors.js +1 -58
  411. package/dist/sdk/eval.js +1 -190
  412. package/dist/sdk/extension/author-manifest.js +1 -92
  413. package/dist/sdk/extension/bundled-catalog.js +1 -332
  414. package/dist/sdk/extension/concurrency.js +1 -25
  415. package/dist/sdk/extension/copy-scope.d.ts +2 -0
  416. package/dist/sdk/extension/copy-scope.js +2 -0
  417. package/dist/sdk/extension/custom-field-collisions.js +1 -30
  418. package/dist/sdk/extension/describe.js +3 -189
  419. package/dist/sdk/extension/doctor.js +1 -606
  420. package/dist/sdk/extension/install-plan.d.ts +69 -0
  421. package/dist/sdk/extension/install-plan.js +2 -0
  422. package/dist/sdk/extension/install-receipts.d.ts +7 -0
  423. package/dist/sdk/extension/install-receipts.js +2 -0
  424. package/dist/sdk/extension/install-runtime.js +3 -313
  425. package/dist/sdk/extension/install-snapshot.js +1 -66
  426. package/dist/sdk/extension/install-sources.js +5 -1057
  427. package/dist/sdk/extension/managed-state.js +2 -252
  428. package/dist/sdk/extension/migrations.js +2 -174
  429. package/dist/sdk/extension/output-ownership.js +1 -25
  430. package/dist/sdk/extension/runtime-summary.js +1 -18
  431. package/dist/sdk/extension/scaffold.js +4 -2308
  432. package/dist/sdk/extension/shared.js +1 -147
  433. package/dist/sdk/extension/source-resolution.js +1 -65
  434. package/dist/sdk/extension/update-check.js +1 -67
  435. package/dist/sdk/extension-command-context.js +1 -44
  436. package/dist/sdk/extension-contracts.js +1 -73
  437. package/dist/sdk/extension.d.ts +7 -2
  438. package/dist/sdk/extension.js +1 -2196
  439. package/dist/sdk/files.js +1 -535
  440. package/dist/sdk/flag-invocation-contracts.d.ts +0 -5
  441. package/dist/sdk/flag-invocation-contracts.js +1 -344
  442. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -2224
  443. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -2236
  444. package/dist/sdk/generated-error-code-catalog.js +1 -16
  445. package/dist/sdk/governance/assurance-action-contracts.js +1 -4
  446. package/dist/sdk/governance/assurance-action.js +1 -411
  447. package/dist/sdk/governance/assurance-limits.js +1 -10
  448. package/dist/sdk/governance/assurance-mutation-error.js +1 -81
  449. package/dist/sdk/governance/assurance-presets.js +1 -135
  450. package/dist/sdk/governance/assurance-runtime.js +1 -238
  451. package/dist/sdk/governance/assurance.js +4 -1182
  452. package/dist/sdk/governance/boundary-fixtures.js +1 -200
  453. package/dist/sdk/governance/coverage-assurance.js +1 -60
  454. package/dist/sdk/governance/defect-recurrence-coverage.js +1 -188
  455. package/dist/sdk/governance/defect-recurrence-graph.js +1 -120
  456. package/dist/sdk/governance/defect-recurrence-signals.js +1 -24
  457. package/dist/sdk/governance/defect-recurrence.js +1 -623
  458. package/dist/sdk/governance/extension-host-version.js +1 -115
  459. package/dist/sdk/governance/gc.js +1 -368
  460. package/dist/sdk/governance/health.js +1 -2367
  461. package/dist/sdk/governance/hierarchy-validation.js +1 -108
  462. package/dist/sdk/governance/linked-file-report.js +1 -71
  463. package/dist/sdk/governance/merge-receipt-history.js +1 -206
  464. package/dist/sdk/governance/provenance-health.js +1 -282
  465. package/dist/sdk/governance/reindex.js +4 -761
  466. package/dist/sdk/governance/stale-work.js +1 -82
  467. package/dist/sdk/governance/status-role-diagnostics.js +1 -35
  468. package/dist/sdk/governance/storage-integrity.js +1 -280
  469. package/dist/sdk/governance/tracked-runtime-cache.js +1 -106
  470. package/dist/sdk/governance/upgrade.js +2 -327
  471. package/dist/sdk/governance/validate-history-drift.js +1 -81
  472. package/dist/sdk/governance/validate-item-reader.js +1 -17
  473. package/dist/sdk/governance/validate-normalization.js +1 -36
  474. package/dist/sdk/governance/validate.d.ts +3 -1
  475. package/dist/sdk/governance/validate.js +1 -2261
  476. package/dist/sdk/governance/workflow-completeness.d.ts +32 -0
  477. package/dist/sdk/governance/workflow-completeness.js +2 -0
  478. package/dist/sdk/governance/workflow-policy.d.ts +47 -0
  479. package/dist/sdk/governance/workflow-policy.js +4 -0
  480. package/dist/sdk/governance/workspace-position.js +1 -163
  481. package/dist/sdk/governance.d.ts +2 -0
  482. package/dist/sdk/governance.js +1 -31
  483. package/dist/sdk/graph/adapter.js +1 -181
  484. package/dist/sdk/graph/analytics.js +1 -474
  485. package/dist/sdk/graph/assembly.js +1 -377
  486. package/dist/sdk/graph/cache.js +1 -160
  487. package/dist/sdk/graph/centrality.js +1 -258
  488. package/dist/sdk/graph/conformance.js +1 -130
  489. package/dist/sdk/graph/deadline-scheduling.d.ts +90 -0
  490. package/dist/sdk/graph/deadline-scheduling.js +2 -0
  491. package/dist/sdk/graph/durable-cache.d.ts +1 -1
  492. package/dist/sdk/graph/durable-cache.js +1 -361
  493. package/dist/sdk/graph/governance-contracts.js +1 -34
  494. package/dist/sdk/graph/governance.d.ts +13 -1
  495. package/dist/sdk/graph/governance.js +1 -735
  496. package/dist/sdk/graph/hierarchy-integrity.js +1 -310
  497. package/dist/sdk/graph/index.d.ts +3 -2
  498. package/dist/sdk/graph/index.js +1 -26
  499. package/dist/sdk/graph/lifecycle-coverage.d.ts +32 -0
  500. package/dist/sdk/graph/lifecycle-coverage.js +2 -0
  501. package/dist/sdk/graph/mutation-advisory.js +1 -176
  502. package/dist/sdk/graph/remediation.js +1 -197
  503. package/dist/sdk/graph/run.d.ts +15 -1
  504. package/dist/sdk/graph/run.js +1 -768
  505. package/dist/sdk/graph/scheduling.js +1 -124
  506. package/dist/sdk/graph/traversal.js +1 -284
  507. package/dist/sdk/graph/workspace-relationship-kind-registry.js +1 -27
  508. package/dist/sdk/graph.js +1 -15
  509. package/dist/sdk/guide-topics.js +1 -707
  510. package/dist/sdk/guide.js +1 -279
  511. package/dist/sdk/history/maintenance.d.ts +71 -0
  512. package/dist/sdk/history/maintenance.js +2 -0
  513. package/dist/sdk/history/salvage.js +2 -247
  514. package/dist/sdk/history/subject.d.ts +19 -0
  515. package/dist/sdk/history/subject.js +2 -0
  516. package/dist/sdk/history-analytics.js +1 -282
  517. package/dist/sdk/history-compact.js +1 -527
  518. package/dist/sdk/history-mcp.js +1 -68
  519. package/dist/sdk/history-provenance.js +1 -182
  520. package/dist/sdk/history-read.js +1 -96
  521. package/dist/sdk/history-redact.d.ts +1 -14
  522. package/dist/sdk/history-redact.js +1 -643
  523. package/dist/sdk/history-repair.d.ts +5 -0
  524. package/dist/sdk/history-repair.js +1 -657
  525. package/dist/sdk/improvement-ledger-validation.js +1 -62
  526. package/dist/sdk/improvement-ledger.js +2 -257
  527. package/dist/sdk/index.d.ts +4 -1
  528. package/dist/sdk/index.js +1 -183
  529. package/dist/sdk/init-agent-guidance.js +2 -496
  530. package/dist/sdk/init.js +2 -820
  531. package/dist/sdk/invocation-author.js +1 -39
  532. package/dist/sdk/item-children.js +1 -90
  533. package/dist/sdk/item-metadata-index.js +1 -15
  534. package/dist/sdk/item-schedule.js +1 -27
  535. package/dist/sdk/item-transaction.js +1 -396
  536. package/dist/sdk/learnings.js +1 -29
  537. package/dist/sdk/lifecycle/append.js +2 -53
  538. package/dist/sdk/lifecycle/claim.d.ts +2 -0
  539. package/dist/sdk/lifecycle/claim.js +1 -242
  540. package/dist/sdk/lifecycle/close-many.js +1 -438
  541. package/dist/sdk/lifecycle/close.js +1 -468
  542. package/dist/sdk/lifecycle/copy.js +1 -212
  543. package/dist/sdk/lifecycle/create.js +1 -1949
  544. package/dist/sdk/lifecycle/delete.js +1 -45
  545. package/dist/sdk/lifecycle/event-validation-messages.js +1 -91
  546. package/dist/sdk/lifecycle/focus.js +1 -91
  547. package/dist/sdk/lifecycle/hierarchy-mutation-lock.js +1 -24
  548. package/dist/sdk/lifecycle/legacy-none-tokens.js +1 -149
  549. package/dist/sdk/lifecycle/lifecycle-transitions.js +1 -40
  550. package/dist/sdk/lifecycle/mcp-actions.d.ts +2 -0
  551. package/dist/sdk/lifecycle/mcp-actions.js +1 -51
  552. package/dist/sdk/lifecycle/metadata-normalizers.js +1 -46
  553. package/dist/sdk/lifecycle/mutation-command-options.js +1 -9
  554. package/dist/sdk/lifecycle/plan.js +1 -1606
  555. package/dist/sdk/lifecycle/recurrence-parsers.d.ts +1 -1
  556. package/dist/sdk/lifecycle/recurrence-parsers.js +1 -147
  557. package/dist/sdk/lifecycle/reopen.js +1 -68
  558. package/dist/sdk/lifecycle/repeatable-metadata-parsers.js +1 -143
  559. package/dist/sdk/lifecycle/restore.d.ts +1 -0
  560. package/dist/sdk/lifecycle/restore.js +1 -330
  561. package/dist/sdk/lifecycle/shared-unset-fields.js +1 -295
  562. package/dist/sdk/lifecycle/update-many.js +1 -861
  563. package/dist/sdk/lifecycle/update.js +1 -2136
  564. package/dist/sdk/lifecycle-completion.js +1 -92
  565. package/dist/sdk/lifecycle-policy.js +1 -120
  566. package/dist/sdk/linked-artifacts.js +1 -530
  567. package/dist/sdk/mcp/apps.js +4 -133
  568. package/dist/sdk/mcp/authorization.js +1 -404
  569. package/dist/sdk/mcp/discovery.js +1 -494
  570. package/dist/sdk/mcp/interactions.js +1 -336
  571. package/dist/sdk/mcp/protocol.d.ts +7 -0
  572. package/dist/sdk/mcp/protocol.js +1 -184
  573. package/dist/sdk/mcp/skills.js +1 -389
  574. package/dist/sdk/mcp/subscriptions.js +1 -211
  575. package/dist/sdk/mcp/tasks.js +2 -430
  576. package/dist/sdk/mcp/transport.js +1 -260
  577. package/dist/sdk/merge/abandoned-receipts.js +1 -46
  578. package/dist/sdk/merge/driver.js +1 -212
  579. package/dist/sdk/merge/index.js +1 -16
  580. package/dist/sdk/merge/install.js +3 -561
  581. package/dist/sdk/merge/receipt-file-boundary.js +1 -46
  582. package/dist/sdk/merge/receipt-operation.js +1 -96
  583. package/dist/sdk/merge/receipt-schema.js +1 -397
  584. package/dist/sdk/merge/receipts.js +4 -525
  585. package/dist/sdk/merge/reconcile.js +1 -352
  586. package/dist/sdk/merge/three-way.js +3 -775
  587. package/dist/sdk/merge.js +1 -10
  588. package/dist/sdk/mutation-events.js +1 -292
  589. package/dist/sdk/mutation-guard.js +1 -216
  590. package/dist/sdk/notes.js +1 -139
  591. package/dist/sdk/output-contracts.js +1 -172
  592. package/dist/sdk/output-projection.js +1 -430
  593. package/dist/sdk/output-token-accounting.js +1 -140
  594. package/dist/sdk/output.js +1 -64
  595. package/dist/sdk/ownership-source.js +1 -21
  596. package/dist/sdk/package-import-adapters.js +1 -442
  597. package/dist/sdk/package-migrations.js +1 -20
  598. package/dist/sdk/package-runtime-options.js +1 -80
  599. package/dist/sdk/pagination.js +1 -162
  600. package/dist/sdk/profile.js +1 -454
  601. package/dist/sdk/provenance.js +1 -258
  602. package/dist/sdk/public-surface.json +1 -1
  603. package/dist/sdk/query/activity.js +1 -401
  604. package/dist/sdk/query/aggregate.d.ts +16 -0
  605. package/dist/sdk/query/aggregate.js +1 -390
  606. package/dist/sdk/query/calendar.js +1 -964
  607. package/dist/sdk/query/complete-list.js +1 -215
  608. package/dist/sdk/query/context.js +1 -1702
  609. package/dist/sdk/query/duplicate-candidates.js +1 -70
  610. package/dist/sdk/query/get.js +1 -450
  611. package/dist/sdk/query/history.js +1 -186
  612. package/dist/sdk/query/item-filter-options.js +1 -9
  613. package/dist/sdk/query/light-metadata.js +1 -18
  614. package/dist/sdk/query/list-filter-shared.js +1 -81
  615. package/dist/sdk/query/list.js +1 -1304
  616. package/dist/sdk/query/multi-value-filters.js +1 -78
  617. package/dist/sdk/query/next.js +1 -513
  618. package/dist/sdk/query/parsers.js +1 -44
  619. package/dist/sdk/query/projection-contracts.js +1 -184
  620. package/dist/sdk/query/search-contracts.d.ts +27 -0
  621. package/dist/sdk/query/search-contracts.js +1 -230
  622. package/dist/sdk/query/search-pagination.js +1 -35
  623. package/dist/sdk/query/search-rendering.js +1 -105
  624. package/dist/sdk/query/search.d.ts +6 -4
  625. package/dist/sdk/query/search.js +2 -1987
  626. package/dist/sdk/query.js +1 -35
  627. package/dist/sdk/read-output/continuation.js +1 -194
  628. package/dist/sdk/read-output-budget.js +1 -135
  629. package/dist/sdk/read-output-contracts.d.ts +1 -1
  630. package/dist/sdk/read-output-contracts.js +1 -1225
  631. package/dist/sdk/read-output-rows.js +1 -186
  632. package/dist/sdk/read-output-session.js +1 -208
  633. package/dist/sdk/relationship-analytics.js +1 -410
  634. package/dist/sdk/relationship-context.js +1 -284
  635. package/dist/sdk/relationship-history.js +4 -519
  636. package/dist/sdk/relationship-kinds/contract.js +1 -22
  637. package/dist/sdk/relationship-migration.js +1 -77
  638. package/dist/sdk/relationships.js +1 -579
  639. package/dist/sdk/reproducibility/process.js +1 -87
  640. package/dist/sdk/runtime-action-aliases.js +1 -59
  641. package/dist/sdk/runtime-extended-actions.js +1 -177
  642. package/dist/sdk/runtime-input.js +1 -614
  643. package/dist/sdk/runtime-primitives.js +1 -84
  644. package/dist/sdk/runtime-public-contracts.d.ts +2 -1
  645. package/dist/sdk/runtime-public-contracts.js +1 -4
  646. package/dist/sdk/runtime-stats-options.js +1 -38
  647. package/dist/sdk/runtime.d.ts +4 -0
  648. package/dist/sdk/runtime.js +1 -1928
  649. package/dist/sdk/scheduling-shortcuts.js +1 -63
  650. package/dist/sdk/schema-migration.js +3 -856
  651. package/dist/sdk/schema.d.ts +2 -1
  652. package/dist/sdk/schema.js +1 -1376
  653. package/dist/sdk/search-refresh-worker.js +1 -18
  654. package/dist/sdk/similarity-scoring.js +1 -53
  655. package/dist/sdk/similarity.js +1 -326
  656. package/dist/sdk/start-task-status.js +1 -14
  657. package/dist/sdk/stats.js +1 -270
  658. package/dist/sdk/structured-mutations.js +1 -580
  659. package/dist/sdk/telemetry-flush.js +1 -13
  660. package/dist/sdk/telemetry.js +1 -405
  661. package/dist/sdk/templates.js +2 -292
  662. package/dist/sdk/test/batch.js +2 -509
  663. package/dist/sdk/test/entry.js +1 -70
  664. package/dist/sdk/test/execution.js +6 -2211
  665. package/dist/sdk/test/linked-command-detection.js +1 -546
  666. package/dist/sdk/test/measurements.js +1 -91
  667. package/dist/sdk/test/parsers.js +1 -545
  668. package/dist/sdk/test/runs.js +1 -193
  669. package/dist/sdk/test/trust.js +2 -206
  670. package/dist/sdk/testing.js +4 -1391
  671. package/dist/sdk/traceability/runtime-files-lookup.js +1 -32
  672. package/dist/sdk/traceability/source-traceability.js +1 -292
  673. package/dist/sdk/tracker-root-discovery.js +1 -9
  674. package/dist/sdk/workspace-contracts-cache.js +1 -28
  675. package/dist/sdk/workspace-contracts.js +1 -33
  676. package/dist/sdk/workspace-memory.js +2 -318
  677. package/dist/sdk/workspace-recipe.js +1 -71
  678. package/dist/sdk/workspace-snapshot.js +4 -613
  679. package/dist/sdk/workspace-transaction-gc.js +1 -149
  680. package/dist/sdk/workspace-transaction.js +2 -363
  681. package/dist/sdk/workspace.js +3 -127
  682. package/dist/types/index.js +1 -9
  683. package/dist/types.d.ts +4 -0
  684. package/dist/types.js +1 -245
  685. package/docs/AGENT_GUIDE.md +1 -1
  686. package/docs/COMMANDS.md +10 -0
  687. package/docs/CONFIGURATION.md +12 -1
  688. package/docs/CONTEXT_ALGORITHM_PORTFOLIO.md +167 -0
  689. package/docs/DIAGNOSTIC_OUTPUT_CONTRACTS.md +9 -3
  690. package/docs/EXTENSIONS.md +1 -0
  691. package/docs/HISTORY_MAINTENANCE.md +125 -0
  692. package/docs/MCP_2026_07_28_CONFORMANCE.md +20 -10
  693. package/docs/PACKAGE_EVIDENCE.md +92 -0
  694. package/docs/PLANNING_MEASUREMENTS.md +183 -0
  695. package/docs/README.md +4 -0
  696. package/docs/READ_OUTPUT_CONTRACTS.md +5 -0
  697. package/docs/SCRIPTING.md +21 -0
  698. package/docs/TESTING.md +33 -0
  699. package/docs/WORKFLOW_POLICIES.md +129 -0
  700. package/docs/generated/FLAG_LEXICON_BUDGETS.md +7 -7
  701. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +11 -5
  702. package/marketplace.json +2 -2
  703. package/package.json +5 -5
  704. package/packages/pm-beads/package.json +1 -1
  705. package/packages/pm-calendar/package.json +1 -1
  706. package/packages/pm-command-kit/package.json +1 -1
  707. package/packages/pm-digital-twin/package.json +1 -1
  708. package/packages/pm-governance-audit/package.json +1 -1
  709. package/packages/pm-guide-shell/package.json +1 -1
  710. package/packages/pm-kanban/package.json +1 -1
  711. package/packages/pm-lifecycle-hooks/package.json +1 -1
  712. package/packages/pm-linked-test-adapters/package.json +1 -1
  713. package/packages/pm-search-advanced/package.json +1 -1
  714. package/packages/pm-templates/package.json +1 -1
  715. package/packages/pm-todos/package.json +1 -1
  716. package/packages/pm-vcs/package.json +1 -1
  717. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  718. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  719. package/scripts/finalize-build.mjs +45 -3
  720. package/dist/cli-bundle/chunks/chunk-AZDFJGH6.js +0 -9
  721. package/dist/cli-bundle/chunks/chunk-CKOL5U7J.js +0 -77
  722. package/dist/cli-bundle/chunks/chunk-JX4DH4WC.js +0 -3
  723. package/dist/cli-bundle/chunks/chunk-OF76PSDQ.js +0 -5
  724. package/dist/cli-bundle/chunks/chunk-QUWFABDM.js +0 -232
  725. package/dist/cli-bundle/chunks/chunk-QWRRFYK3.js +0 -2
  726. package/dist/cli-bundle/chunks/chunk-RWWBOWJ5.js +0 -2
  727. package/dist/cli-bundle/chunks/chunk-WGAOYSYH.js +0 -40
  728. package/dist/cli-bundle/chunks/chunk-WI2AYPA7.js +0 -2
  729. package/dist/cli-bundle/chunks/register-list-query-5JL52D33.js +0 -11
  730. package/dist/cli-bundle/chunks/register-mutation-ZPG7KMVP.js +0 -20
  731. package/dist/cli-bundle/chunks/register-operations-I5W3KMGB.js +0 -2
  732. package/dist/cli-bundle/chunks/register-setup-H4SVAVX7.js +0 -2
  733. package/dist/cli-bundle/focused-chunks/chunk-AL5ON6K6.js +0 -2
  734. package/dist/cli-bundle/focused-chunks/chunk-CHC2IDXA.js +0 -6
  735. package/dist/cli-bundle/focused-chunks/chunk-CK6QFAPZ.js +0 -20
  736. package/dist/cli-bundle/focused-chunks/chunk-EZR3GHFE.js +0 -2
  737. package/dist/cli-bundle/focused-chunks/chunk-H2WJWK7L.js +0 -56
  738. package/dist/cli-bundle/focused-chunks/chunk-NTPY5GSO.js +0 -3
  739. package/dist/cli-bundle/focused-chunks/chunk-P5O7MP5Y.js +0 -2
  740. package/dist/cli-bundle/focused-chunks/chunk-PDMW2E36.js +0 -177
  741. package/dist/cli-bundle/focused-chunks/chunk-PEFABF7E.js +0 -26
  742. package/dist/cli-bundle/focused-chunks/chunk-QTVCLMSZ.js +0 -6
  743. package/dist/cli-bundle/focused-chunks/chunk-QTZRBUYA.js +0 -8
  744. package/dist/cli-bundle/focused-chunks/chunk-SGQST3PQ.js +0 -12
  745. package/dist/cli-bundle/focused-chunks/chunk-UKHASMMP.js +0 -10
  746. package/dist/cli-bundle/focused-chunks/chunk-ZPEKQHOC.js +0 -2
@@ -1,1894 +1,20 @@
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]="c9d736d1-58bf-5088-aaae-0b89ad61d41f")}catch(e){}}();
3
- import { resolveBodyFileContent, resolveCliBulkIdsInput, EXIT_CODE, splitCommaList, PmCliError, createUnknownSubcommandError, } from "../sdk/runtime-primitives.js";
4
- import { CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS, MERGE_SUBCOMMAND_VALUES, PLAN_CREATE_METADATA_PARAMETER_KEYS, UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS, } from "../sdk/cli-contracts.js";
5
- import { BUILTIN_ITEM_TYPE_VALUES, PLAN_STEP_LINK_KIND_VALUES, } from "../types/index.js";
6
- import { MERGE_DRIVER_ARTIFACT_VALUES, runMergeDriver, runMergeInstall, runMergeReconcile, runMergeReceiptEvidenceReport, } from "./commands/merge.js";
7
- import { runAppend } from "./commands/append.js";
8
- import { runClose } from "./commands/close.js";
9
- import { runCloseMany } from "./commands/close-many.js";
10
- import { runCopy } from "./commands/copy.js";
11
- import { runCreate } from "./commands/create.js";
12
- import { runDelete } from "./commands/delete.js";
13
- import { runDeps } from "./commands/deps.js";
14
- import { runDocs } from "./commands/docs.js";
15
- import { runFiles, runFilesDiscover } from "./commands/files.js";
16
- import { runFocus } from "./commands/focus.js";
17
- import { assertHistoryCompactTarget, runHistoryCompact, runHistoryCompactBulk, } from "./commands/history-compact.js";
18
- import { runHistoryRedact } from "./commands/history-redact.js";
19
- import { assertHistoryRepairTarget, runHistoryRepair, runHistoryRepairAll, } from "./commands/history-repair.js";
20
- import * as profileModule from "./commands/profile.js";
21
- import { runRestore } from "./commands/restore.js";
22
- import * as schemaModule from "./commands/schema.js";
23
- import { runUpdate } from "./commands/update.js";
24
- import { runUpdateMany } from "./commands/update-many.js";
25
- import { createStdinTokenResolver, preserveMutationStdinTokenFields, preserveMutationStdinTokenLiterals, } from "../sdk/runtime-primitives.js";
26
- import { resolveDescriptionStdin } from "./description-stdin.js";
27
- import { itemDocumentToMutationOptions } from "../sdk/structured-mutations.js";
28
- import { registerStructuredMutationCommands } from "./register-structured-mutation.js";
29
- import { registerHistoryAuthorAcknowledgeCommand } from "./register-history-author.js";
30
- import { PLAN_SUBCOMMANDS, runPlan } from "./commands/plan.js";
31
- import { registerAnnotationCommands } from "./register-annotations.js";
32
- import { registerFilesLookupCommand } from "./register-files-lookup.js";
33
- import { isPureSnakeCaseAlias, looksLikeSchemaSubcommandTypo, parseSchemaOrderOption, } from "./schema-registration-helpers.js";
34
- export { looksLikeSchemaSubcommandTypo, parseSchemaOrderOption, } from "./schema-registration-helpers.js";
35
- // Lowercase set of built-in type names ("epic", "feature", ...) used by the
36
- // `pm create` positional guard (pm-edge #1, 2026-05-28): if the single
37
- // positional exactly matches a known type AND no --title was given, we throw
38
- // instead of silently creating a Task titled with the type name.
39
- const BUILTIN_TYPE_NAME_LOOKUP = new Set(BUILTIN_ITEM_TYPE_VALUES.map((value) => value.toLowerCase()));
40
- const PLAN_CREATE_METADATA_OPTION_TARGETS = new Set(PLAN_CREATE_METADATA_PARAMETER_KEYS.map((key) => key === "estimate" ? "estimatedMinutes" : key));
41
- import { collect, applyActiveCommandResultService, addHiddenOption, addHiddenOptions, extractUpdateManyMutationOptionSource, formatHookWarnings, getGlobalOptions, invalidateSearchCachesForMutation, normalizeCreateOptions, normalizeUpdateOptions, printError, printResult, readOptionString, writeStdout, } from "./registration-helpers.js";
42
- function dispatchSchemaMigration(schema, inputs) {
43
- const kind = inputs.normalizedSubcommand;
44
- if (kind !== "rename-type" &&
45
- kind !== "rename-field" &&
46
- kind !== "remap-status") {
47
- return null;
48
- }
49
- return schema.runSchemaEvolutionMigration({
50
- kind,
51
- from: inputs.typeName,
52
- to: readOptionString(inputs.options, "to"),
53
- ...(kind === "rename-field" && typeof inputs.options.type === "string"
54
- ? { type: inputs.options.type }
55
- : {}),
56
- }, {
57
- migrationId: readOptionString(inputs.options, "migrationId") ??
58
- readOptionString(inputs.options, "migration_id"),
59
- dryRun: inputs.options.dryRun === true,
60
- author: inputs.author,
61
- force: inputs.force,
62
- }, inputs.globalOptions);
63
- }
64
- function dispatchSchemaReadRemoveOrPreset(schema, inputs) {
65
- const { normalizedSubcommand, typeName, globalOptions, author, force } = inputs;
66
- switch (normalizedSubcommand) {
67
- case "list":
68
- return schema.runSchemaList(globalOptions);
69
- case "show":
70
- return schema.runSchemaShow(typeName, globalOptions);
71
- case "show-status":
72
- return schema.runSchemaShowStatus(typeName, globalOptions);
73
- case "list-fields":
74
- return schema.runSchemaListFields(globalOptions);
75
- case "show-field":
76
- return schema.runSchemaShowField(typeName, globalOptions);
77
- case "remove-type":
78
- return schema.runSchemaRemoveType(typeName, { author, force }, globalOptions);
79
- case "remove-field":
80
- return schema.runSchemaRemoveField(typeName, { author, force }, globalOptions);
81
- case "remove-status":
82
- return schema.runSchemaRemoveStatus(typeName, { author, force }, globalOptions);
83
- case "apply-preset":
84
- return schema.runSchemaApplyPreset(typeName, { author, force }, globalOptions);
85
- default:
86
- return null;
87
- }
88
- }
89
- /** Routes a normalized `pm schema` subcommand to its run function. Extracted from the schema `.action()` body so the per-subcommand dispatch lives in one single-purpose function and registerMutationCommands stays under the cyclomatic-complexity gate. */
90
- async function dispatchSchemaSubcommand(schema, inputs) {
91
- const { normalizedSubcommand, typeName, options, globalOptions } = inputs;
92
- const { author, force, description } = inputs;
93
- const migration = dispatchSchemaMigration(schema, inputs);
94
- if (migration)
95
- return migration;
96
- const readRemoveOrPreset = dispatchSchemaReadRemoveOrPreset(schema, inputs);
97
- if (readRemoveOrPreset)
98
- return readRemoveOrPreset;
99
- switch (normalizedSubcommand) {
100
- case "add-field":
101
- return schema.runSchemaAddField(typeName, {
102
- type: typeof options.type === "string" ? options.type : undefined,
103
- commands: inputs.commands,
104
- description,
105
- cliFlag: typeof options.cliFlag === "string" ? options.cliFlag : undefined,
106
- alias: inputs.aliases,
107
- required: Boolean(options.required),
108
- requiredOnCreate: Boolean(options.requiredOnCreate),
109
- // commander stores --no-allow-unset as allowUnset:false; the default
110
- // (flag omitted) is true. Forward the tri-state faithfully.
111
- allowUnset: options.allowUnset !== false,
112
- requiredTypes: inputs.requiredTypes,
113
- author,
114
- force,
115
- }, globalOptions);
116
- case "add-status":
117
- return schema.runSchemaAddStatus(typeName, {
118
- role: inputs.roles,
119
- alias: inputs.aliases,
120
- description,
121
- order: inputs.order,
122
- author,
123
- force,
124
- }, globalOptions);
125
- default:
126
- // add-type, optionally in --infer mode.
127
- if (options.infer === true) {
128
- return schema.runSchemaInferTypes({
129
- minCount: inputs.minCount,
130
- apply: Boolean(options.apply),
131
- author,
132
- force,
133
- }, globalOptions);
134
- }
135
- return schema.runSchemaAddType(typeName, {
136
- description,
137
- defaultStatus: inputs.defaultStatus,
138
- folder: typeof options.folder === "string" ? options.folder : undefined,
139
- alias: inputs.aliases,
140
- author,
141
- force,
142
- }, globalOptions);
143
- }
144
- }
145
- /** Renders a schema command result for non-JSON, non-quiet output and surfaces any on-write hook warnings. Extracted from the schema `.action()` body to keep registerMutationCommands under the cyclomatic-complexity gate. */
146
- function renderSchemaResultHuman(schema, result) {
147
- if ("migration_id" in result) {
148
- writeStdout(`${schema.formatSchemaEvolutionMigrationHuman(result)}\n`);
149
- return;
150
- }
151
- switch (result.action) {
152
- case "list":
153
- writeStdout(`${schema.formatSchemaListHuman(result)}\n`);
154
- return;
155
- case "show":
156
- writeStdout(`${schema.formatSchemaShowHuman(result)}\n`);
157
- return;
158
- case "show-status":
159
- writeStdout(`${schema.formatSchemaShowStatusHuman(result)}\n`);
160
- return;
161
- case "list-fields":
162
- writeStdout(`${schema.formatSchemaListFieldsHuman(result)}\n`);
163
- return;
164
- case "show-field":
165
- writeStdout(`${schema.formatSchemaShowFieldHuman(result)}\n`);
166
- return;
167
- case "remove-type":
168
- writeStdout(`${schema.formatSchemaRemoveTypeHuman(result)}\n`);
169
- break;
170
- case "remove-field":
171
- writeStdout(`${schema.formatSchemaRemoveFieldHuman(result)}\n`);
172
- break;
173
- case "apply-preset":
174
- writeStdout(`${schema.formatSchemaApplyPresetHuman(result)}\n`);
175
- break;
176
- case "infer-types":
177
- writeStdout(`${schema.formatSchemaInferTypesHuman(result)}\n`);
178
- break;
179
- case "add-field":
180
- writeStdout(`${schema.formatSchemaAddFieldHuman(result)}\n`);
181
- break;
182
- case "add-status":
183
- writeStdout(`${schema.formatSchemaAddStatusHuman(result)}\n`);
184
- break;
185
- case "remove-status":
186
- writeStdout(`${schema.formatSchemaRemoveStatusHuman(result)}\n`);
187
- break;
188
- default:
189
- writeStdout(`${schema.formatSchemaAddTypeHuman(result)}\n`);
190
- break;
191
- }
192
- // Surface extension on-write hook diagnostics (mutation subcommands only;
193
- // inspection results carry no warnings array).
194
- if (result.warnings.length > 0) {
195
- printError(`schema ${result.action} warnings: ${formatHookWarnings(result.warnings)}`);
196
- }
197
- }
198
- /** Routes a normalized `pm profile` subcommand to its run function. Extracted from the profile `.action()` body so the per-subcommand dispatch lives in one place. */
199
- async function dispatchProfileSubcommand(profile, subcommand, name, options, globalOptions) {
200
- switch (subcommand) {
201
- case "list":
202
- return profile.runProfileList();
203
- case "show":
204
- return profile.runProfileShow(name);
205
- case "lint":
206
- return profile.runProfileLint(name);
207
- default:
208
- return profile.runProfileApply(name, {
209
- dryRun: options.dryRun === true,
210
- author: typeof options.author === "string" ? options.author : undefined,
211
- force: options.force === true,
212
- }, globalOptions);
213
- }
214
- }
215
- /** Renders a profile command result for non-JSON, non-quiet output and surfaces any on-write hook warnings from an apply. */
216
- function renderProfileResultHuman(profile, result) {
217
- switch (result.action) {
218
- case "list":
219
- writeStdout(`${profile.formatProfileListHuman(result)}\n`);
220
- return;
221
- case "show":
222
- writeStdout(`${profile.formatProfileShowHuman(result)}\n`);
223
- return;
224
- case "lint":
225
- writeStdout(`${profile.formatProfileLintHuman(result)}\n`);
226
- return;
227
- default:
228
- writeStdout(`${profile.formatProfileApplyHuman(result)}\n`);
229
- if (result.warnings.length > 0) {
230
- printError(`profile apply warnings: ${formatHookWarnings(result.warnings)}`);
231
- }
232
- break;
233
- }
234
- }
235
- /** Build a commander argParser that coerces a flag value into a positive (1-based) integer, throwing a usage error when the supplied value is not a whole number >= 1. Used by `pm comments --edit/--delete <index>` so an invalid index fails fast with a clear message instead of silently coercing. */
236
- export function parsePositiveIntOption(flag) {
237
- return (value) => {
238
- const parsed = Number(value);
239
- if (!Number.isInteger(parsed) || parsed < 1) {
240
- throw new PmCliError(`${flag} must be a positive integer (1-based index).`, EXIT_CODE.USAGE);
241
- }
242
- return parsed;
243
- };
244
- }
245
- // Bulk content-field selection filters (GH-242) shared by update-many and
246
- // close-many. Each pair mirrors the list-family presence/absence flags but uses
247
- // the `--filter-` prefix so they live in the bulk-selection namespace. The
248
- // governance-missing filters (GH-236) reuse the same `--filter-<gov>-missing`
249
- // spelling as the list family.
250
- function registerBulkContentAndGovernanceFilters(command, action) {
251
- command
252
- .option("--filter-has-notes", `Select only items that have notes before ${action}`)
253
- .option("--filter-no-notes", `Select only items that have no notes before ${action}`)
254
- .option("--filter-has-learnings", `Select only items that have learnings before ${action}`)
255
- .option("--filter-no-learnings", `Select only items that have no learnings before ${action}`)
256
- .option("--filter-has-files", `Select only items that have linked files before ${action}`)
257
- .option("--filter-no-files", `Select only items that have no linked files before ${action}`)
258
- .option("--filter-has-docs", `Select only items that have linked docs before ${action}`)
259
- .option("--filter-no-docs", `Select only items that have no linked docs before ${action}`)
260
- .option("--filter-has-tests", `Select only items that have linked tests before ${action}`)
261
- .option("--filter-no-tests", `Select only items that have no linked tests before ${action}`)
262
- .option("--filter-has-comments", `Select only items that have comments before ${action}`)
263
- .option("--filter-no-comments", `Select only items that have no comments before ${action}`)
264
- .option("--filter-has-deps", `Select only items that have dependencies before ${action}`)
265
- .option("--filter-no-deps", `Select only items that have no dependencies before ${action}`)
266
- .option("--filter-has-body", `Select only items that have a non-empty body before ${action}`)
267
- .option("--filter-empty-body", `Select only items with an empty body before ${action}`)
268
- .option("--filter-has-linked-command", `Select only items whose linked tests carry a runnable command before ${action}`)
269
- .option("--filter-no-linked-command", `Select only items whose linked tests carry no runnable command before ${action}`)
270
- .option("--filter-reviewer-missing", `Select only items missing reviewer before ${action}`)
271
- .option("--filter-risk-missing", `Select only items missing risk before ${action}`)
272
- .option("--filter-confidence-missing", `Select only items missing confidence before ${action}`)
273
- .option("--filter-sprint-missing", `Select only items missing sprint before ${action}`)
274
- .option("--filter-release-missing", `Select only items missing release before ${action}`);
275
- }
276
- // Map the bulk content/governance `--filter-*` commander options into the
277
- // ListOptions content/governance fields runList consumes. Shared by update-many
278
- // and close-many.
279
- // [hasCommanderKey, noCommanderKey, --filter-has flag, --filter-no flag]
280
- const BULK_CONTENT_FILTER_CONFLICTS = [
281
- [
282
- "filterHasNotes",
283
- "filterNoNotes",
284
- "--filter-has-notes",
285
- "--filter-no-notes",
286
- ],
287
- [
288
- "filterHasLearnings",
289
- "filterNoLearnings",
290
- "--filter-has-learnings",
291
- "--filter-no-learnings",
292
- ],
293
- [
294
- "filterHasFiles",
295
- "filterNoFiles",
296
- "--filter-has-files",
297
- "--filter-no-files",
298
- ],
299
- ["filterHasDocs", "filterNoDocs", "--filter-has-docs", "--filter-no-docs"],
300
- [
301
- "filterHasTests",
302
- "filterNoTests",
303
- "--filter-has-tests",
304
- "--filter-no-tests",
305
- ],
306
- [
307
- "filterHasComments",
308
- "filterNoComments",
309
- "--filter-has-comments",
310
- "--filter-no-comments",
311
- ],
312
- ["filterHasDeps", "filterNoDeps", "--filter-has-deps", "--filter-no-deps"],
313
- [
314
- "filterHasBody",
315
- "filterEmptyBody",
316
- "--filter-has-body",
317
- "--filter-empty-body",
318
- ],
319
- [
320
- "filterHasLinkedCommand",
321
- "filterNoLinkedCommand",
322
- "--filter-has-linked-command",
323
- "--filter-no-linked-command",
324
- ],
325
- ];
326
- function mapBulkContentAndGovernanceFilters(options) {
327
- const presence = (key) => options[key] === true ? true : undefined;
328
- // Catch a both-present-and-absent bulk request here so the error names the
329
- // bulk --filter-* flags the user actually typed, rather than the downstream
330
- // list-level --has-/--no- flags resolveContentFieldFilters would report.
331
- for (const [hasKey, noKey, hasFlag, noFlag,] of BULK_CONTENT_FILTER_CONFLICTS) {
332
- if (options[hasKey] === true && options[noKey] === true) {
333
- throw new PmCliError(`Cannot combine ${hasFlag} with ${noFlag} for the same field.`, EXIT_CODE.USAGE);
334
- }
335
- }
336
- return {
337
- filterReviewerMissing: presence("filterReviewerMissing"),
338
- filterRiskMissing: presence("filterRiskMissing"),
339
- filterConfidenceMissing: presence("filterConfidenceMissing"),
340
- filterSprintMissing: presence("filterSprintMissing"),
341
- filterReleaseMissing: presence("filterReleaseMissing"),
342
- hasNotes: presence("filterHasNotes"),
343
- hasLearnings: presence("filterHasLearnings"),
344
- hasFiles: presence("filterHasFiles"),
345
- hasDocs: presence("filterHasDocs"),
346
- hasTests: presence("filterHasTests"),
347
- hasComments: presence("filterHasComments"),
348
- hasDeps: presence("filterHasDeps"),
349
- hasBody: presence("filterHasBody"),
350
- hasLinkedCommand: presence("filterHasLinkedCommand"),
351
- noNotes: presence("filterNoNotes"),
352
- noLearnings: presence("filterNoLearnings"),
353
- noFiles: presence("filterNoFiles"),
354
- noDocs: presence("filterNoDocs"),
355
- noTests: presence("filterNoTests"),
356
- noComments: presence("filterNoComments"),
357
- noDeps: presence("filterNoDeps"),
358
- emptyBody: presence("filterEmptyBody"),
359
- noLinkedCommand: presence("filterNoLinkedCommand"),
360
- };
361
- }
362
- /** Implements register commander option contracts for the public runtime surface of this module. */
363
- export function registerCommanderOptionContracts(command, contracts) {
364
- for (const contract of contracts) {
365
- const sharedValues = [];
366
- let activeParseArgs = command.args;
367
- const repeatableParser = (value) => {
368
- if (command.args !== activeParseArgs) {
369
- sharedValues.length = 0;
370
- activeParseArgs = command.args;
371
- }
372
- sharedValues.push(value);
373
- return sharedValues;
374
- };
375
- if (contract.required) {
376
- command.requiredOption(contract.option, contract.description);
377
- }
378
- else if (contract.repeatable) {
379
- command.option(contract.option, contract.description, repeatableParser);
380
- }
381
- else {
382
- command.option(contract.option, contract.description);
383
- }
384
- for (const aliasContract of contract.aliasOptions ?? []) {
385
- // Hide pure snake_case underscore-duplicate aliases (e.g. --create_mode
386
- // for --create-mode) from --help, but keep semantically-distinct aliases
387
- // (e.g. --ac for --acceptance-criteria) visible.
388
- if (isPureSnakeCaseAlias(contract.option, aliasContract.option)) {
389
- addHiddenOption(command, aliasContract.option, aliasContract.description, contract.repeatable === true, contract.repeatable ? repeatableParser : undefined);
390
- }
391
- else if (contract.repeatable) {
392
- command.option(aliasContract.option, aliasContract.description, repeatableParser);
393
- }
394
- else {
395
- command.option(aliasContract.option, aliasContract.description);
396
- }
397
- }
398
- }
399
- }
400
- /** Map raw `update-many --filter-*` commander options into the ListOptions shape runList consumes. Extracted from registerMutationCommands so its many string/boolean coercions do not inflate that function's cyclomatic complexity. */
401
- function buildUpdateManyListOptions(options) {
402
- const readString = (key) => typeof options[key] === "string" ? options[key] : undefined;
403
- return {
404
- type: readString("filterType"),
405
- tag: readString("filterTag"),
406
- priority: readString("filterPriority"),
407
- deadlineBefore: readString("filterDeadlineBefore"),
408
- deadlineAfter: readString("filterDeadlineAfter"),
409
- updatedAfter: readString("filterUpdatedAfter"),
410
- updatedBefore: readString("filterUpdatedBefore"),
411
- createdAfter: readString("filterCreatedAfter"),
412
- createdBefore: readString("filterCreatedBefore"),
413
- ids: readString("ids"),
414
- assignee: readString("filterAssignee"),
415
- assigneeFilter: readString("filterAssigneeFilter") ?? readString("filterAssignee_filter"),
416
- parent: readString("filterParent"),
417
- sprint: readString("filterSprint"),
418
- release: readString("filterRelease"),
419
- filterAcMissing: options.filterAcMissing === true ? true : undefined,
420
- filterEstimatesMissing: options.filterEstimatesMissing === true ||
421
- options.filterEstimateMissing === true
422
- ? true
423
- : undefined,
424
- filterResolutionMissing: options.filterResolutionMissing === true ? true : undefined,
425
- filterMetadataMissing: options.filterMetadataMissing === true ? true : undefined,
426
- ...mapBulkContentAndGovernanceFilters(options),
427
- limit: readString("limit"),
428
- offset: readString("offset"),
429
- includeBody: true,
430
- };
431
- }
432
- function pickStringOption(...candidates) {
433
- for (const candidate of candidates) {
434
- if (typeof candidate === "string") {
435
- return candidate;
436
- }
437
- }
438
- return undefined;
439
- }
440
- function stringArrayOption(value) {
441
- if (Array.isArray(value)) {
442
- return value;
443
- }
444
- if (typeof value === "string") {
445
- return [value];
446
- }
447
- return undefined;
448
- }
449
- function resolveCreatePositionals(typeOrTitle, secondTitle, options) {
450
- if (typeof secondTitle === "string" && secondTitle.length > 0) {
451
- return { positionalType: typeOrTitle, positionalTitle: secondTitle };
452
- }
453
- if (typeof typeOrTitle !== "string" || typeOrTitle.length === 0) {
454
- return { positionalType: undefined, positionalTitle: undefined };
455
- }
456
- const explicitTitleProvided = typeof options.title === "string" && options.title.trim().length > 0;
457
- return explicitTitleProvided && options.type === undefined
458
- ? { positionalType: typeOrTitle, positionalTitle: undefined }
459
- : { positionalType: undefined, positionalTitle: typeOrTitle };
460
- }
461
- function assertCreatePositionalTypeHasTitle(positionalType, positionalTitle, options) {
462
- if (positionalType !== undefined ||
463
- typeof positionalTitle !== "string" ||
464
- positionalTitle.length === 0 ||
465
- options.title !== undefined ||
466
- options.type !== undefined ||
467
- !BUILTIN_TYPE_NAME_LOOKUP.has(positionalTitle.trim().toLowerCase())) {
468
- return;
469
- }
470
- const matchedType = positionalTitle.trim();
471
- throw new PmCliError(`pm create needs a title — "${matchedType}" looks like an item type, not a title. Use either: pm create ${matchedType} "<title>" or pm create "<title>" --type ${matchedType}.`, EXIT_CODE.USAGE, {
472
- code: "create_positional_type_without_title",
473
- why: 'Without this guard the single positional is used as the title and the type defaults to Task — so the command would silently create a Task literally titled "' +
474
- matchedType +
475
- '".',
476
- examples: [
477
- `pm create ${matchedType} "Wire up SSO for the agent harness"`,
478
- `pm create "Wire up SSO for the agent harness" --type ${matchedType}`,
479
- ],
480
- nextSteps: [
481
- `Re-run with both type and title: pm create ${matchedType} "<title>"`,
482
- ],
483
- });
484
- }
485
- const STRUCTURED_STDIN_CONFLICT_KEYS = [
486
- "body",
487
- "bodyFile",
488
- "description",
489
- "dep",
490
- "depRemove",
491
- "comment",
492
- "note",
493
- "learning",
494
- "file",
495
- "test",
496
- "doc",
497
- "reminder",
498
- "event",
499
- "typeOption",
500
- "field",
501
- "ids",
502
- ];
503
- function assertSingleMutationStdinConsumer(options) {
504
- const stdinFlags = STRUCTURED_STDIN_CONFLICT_KEYS.flatMap((key) => {
505
- const value = options[key];
506
- const count = typeof value === "string" && value.trim() === "-"
507
- ? 1
508
- : Array.isArray(value)
509
- ? value.filter((entry) => typeof entry === "string" && entry.trim() === "-").length
510
- : 0;
511
- const flag = `--${key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}`;
512
- return Array.from({ length: count }, () => flag);
513
- });
514
- if (options.stdinJson === true) {
515
- stdinFlags.unshift("--stdin-json");
516
- }
517
- if (stdinFlags.length > 1) {
518
- throw new PmCliError(`Only one option may consume stdin per command invocation. Found: ${stdinFlags.join(", ")}.`, EXIT_CODE.USAGE);
519
- }
520
- }
521
- function preserveResolvedMutationStdinFields(options, bodyFileResolved, descriptionStdinResolved) {
522
- const fields = [];
523
- if (bodyFileResolved)
524
- fields.push("body");
525
- if (descriptionStdinResolved)
526
- fields.push("description");
527
- preserveMutationStdinTokenFields(options, fields);
528
- }
529
- function isDescriptionStdinConsumer(options, stdinJsonConsumed) {
530
- return (!stdinJsonConsumed &&
531
- typeof options.description === "string" &&
532
- options.description.trim() === "-");
533
- }
534
- async function runCreateAction(typeOrTitle, secondTitle, options, command) {
535
- const globalOptions = getGlobalOptions(command);
536
- const startedAt = Date.now();
537
- assertSingleMutationStdinConsumer(options);
538
- const stdinJsonConsumed = options.stdinJson === true;
539
- if (stdinJsonConsumed) {
540
- const input = await createStdinTokenResolver().resolveValue("-", "--stdin-json");
541
- options = itemDocumentToMutationOptions(input ?? "", "create", options);
542
- }
543
- const positionals = resolveCreatePositionals(typeOrTitle, secondTitle, options);
544
- assertCreatePositionalTypeHasTitle(positionals.positionalType, positionals.positionalTitle, options);
545
- if (typeof positionals.positionalType === "string" &&
546
- positionals.positionalType.length > 0 &&
547
- options.type === undefined) {
548
- options.type = positionals.positionalType;
549
- }
550
- if (typeof positionals.positionalTitle === "string" &&
551
- positionals.positionalTitle.length > 0 &&
552
- options.title === undefined)
553
- options.title = positionals.positionalTitle;
554
- const descriptionStdinResolved = isDescriptionStdinConsumer(options, stdinJsonConsumed);
555
- if (!stdinJsonConsumed) {
556
- await resolveDescriptionStdin(options);
557
- }
558
- const bodyFileResolved = typeof options.bodyFile === "string";
559
- if (bodyFileResolved) {
560
- options.body = await resolveBodyFileContent(String(options.bodyFile), options.body !== undefined ? String(options.body) : undefined);
561
- delete options.bodyFile;
562
- }
563
- const normalized = normalizeCreateOptions(options, { requireType: false });
564
- preserveResolvedMutationStdinFields(normalized, bodyFileResolved, descriptionStdinResolved);
565
- if (stdinJsonConsumed)
566
- preserveMutationStdinTokenLiterals(normalized);
567
- const result = await runCreate(normalized, globalOptions);
568
- await invalidateSearchCachesForMutation(globalOptions, result);
569
- printResult(result, globalOptions);
570
- if (globalOptions.profile) {
571
- printError(`profile:command=create took_ms=${Date.now() - startedAt}`);
572
- }
573
- }
574
- function buildCloseManyListOptions(options) {
575
- return {
576
- type: readOptionString(options, "filterType"),
577
- tag: readOptionString(options, "filterTag"),
578
- priority: readOptionString(options, "filterPriority"),
579
- deadlineBefore: readOptionString(options, "filterDeadlineBefore"),
580
- deadlineAfter: readOptionString(options, "filterDeadlineAfter"),
581
- updatedAfter: readOptionString(options, "filterUpdatedAfter"),
582
- updatedBefore: readOptionString(options, "filterUpdatedBefore"),
583
- createdAfter: readOptionString(options, "filterCreatedAfter"),
584
- createdBefore: readOptionString(options, "filterCreatedBefore"),
585
- ids: readOptionString(options, "ids"),
586
- assignee: readOptionString(options, "filterAssignee"),
587
- assigneeFilter: pickStringOption(options.filterAssigneeFilter, options.filterAssignee_filter),
588
- parent: readOptionString(options, "filterParent"),
589
- sprint: readOptionString(options, "filterSprint"),
590
- release: readOptionString(options, "filterRelease"),
591
- ...mapBulkContentAndGovernanceFilters(options),
592
- limit: readOptionString(options, "limit"),
593
- offset: readOptionString(options, "offset"),
594
- };
595
- }
596
- async function runCloseManyAction(options, command) {
597
- const globalOptions = getGlobalOptions(command);
598
- const startedAt = Date.now();
599
- assertSingleMutationStdinConsumer(options);
600
- options.ids = await resolveCliBulkIdsInput(readOptionString(options, "ids"));
601
- const result = await runCloseMany({
602
- status: readOptionString(options, "filterStatus"),
603
- list: buildCloseManyListOptions(options),
604
- reason: readOptionString(options, "reason"),
605
- completedAt: readOptionString(options, "completedAt"),
606
- resolution: readOptionString(options, "resolution"),
607
- expectedResult: pickStringOption(options.expectedResult, options.expected_result, options.expected),
608
- actualResult: pickStringOption(options.actualResult, options.actual_result, options.actual),
609
- validateClose: options.validateClose === true
610
- ? "warn"
611
- : readOptionString(options, "validateClose"),
612
- author: readOptionString(options, "author"),
613
- message: readOptionString(options, "message"),
614
- force: Boolean(options.force),
615
- dryRun: options.dryRun === true ? true : undefined,
616
- rollback: readOptionString(options, "rollback"),
617
- checkpoint: options.checkpoint === false ? false : undefined,
618
- }, globalOptions);
619
- await invalidateSearchCachesForMutation(globalOptions, result);
620
- printResult(result, globalOptions);
621
- if (globalOptions.profile) {
622
- printError(`profile:command=close-many took_ms=${Date.now() - startedAt}`);
623
- }
624
- }
625
- async function runUpdateManyAction(options, command) {
626
- const globalOptions = getGlobalOptions(command);
627
- const startedAt = Date.now();
628
- assertSingleMutationStdinConsumer(options);
629
- options.ids = await resolveCliBulkIdsInput(readOptionString(options, "ids"));
630
- const result = await runUpdateMany({
631
- status: readOptionString(options, "filterStatus"),
632
- list: buildUpdateManyListOptions(options),
633
- update: normalizeUpdateOptions(extractUpdateManyMutationOptionSource(options)),
634
- dryRun: options.dryRun === true ? true : undefined,
635
- rollback: readOptionString(options, "rollback"),
636
- checkpoint: options.checkpoint === false ? false : undefined,
637
- }, globalOptions);
638
- await invalidateSearchCachesForMutation(globalOptions, result);
639
- printResult(await applyActiveCommandResultService("update-many", [], options, globalOptions, result), globalOptions);
640
- if (globalOptions.profile) {
641
- printError(`profile:command=update-many took_ms=${Date.now() - startedAt}`);
642
- }
643
- }
644
- async function runCloseAction(id, text, options, command) {
645
- const globalOptions = getGlobalOptions(command);
646
- const startedAt = Date.now();
647
- const reasonFromOption = (typeof options.reason === "string" &&
648
- options.reason.trim().length > 0 &&
649
- options.reason) ||
650
- (typeof options.closeReason === "string" &&
651
- options.closeReason.trim().length > 0 &&
652
- options.closeReason) ||
653
- undefined;
654
- const resolvedText = typeof text === "string" && text.length > 0 ? text : reasonFromOption;
655
- const result = await runClose(id, resolvedText, {
656
- author: readOptionString(options, "author"),
657
- message: readOptionString(options, "message"),
658
- validateClose: options.validateClose === true
659
- ? "warn"
660
- : readOptionString(options, "validateClose"),
661
- force: Boolean(options.force),
662
- duplicateOf: readOptionString(options, "duplicateOf"),
663
- completedAt: readOptionString(options, "completedAt"),
664
- resolution: readOptionString(options, "resolution"),
665
- expectedResult: pickStringOption(options.expectedResult, options.expected_result, options.expected),
666
- actualResult: pickStringOption(options.actualResult, options.actual_result, options.actual),
667
- }, globalOptions);
668
- await invalidateSearchCachesForMutation(globalOptions, result);
669
- printResult(result, globalOptions);
670
- if (globalOptions.profile) {
671
- printError(`profile:command=close took_ms=${Date.now() - startedAt}`);
672
- }
673
- }
674
- function normalizePlanAliases(options) {
675
- const planOptions = { ...options };
676
- const aliasPairs = [
677
- ["blocked_by", "blockedBy"],
678
- ["resume_context", "resumeContext"],
679
- ["from_search", "fromSearch"],
680
- ["step_title", "stepTitle"],
681
- ["step_body", "stepBody"],
682
- ["step_owner", "stepOwner"],
683
- ["step_status", "stepStatus"],
684
- ["step_evidence", "stepEvidence"],
685
- ["step_blocked_reason", "stepBlockedReason"],
686
- ["step_replacement", "stepReplacement"],
687
- ["depends_on", "dependsOn"],
688
- ["link_kind", "linkKind"],
689
- ["link_note", "linkNote"],
690
- ["promote_to_item_dep", "promoteToItemDep"],
691
- ["allow_multiple_active", "allowMultipleActive"],
692
- ["decision_text", "decisionText"],
693
- ["decision_rationale", "decisionRationale"],
694
- ["decision_evidence", "decisionEvidence"],
695
- ["discovery_text", "discoveryText"],
696
- ["validation_text", "validationText"],
697
- ["validation_command", "validationCommand"],
698
- ["validation_expected", "validationExpected"],
699
- ["materialize_type", "materializeType"],
700
- ["materialize_parent", "materializeParent"],
701
- ["materialize_tags", "materializeTags"],
702
- ];
703
- for (const [snake, camel] of aliasPairs) {
704
- if (planOptions[snake] !== undefined && planOptions[camel] === undefined) {
705
- planOptions[camel] = planOptions[snake];
706
- }
707
- }
708
- const normalized = normalizeCreateOptions(planOptions, {
709
- requireType: false,
710
- });
711
- normalized.blockedBy = planOptions.blockedBy;
712
- return normalized;
713
- }
714
- function assertKnownPlanSubcommand(normalized, allowed) {
715
- if (!normalized) {
716
- throw new PmCliError(`pm plan requires a subcommand. Allowed: ${allowed.join(", ")}`, EXIT_CODE.USAGE, {
717
- code: "missing_required_argument",
718
- examples: [
719
- 'pm plan create --title "Refactor lock retry"',
720
- "pm plan show pm-a1b2 --depth standard",
721
- 'pm plan add-step pm-a1b2 --step-title "Read lock.ts"',
722
- ],
723
- });
724
- }
725
- if (allowed.includes(normalized)) {
726
- return;
727
- }
728
- const examples = normalized === "list" || normalized === "ls"
729
- ? ["pm list --type Plan", "pm list-all --type Plan"]
730
- : undefined;
731
- throw createUnknownSubcommandError({
732
- command_path: "plan",
733
- token: normalized,
734
- allowed,
735
- examples,
736
- retry_command: normalized === "list" || normalized === "ls"
737
- ? "pm list --type Plan"
738
- : undefined,
739
- });
740
- }
741
- function parsePlanReorderTo(normalizedSubcommand, reorderToken) {
742
- if (normalizedSubcommand !== "reorder-step" ||
743
- typeof reorderToken !== "string") {
744
- return undefined;
745
- }
746
- const parsed = Number.parseInt(reorderToken, 10);
747
- if (!Number.isFinite(parsed)) {
748
- throw new PmCliError(`reorder-step requires an integer new order, got "${reorderToken}"`, EXIT_CODE.USAGE);
749
- }
750
- return parsed;
751
- }
752
- async function runPlanAction(subcommand, id, stepRef, reorderToken, options, command) {
753
- const globalOptions = getGlobalOptions(command);
754
- const startedAt = Date.now();
755
- const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
756
- assertKnownPlanSubcommand(normalizedSubcommand, PLAN_SUBCOMMANDS);
757
- const planOptions = normalizePlanAliases(options);
758
- const reorderTo = parsePlanReorderTo(normalizedSubcommand, reorderToken);
759
- const planId = normalizedSubcommand === "create" &&
760
- typeof id === "string" &&
761
- id.length > 0 &&
762
- planOptions.title === undefined
763
- ? undefined
764
- : id;
765
- if (planId === undefined && typeof id === "string" && id.length > 0) {
766
- planOptions.title = id;
767
- }
768
- const result = await runPlan({
769
- subcommand: normalizedSubcommand,
770
- id: planId,
771
- stepRef,
772
- reorderTo,
773
- options: planOptions,
774
- global: globalOptions,
775
- });
776
- await invalidateSearchCachesForMutation(globalOptions, result);
777
- printResult(result, globalOptions);
778
- if (globalOptions.profile) {
779
- printError(`profile:command=plan took_ms=${Date.now() - startedAt}`);
780
- }
781
- }
782
- function parseNonNegativeIntFlag(raw, flag) {
783
- if (typeof raw !== "string") {
784
- return undefined;
785
- }
786
- if (!/^\d+$/.test(raw.trim())) {
787
- throw new PmCliError(`history-compact ${flag} must be a non-negative integer.`, EXIT_CODE.USAGE);
788
- }
789
- return Number.parseInt(raw, 10);
790
- }
791
- /** Run the audited post-merge reconciliation branch and map failures to CLI exit state. */
792
- async function runMergeReconcileSubcommand(artifact, options, globalOptions) {
793
- if (artifact !== undefined) {
794
- throw new PmCliError("merge reconcile takes no positional arguments.", EXIT_CODE.USAGE);
795
- }
796
- const result = await runMergeReconcile({
797
- dryRun: options.dryRun === true,
798
- force: options.force === true,
799
- message: typeof options.message === "string" ? options.message : undefined,
800
- author: globalOptions.author,
801
- }, globalOptions);
802
- printResult(result, globalOptions);
803
- if (!result.ok)
804
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
805
- }
806
- /** Run the field-aware merge-driver branch and map unresolved conflicts to git's expected nonzero exit state. */
807
- async function runMergeDriverSubcommand(artifact, base, ours, theirs, options, globalOptions) {
808
- if (artifact === undefined ||
809
- base === undefined ||
810
- ours === undefined ||
811
- theirs === undefined) {
812
- throw new PmCliError("merge driver requires <artifact> <base> <ours> <theirs> (git supplies %O %A %B). Example: pm merge driver history %O %A %B", EXIT_CODE.USAGE);
813
- }
814
- const result = await runMergeDriver({
815
- artifact,
816
- basePath: base,
817
- oursPath: ours,
818
- theirsPath: theirs,
819
- outputPath: typeof options.output === "string" ? options.output : undefined,
820
- itemPath: typeof options.itemPath === "string" ? options.itemPath : undefined,
821
- prefer: typeof options.prefer === "string" ? options.prefer : undefined,
822
- }, globalOptions);
823
- printResult(result, globalOptions);
824
- if (!result.ok) {
825
- // Nonzero exit tells git the path is still conflicted; the merged file
826
- // stays parseable with the preferred side's values.
827
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
828
- }
829
- }
830
- async function runMergeAction(subcommand, artifact, base, ours, theirs, options, command) {
831
- const globalOptions = getGlobalOptions(command);
832
- const startedAt = Date.now();
833
- const normalized = subcommand.trim().toLowerCase();
834
- switch (normalized) {
835
- case "install": {
836
- if (artifact !== undefined) {
837
- throw new PmCliError("merge install takes no positional arguments.", EXIT_CODE.USAGE);
838
- }
839
- const result = await runMergeInstall({ dryRun: options.dryRun === true }, globalOptions);
840
- printResult(result, globalOptions);
841
- break;
842
- }
843
- case "reconcile":
844
- await runMergeReconcileSubcommand(artifact, options, globalOptions);
845
- break;
846
- case "report": {
847
- if (artifact !== undefined) {
848
- throw new PmCliError("merge report takes no positional arguments.", EXIT_CODE.USAGE);
849
- }
850
- const result = await runMergeReceiptEvidenceReport({
851
- includeReconciled: options.includeReconciled === true,
852
- });
853
- printResult(result, globalOptions);
854
- if (!result.ok)
855
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
856
- break;
857
- }
858
- case "driver":
859
- await runMergeDriverSubcommand(artifact, base, ours, theirs, options, globalOptions);
860
- break;
861
- default:
862
- throw createUnknownSubcommandError({
863
- command_path: "merge",
864
- token: subcommand,
865
- allowed: MERGE_SUBCOMMAND_VALUES,
866
- display_name: "merge",
867
- });
868
- }
869
- if (globalOptions.profile) {
870
- printError(`profile:command=merge took_ms=${Date.now() - startedAt}`);
871
- }
872
- }
873
- async function runHistoryCompactAction(id, options, command) {
874
- const globalOptions = getGlobalOptions(command);
875
- const startedAt = Date.now();
876
- const idsValue = await resolveCliBulkIdsInput(readOptionString(options, "ids"));
877
- const ids = idsValue === undefined ? undefined : splitCommaList(idsValue);
878
- const allOver = parseNonNegativeIntFlag(options.allOver, "--all-over");
879
- const minEntries = parseNonNegativeIntFlag(options.minEntries, "--min-entries");
880
- if (options.closed === true && options.allStreams === true) {
881
- throw new PmCliError("history-compact: --closed and --all-streams are mutually exclusive; pick one lifecycle scope.", EXIT_CODE.USAGE);
882
- }
883
- const scope = options.closed === true
884
- ? "closed"
885
- : options.allStreams === true
886
- ? "all-streams"
887
- : undefined;
888
- const isBulk = ids !== undefined || allOver !== undefined || scope !== undefined;
889
- if (isBulk && typeof options.before === "string") {
890
- throw new PmCliError("history-compact: --before applies only in single-id mode (bulk mode always compacts full streams).", EXIT_CODE.USAGE);
891
- }
892
- assertHistoryCompactTarget(id, { ids, allOver, scope });
893
- if (id === undefined) {
894
- const result = await runHistoryCompactBulk({
895
- ids,
896
- scope,
897
- allOver,
898
- minEntries,
899
- dryRun: options.dryRun === true,
900
- author: readOptionString(options, "author"),
901
- message: readOptionString(options, "message"),
902
- force: Boolean(options.force),
903
- }, globalOptions);
904
- printResult(result, globalOptions);
905
- if (result.totals.items_errored > 0) {
906
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
907
- }
908
- }
909
- else {
910
- const result = await runHistoryCompact(id, {
911
- before: readOptionString(options, "before"),
912
- dryRun: options.dryRun === true,
913
- author: readOptionString(options, "author"),
914
- message: readOptionString(options, "message"),
915
- force: Boolean(options.force),
916
- }, globalOptions);
917
- printResult(result, globalOptions);
918
- }
919
- if (globalOptions.profile) {
920
- printError(`profile:command=history-compact took_ms=${Date.now() - startedAt}`);
921
- }
922
- }
923
- function splitCollectedCommaList(raw) {
924
- if (!Array.isArray(raw)) {
925
- return undefined;
926
- }
927
- return raw
928
- .flatMap((value) => value.split(","))
929
- .map((value) => value.trim())
930
- .filter((value) => value.length > 0);
931
- }
932
- async function runSchemaAction(subcommand, name, options, command) {
933
- const globalOptions = getGlobalOptions(command);
934
- const startedAt = Date.now();
935
- const { SCHEMA_SUBCOMMANDS } = schemaModule;
936
- let normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
937
- let typeName = name;
938
- assertSchemaSubcommandPresent(normalizedSubcommand, SCHEMA_SUBCOMMANDS);
939
- if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand) &&
940
- typeName === undefined &&
941
- !looksLikeSchemaSubcommandTypo(subcommand)) {
942
- typeName = subcommand;
943
- normalizedSubcommand = "add-type";
944
- }
945
- if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand)) {
946
- throw createUnknownSubcommandError({
947
- command_path: "schema",
948
- token: normalizedSubcommand,
949
- allowed: SCHEMA_SUBCOMMANDS,
950
- });
951
- }
952
- const result = await dispatchSchemaSubcommand(schemaModule, {
953
- normalizedSubcommand,
954
- typeName,
955
- options,
956
- aliases: stringArrayOption(options.alias),
957
- roles: stringArrayOption(options.role),
958
- commands: splitCollectedCommaList(options.commands),
959
- requiredTypes: splitCollectedCommaList(options.requiredTypes),
960
- defaultStatus: pickStringOption(options.defaultStatus, options.default_status),
961
- order: parseSchemaOrderOption(options.order),
962
- minCount: parseSchemaOrderOption(options.minCount),
963
- author: readOptionString(options, "author"),
964
- force: Boolean(options.force),
965
- description: readOptionString(options, "description"),
966
- globalOptions,
967
- });
968
- if (globalOptions.json === true ||
969
- globalOptions.defaultOutputFormat === "json") {
970
- printResult(result, globalOptions);
971
- }
972
- else if (!globalOptions.quiet) {
973
- renderSchemaResultHuman(schemaModule, result);
974
- }
975
- if (globalOptions.profile) {
976
- printError(`profile:command=schema took_ms=${Date.now() - startedAt}`);
977
- }
978
- }
979
- function assertSchemaSubcommandPresent(normalizedSubcommand, allowed) {
980
- if (normalizedSubcommand) {
981
- return;
982
- }
983
- throw new PmCliError(`pm schema requires a subcommand. Allowed: ${allowed.join(", ")}`, EXIT_CODE.USAGE, {
984
- code: "missing_required_argument",
985
- examples: [
986
- "pm schema list",
987
- "pm schema show Task",
988
- "pm schema show-status open",
989
- 'pm schema add-type Spike --description "Time-boxed investigation" --default-status open',
990
- "pm schema remove-type Spike",
991
- "pm schema add-status review --role active --alias in_review",
992
- "pm schema remove-status review",
993
- "pm schema add-field severity_level --type string --commands create,update",
994
- "pm schema list-fields",
995
- "pm schema apply-preset agile",
996
- "pm schema add-type --infer --min-count 10",
997
- "pm schema rename-type Spike --to Experiment --migration-id spike-v2 --dry-run",
998
- "pm schema rename-field severity --to impact --migration-id severity-v2",
999
- "pm schema remap-status review --to verifying --migration-id review-v2",
1000
- ],
1001
- });
1002
- }
1003
- async function runCopyAction(id, options, command) {
1004
- const globalOptions = getGlobalOptions(command);
1005
- const startedAt = Date.now();
1006
- const result = await runCopy(id, {
1007
- title: readOptionString(options, "title"),
1008
- author: readOptionString(options, "author"),
1009
- message: readOptionString(options, "message"),
1010
- allowDuplicate: options.allowDuplicate === true,
1011
- }, globalOptions);
1012
- await invalidateSearchCachesForMutation(globalOptions, result);
1013
- printResult(result, globalOptions);
1014
- if (globalOptions.profile) {
1015
- printError(`profile:command=copy took_ms=${Date.now() - startedAt}`);
1016
- }
1017
- }
1018
- async function runFocusAction(id, options, command) {
1019
- const globalOptions = getGlobalOptions(command);
1020
- const startedAt = Date.now();
1021
- const result = await runFocus(id, { clear: options.clear === true }, globalOptions);
1022
- printResult(result, globalOptions);
1023
- if (globalOptions.profile) {
1024
- printError(`profile:command=focus took_ms=${Date.now() - startedAt}`);
1025
- }
1026
- }
1027
- async function runUpdateAction(id, options, command) {
1028
- const globalOptions = getGlobalOptions(command);
1029
- const startedAt = Date.now();
1030
- assertSingleMutationStdinConsumer(options);
1031
- const stdinJsonConsumed = options.stdinJson === true;
1032
- if (stdinJsonConsumed) {
1033
- const input = await createStdinTokenResolver().resolveValue("-", "--stdin-json");
1034
- options = itemDocumentToMutationOptions(input ?? "", "update", options);
1035
- }
1036
- const descriptionStdinResolved = isDescriptionStdinConsumer(options, stdinJsonConsumed);
1037
- if (!stdinJsonConsumed) {
1038
- await resolveDescriptionStdin(options);
1039
- }
1040
- // GH-214: resolve --body-file into the existing body field before
1041
- // normalization so the rest of update is unchanged. CLI-only input alias.
1042
- const bodyFileResolved = typeof options.bodyFile === "string";
1043
- if (bodyFileResolved) {
1044
- options.body = await resolveBodyFileContent(String(options.bodyFile), options.body !== undefined ? String(options.body) : undefined);
1045
- delete options.bodyFile;
1046
- }
1047
- const normalized = normalizeUpdateOptions(options);
1048
- preserveResolvedMutationStdinFields(normalized, bodyFileResolved, descriptionStdinResolved);
1049
- if (stdinJsonConsumed)
1050
- preserveMutationStdinTokenLiterals(normalized);
1051
- const result = await runUpdate(id, normalized, globalOptions);
1052
- await invalidateSearchCachesForMutation(globalOptions, result);
1053
- printResult(await applyActiveCommandResultService("update", [id], options, globalOptions, result), globalOptions);
1054
- if (globalOptions.profile) {
1055
- printError(`profile:command=update took_ms=${Date.now() - startedAt}`);
1056
- }
1057
- }
1058
- async function runDeleteAction(id, options, command) {
1059
- const globalOptions = getGlobalOptions(command);
1060
- const startedAt = Date.now();
1061
- const result = await runDelete(id, {
1062
- author: readOptionString(options, "author"),
1063
- message: readOptionString(options, "message"),
1064
- force: Boolean(options.force),
1065
- dryRun: options.dryRun === true,
1066
- }, globalOptions);
1067
- if (result.dry_run !== true) {
1068
- await invalidateSearchCachesForMutation(globalOptions, result);
1069
- }
1070
- printResult(result, globalOptions);
1071
- if (globalOptions.profile) {
1072
- printError(`profile:command=delete took_ms=${Date.now() - startedAt}`);
1073
- }
1074
- }
1075
- function resolveAppendBody(text, options) {
1076
- const bodyFromOption = readOptionString(options, "body");
1077
- const bodyFromAlias = readOptionString(options, "text");
1078
- const bodyFromPositional = typeof text === "string" ? text : undefined;
1079
- const bodySourceCount = [
1080
- bodyFromOption,
1081
- bodyFromAlias,
1082
- bodyFromPositional,
1083
- ].filter((value) => value !== undefined).length;
1084
- if (bodySourceCount > 1) {
1085
- throw new PmCliError("Specify append text with exactly one source: positional [text], --body, or --text", EXIT_CODE.USAGE);
1086
- }
1087
- const resolvedBody = bodyFromOption ?? bodyFromAlias ?? bodyFromPositional;
1088
- if (resolvedBody === undefined) {
1089
- throw new PmCliError("Missing append text. Provide it as positional [text], --body <value>, or --text <value> (use - for stdin).", EXIT_CODE.USAGE);
1090
- }
1091
- return resolvedBody;
1092
- }
1093
- async function runAppendAction(id, text, options, command) {
1094
- const globalOptions = getGlobalOptions(command);
1095
- const startedAt = Date.now();
1096
- const result = await runAppend(id, {
1097
- body: resolveAppendBody(text, options),
1098
- author: readOptionString(options, "author"),
1099
- message: readOptionString(options, "message"),
1100
- force: Boolean(options.force),
1101
- }, globalOptions);
1102
- await invalidateSearchCachesForMutation(globalOptions, result);
1103
- printResult(result, globalOptions);
1104
- if (globalOptions.profile) {
1105
- printError(`profile:command=append took_ms=${Date.now() - startedAt}`);
1106
- }
1107
- }
1108
- async function runRestoreAction(id, target, options, command) {
1109
- const globalOptions = getGlobalOptions(command);
1110
- const startedAt = Date.now();
1111
- const result = await runRestore(id, target, {
1112
- author: readOptionString(options, "author"),
1113
- message: readOptionString(options, "message"),
1114
- force: Boolean(options.force),
1115
- }, globalOptions);
1116
- await invalidateSearchCachesForMutation(globalOptions, result);
1117
- printResult(result, globalOptions);
1118
- if (globalOptions.profile) {
1119
- printError(`profile:command=restore took_ms=${Date.now() - startedAt}`);
1120
- }
1121
- }
1122
- async function runProfileAction(subcommand, name, options, command) {
1123
- const globalOptions = getGlobalOptions(command);
1124
- const startedAt = Date.now();
1125
- const { PROFILE_SUBCOMMANDS } = profileModule;
1126
- const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
1127
- if (!normalizedSubcommand) {
1128
- throw new PmCliError(`pm profile requires a subcommand. Allowed: ${PROFILE_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
1129
- code: "missing_required_argument",
1130
- examples: [
1131
- "pm profile list",
1132
- "pm profile show agile",
1133
- "pm profile apply agile --dry-run",
1134
- "pm profile lint agile",
1135
- ],
1136
- });
1137
- }
1138
- if (!PROFILE_SUBCOMMANDS.includes(normalizedSubcommand)) {
1139
- throw createUnknownSubcommandError({
1140
- command_path: "profile",
1141
- token: normalizedSubcommand,
1142
- allowed: PROFILE_SUBCOMMANDS,
1143
- });
1144
- }
1145
- const result = await dispatchProfileSubcommand(profileModule, normalizedSubcommand, name, options, globalOptions);
1146
- // Profile inspection and schema staging do not mutate item content, so search caches stay valid (mirrors pm schema).
1147
- if (globalOptions.json === true ||
1148
- globalOptions.defaultOutputFormat === "json") {
1149
- printResult(result, globalOptions);
1150
- }
1151
- else if (!globalOptions.quiet) {
1152
- renderProfileResultHuman(profileModule, result);
1153
- }
1154
- // `pm profile lint` is a validation gate: exit non-zero when the profile has
1155
- // error-severity findings so shell/CI callers can fail on them. Warnings keep
1156
- // `ok` true and never fail the command.
1157
- if (result.action === "lint" && !result.ok) {
1158
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
1159
- }
1160
- if (globalOptions.profile) {
1161
- printError(`profile:command=profile took_ms=${Date.now() - startedAt}`);
1162
- }
1163
- }
1164
- function readStringArrayOption(options, key) {
1165
- return stringArrayOption(options[key]) ?? [];
1166
- }
1167
- async function runFilesAction(id, options, command) {
1168
- const globalOptions = getGlobalOptions(command);
1169
- const startedAt = Date.now();
1170
- const addValues = readStringArrayOption(options, "add");
1171
- const addGlobValues = readStringArrayOption(options, "addGlob");
1172
- const removeValues = readStringArrayOption(options, "remove");
1173
- const migrateValues = readStringArrayOption(options, "migrate");
1174
- const result = await runFiles(id, {
1175
- add: addValues,
1176
- addGlob: addGlobValues,
1177
- remove: removeValues,
1178
- migrate: migrateValues,
1179
- note: readOptionString(options, "note"),
1180
- list: Boolean(options.list),
1181
- appendStable: Boolean(options.appendStable),
1182
- validatePaths: Boolean(options.validatePaths),
1183
- author: readOptionString(options, "author"),
1184
- message: readOptionString(options, "message"),
1185
- force: Boolean(options.force),
1186
- }, globalOptions);
1187
- if (addValues.length > 0 ||
1188
- addGlobValues.length > 0 ||
1189
- removeValues.length > 0 ||
1190
- migrateValues.length > 0) {
1191
- await invalidateSearchCachesForMutation(globalOptions, result);
1192
- }
1193
- printResult(await applyActiveCommandResultService("files", [id], options, globalOptions, result), globalOptions);
1194
- if (globalOptions.profile) {
1195
- printError(`profile:command=files took_ms=${Date.now() - startedAt}`);
1196
- }
1197
- }
1198
- async function runFilesDiscoverAction(id, options, command) {
1199
- const globalOptions = getGlobalOptions(command);
1200
- const startedAt = Date.now();
1201
- // Flags also declared on the parent files command (--note/--append-stable/
1202
- // --author/--message/--force) are consumed by the parent during parse, so
1203
- // merge ancestor opts back in (own options win) instead of reading opts() alone.
1204
- const mergedOptions = {
1205
- ...command.optsWithGlobals(),
1206
- ...options,
1207
- };
1208
- const result = await runFilesDiscover(id, {
1209
- apply: Boolean(mergedOptions.apply),
1210
- note: readOptionString(mergedOptions, "note"),
1211
- appendStable: Boolean(mergedOptions.appendStable),
1212
- author: readOptionString(mergedOptions, "author"),
1213
- message: readOptionString(mergedOptions, "message"),
1214
- force: Boolean(mergedOptions.force),
1215
- }, globalOptions);
1216
- if (result.changed) {
1217
- await invalidateSearchCachesForMutation(globalOptions, result);
1218
- }
1219
- printResult(result, globalOptions);
1220
- if (globalOptions.profile) {
1221
- printError(`profile:command=files.discover took_ms=${Date.now() - startedAt}`);
1222
- }
1223
- }
1224
- async function runDocsAction(id, options, command) {
1225
- const globalOptions = getGlobalOptions(command);
1226
- const startedAt = Date.now();
1227
- const addValues = readStringArrayOption(options, "add");
1228
- const addGlobValues = readStringArrayOption(options, "addGlob");
1229
- const removeValues = readStringArrayOption(options, "remove");
1230
- const migrateValues = readStringArrayOption(options, "migrate");
1231
- const result = await runDocs(id, {
1232
- add: addValues,
1233
- addGlob: addGlobValues,
1234
- remove: removeValues,
1235
- migrate: migrateValues,
1236
- note: readOptionString(options, "note"),
1237
- list: Boolean(options.list),
1238
- validatePaths: Boolean(options.validatePaths),
1239
- author: readOptionString(options, "author"),
1240
- message: readOptionString(options, "message"),
1241
- force: Boolean(options.force),
1242
- }, globalOptions);
1243
- if (addValues.length > 0 ||
1244
- addGlobValues.length > 0 ||
1245
- removeValues.length > 0 ||
1246
- migrateValues.length > 0) {
1247
- await invalidateSearchCachesForMutation(globalOptions, result);
1248
- }
1249
- printResult(await applyActiveCommandResultService("docs", [id], options, globalOptions, result), globalOptions);
1250
- if (globalOptions.profile) {
1251
- printError(`profile:command=docs took_ms=${Date.now() - startedAt}`);
1252
- }
1253
- }
1254
- async function runDepsAction(id, options, command) {
1255
- const globalOptions = getGlobalOptions(command);
1256
- const startedAt = Date.now();
1257
- // --format and --collapse carry commander defaults ("tree"/"none"), so
1258
- // they are always strings by the time the action runs; --maxDepth has no
1259
- // default and may be unset. Use `as string` rather than String(...) so an
1260
- // omitted option stays undefined instead of becoming the literal "undefined".
1261
- const result = await runDeps(id, {
1262
- format: options.format,
1263
- maxDepth: readOptionString(options, "maxDepth"),
1264
- collapse: options.collapse,
1265
- summary: options.summary === true,
1266
- full: options.full === true,
1267
- nodeLimit: readOptionString(options, "nodeLimit"),
1268
- edgeLimit: readOptionString(options, "edgeLimit"),
1269
- tokenBudget: readOptionString(options, "tokenBudget"),
1270
- cursor: readOptionString(options, "cursor"),
1271
- direction: readOptionString(options, "direction"),
1272
- ...(Array.isArray(options.kind)
1273
- ? { kind: options.kind }
1274
- : {}),
1275
- }, globalOptions);
1276
- printResult(result, globalOptions);
1277
- if (globalOptions.profile) {
1278
- printError(`profile:command=deps took_ms=${Date.now() - startedAt}`);
1279
- }
1280
- }
1281
- /** Implements register mutation commands for the public runtime surface of this module. */
1282
- export function registerMutationCommands(program, registrationOptions = {}) {
1283
- const createCommand = program
1284
- .command("create")
1285
- .argument("[type-or-title]", 'Item title, or item type when a title follows (e.g. `pm create task "Fix bug"`)')
1286
- .argument("[title]", "Item title when the first argument is an item type")
1287
- .description("Create a new project management item.");
1288
- registerCommanderOptionContracts(createCommand, CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS);
1289
- createCommand
1290
- .option("--stdin-json", "Read a full item JSON document from stdin; explicit flags override document values")
1291
- .option("--body-file <path>", "Load body from a file or stdin (-); conflicts with --body")
1292
- .option("--clear-deps", "Clear dependency entries")
1293
- .option("--clear-comments", "Clear comments")
1294
- .option("--clear-notes", "Clear notes")
1295
- .option("--clear-learnings", "Clear learnings")
1296
- .option("--clear-files", "Clear linked files")
1297
- .option("--clear-tests", "Clear linked tests")
1298
- .option("--clear-docs", "Clear linked docs")
1299
- .option("--clear-reminders", "Clear reminders")
1300
- .option("--clear-events", "Clear events")
1301
- .option("--clear-type-options", "Clear type options")
1302
- .option("--allow-duplicate", "Explicitly create even when strict similarity governance finds likely duplicates")
1303
- .action(runCreateAction);
1304
- if (registrationOptions.targetCommandName === "create") {
1305
- return;
1306
- }
1307
- program
1308
- .command("copy")
1309
- .argument("<id>", "Source item id")
1310
- .option("--title <value>", "Optional title override for the copied item")
1311
- .option("--author <value>", "Mutation author")
1312
- .option("--message <value>", "History message")
1313
- .option("--allow-duplicate", "Explicitly copy even when strict similarity governance finds likely duplicates")
1314
- .description("Copy an item into a new item id while resetting lifecycle fields.")
1315
- .action(runCopyAction);
1316
- program
1317
- .command("focus")
1318
- .argument("[id]", "Item id to focus (omit to show current focus)")
1319
- .option("--clear", "Clear the focused item")
1320
- .description("Set/clear/show the session focused item that new items default --parent to.")
1321
- .action(runFocusAction);
1322
- const updateCommand = program
1323
- .command("update")
1324
- .argument("<id>", "Item id")
1325
- .description("Update item fields and metadata.");
1326
- registerCommanderOptionContracts(updateCommand, UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS);
1327
- updateCommand
1328
- .option("--stdin-json", "Read a full item JSON document from stdin; explicit flags override document values")
1329
- .option("--body-file <path>", "Load body from a file or stdin (-); conflicts with --body")
1330
- .option("--replace-deps", "Atomically replace dependency entries with the provided --dep values")
1331
- .option("--replace-tests", "Atomically replace linked test entries with the provided --test values")
1332
- .option("--replace-files", "Atomically replace linked file entries with the provided --file values")
1333
- .option("--replace-docs", "Atomically replace linked doc entries with the provided --doc values")
1334
- .option("--clear-deps", "Clear dependency entries")
1335
- .option("--clear-comments", "Clear comments")
1336
- .option("--clear-notes", "Clear notes")
1337
- .option("--clear-learnings", "Clear learnings")
1338
- .option("--clear-files", "Clear linked files")
1339
- .option("--clear-tests", "Clear linked tests")
1340
- .option("--clear-docs", "Clear linked docs")
1341
- .option("--clear-reminders", "Clear reminders")
1342
- .option("--clear-events", "Clear events")
1343
- .option("--clear-type-options", "Clear type options")
1344
- .option("--force", "Force ownership override");
1345
- updateCommand.action(runUpdateAction);
1346
- registerStructuredMutationCommands(program);
1347
- const updateManyCommand = program
1348
- .command("update-many")
1349
- .description("Bulk-update matched items with dry-run plans and rollback checkpoints.")
1350
- .option("--filter-status <value>", "Filter by status before applying updates")
1351
- .option("--filter-type <value>", "Filter by item type before applying updates")
1352
- .option("--filter-tag <value>", "Filter by tag before applying updates")
1353
- .option("--filter-priority <value>", "Filter by priority before applying updates")
1354
- .option("--filter-deadline-before <value>", "Filter by deadline upper bound before applying updates")
1355
- .option("--filter-deadline-after <value>", "Filter by deadline lower bound before applying updates")
1356
- .option("--filter-updated-after <value>", "Filter by updated_at lower bound before applying updates (ISO/relative)")
1357
- .option("--filter-updated-before <value>", "Filter by updated_at upper bound before applying updates (ISO/relative)")
1358
- .option("--filter-created-after <value>", "Filter by created_at lower bound before applying updates (ISO/relative)")
1359
- .option("--filter-created-before <value>", "Filter by created_at upper bound before applying updates (ISO/relative)")
1360
- .option("--filter-assignee <value>", "Filter by assignee before applying updates")
1361
- .option("--filter-assignee-filter <value>", "Filter assignee presence: assigned|unassigned before applying updates")
1362
- .option("--filter-parent <value>", "Filter by parent item ID before applying updates")
1363
- .option("--filter-sprint <value>", "Filter by sprint before applying updates")
1364
- .option("--filter-release <value>", "Filter by release before applying updates")
1365
- .option("--filter-ac-missing", "Select only items missing acceptance_criteria (bulk backfill)")
1366
- .option("--filter-estimates-missing", "Select only items missing estimated_minutes (bulk backfill)")
1367
- .option("--filter-resolution-missing", "Select only terminal items missing resolution (bulk backfill)")
1368
- .option("--filter-metadata-missing", "Select only items missing any tracked metadata (AC, estimate, or resolution)");
1369
- registerBulkContentAndGovernanceFilters(updateManyCommand, "applying updates");
1370
- updateManyCommand
1371
- .option("--ids <value>", "Explicit ID allowlist: comma/newline text, - stdin, or @path file")
1372
- .option("--limit <n>", "Limit matched item count before apply/preview")
1373
- .option("--offset <n>", "Skip first n matched rows before apply/preview")
1374
- .option("--dry-run", "Preview per-item diffs and checkpoint intent without mutating")
1375
- .option("--rollback <value>", "Rollback a prior update-many checkpoint ID")
1376
- .option("--no-checkpoint", "Disable checkpoint creation during apply mode")
1377
- .option("--title, -t <value>", "Set title")
1378
- .option("--description, -d <value>", "Set description")
1379
- .option("--body, -b <value>", "Set body (allow empty string)")
1380
- .option("--status, -s <value>", "Set status (use close command for closed)")
1381
- .option("--priority, -p <value>", "Set priority")
1382
- .option("--type <value>", "Set type")
1383
- .option("--tags <value>", "Set comma-separated tags (replaces existing). Use --add-tags / --remove-tags to mutate additively.")
1384
- .option("--add-tags <value>", "Add tags additively without replacing existing (repeatable; CSV accepted)", collect)
1385
- .option("--remove-tags <value>", "Remove tags from the existing list (repeatable; CSV accepted)", collect)
1386
- .option("--deadline <value>", "Set deadline (ISO/date string or relative)")
1387
- .option("--estimate, --estimated-minutes <value>", "Set estimated minutes")
1388
- .option("--acceptance-criteria <value>", "Set acceptance criteria")
1389
- .option("--ac <value>", "Alias for --acceptance-criteria")
1390
- .option("--add-ac <value>", "Add one semicolon-free acceptance criterion without replacing the existing list (repeatable)", collect)
1391
- .option("--remove-ac <value>", "Remove one semicolon-free acceptance criterion by exact text match (repeatable)", collect)
1392
- .option("--definition-of-ready <value>", "Set definition of ready")
1393
- .option("--order <value>", "Set planning order/rank integer")
1394
- .option("--rank <value>", "Alias for --order")
1395
- .option("--goal <value>", "Set goal identifier")
1396
- .option("--objective <value>", "Set objective identifier")
1397
- .option("--value <value>", "Set business value summary")
1398
- .option("--impact <value>", "Set business impact summary")
1399
- .option("--outcome <value>", "Set expected outcome summary")
1400
- .option("--why-now <value>", "Set why-now rationale")
1401
- .option("--assignee <value>", "Set assignee")
1402
- .option("--parent <value>", "Set parent item ID")
1403
- .option("--reviewer <value>", "Set reviewer")
1404
- .option("--risk <value>", "Set risk level")
1405
- .option("--confidence <value>", "Set confidence level")
1406
- .option("--sprint <value>", "Set sprint identifier")
1407
- .option("--release <value>", "Set release identifier")
1408
- .option("--blocked-by <value>", "Set blocked-by item ID or reason")
1409
- .option("--blocked-reason <value>", "Set blocked reason")
1410
- .option("--unblock-note <value>", "Set unblock rationale note")
1411
- .option("--reporter <value>", "Set issue reporter")
1412
- .option("--severity <value>", "Set issue severity")
1413
- .option("--environment <value>", "Set issue environment context")
1414
- .option("--repro-steps <value>", "Set issue reproduction steps")
1415
- .option("--resolution <value>", "Set issue resolution summary")
1416
- .option("--expected-result <value>", "Set issue expected behavior")
1417
- .option("--expected <value>", "Short alias for --expected-result")
1418
- .option("--actual-result <value>", "Set issue observed behavior")
1419
- .option("--actual <value>", "Short alias for --actual-result")
1420
- .option("--affected-version <value>", "Set affected version identifier")
1421
- .option("--fixed-version <value>", "Set fixed version identifier")
1422
- .option("--component <value>", "Set issue component ownership")
1423
- .option("--regression [value]", "Set regression marker; bare flag means true, or pass true|false|1|0")
1424
- .option("--customer-impact <value>", "Set customer impact summary")
1425
- .option("--dep <value>", "Add dependency entry id=<id>,kind=<kind>,author=<author>,created_at=<timestamp>", collect)
1426
- .option("--dep-remove <value>", "Remove dependency entries by id/kind/author/timestamp signature", collect)
1427
- .option("--replace-deps", "Atomically replace dependency entries with provided --dep values")
1428
- .option("--replace-tests", "Atomically replace linked tests with provided --test values")
1429
- .option("--replace-files", "Atomically replace linked files with provided --file values")
1430
- .option("--replace-docs", "Atomically replace linked docs with provided --doc values")
1431
- .option("--comment <value>", "Add comment seed author=<value>,created_at=<iso|now>,text=<value>", collect)
1432
- .option("--note <value>", "Add note seed author=<value>,created_at=<iso|now>,text=<value>", collect)
1433
- .option("--learning <value>", "Add learning seed author=<value>,created_at=<iso|now>,text=<value>", collect)
1434
- .option("--file <value>", "Add linked file path=<value>,scope=<project|global>,note=<text>", collect)
1435
- .option("--test <value>", "Add linked test command=<value>,path=<value>,scope=<project|global>", collect)
1436
- .option("--doc <value>", "Add linked doc path=<value>,scope=<project|global>,note=<text>", collect)
1437
- .option("--reminder <value>", "Add reminder entry at=<iso|relative>|date=<iso|relative>,text=<text>|title=<text>", collect)
1438
- .option("--event <value>", "Add event entry start=<iso|relative>,end=<iso|relative>,recur_*", collect)
1439
- .option("--type-option <value>", "Set type options key=value (repeatable)", collect)
1440
- .option("--unset <field>", "Clear scalar metadata field by name (repeatable)", collect)
1441
- .option("--clear-deps", "Clear dependency entries")
1442
- .option("--clear-comments", "Clear comments")
1443
- .option("--clear-notes", "Clear notes")
1444
- .option("--clear-learnings", "Clear learnings")
1445
- .option("--clear-files", "Clear linked files")
1446
- .option("--clear-tests", "Clear linked tests")
1447
- .option("--clear-docs", "Clear linked docs")
1448
- .option("--clear-reminders", "Clear reminders")
1449
- .option("--clear-events", "Clear events")
1450
- .option("--clear-type-options", "Clear type options")
1451
- .option("--author <value>", "Mutation author")
1452
- .option("--message <value>", "Mutation message")
1453
- .option("--force", "Force ownership override");
1454
- // Hidden pure snake_case underscore-duplicate aliases (kept parse-functional,
1455
- // omitted from --help to save agent context).
1456
- addHiddenOptions(updateManyCommand, [
1457
- [
1458
- "--filter-assignee_filter <value>",
1459
- "Alias for --filter-assignee-filter",
1460
- ],
1461
- ["--estimated_minutes <value>", "Alias for --estimated-minutes"],
1462
- ["--acceptance_criteria <value>", "Alias for --acceptance-criteria"],
1463
- ["--definition_of_ready <value>", "Alias for --definition-of-ready"],
1464
- ["--why_now <value>", "Alias for --why-now"],
1465
- ["--blocked_by <value>", "Alias for --blocked-by"],
1466
- ["--blocked_reason <value>", "Alias for --blocked-reason"],
1467
- ["--unblock_note <value>", "Alias for --unblock-note"],
1468
- ["--repro_steps <value>", "Alias for --repro-steps"],
1469
- ["--expected_result <value>", "Alias for --expected-result"],
1470
- ["--actual_result <value>", "Alias for --actual-result"],
1471
- ["--affected_version <value>", "Alias for --affected-version"],
1472
- ["--fixed_version <value>", "Alias for --fixed-version"],
1473
- ["--customer_impact <value>", "Alias for --customer-impact"],
1474
- ["--filter-estimate-missing", "Alias for --filter-estimates-missing"],
1475
- ], false);
1476
- addHiddenOptions(updateManyCommand, [
1477
- ["--dep_remove <value>", "Alias for --dep-remove"],
1478
- ["--type_option <value>", "Alias for --type-option"],
1479
- ["--add_tags <value>", "Alias for --add-tags"],
1480
- ["--remove_tags <value>", "Alias for --remove-tags"],
1481
- ["--add_ac <value>", "Alias for --add-ac"],
1482
- ["--remove_ac <value>", "Alias for --remove-ac"],
1483
- ], true);
1484
- updateManyCommand.action(runUpdateManyAction);
1485
- const closeCommand = program
1486
- .command("close")
1487
- .argument("<id>", "Item id")
1488
- .argument("[text]", "Close reason text (alias: --reason)")
1489
- .option("-r, --reason <value>", "Close reason text (alias for positional <text>)")
1490
- .option("--close-reason <value>", "Close reason text (alias for positional <text>)")
1491
- .option("--completed-at <value>", "Actual completion timestamp (ISO or relative), distinct from tracker close time")
1492
- .option("-d, --duplicate-of <id>", "Close as a duplicate of the canonical item id and auto-fill duplicate closure metadata")
1493
- .option("--author <value>", "Mutation author")
1494
- .option("-m, --message <value>", "History message")
1495
- .option("--validate-close [mode]", 'Validate closure metadata before close: "off", "warn", or "strict" (default: settings governance preset)')
1496
- .option("--resolution <value>", "Set the closure resolution summary inline (same field --validate-close strict checks; previously required a prior pm update)")
1497
- .option("--expected-result <value>", "Set the expected-result note inline (closure validation field)")
1498
- .option("--expected <value>", "Short alias for --expected-result")
1499
- .option("--actual-result <value>", "Set the actual-result note inline (closure validation field)")
1500
- .option("--actual <value>", "Short alias for --actual-result")
1501
- .option("--force", "Force ownership override")
1502
- .description("Close an item. Close reason requirement follows governance.require_close_reason.");
1503
- // pm-fl0c #11 (2026-05-28): expose snake_case aliases alongside the canonical
1504
- // kebab-case so agents using --expected_result/--actual_result do not get an
1505
- // Unknown option error; the rendered help stays clean (aliases hidden).
1506
- addHiddenOption(closeCommand, "--expected_result <value>", "Alias for --expected-result", false);
1507
- addHiddenOption(closeCommand, "--actual_result <value>", "Alias for --actual-result", false);
1508
- closeCommand.action(runCloseAction);
1509
- const closeManyCommand = program
1510
- .command("close-many")
1511
- .description("Bulk-close matched items with a shared reason and full runClose semantics (dry-run + rollback checkpoint).")
1512
- .option("--filter-status <value>", "Filter by status before closing")
1513
- .option("--filter-type <value>", "Filter by item type before closing")
1514
- .option("--filter-tag <value>", "Filter by tag before closing")
1515
- .option("--filter-priority <value>", "Filter by priority before closing")
1516
- .option("--filter-deadline-before <value>", "Filter by deadline upper bound before closing")
1517
- .option("--filter-deadline-after <value>", "Filter by deadline lower bound before closing")
1518
- .option("--filter-updated-after <value>", "Filter by updated_at lower bound before closing (ISO/relative)")
1519
- .option("--filter-updated-before <value>", "Filter by updated_at upper bound before closing (ISO/relative)")
1520
- .option("--filter-created-after <value>", "Filter by created_at lower bound before closing (ISO/relative)")
1521
- .option("--filter-created-before <value>", "Filter by created_at upper bound before closing (ISO/relative)")
1522
- .option("--filter-assignee <value>", "Filter by assignee before closing")
1523
- .option("--filter-assignee-filter <value>", "Filter assignee presence: assigned|unassigned before closing")
1524
- .option("--filter-parent <value>", "Filter by parent item ID before closing")
1525
- .option("--filter-sprint <value>", "Filter by sprint before closing")
1526
- .option("--filter-release <value>", "Filter by release before closing");
1527
- registerBulkContentAndGovernanceFilters(closeManyCommand, "closing");
1528
- closeManyCommand
1529
- .option("--ids <value>", "Explicit ID allowlist: comma/newline text, - stdin, or @path file")
1530
- .option("--limit <n>", "Limit matched item count before apply/preview")
1531
- .option("--offset <n>", "Skip first n matched rows before apply/preview")
1532
- .option("--reason <value>", "Shared close reason applied to matched items (required when governance.require_close_reason is enabled)")
1533
- .option("--completed-at <value>", "Actual completion timestamp (ISO or relative) applied to every matched item")
1534
- .option("--resolution <value>", "Shared closure resolution applied to every matched item (closure-validation field)")
1535
- .option("--expected-result <value>", "Shared expected-result note (closure-validation field)")
1536
- .option("--expected <value>", "Short alias for --expected-result")
1537
- .option("--actual-result <value>", "Shared actual-result note (closure-validation field)")
1538
- .option("--actual <value>", "Short alias for --actual-result")
1539
- .option("--validate-close [mode]", 'Validate closure metadata per item: "off", "warn", or "strict" (default: settings governance preset)')
1540
- .option("--author <value>", "Mutation author")
1541
- .option("--message <value>", "History message")
1542
- .option("--force", "Re-close already-terminal matches and override ownership")
1543
- .option("--dry-run", "Preview matched items + per-item skip/active-child plan without mutating")
1544
- .option("--rollback <value>", "Rollback a prior close-many checkpoint ID")
1545
- .option("--no-checkpoint", "Disable checkpoint creation during apply mode");
1546
- addHiddenOption(closeManyCommand, "--filter-assignee_filter <value>", "Alias for --filter-assignee-filter", false);
1547
- addHiddenOption(closeManyCommand, "--expected_result <value>", "Alias for --expected-result", false);
1548
- addHiddenOption(closeManyCommand, "--actual_result <value>", "Alias for --actual-result", false);
1549
- closeManyCommand.action(runCloseManyAction);
1550
- program
1551
- .command("delete")
1552
- .argument("<id>", "Item id")
1553
- .option("--author <value>", "Mutation author")
1554
- .option("--message <value>", "History message")
1555
- .option("--force", "Force ownership override")
1556
- .option("--dry-run", "Preview the item file that would be deleted without mutating")
1557
- .description("Delete an item and record the change in history.")
1558
- .action(runDeleteAction);
1559
- program
1560
- .command("append")
1561
- .argument("<id>", "Item id")
1562
- .argument("[text]", "Body text; same as --body (- reads stdin)")
1563
- .option("--body <value>", "Text to append to body (or - for stdin)")
1564
- .option("--text <value>", "Alias for --body")
1565
- .option("--author <value>", "Mutation author")
1566
- .option("--message <value>", "Mutation message")
1567
- .option("--force", "Force ownership override")
1568
- .description("Append text to an item's body. For concurrent writes, use pm notes.")
1569
- .action(runAppendAction);
1570
- program
1571
- .command("restore")
1572
- .argument("<id>", "Item id")
1573
- .argument("<target>", "Restore target timestamp or version number")
1574
- .option("--author <value>", "Mutation author")
1575
- .option("--message <value>", "History message")
1576
- .option("--force", "Force ownership/lock override")
1577
- .description("Restore an item to an earlier timestamp or version.")
1578
- .action(runRestoreAction);
1579
- const planCommand = program
1580
- .command("plan")
1581
- .description("Agent-optimized Plan item workflow: create, manage steps, link dependencies, approve, and materialize.")
1582
- .argument("[subcommand]", "Required; Plan subcommand: create|show|add-step|update-step|complete-step|block-step|reorder-step|remove-step|link|unlink|decision|discovery|validation|resume|approve|materialize")
1583
- .argument("[id]", "Plan id (required for non-create subcommands); for create this may be the positional title")
1584
- .argument("[step]", "Step reference: stable id (plan-step-001) or order integer")
1585
- .argument("[new-order]", "New order integer for reorder-step")
1586
- .option("--title <value>", "Plan title")
1587
- .option("--description <value>", "Plan description")
1588
- .option("--scope <value>", "Short scope statement of the target change or investigation")
1589
- .option("--parent <value>", "Parent pm item id")
1590
- .option("--related <value>", "Related pm item ids (repeatable, csv-friendly)", collect)
1591
- .option("--blocks <value>", "Pm item ids this plan blocks (repeatable, csv-friendly)", collect)
1592
- .option("--blocked-by <value>", "Pm item ids that block this plan (repeatable, csv-friendly)", collect)
1593
- .option("--harness <value>", "Plan harness provenance: codex|claude-code|cursor|generic")
1594
- .option("--mode <value>", "Plan mode: draft|research|review|approved|executing|paused|completed|superseded")
1595
- .option("--resume-context <value>", "Compact context summary for a future stateless agent")
1596
- .option("--tags <value>", "Comma-separated tags")
1597
- .option("--priority <value>", "Priority 0-4")
1598
- .option("--body <value>", "Plan item body")
1599
- .option("--claim", "Claim the plan on create for the author")
1600
- .option("--from-search <value>", "Record the search query that led to plan creation")
1601
- .option("--template <value>", "Seed plan steps from a built-in template: bug-investigation|feature-implementation|refactoring-sprint")
1602
- .option("--step-title <value>", "Step title for add-step / update-step")
1603
- // pm-6mit: --step is a Commander collect repeatable so `pm plan create
1604
- // --step A --step B` seeds ordered steps (previously a single-value alias
1605
- // for --step-title where the last value silently won). It must NOT be
1606
- // list:true in contracts — the bootstrap coalescer would comma-join values
1607
- // and corrupt titles containing commas.
1608
- .option("--step <value>", "Step title (repeatable on create: each --step appends an ordered step; elsewhere a single value aliases --step-title)", collect)
1609
- .option("--step-body <value>", "Step body text")
1610
- .option("--step-owner <value>", "Step owner")
1611
- .option("--step-status <value>", "Step status: pending|in_progress|completed|blocked|skipped|superseded")
1612
- .option("--step-evidence <value>", "Step evidence text (used by update-step/complete-step)")
1613
- .option("--step-blocked-reason <value>", "Step blocked reason (required when blocking)")
1614
- .option("--step-replacement <value>", "Replacement reference for a superseded step")
1615
- .option("--depends-on <value>", "Pm item ids the step depends on (repeatable, csv-friendly)", collect)
1616
- .option("--link <value>", "Pm item id to link (repeatable, csv-friendly)", collect)
1617
- .option("--link-kind <value>", `Link kind: ${PLAN_STEP_LINK_KIND_VALUES.join("|")}`)
1618
- .option("--link-note <value>", "Optional note for the link")
1619
- .option("--promote-to-item-dep", "Also add the linked id as a top-level item dependency when linking")
1620
- .option("--allow-multiple-active", "Allow multiple steps to be in_progress at once")
1621
- .option("--file <value>", "Step linked file path=<value>[,scope=project|global,note=<text>] (repeatable)", collect)
1622
- .option("--test <value>", "Step linked test command=<value>[,path=<value>,note=<text>] (repeatable)", collect)
1623
- .option("--doc <value>", "Step linked doc path=<value>[,scope=project|global,note=<text>] (repeatable)", collect)
1624
- .option("--decision-text <value>", "Decision log entry text")
1625
- .option("--decision <value>", "Alias for --decision-text")
1626
- .option("--decision-rationale <value>", "Decision log entry rationale")
1627
- .option("--decision-evidence <value>", "Decision log entry evidence")
1628
- .option("--discovery-text <value>", "Discovery log entry text")
1629
- .option("--discovery <value>", "Alias for --discovery-text")
1630
- .option("--validation-text <value>", "Validation log entry text")
1631
- .option("--validation <value>", "Alias for --validation-text")
1632
- .option("--validation-command <value>", "Validation log entry command")
1633
- .option("--validation-expected <value>", "Validation log entry expected outcome")
1634
- .option("--depth <value>", "Show depth: brief|standard|deep (default: brief)")
1635
- .option("--fields <value>", "Comma-separated field projection for show output")
1636
- .option("--steps <value>", "Comma-separated step ids/orders for materialize")
1637
- .option("--materialize-type <value>", "Item type for materialized steps (default: Task)")
1638
- .option("--materialize-parent <value>", "Parent item id for materialized children (default: the plan)")
1639
- .option("--materialize-tags <value>", "Comma-separated tags for materialized children")
1640
- .option("--field <name=value>", "Custom field value forwarded to every materialized child (repeatable)", collect)
1641
- .option("--author <value>", "Mutation author")
1642
- .option("--message <value>", "Mutation message")
1643
- .option("--force", "Force ownership override");
1644
- registerCommanderOptionContracts(planCommand, CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS.filter((contract) => PLAN_CREATE_METADATA_OPTION_TARGETS.has(contract.target)));
1645
- // Hidden pure snake_case underscore-duplicate aliases (kept parse-functional,
1646
- // omitted from --help to save agent context).
1647
- addHiddenOptions(planCommand, [
1648
- ["--resume_context <value>", "Alias for --resume-context"],
1649
- ["--from_search <value>", "Alias for --from-search"],
1650
- ["--step_title <value>", "Alias for --step-title"],
1651
- ["--step_body <value>", "Alias for --step-body"],
1652
- ["--step_owner <value>", "Alias for --step-owner"],
1653
- ["--step_status <value>", "Alias for --step-status"],
1654
- ["--step_evidence <value>", "Alias for --step-evidence"],
1655
- ["--step_blocked_reason <value>", "Alias for --step-blocked-reason"],
1656
- ["--step_replacement <value>", "Alias for --step-replacement"],
1657
- ["--link_kind <value>", "Alias for --link-kind"],
1658
- ["--link_note <value>", "Alias for --link-note"],
1659
- ["--promote_to_item_dep", "Alias for --promote-to-item-dep"],
1660
- ["--allow_multiple_active", "Alias for --allow-multiple-active"],
1661
- ["--decision_text <value>", "Alias for --decision-text"],
1662
- ["--decision_rationale <value>", "Alias for --decision-rationale"],
1663
- ["--decision_evidence <value>", "Alias for --decision-evidence"],
1664
- ["--discovery_text <value>", "Alias for --discovery-text"],
1665
- ["--validation_text <value>", "Alias for --validation-text"],
1666
- ["--validation_command <value>", "Alias for --validation-command"],
1667
- ["--validation_expected <value>", "Alias for --validation-expected"],
1668
- ["--materialize_type <value>", "Alias for --materialize-type"],
1669
- ["--materialize_parent <value>", "Alias for --materialize-parent"],
1670
- ["--materialize_tags <value>", "Alias for --materialize-tags"],
1671
- ], false);
1672
- addHiddenOptions(planCommand, [
1673
- ["--blocked_by <value>", "Alias for --blocked-by"],
1674
- ["--depends_on <value>", "Alias for --depends-on"],
1675
- ], true);
1676
- planCommand.action(runPlanAction);
1677
- void planCommand;
1678
- program
1679
- .command("history-redact")
1680
- .argument("<id>", "Item id")
1681
- .option("--literal <value>", "Literal string to redact (repeatable)", collect)
1682
- .option("--regex <value>", "Regex pattern to redact (repeatable; accepts /pattern/flags or raw pattern)", collect)
1683
- .option("--replacement <value>", 'Replacement string (default: "[redacted]")')
1684
- .option("--dry-run", "Preview redaction impact without writing item/history files")
1685
- .option("--author <value>", "Mutation author")
1686
- .option("--message <value>", "Audit history message for the redaction marker entry")
1687
- .option("--force", "Force ownership/lock override")
1688
- .description("Redact sensitive literals/patterns from an item history stream and recompute hashes.")
1689
- .action(async (id, options, command) => {
1690
- const globalOptions = getGlobalOptions(command);
1691
- const startedAt = Date.now();
1692
- const literal = Array.isArray(options.literal)
1693
- ? options.literal
1694
- : undefined;
1695
- const regex = Array.isArray(options.regex)
1696
- ? options.regex
1697
- : undefined;
1698
- const result = await runHistoryRedact(id, {
1699
- literal,
1700
- regex,
1701
- replacement: typeof options.replacement === "string"
1702
- ? options.replacement
1703
- : undefined,
1704
- dryRun: options.dryRun === true,
1705
- author: typeof options.author === "string" ? options.author : undefined,
1706
- message: typeof options.message === "string" ? options.message : undefined,
1707
- force: Boolean(options.force),
1708
- }, globalOptions);
1709
- if (result.changed && !result.dry_run) {
1710
- await invalidateSearchCachesForMutation(globalOptions, result);
1711
- }
1712
- printResult(result, globalOptions);
1713
- if (globalOptions.profile) {
1714
- printError(`profile:command=history-redact took_ms=${Date.now() - startedAt}`);
1715
- }
1716
- });
1717
- program
1718
- .command("history-repair")
1719
- .argument("[id]", "Item id (omit with --all)")
1720
- .option("--salvage-tail", "Recover invalid tail; requires verified prefix")
1721
- .option("--all", "Scan every stream for drift and repair each drifted stream in one audited pass")
1722
- .option("--dry-run", "Preview the re-anchor impact without writing the history file")
1723
- .option("--normalize-provenance", "Remove invalid provenance; return aggregate-only evidence")
1724
- .option("--author <value>", "Mutation author")
1725
- .option("--message <value>", "Audit history message for the repair marker entry")
1726
- .option("--force", "Force ownership/lock override")
1727
- .description("Re-anchor a drifted item history chain (recompute hashes, reconcile with the on-disk item) and record an audit marker. Use --all to repair every drifted stream.")
1728
- .action(async (id, options, command) => {
1729
- const globalOptions = getGlobalOptions(command);
1730
- const startedAt = Date.now();
1731
- const all = options.all === true;
1732
- assertHistoryRepairTarget(id, all);
1733
- const repairOptions = {
1734
- dryRun: options.dryRun === true,
1735
- author: typeof options.author === "string" ? options.author : undefined,
1736
- message: typeof options.message === "string" ? options.message : undefined,
1737
- force: Boolean(options.force),
1738
- normalizeProvenance: options.normalizeProvenance === true,
1739
- salvageTail: options.salvageTail === true,
1740
- };
1741
- // history-repair only re-anchors the audit stream; item content is untouched,
1742
- // so search caches do not need invalidation.
1743
- if (all) {
1744
- const result = await runHistoryRepairAll(repairOptions, globalOptions);
1745
- printResult(result, globalOptions);
1746
- if (result.totals.failed > 0) {
1747
- // Per-stream failures are collected (one bad stream never aborts the
1748
- // pass) but must still fail the command for gating callers.
1749
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
1750
- }
1751
- }
1752
- else {
1753
- const result = await runHistoryRepair(id, repairOptions, globalOptions);
1754
- printResult(result, globalOptions);
1755
- }
1756
- if (globalOptions.profile) {
1757
- printError(`profile:command=history-repair took_ms=${Date.now() - startedAt}`);
1758
- }
1759
- });
1760
- registerHistoryAuthorAcknowledgeCommand(program);
1761
- program
1762
- .command("history-compact")
1763
- .argument("[id]", "Item id (omit when using a bulk selector)")
1764
- .option("--before <value>", "Compact entries strictly before this version number or ISO timestamp (single-id mode only)")
1765
- .option("--ids <value>", "Bulk IDs: comma/newline text, - stdin, or @path file")
1766
- .option("--all-over <n>", "Bulk: compact every stream with more than N entries")
1767
- .option("--closed", "Bulk: compact only closed (terminal) items' streams")
1768
- .option("--all-streams", "Bulk: compact every history stream regardless of lifecycle state")
1769
- .option("--min-entries <n>", "Bulk: skip streams with at most N entries (already compact; default 3)")
1770
- .option("--dry-run", "Preview compaction impact without writing the history file")
1771
- .option("--author <value>", "Mutation author")
1772
- .option("--message <value>", "Audit history message for the compaction marker entry")
1773
- .option("--force", "Force ownership/lock override")
1774
- .description("Compact item history streams into a synthetic baseline plus retained tail entries. Pass an item id for one stream, or a bulk selector (--ids/--all-over/--closed/--all-streams) to compact many.")
1775
- .action(runHistoryCompactAction);
1776
- program
1777
- .command("merge")
1778
- .argument("<subcommand>", `Merge subcommand: ${MERGE_SUBCOMMAND_VALUES.join(", ")}`)
1779
- .argument("[artifact]", `driver only: artifact class to merge (${MERGE_DRIVER_ARTIFACT_VALUES.join(", ")})`)
1780
- .argument("[base]", "driver only: common-ancestor file path (git %O)")
1781
- .argument("[ours]", "driver only: current-branch file path (git %A)")
1782
- .argument("[theirs]", "driver only: other-branch file path (git %B)")
1783
- .option("--dry-run", "install/reconcile: preview changes without writing")
1784
- .option("--message <text>", "reconcile only: audit message recorded on repaired history streams")
1785
- .option("--force", "reconcile only: permit the underlying audited history ownership override")
1786
- .option("--include-reconciled", "report only: include clone-local receipts already recorded in history")
1787
- .option("--output <path>", "driver only: write the merged content to this path instead of the ours path")
1788
- .option("--item-path <path>", "driver only: original repository-relative path supplied by git as %P")
1789
- .option("--prefer <side>", "driver only: side that wins unresolvable conflicts (ours|theirs; default ours)")
1790
- .description("Install merge drivers, reconcile or report post-merge history, or run a field-aware driver.")
1791
- .action(runMergeAction);
1792
- const schemaCommand = program
1793
- .command("schema")
1794
- .argument("[subcommand]", "Required; Schema subcommand: list, show, show-status, add/remove type/status/field, rename-type, rename-field, remap-status, or a custom item type name shorthand")
1795
- .argument("[name]", "Definition name, or source name for rename/remap migrations")
1796
- .option("--description <text>", "Human description for the custom item type, status, or field")
1797
- .option("--default-status <status>", "Default status hint recorded for the custom item type")
1798
- .option("--folder <dir>", "Storage folder for items of this custom type")
1799
- .option("--alias <name>", "Alias for the custom type, status, or field flag (repeatable, csv-friendly)", collect)
1800
- .option("--role <value>", "Lifecycle role for a custom status (repeatable): draft, active, blocked, terminal, terminal_done, terminal_canceled, default_open, default_close, default_cancel", collect)
1801
- .option("--order <n>", "Display/sort order for a custom status")
1802
- .option("--type <type>", "Value type for a custom field (add-field): string, number, boolean, string_array, array, object")
1803
- .option("--commands <list>", "Commands a custom field is wired onto (add-field; repeatable, comma-friendly): create, update, update_many, list, search, calendar, context", collect)
1804
- .option("--cli-flag <flag>", "Override the auto-derived CLI flag for a custom field (add-field)")
1805
- .option("--required", "Mark a custom field as always required (add-field)")
1806
- .option("--required-on-create", "Mark a custom field as required at create time (add-field)")
1807
- .option("--no-allow-unset", "Disallow clearing a custom field via --unset (add-field)")
1808
- .option("--required-types <list>", "Restrict a custom field's requirement to specific item types (add-field; repeatable, comma-friendly)", collect)
1809
- .option("--infer", "Infer custom item types from title-prefix conventions (add-type; preview unless --apply)")
1810
- .option("--min-count <n>", "Minimum items sharing a prefix for add-type --infer (default 10)")
1811
- .option("--apply", "Register inferred types (add-type --infer); without it the command previews only")
1812
- .option("--to <name>", "Target definition name for rename/remap migrations")
1813
- .option("--migration-id <id>", "Stable idempotency key for a resumable schema migration")
1814
- .option("--dry-run", "Plan a schema migration without writing schema, items, or history")
1815
- .option("--author <value>", "Mutation author")
1816
- .option("--force", "Force ownership/lock override")
1817
- .description("Inspect and manage config-driven runtime schema (types, statuses, fields, presets).");
1818
- // Hidden pure snake_case underscore-duplicate alias.
1819
- addHiddenOption(schemaCommand, "--default_status <status>", "Alias for --default-status", false);
1820
- addHiddenOption(schemaCommand, "--migration_id <id>", "Alias for --migration-id", false);
1821
- schemaCommand.action(runSchemaAction);
1822
- const profileCommand = program
1823
- .command("profile")
1824
- .argument("[subcommand]", "Required; Profile subcommand: list, show, apply, or lint")
1825
- .argument("[name]", "Profile name for show/apply/lint: agile, ops, or research")
1826
- .option("--dry-run", "Preview the apply diff without writing any files (apply)")
1827
- .option("--author <value>", "Mutation author")
1828
- .option("--force", "Force ownership/lock override")
1829
- .description("List, show, apply, and lint project profiles — archetype bundles of item types, statuses, fields, workflows, config, templates, and recommended packages.");
1830
- profileCommand.action(runProfileAction);
1831
- registerAnnotationCommands(program, parsePositiveIntOption);
1832
- const filesCommand = program
1833
- .command("files")
1834
- .description("Manage files linked to an item.");
1835
- filesCommand
1836
- .argument("<id>", "Item id")
1837
- .option("--add <value>", "Add linked file entry (CSV/markdown pairs or - for stdin)", collect)
1838
- .option("--add-glob <value>", "Add linked file entries from a glob (plain glob or pattern=<glob>,scope=<scope>,note=<text>; repeatable)", collect)
1839
- .option("--remove <value>", "Remove linked file by path only (path=<value>, path:<value>, plain path, or - for stdin); does not accept note=/scope= — record removal context with --message", collect)
1840
- .option("--migrate <value>", "Migrate linked file paths in-place (from=<prefix>,to=<prefix>; repeatable)", collect)
1841
- .option("--note <value>", "Note attached to every link added by --add/--add-glob in this invocation (embedded note= wins)")
1842
- .option("--list", "List linked files without mutating")
1843
- .option("--append-stable", "Preserve existing linked-file order and append new links without full-array resorting")
1844
- .option("--validate-paths", "Validate linked file paths for existence and file shape")
1845
- .option("--author <value>", "Mutation author")
1846
- .option("--message <value>", "History message")
1847
- .option("--force", "Force ownership override")
1848
- .action(runFilesAction);
1849
- filesCommand
1850
- .command("discover")
1851
- .argument("<id>", "Item id")
1852
- .option("--apply", "Add discovered missing files to the item")
1853
- .option("--note <value>", "Note to attach to discovered file links")
1854
- .option("--append-stable", "Preserve existing linked-file order and append discovered links without full-array resorting")
1855
- .option("--author <value>", "Mutation author")
1856
- .option("--message <value>", "History message")
1857
- .option("--force", "Force ownership override")
1858
- .description("Discover existing file paths referenced in item text and optionally link missing files.")
1859
- .action(runFilesDiscoverAction);
1860
- registerFilesLookupCommand(filesCommand);
1861
- program
1862
- .command("docs")
1863
- .argument("<id>", "Item id")
1864
- .option("--add <value>", "Add linked doc entry (CSV/markdown pairs or - for stdin)", collect)
1865
- .option("--add-glob <value>", "Add linked doc entries from a glob (plain glob or pattern=<glob>,scope=<scope>,note=<text>; repeatable)", collect)
1866
- .option("--remove <value>", "Remove linked doc by path only (path=<value>, path:<value>, plain path, or - for stdin); does not accept note=/scope= — record removal context with --message", collect)
1867
- .option("--migrate <value>", "Migrate linked doc paths in-place (from=<prefix>,to=<prefix>; repeatable)", collect)
1868
- .option("--note <value>", "Note attached to every link added by --add/--add-glob in this invocation (embedded note= wins)")
1869
- .option("--list", "List linked docs without mutating")
1870
- .option("--validate-paths", "Validate linked doc paths for existence and file shape")
1871
- .option("--author <value>", "Mutation author")
1872
- .option("--message <value>", "History message")
1873
- .option("--force", "Force ownership override")
1874
- .description("Manage docs linked to an item.")
1875
- .action(runDocsAction);
1876
- program
1877
- .command("deps")
1878
- .argument("<id>", "Item id")
1879
- .option("--format <value>", "Output format (tree, graph, or context)", "tree")
1880
- .option("--max-depth <value>", "Maximum dependency traversal depth (0 keeps only the root)")
1881
- .option("--collapse <value>", "Collapse mode (none or repeated)", "none")
1882
- .option("--summary", "Return counts only without full tree/graph payload")
1883
- .option("--full", "Return the complete dependency row projection")
1884
- .option("--node-limit <value>", "Maximum nodes in context output")
1885
- .option("--edge-limit <value>", "Maximum edges and missing-reference rows in context output")
1886
- .option("--token-budget <value>", "Maximum estimated tokens in context output")
1887
- .option("--cursor <value>", "Continue an equivalent context query")
1888
- .option("--direction <value>", "Context traversal direction (outgoing, incoming, or both)")
1889
- .option("--kind <value>", "Restrict context traversal to registered relationship kinds (repeatable or comma-separated)", collect)
1890
- .description("Show dependency relationships for an item.")
1891
- .action(runDepsAction);
1892
- }
1
+ !(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]="d60cc408-7587-50c3-8d07-6212cbe881e2")}catch(e2){}})();import{WORKFLOW_POLICY_ACTIONS}from"../sdk/cli-contracts/enum-contracts.js";import{resolveBodyFileContent,resolveCliBulkIdsInput,EXIT_CODE,PmCliError,createUnknownSubcommandError}from"../sdk/runtime-primitives.js";import{CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS,MERGE_SUBCOMMAND_VALUES,PLAN_CREATE_METADATA_PARAMETER_KEYS,UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS}from"../sdk/cli-contracts.js";import{BUILTIN_ITEM_TYPE_VALUES,PLAN_STEP_LINK_KIND_VALUES}from"../types/index.js";import{MERGE_DRIVER_ARTIFACT_VALUES,runMergeDriver,runMergeInstall,runMergeReconcile,runMergeReceiptEvidenceReport}from"./commands/merge.js";import{runAppend}from"./commands/append.js";import{runClose}from"./commands/close.js";import{runCloseMany}from"./commands/close-many.js";import{runCopy}from"./commands/copy.js";import{runCreate}from"./commands/create.js";import{runDelete}from"./commands/delete.js";import{runDeps}from"./commands/deps.js";import{runDocs}from"./commands/docs.js";import{runFiles,runFilesDiscover}from"./commands/files.js";import{runFocus}from"./commands/focus.js";import*as profileModule from"./commands/profile.js";import*as schemaModule from"./commands/schema.js";import{runUpdate}from"./commands/update.js";import{runUpdateMany}from"./commands/update-many.js";import{createStdinTokenResolver,preserveMutationStdinTokenFields,preserveMutationStdinTokenLiterals}from"../sdk/runtime-primitives.js";import{resolveDescriptionStdin}from"./description-stdin.js";import{itemDocumentToMutationOptions}from"../sdk/structured-mutations.js";import{registerStructuredMutationCommands}from"./register-structured-mutation.js";import{registerHistoryMaintenanceCommands}from"./register-history-maintenance.js";import{registerHistoryAuthorAcknowledgeCommand}from"./register-history-author.js";import{PLAN_SUBCOMMANDS,runPlan}from"./commands/plan.js";import{registerAnnotationCommands}from"./register-annotations.js";import{registerFilesLookupCommand}from"./register-files-lookup.js";import{isPureSnakeCaseAlias,looksLikeSchemaSubcommandTypo,parseSchemaOrderOption}from"./schema-registration-helpers.js";import{looksLikeSchemaSubcommandTypo as looksLikeSchemaSubcommandTypo2,parseSchemaOrderOption as parseSchemaOrderOption2}from"./schema-registration-helpers.js";const BUILTIN_TYPE_NAME_LOOKUP=new Set(BUILTIN_ITEM_TYPE_VALUES.map(value=>value.toLowerCase()));const PLAN_CREATE_METADATA_OPTION_TARGETS=new Set(PLAN_CREATE_METADATA_PARAMETER_KEYS.map(key=>key==="estimate"?"estimatedMinutes":key));import{collect,applyActiveCommandResultService,addHiddenOption,addHiddenOptions,extractUpdateManyMutationOptionSource,formatHookWarnings,getGlobalOptions,invalidateSearchCachesForMutation,normalizeCreateOptions,normalizeUpdateOptions,printError,printResult,readOptionString,writeStdout}from"./registration-helpers.js";function dispatchSchemaMigration(schema,inputs){const kind=inputs.normalizedSubcommand;if(kind!=="rename-type"&&kind!=="rename-field"&&kind!=="remap-status"){return null}return schema.runSchemaEvolutionMigration({kind,from:inputs.typeName,to:readOptionString(inputs.options,"to"),...kind==="rename-field"&&typeof inputs.options.type==="string"?{type:inputs.options.type}:{}},{migrationId:readOptionString(inputs.options,"migrationId")??readOptionString(inputs.options,"migration_id"),dryRun:inputs.options.dryRun===true,author:inputs.author,force:inputs.force},inputs.globalOptions)}function dispatchSchemaReadRemoveOrPreset(schema,inputs){const{normalizedSubcommand,typeName,globalOptions,author,force}=inputs;switch(normalizedSubcommand){case"list":return schema.runSchemaList(globalOptions);case"show":return schema.runSchemaShow(typeName,globalOptions);case"show-status":return schema.runSchemaShowStatus(typeName,globalOptions);case"list-fields":return schema.runSchemaListFields(globalOptions);case"show-field":return schema.runSchemaShowField(typeName,globalOptions);case"remove-type":return schema.runSchemaRemoveType(typeName,{author,force},globalOptions);case"remove-field":return schema.runSchemaRemoveField(typeName,{author,force},globalOptions);case"remove-status":return schema.runSchemaRemoveStatus(typeName,{author,force},globalOptions);case"apply-preset":return schema.runSchemaApplyPreset(typeName,{author,force},globalOptions);default:return null}}async function dispatchSchemaSubcommand(schema,inputs){const{normalizedSubcommand,typeName,options,globalOptions}=inputs;const{author,force,description}=inputs;const migration=dispatchSchemaMigration(schema,inputs);if(migration)return migration;const readRemoveOrPreset=dispatchSchemaReadRemoveOrPreset(schema,inputs);if(readRemoveOrPreset)return readRemoveOrPreset;switch(normalizedSubcommand){case"add-field":return schema.runSchemaAddField(typeName,{type:typeof options.type==="string"?options.type:void 0,commands:inputs.commands,description,cliFlag:typeof options.cliFlag==="string"?options.cliFlag:void 0,alias:inputs.aliases,required:Boolean(options.required),requiredOnCreate:Boolean(options.requiredOnCreate),allowUnset:options.allowUnset!==false,requiredTypes:inputs.requiredTypes,author,force},globalOptions);case"add-status":return schema.runSchemaAddStatus(typeName,{role:inputs.roles,alias:inputs.aliases,description,order:inputs.order,author,force},globalOptions);default:if(options.infer===true){return schema.runSchemaInferTypes({minCount:inputs.minCount,apply:Boolean(options.apply),author,force},globalOptions)}return schema.runSchemaAddType(typeName,{description,defaultStatus:inputs.defaultStatus,folder:typeof options.folder==="string"?options.folder:void 0,alias:inputs.aliases,author,force},globalOptions)}}function renderSchemaResultHuman(schema,result){if("migration_id"in result){writeStdout(`${schema.formatSchemaEvolutionMigrationHuman(result)}
2
+ `);return}switch(result.action){case"list":writeStdout(`${schema.formatSchemaListHuman(result)}
3
+ `);return;case"show":writeStdout(`${schema.formatSchemaShowHuman(result)}
4
+ `);return;case"show-status":writeStdout(`${schema.formatSchemaShowStatusHuman(result)}
5
+ `);return;case"list-fields":writeStdout(`${schema.formatSchemaListFieldsHuman(result)}
6
+ `);return;case"show-field":writeStdout(`${schema.formatSchemaShowFieldHuman(result)}
7
+ `);return;case"remove-type":writeStdout(`${schema.formatSchemaRemoveTypeHuman(result)}
8
+ `);break;case"remove-field":writeStdout(`${schema.formatSchemaRemoveFieldHuman(result)}
9
+ `);break;case"apply-preset":writeStdout(`${schema.formatSchemaApplyPresetHuman(result)}
10
+ `);break;case"infer-types":writeStdout(`${schema.formatSchemaInferTypesHuman(result)}
11
+ `);break;case"add-field":writeStdout(`${schema.formatSchemaAddFieldHuman(result)}
12
+ `);break;case"add-status":writeStdout(`${schema.formatSchemaAddStatusHuman(result)}
13
+ `);break;case"remove-status":writeStdout(`${schema.formatSchemaRemoveStatusHuman(result)}
14
+ `);break;default:writeStdout(`${schema.formatSchemaAddTypeHuman(result)}
15
+ `);break}if(result.warnings.length>0){printError(`schema ${result.action} warnings: ${formatHookWarnings(result.warnings)}`)}}async function dispatchProfileSubcommand(profile,subcommand,name,options,globalOptions){switch(subcommand){case"list":return profile.runProfileList();case"show":return profile.runProfileShow(name);case"lint":return profile.runProfileLint(name);default:return profile.runProfileApply(name,{dryRun:options.dryRun===true,author:typeof options.author==="string"?options.author:void 0,force:options.force===true},globalOptions)}}function renderProfileResultHuman(profile,result){switch(result.action){case"list":writeStdout(`${profile.formatProfileListHuman(result)}
16
+ `);return;case"show":writeStdout(`${profile.formatProfileShowHuman(result)}
17
+ `);return;case"lint":writeStdout(`${profile.formatProfileLintHuman(result)}
18
+ `);return;default:writeStdout(`${profile.formatProfileApplyHuman(result)}
19
+ `);if(result.warnings.length>0){printError(`profile apply warnings: ${formatHookWarnings(result.warnings)}`)}break}}function parsePositiveIntOption(flag){return value=>{const parsed=Number(value);if(!Number.isInteger(parsed)||parsed<1){throw new PmCliError(`${flag} must be a positive integer (1-based index).`,EXIT_CODE.USAGE)}return parsed}}function registerBulkContentAndGovernanceFilters(command,action){command.option("--filter-has-notes",`Select only items that have notes before ${action}`).option("--filter-no-notes",`Select only items that have no notes before ${action}`).option("--filter-has-learnings",`Select only items that have learnings before ${action}`).option("--filter-no-learnings",`Select only items that have no learnings before ${action}`).option("--filter-has-files",`Select only items that have linked files before ${action}`).option("--filter-no-files",`Select only items that have no linked files before ${action}`).option("--filter-has-docs",`Select only items that have linked docs before ${action}`).option("--filter-no-docs",`Select only items that have no linked docs before ${action}`).option("--filter-has-tests",`Select only items that have linked tests before ${action}`).option("--filter-no-tests",`Select only items that have no linked tests before ${action}`).option("--filter-has-comments",`Select only items that have comments before ${action}`).option("--filter-no-comments",`Select only items that have no comments before ${action}`).option("--filter-has-deps",`Select only items that have dependencies before ${action}`).option("--filter-no-deps",`Select only items that have no dependencies before ${action}`).option("--filter-has-body",`Select only items that have a non-empty body before ${action}`).option("--filter-empty-body",`Select only items with an empty body before ${action}`).option("--filter-has-linked-command",`Select only items whose linked tests carry a runnable command before ${action}`).option("--filter-no-linked-command",`Select only items whose linked tests carry no runnable command before ${action}`).option("--filter-reviewer-missing",`Select only items missing reviewer before ${action}`).option("--filter-risk-missing",`Select only items missing risk before ${action}`).option("--filter-confidence-missing",`Select only items missing confidence before ${action}`).option("--filter-sprint-missing",`Select only items missing sprint before ${action}`).option("--filter-release-missing",`Select only items missing release before ${action}`)}const BULK_CONTENT_FILTER_CONFLICTS=[["filterHasNotes","filterNoNotes","--filter-has-notes","--filter-no-notes"],["filterHasLearnings","filterNoLearnings","--filter-has-learnings","--filter-no-learnings"],["filterHasFiles","filterNoFiles","--filter-has-files","--filter-no-files"],["filterHasDocs","filterNoDocs","--filter-has-docs","--filter-no-docs"],["filterHasTests","filterNoTests","--filter-has-tests","--filter-no-tests"],["filterHasComments","filterNoComments","--filter-has-comments","--filter-no-comments"],["filterHasDeps","filterNoDeps","--filter-has-deps","--filter-no-deps"],["filterHasBody","filterEmptyBody","--filter-has-body","--filter-empty-body"],["filterHasLinkedCommand","filterNoLinkedCommand","--filter-has-linked-command","--filter-no-linked-command"]];function mapBulkContentAndGovernanceFilters(options){const presence=key=>options[key]===true?true:void 0;for(const[hasKey,noKey,hasFlag,noFlag]of BULK_CONTENT_FILTER_CONFLICTS){if(options[hasKey]===true&&options[noKey]===true){throw new PmCliError(`Cannot combine ${hasFlag} with ${noFlag} for the same field.`,EXIT_CODE.USAGE)}}return{filterReviewerMissing:presence("filterReviewerMissing"),filterRiskMissing:presence("filterRiskMissing"),filterConfidenceMissing:presence("filterConfidenceMissing"),filterSprintMissing:presence("filterSprintMissing"),filterReleaseMissing:presence("filterReleaseMissing"),hasNotes:presence("filterHasNotes"),hasLearnings:presence("filterHasLearnings"),hasFiles:presence("filterHasFiles"),hasDocs:presence("filterHasDocs"),hasTests:presence("filterHasTests"),hasComments:presence("filterHasComments"),hasDeps:presence("filterHasDeps"),hasBody:presence("filterHasBody"),hasLinkedCommand:presence("filterHasLinkedCommand"),noNotes:presence("filterNoNotes"),noLearnings:presence("filterNoLearnings"),noFiles:presence("filterNoFiles"),noDocs:presence("filterNoDocs"),noTests:presence("filterNoTests"),noComments:presence("filterNoComments"),noDeps:presence("filterNoDeps"),emptyBody:presence("filterEmptyBody"),noLinkedCommand:presence("filterNoLinkedCommand")}}function registerCommanderOptionContracts(command,contracts){for(const contract of contracts){const sharedValues=[];let activeParseArgs=command.args;const repeatableParser=value=>{if(command.args!==activeParseArgs){sharedValues.length=0;activeParseArgs=command.args}sharedValues.push(value);return sharedValues};if(contract.required){command.requiredOption(contract.option,contract.description)}else if(contract.repeatable){command.option(contract.option,contract.description,repeatableParser)}else{command.option(contract.option,contract.description)}for(const aliasContract of contract.aliasOptions??[]){if(isPureSnakeCaseAlias(contract.option,aliasContract.option)){addHiddenOption(command,aliasContract.option,aliasContract.description,contract.repeatable===true,contract.repeatable?repeatableParser:void 0)}else if(contract.repeatable){command.option(aliasContract.option,aliasContract.description,repeatableParser)}else{command.option(aliasContract.option,aliasContract.description)}}}}function buildUpdateManyListOptions(options){const readString=key=>typeof options[key]==="string"?options[key]:void 0;return{type:readString("filterType"),tag:readString("filterTag"),priority:readString("filterPriority"),deadlineBefore:readString("filterDeadlineBefore"),deadlineAfter:readString("filterDeadlineAfter"),updatedAfter:readString("filterUpdatedAfter"),updatedBefore:readString("filterUpdatedBefore"),createdAfter:readString("filterCreatedAfter"),createdBefore:readString("filterCreatedBefore"),ids:readString("ids"),assignee:readString("filterAssignee"),assigneeFilter:readString("filterAssigneeFilter")??readString("filterAssignee_filter"),parent:readString("filterParent"),sprint:readString("filterSprint"),release:readString("filterRelease"),filterAcMissing:options.filterAcMissing===true?true:void 0,filterEstimatesMissing:options.filterEstimatesMissing===true||options.filterEstimateMissing===true?true:void 0,filterResolutionMissing:options.filterResolutionMissing===true?true:void 0,filterMetadataMissing:options.filterMetadataMissing===true?true:void 0,...mapBulkContentAndGovernanceFilters(options),limit:readString("limit"),offset:readString("offset"),includeBody:true}}function pickStringOption(...candidates){for(const candidate of candidates){if(typeof candidate==="string"){return candidate}}return void 0}function stringArrayOption(value){if(Array.isArray(value)){return value}if(typeof value==="string"){return[value]}return void 0}function resolveCreatePositionals(typeOrTitle,secondTitle,options){if(typeof secondTitle==="string"&&secondTitle.length>0){return{positionalType:typeOrTitle,positionalTitle:secondTitle}}if(typeof typeOrTitle!=="string"||typeOrTitle.length===0){return{positionalType:void 0,positionalTitle:void 0}}const explicitTitleProvided=typeof options.title==="string"&&options.title.trim().length>0;return explicitTitleProvided&&options.type===void 0?{positionalType:typeOrTitle,positionalTitle:void 0}:{positionalType:void 0,positionalTitle:typeOrTitle}}function assertCreatePositionalTypeHasTitle(positionalType,positionalTitle,options){if(positionalType!==void 0||typeof positionalTitle!=="string"||positionalTitle.length===0||options.title!==void 0||options.type!==void 0||!BUILTIN_TYPE_NAME_LOOKUP.has(positionalTitle.trim().toLowerCase())){return}const matchedType=positionalTitle.trim();throw new PmCliError(`pm create needs a title \u2014 "${matchedType}" looks like an item type, not a title. Use either: pm create ${matchedType} "<title>" or pm create "<title>" --type ${matchedType}.`,EXIT_CODE.USAGE,{code:"create_positional_type_without_title",why:'Without this guard the single positional is used as the title and the type defaults to Task \u2014 so the command would silently create a Task literally titled "'+matchedType+'".',examples:[`pm create ${matchedType} "Wire up SSO for the agent harness"`,`pm create "Wire up SSO for the agent harness" --type ${matchedType}`],nextSteps:[`Re-run with both type and title: pm create ${matchedType} "<title>"`]})}const STRUCTURED_STDIN_CONFLICT_KEYS=["body","bodyFile","description","dep","depRemove","comment","note","learning","file","test","doc","reminder","event","typeOption","field","ids"];function assertSingleMutationStdinConsumer(options){const stdinFlags=STRUCTURED_STDIN_CONFLICT_KEYS.flatMap(key=>{const value=options[key];const count=typeof value==="string"&&value.trim()==="-"?1:Array.isArray(value)?value.filter(entry=>typeof entry==="string"&&entry.trim()==="-").length:0;const flag=`--${key.replace(/[A-Z]/g,letter=>`-${letter.toLowerCase()}`)}`;return Array.from({length:count},()=>flag)});if(options.stdinJson===true){stdinFlags.unshift("--stdin-json")}if(stdinFlags.length>1){throw new PmCliError(`Only one option may consume stdin per command invocation. Found: ${stdinFlags.join(", ")}.`,EXIT_CODE.USAGE)}}function preserveResolvedMutationStdinFields(options,bodyFileResolved,descriptionStdinResolved){const fields=[];if(bodyFileResolved)fields.push("body");if(descriptionStdinResolved)fields.push("description");preserveMutationStdinTokenFields(options,fields)}function isDescriptionStdinConsumer(options,stdinJsonConsumed){return!stdinJsonConsumed&&typeof options.description==="string"&&options.description.trim()==="-"}async function runCreateAction(typeOrTitle,secondTitle,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();assertSingleMutationStdinConsumer(options);const stdinJsonConsumed=options.stdinJson===true;if(stdinJsonConsumed){const input=await createStdinTokenResolver().resolveValue("-","--stdin-json");options=itemDocumentToMutationOptions(input??"","create",options)}const positionals=resolveCreatePositionals(typeOrTitle,secondTitle,options);assertCreatePositionalTypeHasTitle(positionals.positionalType,positionals.positionalTitle,options);if(typeof positionals.positionalType==="string"&&positionals.positionalType.length>0&&options.type===void 0){options.type=positionals.positionalType}if(typeof positionals.positionalTitle==="string"&&positionals.positionalTitle.length>0&&options.title===void 0)options.title=positionals.positionalTitle;const descriptionStdinResolved=isDescriptionStdinConsumer(options,stdinJsonConsumed);if(!stdinJsonConsumed){await resolveDescriptionStdin(options)}const bodyFileResolved=typeof options.bodyFile==="string";if(bodyFileResolved){options.body=await resolveBodyFileContent(String(options.bodyFile),options.body!==void 0?String(options.body):void 0);delete options.bodyFile}const normalized=normalizeCreateOptions(options,{requireType:false});preserveResolvedMutationStdinFields(normalized,bodyFileResolved,descriptionStdinResolved);if(stdinJsonConsumed)preserveMutationStdinTokenLiterals(normalized);const result=await runCreate(normalized,globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=create took_ms=${Date.now()-startedAt}`)}}function buildCloseManyListOptions(options){return{type:readOptionString(options,"filterType"),tag:readOptionString(options,"filterTag"),priority:readOptionString(options,"filterPriority"),deadlineBefore:readOptionString(options,"filterDeadlineBefore"),deadlineAfter:readOptionString(options,"filterDeadlineAfter"),updatedAfter:readOptionString(options,"filterUpdatedAfter"),updatedBefore:readOptionString(options,"filterUpdatedBefore"),createdAfter:readOptionString(options,"filterCreatedAfter"),createdBefore:readOptionString(options,"filterCreatedBefore"),ids:readOptionString(options,"ids"),assignee:readOptionString(options,"filterAssignee"),assigneeFilter:pickStringOption(options.filterAssigneeFilter,options.filterAssignee_filter),parent:readOptionString(options,"filterParent"),sprint:readOptionString(options,"filterSprint"),release:readOptionString(options,"filterRelease"),...mapBulkContentAndGovernanceFilters(options),limit:readOptionString(options,"limit"),offset:readOptionString(options,"offset")}}async function runCloseManyAction(options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();assertSingleMutationStdinConsumer(options);options.ids=await resolveCliBulkIdsInput(readOptionString(options,"ids"));const result=await runCloseMany({status:readOptionString(options,"filterStatus"),list:buildCloseManyListOptions(options),reason:readOptionString(options,"reason"),completedAt:readOptionString(options,"completedAt"),resolution:readOptionString(options,"resolution"),expectedResult:pickStringOption(options.expectedResult,options.expected_result,options.expected),actualResult:pickStringOption(options.actualResult,options.actual_result,options.actual),validateClose:options.validateClose===true?"warn":readOptionString(options,"validateClose"),author:readOptionString(options,"author"),message:readOptionString(options,"message"),force:Boolean(options.force),dryRun:options.dryRun===true?true:void 0,rollback:readOptionString(options,"rollback"),checkpoint:options.checkpoint===false?false:void 0},globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=close-many took_ms=${Date.now()-startedAt}`)}}async function runUpdateManyAction(options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();assertSingleMutationStdinConsumer(options);options.ids=await resolveCliBulkIdsInput(readOptionString(options,"ids"));const result=await runUpdateMany({status:readOptionString(options,"filterStatus"),list:buildUpdateManyListOptions(options),update:normalizeUpdateOptions(extractUpdateManyMutationOptionSource(options)),dryRun:options.dryRun===true?true:void 0,rollback:readOptionString(options,"rollback"),checkpoint:options.checkpoint===false?false:void 0},globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(await applyActiveCommandResultService("update-many",[],options,globalOptions,result),globalOptions);if(globalOptions.profile){printError(`profile:command=update-many took_ms=${Date.now()-startedAt}`)}}async function runCloseAction(id,text,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const reasonFromOption=typeof options.reason==="string"&&options.reason.trim().length>0&&options.reason||typeof options.closeReason==="string"&&options.closeReason.trim().length>0&&options.closeReason||void 0;const resolvedText=typeof text==="string"&&text.length>0?text:reasonFromOption;const result=await runClose(id,resolvedText,{author:readOptionString(options,"author"),message:readOptionString(options,"message"),validateClose:options.validateClose===true?"warn":readOptionString(options,"validateClose"),force:Boolean(options.force),duplicateOf:readOptionString(options,"duplicateOf"),completedAt:readOptionString(options,"completedAt"),resolution:readOptionString(options,"resolution"),expectedResult:pickStringOption(options.expectedResult,options.expected_result,options.expected),actualResult:pickStringOption(options.actualResult,options.actual_result,options.actual)},globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=close took_ms=${Date.now()-startedAt}`)}}function normalizePlanAliases(options){const planOptions={...options};const aliasPairs=[["blocked_by","blockedBy"],["resume_context","resumeContext"],["from_search","fromSearch"],["step_title","stepTitle"],["step_body","stepBody"],["step_owner","stepOwner"],["step_status","stepStatus"],["step_evidence","stepEvidence"],["step_blocked_reason","stepBlockedReason"],["step_replacement","stepReplacement"],["depends_on","dependsOn"],["link_kind","linkKind"],["link_note","linkNote"],["promote_to_item_dep","promoteToItemDep"],["allow_multiple_active","allowMultipleActive"],["decision_text","decisionText"],["decision_rationale","decisionRationale"],["decision_evidence","decisionEvidence"],["discovery_text","discoveryText"],["validation_text","validationText"],["validation_command","validationCommand"],["validation_expected","validationExpected"],["materialize_type","materializeType"],["materialize_parent","materializeParent"],["materialize_tags","materializeTags"]];for(const[snake,camel]of aliasPairs){if(planOptions[snake]!==void 0&&planOptions[camel]===void 0){planOptions[camel]=planOptions[snake]}}const normalized=normalizeCreateOptions(planOptions,{requireType:false});normalized.blockedBy=planOptions.blockedBy;return normalized}function assertKnownPlanSubcommand(normalized,allowed){if(!normalized){throw new PmCliError(`pm plan requires a subcommand. Allowed: ${allowed.join(", ")}`,EXIT_CODE.USAGE,{code:"missing_required_argument",examples:['pm plan create --title "Refactor lock retry"',"pm plan show pm-a1b2 --depth standard",'pm plan add-step pm-a1b2 --step-title "Read lock.ts"']})}if(allowed.includes(normalized)){return}const examples=normalized==="list"||normalized==="ls"?["pm list --type Plan","pm list-all --type Plan"]:void 0;throw createUnknownSubcommandError({command_path:"plan",token:normalized,allowed,examples,retry_command:normalized==="list"||normalized==="ls"?"pm list --type Plan":void 0})}function parsePlanReorderTo(normalizedSubcommand,reorderToken){if(normalizedSubcommand!=="reorder-step"||typeof reorderToken!=="string"){return void 0}const parsed=Number.parseInt(reorderToken,10);if(!Number.isFinite(parsed)){throw new PmCliError(`reorder-step requires an integer new order, got "${reorderToken}"`,EXIT_CODE.USAGE)}return parsed}async function runPlanAction(subcommand,id,stepRef,reorderToken,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const normalizedSubcommand=(subcommand??"").trim().toLowerCase();assertKnownPlanSubcommand(normalizedSubcommand,PLAN_SUBCOMMANDS);const planOptions=normalizePlanAliases(options);const reorderTo=parsePlanReorderTo(normalizedSubcommand,reorderToken);const planId=normalizedSubcommand==="create"&&typeof id==="string"&&id.length>0&&planOptions.title===void 0?void 0:id;if(planId===void 0&&typeof id==="string"&&id.length>0){planOptions.title=id}const result=await runPlan({subcommand:normalizedSubcommand,id:planId,stepRef,reorderTo,options:planOptions,global:globalOptions});await invalidateSearchCachesForMutation(globalOptions,result);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=plan took_ms=${Date.now()-startedAt}`)}}async function runMergeReconcileSubcommand(artifact,options,globalOptions){if(artifact!==void 0){throw new PmCliError("merge reconcile takes no positional arguments.",EXIT_CODE.USAGE)}const result=await runMergeReconcile({dryRun:options.dryRun===true,force:options.force===true,message:typeof options.message==="string"?options.message:void 0,author:globalOptions.author},globalOptions);printResult(result,globalOptions);if(!result.ok)process.exitCode=EXIT_CODE.GENERIC_FAILURE}async function runMergeDriverSubcommand(artifact,base,ours,theirs,options,globalOptions){if(artifact===void 0||base===void 0||ours===void 0||theirs===void 0){throw new PmCliError("merge driver requires <artifact> <base> <ours> <theirs> (git supplies %O %A %B). Example: pm merge driver history %O %A %B",EXIT_CODE.USAGE)}const result=await runMergeDriver({artifact,basePath:base,oursPath:ours,theirsPath:theirs,outputPath:typeof options.output==="string"?options.output:void 0,itemPath:typeof options.itemPath==="string"?options.itemPath:void 0,prefer:typeof options.prefer==="string"?options.prefer:void 0},globalOptions);printResult(result,globalOptions);if(!result.ok){process.exitCode=EXIT_CODE.GENERIC_FAILURE}}async function runMergeAction(subcommand,artifact,base,ours,theirs,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const normalized=subcommand.trim().toLowerCase();switch(normalized){case"install":{if(artifact!==void 0){throw new PmCliError("merge install takes no positional arguments.",EXIT_CODE.USAGE)}const result=await runMergeInstall({dryRun:options.dryRun===true},globalOptions);printResult(result,globalOptions);break}case"reconcile":await runMergeReconcileSubcommand(artifact,options,globalOptions);break;case"report":{if(artifact!==void 0){throw new PmCliError("merge report takes no positional arguments.",EXIT_CODE.USAGE)}const result=await runMergeReceiptEvidenceReport({includeReconciled:options.includeReconciled===true});printResult(result,globalOptions);if(!result.ok)process.exitCode=EXIT_CODE.GENERIC_FAILURE;break}case"driver":await runMergeDriverSubcommand(artifact,base,ours,theirs,options,globalOptions);break;default:throw createUnknownSubcommandError({command_path:"merge",token:subcommand,allowed:MERGE_SUBCOMMAND_VALUES,display_name:"merge"})}if(globalOptions.profile){printError(`profile:command=merge took_ms=${Date.now()-startedAt}`)}}function splitCollectedCommaList(raw){if(!Array.isArray(raw)){return void 0}return raw.flatMap(value=>value.split(",")).map(value=>value.trim()).filter(value=>value.length>0)}async function runSchemaAction(subcommand,name,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const{SCHEMA_SUBCOMMANDS}=schemaModule;let normalizedSubcommand=(subcommand??"").trim().toLowerCase();let typeName=name;assertSchemaSubcommandPresent(normalizedSubcommand,SCHEMA_SUBCOMMANDS);if(!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand)&&typeName===void 0&&!looksLikeSchemaSubcommandTypo(subcommand)){typeName=subcommand;normalizedSubcommand="add-type"}if(!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand)){throw createUnknownSubcommandError({command_path:"schema",token:normalizedSubcommand,allowed:SCHEMA_SUBCOMMANDS})}const policyAction=WORKFLOW_POLICY_ACTIONS.find(action=>action===normalizedSubcommand);if(policyAction){printResult(await schemaModule.runWorkflowPolicyAction(policyAction,name,{definition:options.definition,policy:readOptionString(options,"policy"),message:readOptionString(options,"message"),author:readOptionString(options,"author"),dryRun:options.dryRun===true},globalOptions),globalOptions)}else{const result=await dispatchSchemaSubcommand(schemaModule,{normalizedSubcommand,typeName,options,aliases:stringArrayOption(options.alias),roles:stringArrayOption(options.role),commands:splitCollectedCommaList(options.commands),requiredTypes:splitCollectedCommaList(options.requiredTypes),defaultStatus:pickStringOption(options.defaultStatus,options.default_status),order:parseSchemaOrderOption(options.order),minCount:parseSchemaOrderOption(options.minCount),author:readOptionString(options,"author"),force:Boolean(options.force),description:readOptionString(options,"description"),globalOptions});if(globalOptions.json===true||globalOptions.defaultOutputFormat==="json"){printResult(result,globalOptions)}else if(!globalOptions.quiet){renderSchemaResultHuman(schemaModule,result)}}if(globalOptions.profile){printError(`profile:command=schema took_ms=${Date.now()-startedAt}`)}}function assertSchemaSubcommandPresent(normalizedSubcommand,allowed){if(normalizedSubcommand){return}throw new PmCliError(`pm schema requires a subcommand. Allowed: ${allowed.join(", ")}`,EXIT_CODE.USAGE,{code:"missing_required_argument",examples:["pm schema list","pm schema show Task","pm schema show-status open",'pm schema add-type Spike --description "Time-boxed investigation" --default-status open',"pm schema remove-type Spike","pm schema add-status review --role active --alias in_review","pm schema remove-status review","pm schema add-field severity_level --type string --commands create,update","pm schema list-fields","pm schema apply-preset agile","pm schema add-type --infer --min-count 10","pm schema rename-type Spike --to Experiment --migration-id spike-v2 --dry-run","pm schema rename-field severity --to impact --migration-id severity-v2","pm schema remap-status review --to verifying --migration-id review-v2"]})}async function runCopyAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const result=await runCopy(id,{title:readOptionString(options,"title"),author:readOptionString(options,"author"),message:readOptionString(options,"message"),allowDuplicate:options.allowDuplicate===true},globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=copy took_ms=${Date.now()-startedAt}`)}}async function runFocusAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const result=await runFocus(id,{clear:options.clear===true},globalOptions);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=focus took_ms=${Date.now()-startedAt}`)}}async function runUpdateAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();assertSingleMutationStdinConsumer(options);const stdinJsonConsumed=options.stdinJson===true;if(stdinJsonConsumed){const input=await createStdinTokenResolver().resolveValue("-","--stdin-json");options=itemDocumentToMutationOptions(input??"","update",options)}const descriptionStdinResolved=isDescriptionStdinConsumer(options,stdinJsonConsumed);if(!stdinJsonConsumed){await resolveDescriptionStdin(options)}const bodyFileResolved=typeof options.bodyFile==="string";if(bodyFileResolved){options.body=await resolveBodyFileContent(String(options.bodyFile),options.body!==void 0?String(options.body):void 0);delete options.bodyFile}const normalized=normalizeUpdateOptions(options);preserveResolvedMutationStdinFields(normalized,bodyFileResolved,descriptionStdinResolved);if(stdinJsonConsumed)preserveMutationStdinTokenLiterals(normalized);const result=await runUpdate(id,normalized,globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(await applyActiveCommandResultService("update",[id],options,globalOptions,result),globalOptions);if(globalOptions.profile){printError(`profile:command=update took_ms=${Date.now()-startedAt}`)}}async function runDeleteAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const result=await runDelete(id,{author:readOptionString(options,"author"),message:readOptionString(options,"message"),force:Boolean(options.force),dryRun:options.dryRun===true},globalOptions);if(result.dry_run!==true){await invalidateSearchCachesForMutation(globalOptions,result)}printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=delete took_ms=${Date.now()-startedAt}`)}}function resolveAppendBody(text,options){const bodyFromOption=readOptionString(options,"body");const bodyFromAlias=readOptionString(options,"text");const bodyFromPositional=typeof text==="string"?text:void 0;const bodySourceCount=[bodyFromOption,bodyFromAlias,bodyFromPositional].filter(value=>value!==void 0).length;if(bodySourceCount>1){throw new PmCliError("Specify append text with exactly one source: positional [text], --body, or --text",EXIT_CODE.USAGE)}const resolvedBody=bodyFromOption??bodyFromAlias??bodyFromPositional;if(resolvedBody===void 0){throw new PmCliError("Missing append text. Provide it as positional [text], --body <value>, or --text <value> (use - for stdin).",EXIT_CODE.USAGE)}return resolvedBody}async function runAppendAction(id,text,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const result=await runAppend(id,{body:resolveAppendBody(text,options),author:readOptionString(options,"author"),message:readOptionString(options,"message"),force:Boolean(options.force)},globalOptions);await invalidateSearchCachesForMutation(globalOptions,result);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=append took_ms=${Date.now()-startedAt}`)}}async function runProfileAction(subcommand,name,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const{PROFILE_SUBCOMMANDS}=profileModule;const normalizedSubcommand=(subcommand??"").trim().toLowerCase();if(!normalizedSubcommand){throw new PmCliError(`pm profile requires a subcommand. Allowed: ${PROFILE_SUBCOMMANDS.join(", ")}`,EXIT_CODE.USAGE,{code:"missing_required_argument",examples:["pm profile list","pm profile show agile","pm profile apply agile --dry-run","pm profile lint agile"]})}if(!PROFILE_SUBCOMMANDS.includes(normalizedSubcommand)){throw createUnknownSubcommandError({command_path:"profile",token:normalizedSubcommand,allowed:PROFILE_SUBCOMMANDS})}const result=await dispatchProfileSubcommand(profileModule,normalizedSubcommand,name,options,globalOptions);if(globalOptions.json===true||globalOptions.defaultOutputFormat==="json"){printResult(result,globalOptions)}else if(!globalOptions.quiet){renderProfileResultHuman(profileModule,result)}if(result.action==="lint"&&!result.ok){process.exitCode=EXIT_CODE.GENERIC_FAILURE}if(globalOptions.profile){printError(`profile:command=profile took_ms=${Date.now()-startedAt}`)}}function readStringArrayOption(options,key){return stringArrayOption(options[key])??[]}async function runFilesAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const addValues=readStringArrayOption(options,"add");const addGlobValues=readStringArrayOption(options,"addGlob");const removeValues=readStringArrayOption(options,"remove");const migrateValues=readStringArrayOption(options,"migrate");const result=await runFiles(id,{add:addValues,addGlob:addGlobValues,remove:removeValues,migrate:migrateValues,note:readOptionString(options,"note"),list:Boolean(options.list),appendStable:Boolean(options.appendStable),validatePaths:Boolean(options.validatePaths),author:readOptionString(options,"author"),message:readOptionString(options,"message"),force:Boolean(options.force)},globalOptions);if(addValues.length>0||addGlobValues.length>0||removeValues.length>0||migrateValues.length>0){await invalidateSearchCachesForMutation(globalOptions,result)}printResult(await applyActiveCommandResultService("files",[id],options,globalOptions,result),globalOptions);if(globalOptions.profile){printError(`profile:command=files took_ms=${Date.now()-startedAt}`)}}async function runFilesDiscoverAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const mergedOptions={...command.optsWithGlobals(),...options};const result=await runFilesDiscover(id,{apply:Boolean(mergedOptions.apply),note:readOptionString(mergedOptions,"note"),appendStable:Boolean(mergedOptions.appendStable),author:readOptionString(mergedOptions,"author"),message:readOptionString(mergedOptions,"message"),force:Boolean(mergedOptions.force)},globalOptions);if(result.changed){await invalidateSearchCachesForMutation(globalOptions,result)}printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=files.discover took_ms=${Date.now()-startedAt}`)}}async function runDocsAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const addValues=readStringArrayOption(options,"add");const addGlobValues=readStringArrayOption(options,"addGlob");const removeValues=readStringArrayOption(options,"remove");const migrateValues=readStringArrayOption(options,"migrate");const result=await runDocs(id,{add:addValues,addGlob:addGlobValues,remove:removeValues,migrate:migrateValues,note:readOptionString(options,"note"),list:Boolean(options.list),validatePaths:Boolean(options.validatePaths),author:readOptionString(options,"author"),message:readOptionString(options,"message"),force:Boolean(options.force)},globalOptions);if(addValues.length>0||addGlobValues.length>0||removeValues.length>0||migrateValues.length>0){await invalidateSearchCachesForMutation(globalOptions,result)}printResult(await applyActiveCommandResultService("docs",[id],options,globalOptions,result),globalOptions);if(globalOptions.profile){printError(`profile:command=docs took_ms=${Date.now()-startedAt}`)}}async function runDepsAction(id,options,command){const globalOptions=getGlobalOptions(command);const startedAt=Date.now();const result=await runDeps(id,{format:options.format,maxDepth:readOptionString(options,"maxDepth"),collapse:options.collapse,summary:options.summary===true,full:options.full===true,nodeLimit:readOptionString(options,"nodeLimit"),edgeLimit:readOptionString(options,"edgeLimit"),tokenBudget:readOptionString(options,"tokenBudget"),cursor:readOptionString(options,"cursor"),direction:readOptionString(options,"direction"),...Array.isArray(options.kind)?{kind:options.kind}:{}},globalOptions);printResult(result,globalOptions);if(globalOptions.profile){printError(`profile:command=deps took_ms=${Date.now()-startedAt}`)}}function registerMutationCommands(program,registrationOptions={}){const createCommand=program.command("create").argument("[type-or-title]",'Item title, or item type when a title follows (e.g. `pm create task "Fix bug"`)').argument("[title]","Item title when the first argument is an item type").description("Create a new project management item.");registerCommanderOptionContracts(createCommand,CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS);createCommand.option("--stdin-json","Read a full item JSON document from stdin; explicit flags override document values").option("--body-file <path>","Load body from a file or stdin (-); conflicts with --body").option("--clear-deps","Clear dependency entries").option("--clear-comments","Clear comments").option("--clear-notes","Clear notes").option("--clear-learnings","Clear learnings").option("--clear-files","Clear linked files").option("--clear-tests","Clear linked tests").option("--clear-docs","Clear linked docs").option("--clear-reminders","Clear reminders").option("--clear-events","Clear events").option("--clear-type-options","Clear type options").option("--allow-duplicate","Explicitly create even when strict similarity governance finds likely duplicates").action(runCreateAction);if(registrationOptions.targetCommandName==="create"){return}program.command("copy").argument("<id>","Source item id").option("--title <value>","Optional title override for the copied item").option("--author <value>","Mutation author").option("--message <value>","History message").option("--allow-duplicate","Explicitly copy even when strict similarity governance finds likely duplicates").description("Copy an item into a new item id while resetting lifecycle fields.").action(runCopyAction);program.command("focus").argument("[id]","Item id to focus (omit to show current focus)").option("--clear","Clear the focused item").description("Set/clear/show the session focused item that new items default --parent to.").action(runFocusAction);const updateCommand=program.command("update").argument("<id>","Item id").description("Update item fields and metadata.");registerCommanderOptionContracts(updateCommand,UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS);updateCommand.option("--stdin-json","Read a full item JSON document from stdin; explicit flags override document values").option("--body-file <path>","Load body from a file or stdin (-); conflicts with --body").option("--replace-deps","Atomically replace dependency entries with the provided --dep values").option("--replace-tests","Atomically replace linked test entries with the provided --test values").option("--replace-files","Atomically replace linked file entries with the provided --file values").option("--replace-docs","Atomically replace linked doc entries with the provided --doc values").option("--clear-deps","Clear dependency entries").option("--clear-comments","Clear comments").option("--clear-notes","Clear notes").option("--clear-learnings","Clear learnings").option("--clear-files","Clear linked files").option("--clear-tests","Clear linked tests").option("--clear-docs","Clear linked docs").option("--clear-reminders","Clear reminders").option("--clear-events","Clear events").option("--clear-type-options","Clear type options").option("--force","Force ownership override");updateCommand.action(runUpdateAction);registerStructuredMutationCommands(program);const updateManyCommand=program.command("update-many").description("Bulk-update matched items with dry-run plans and rollback checkpoints.").option("--filter-status <value>","Filter by status before applying updates").option("--filter-type <value>","Filter by item type before applying updates").option("--filter-tag <value>","Filter by tag before applying updates").option("--filter-priority <value>","Filter by priority before applying updates").option("--filter-deadline-before <value>","Filter by deadline upper bound before applying updates").option("--filter-deadline-after <value>","Filter by deadline lower bound before applying updates").option("--filter-updated-after <value>","Filter by updated_at lower bound before applying updates (ISO/relative)").option("--filter-updated-before <value>","Filter by updated_at upper bound before applying updates (ISO/relative)").option("--filter-created-after <value>","Filter by created_at lower bound before applying updates (ISO/relative)").option("--filter-created-before <value>","Filter by created_at upper bound before applying updates (ISO/relative)").option("--filter-assignee <value>","Filter by assignee before applying updates").option("--filter-assignee-filter <value>","Filter assignee presence: assigned|unassigned before applying updates").option("--filter-parent <value>","Filter by parent item ID before applying updates").option("--filter-sprint <value>","Filter by sprint before applying updates").option("--filter-release <value>","Filter by release before applying updates").option("--filter-ac-missing","Select only items missing acceptance_criteria (bulk backfill)").option("--filter-estimates-missing","Select only items missing estimated_minutes (bulk backfill)").option("--filter-resolution-missing","Select only terminal items missing resolution (bulk backfill)").option("--filter-metadata-missing","Select only items missing any tracked metadata (AC, estimate, or resolution)");registerBulkContentAndGovernanceFilters(updateManyCommand,"applying updates");updateManyCommand.option("--ids <value>","Explicit ID allowlist: comma/newline text, - stdin, or @path file").option("--limit <n>","Limit matched item count before apply/preview").option("--offset <n>","Skip first n matched rows before apply/preview").option("--dry-run","Preview per-item diffs and checkpoint intent without mutating").option("--rollback <value>","Rollback a prior update-many checkpoint ID").option("--no-checkpoint","Disable checkpoint creation during apply mode").option("--title, -t <value>","Set title").option("--description, -d <value>","Set description").option("--body, -b <value>","Set body (allow empty string)").option("--status, -s <value>","Set status (use close command for closed)").option("--priority, -p <value>","Set priority").option("--type <value>","Set type").option("--tags <value>","Set comma-separated tags (replaces existing). Use --add-tags / --remove-tags to mutate additively.").option("--add-tags <value>","Add tags additively without replacing existing (repeatable; CSV accepted)",collect).option("--remove-tags <value>","Remove tags from the existing list (repeatable; CSV accepted)",collect).option("--deadline <value>","Set deadline (ISO/date string or relative)").option("--estimate, --estimated-minutes <value>","Set estimated minutes").option("--acceptance-criteria <value>","Set acceptance criteria").option("--ac <value>","Alias for --acceptance-criteria").option("--add-ac <value>","Add one semicolon-free acceptance criterion without replacing the existing list (repeatable)",collect).option("--remove-ac <value>","Remove one semicolon-free acceptance criterion by exact text match (repeatable)",collect).option("--definition-of-ready <value>","Set definition of ready").option("--order <value>","Set planning order/rank integer").option("--rank <value>","Alias for --order").option("--goal <value>","Set goal identifier").option("--objective <value>","Set objective identifier").option("--value <value>","Set business value summary").option("--impact <value>","Set business impact summary").option("--outcome <value>","Set expected outcome summary").option("--why-now <value>","Set why-now rationale").option("--assignee <value>","Set assignee").option("--parent <value>","Set parent item ID").option("--reviewer <value>","Set reviewer").option("--risk <value>","Set risk level").option("--confidence <value>","Set confidence level").option("--sprint <value>","Set sprint identifier").option("--release <value>","Set release identifier").option("--blocked-by <value>","Set blocked-by item ID or reason").option("--blocked-reason <value>","Set blocked reason").option("--unblock-note <value>","Set unblock rationale note").option("--reporter <value>","Set issue reporter").option("--severity <value>","Set issue severity").option("--environment <value>","Set issue environment context").option("--repro-steps <value>","Set issue reproduction steps").option("--resolution <value>","Set issue resolution summary").option("--expected-result <value>","Set issue expected behavior").option("--expected <value>","Short alias for --expected-result").option("--actual-result <value>","Set issue observed behavior").option("--actual <value>","Short alias for --actual-result").option("--affected-version <value>","Set affected version identifier").option("--fixed-version <value>","Set fixed version identifier").option("--component <value>","Set issue component ownership").option("--regression [value]","Set regression marker; bare flag means true, or pass true|false|1|0").option("--customer-impact <value>","Set customer impact summary").option("--dep <value>","Add dependency entry id=<id>,kind=<kind>,author=<author>,created_at=<timestamp>",collect).option("--dep-remove <value>","Remove dependency entries by id/kind/author/timestamp signature",collect).option("--replace-deps","Atomically replace dependency entries with provided --dep values").option("--replace-tests","Atomically replace linked tests with provided --test values").option("--replace-files","Atomically replace linked files with provided --file values").option("--replace-docs","Atomically replace linked docs with provided --doc values").option("--comment <value>","Add comment seed author=<value>,created_at=<iso|now>,text=<value>",collect).option("--note <value>","Add note seed author=<value>,created_at=<iso|now>,text=<value>",collect).option("--learning <value>","Add learning seed author=<value>,created_at=<iso|now>,text=<value>",collect).option("--file <value>","Add linked file path=<value>,scope=<project|global>,note=<text>",collect).option("--test <value>","Add linked test command=<value>,path=<value>,scope=<project|global>",collect).option("--doc <value>","Add linked doc path=<value>,scope=<project|global>,note=<text>",collect).option("--reminder <value>","Add reminder entry at=<iso|relative>|date=<iso|relative>,text=<text>|title=<text>",collect).option("--event <value>","Add event entry start=<iso|relative>,end=<iso|relative>,recur_*",collect).option("--type-option <value>","Set type options key=value (repeatable)",collect).option("--unset <field>","Clear scalar metadata field by name (repeatable)",collect).option("--clear-deps","Clear dependency entries").option("--clear-comments","Clear comments").option("--clear-notes","Clear notes").option("--clear-learnings","Clear learnings").option("--clear-files","Clear linked files").option("--clear-tests","Clear linked tests").option("--clear-docs","Clear linked docs").option("--clear-reminders","Clear reminders").option("--clear-events","Clear events").option("--clear-type-options","Clear type options").option("--author <value>","Mutation author").option("--message <value>","Mutation message").option("--force","Force ownership override");addHiddenOptions(updateManyCommand,[["--filter-assignee_filter <value>","Alias for --filter-assignee-filter"],["--estimated_minutes <value>","Alias for --estimated-minutes"],["--acceptance_criteria <value>","Alias for --acceptance-criteria"],["--definition_of_ready <value>","Alias for --definition-of-ready"],["--why_now <value>","Alias for --why-now"],["--blocked_by <value>","Alias for --blocked-by"],["--blocked_reason <value>","Alias for --blocked-reason"],["--unblock_note <value>","Alias for --unblock-note"],["--repro_steps <value>","Alias for --repro-steps"],["--expected_result <value>","Alias for --expected-result"],["--actual_result <value>","Alias for --actual-result"],["--affected_version <value>","Alias for --affected-version"],["--fixed_version <value>","Alias for --fixed-version"],["--customer_impact <value>","Alias for --customer-impact"],["--filter-estimate-missing","Alias for --filter-estimates-missing"]],false);addHiddenOptions(updateManyCommand,[["--dep_remove <value>","Alias for --dep-remove"],["--type_option <value>","Alias for --type-option"],["--add_tags <value>","Alias for --add-tags"],["--remove_tags <value>","Alias for --remove-tags"],["--add_ac <value>","Alias for --add-ac"],["--remove_ac <value>","Alias for --remove-ac"]],true);updateManyCommand.action(runUpdateManyAction);const closeCommand=program.command("close").argument("<id>","Item id").argument("[text]","Close reason text (alias: --reason)").option("-r, --reason <value>","Close reason text (alias for positional <text>)").option("--close-reason <value>","Close reason text (alias for positional <text>)").option("--completed-at <value>","Actual completion timestamp (ISO or relative), distinct from tracker close time").option("-d, --duplicate-of <id>","Close as a duplicate of the canonical item id and auto-fill duplicate closure metadata").option("--author <value>","Mutation author").option("-m, --message <value>","History message").option("--validate-close [mode]",'Validate closure metadata before close: "off", "warn", or "strict" (default: settings governance preset)').option("--resolution <value>","Set the closure resolution summary inline (same field --validate-close strict checks; previously required a prior pm update)").option("--expected-result <value>","Set the expected-result note inline (closure validation field)").option("--expected <value>","Short alias for --expected-result").option("--actual-result <value>","Set the actual-result note inline (closure validation field)").option("--actual <value>","Short alias for --actual-result").option("--force","Force ownership override").description("Close an item. Close reason requirement follows governance.require_close_reason.");addHiddenOption(closeCommand,"--expected_result <value>","Alias for --expected-result",false);addHiddenOption(closeCommand,"--actual_result <value>","Alias for --actual-result",false);closeCommand.action(runCloseAction);const closeManyCommand=program.command("close-many").description("Bulk-close matched items with a shared reason and full runClose semantics (dry-run + rollback checkpoint).").option("--filter-status <value>","Filter by status before closing").option("--filter-type <value>","Filter by item type before closing").option("--filter-tag <value>","Filter by tag before closing").option("--filter-priority <value>","Filter by priority before closing").option("--filter-deadline-before <value>","Filter by deadline upper bound before closing").option("--filter-deadline-after <value>","Filter by deadline lower bound before closing").option("--filter-updated-after <value>","Filter by updated_at lower bound before closing (ISO/relative)").option("--filter-updated-before <value>","Filter by updated_at upper bound before closing (ISO/relative)").option("--filter-created-after <value>","Filter by created_at lower bound before closing (ISO/relative)").option("--filter-created-before <value>","Filter by created_at upper bound before closing (ISO/relative)").option("--filter-assignee <value>","Filter by assignee before closing").option("--filter-assignee-filter <value>","Filter assignee presence: assigned|unassigned before closing").option("--filter-parent <value>","Filter by parent item ID before closing").option("--filter-sprint <value>","Filter by sprint before closing").option("--filter-release <value>","Filter by release before closing");registerBulkContentAndGovernanceFilters(closeManyCommand,"closing");closeManyCommand.option("--ids <value>","Explicit ID allowlist: comma/newline text, - stdin, or @path file").option("--limit <n>","Limit matched item count before apply/preview").option("--offset <n>","Skip first n matched rows before apply/preview").option("--reason <value>","Shared close reason applied to matched items (required when governance.require_close_reason is enabled)").option("--completed-at <value>","Actual completion timestamp (ISO or relative) applied to every matched item").option("--resolution <value>","Shared closure resolution applied to every matched item (closure-validation field)").option("--expected-result <value>","Shared expected-result note (closure-validation field)").option("--expected <value>","Short alias for --expected-result").option("--actual-result <value>","Shared actual-result note (closure-validation field)").option("--actual <value>","Short alias for --actual-result").option("--validate-close [mode]",'Validate closure metadata per item: "off", "warn", or "strict" (default: settings governance preset)').option("--author <value>","Mutation author").option("--message <value>","History message").option("--force","Re-close already-terminal matches and override ownership").option("--dry-run","Preview matched items + per-item skip/active-child plan without mutating").option("--rollback <value>","Rollback a prior close-many checkpoint ID").option("--no-checkpoint","Disable checkpoint creation during apply mode");addHiddenOption(closeManyCommand,"--filter-assignee_filter <value>","Alias for --filter-assignee-filter",false);addHiddenOption(closeManyCommand,"--expected_result <value>","Alias for --expected-result",false);addHiddenOption(closeManyCommand,"--actual_result <value>","Alias for --actual-result",false);closeManyCommand.action(runCloseManyAction);program.command("delete").argument("<id>","Item id").option("--author <value>","Mutation author").option("--message <value>","History message").option("--force","Force ownership override").option("--dry-run","Preview the item file that would be deleted without mutating").description("Delete an item and record the change in history.").action(runDeleteAction);program.command("append").argument("<id>","Item id").argument("[text]","Body text; same as --body (- reads stdin)").option("--body <value>","Text to append to body (or - for stdin)").option("--text <value>","Alias for --body").option("--author <value>","Mutation author").option("--message <value>","Mutation message").option("--force","Force ownership override").description("Append text to an item's body. For concurrent writes, use pm notes.").action(runAppendAction);const planCommand=program.command("plan").description("Agent-optimized Plan item workflow: create, manage steps, link dependencies, approve, and materialize.").argument("[subcommand]","Required; Plan subcommand: create|show|add-step|update-step|complete-step|block-step|reorder-step|remove-step|link|unlink|decision|discovery|validation|resume|approve|materialize").argument("[id]","Plan id (required for non-create subcommands); for create this may be the positional title").argument("[step]","Step reference: stable id (plan-step-001) or order integer").argument("[new-order]","New order integer for reorder-step").option("--title <value>","Plan title").option("--description <value>","Plan description").option("--scope <value>","Short scope statement of the target change or investigation").option("--parent <value>","Parent pm item id").option("--related <value>","Related pm item ids (repeatable, csv-friendly)",collect).option("--blocks <value>","Pm item ids this plan blocks (repeatable, csv-friendly)",collect).option("--blocked-by <value>","Pm item ids that block this plan (repeatable, csv-friendly)",collect).option("--harness <value>","Plan harness provenance: codex|claude-code|cursor|generic").option("--mode <value>","Plan mode: draft|research|review|approved|executing|paused|completed|superseded").option("--resume-context <value>","Compact context summary for a future stateless agent").option("--tags <value>","Comma-separated tags").option("--priority <value>","Priority 0-4").option("--body <value>","Plan item body").option("--claim","Claim the plan on create for the author").option("--from-search <value>","Record the search query that led to plan creation").option("--template <value>","Seed plan steps from a built-in template: bug-investigation|feature-implementation|refactoring-sprint").option("--step-title <value>","Step title for add-step / update-step").option("--step <value>","Step title (repeatable on create: each --step appends an ordered step; elsewhere a single value aliases --step-title)",collect).option("--step-body <value>","Step body text").option("--step-owner <value>","Step owner").option("--step-status <value>","Step status: pending|in_progress|completed|blocked|skipped|superseded").option("--step-evidence <value>","Step evidence text (used by update-step/complete-step)").option("--step-blocked-reason <value>","Step blocked reason (required when blocking)").option("--step-replacement <value>","Replacement reference for a superseded step").option("--depends-on <value>","Pm item ids the step depends on (repeatable, csv-friendly)",collect).option("--link <value>","Pm item id to link (repeatable, csv-friendly)",collect).option("--link-kind <value>",`Link kind: ${PLAN_STEP_LINK_KIND_VALUES.join("|")}`).option("--link-note <value>","Optional note for the link").option("--promote-to-item-dep","Also add the linked id as a top-level item dependency when linking").option("--allow-multiple-active","Allow multiple steps to be in_progress at once").option("--file <value>","Step linked file path=<value>[,scope=project|global,note=<text>] (repeatable)",collect).option("--test <value>","Step linked test command=<value>[,path=<value>,note=<text>] (repeatable)",collect).option("--doc <value>","Step linked doc path=<value>[,scope=project|global,note=<text>] (repeatable)",collect).option("--decision-text <value>","Decision log entry text").option("--decision <value>","Alias for --decision-text").option("--decision-rationale <value>","Decision log entry rationale").option("--decision-evidence <value>","Decision log entry evidence").option("--discovery-text <value>","Discovery log entry text").option("--discovery <value>","Alias for --discovery-text").option("--validation-text <value>","Validation log entry text").option("--validation <value>","Alias for --validation-text").option("--validation-command <value>","Validation log entry command").option("--validation-expected <value>","Validation log entry expected outcome").option("--depth <value>","Show depth: brief|standard|deep (default: brief)").option("--fields <value>","Comma-separated field projection for show output").option("--steps <value>","Comma-separated step ids/orders for materialize").option("--materialize-type <value>","Item type for materialized steps (default: Task)").option("--materialize-parent <value>","Parent item id for materialized children (default: the plan)").option("--materialize-tags <value>","Comma-separated tags for materialized children").option("--field <name=value>","Custom field value forwarded to every materialized child (repeatable)",collect).option("--author <value>","Mutation author").option("--message <value>","Mutation message").option("--force","Force ownership override");registerCommanderOptionContracts(planCommand,CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS.filter(contract=>PLAN_CREATE_METADATA_OPTION_TARGETS.has(contract.target)));addHiddenOptions(planCommand,[["--resume_context <value>","Alias for --resume-context"],["--from_search <value>","Alias for --from-search"],["--step_title <value>","Alias for --step-title"],["--step_body <value>","Alias for --step-body"],["--step_owner <value>","Alias for --step-owner"],["--step_status <value>","Alias for --step-status"],["--step_evidence <value>","Alias for --step-evidence"],["--step_blocked_reason <value>","Alias for --step-blocked-reason"],["--step_replacement <value>","Alias for --step-replacement"],["--link_kind <value>","Alias for --link-kind"],["--link_note <value>","Alias for --link-note"],["--promote_to_item_dep","Alias for --promote-to-item-dep"],["--allow_multiple_active","Alias for --allow-multiple-active"],["--decision_text <value>","Alias for --decision-text"],["--decision_rationale <value>","Alias for --decision-rationale"],["--decision_evidence <value>","Alias for --decision-evidence"],["--discovery_text <value>","Alias for --discovery-text"],["--validation_text <value>","Alias for --validation-text"],["--validation_command <value>","Alias for --validation-command"],["--validation_expected <value>","Alias for --validation-expected"],["--materialize_type <value>","Alias for --materialize-type"],["--materialize_parent <value>","Alias for --materialize-parent"],["--materialize_tags <value>","Alias for --materialize-tags"]],false);addHiddenOptions(planCommand,[["--blocked_by <value>","Alias for --blocked-by"],["--depends_on <value>","Alias for --depends-on"]],true);planCommand.action(runPlanAction);void planCommand;registerHistoryMaintenanceCommands(program,false);registerHistoryAuthorAcknowledgeCommand(program);program.command("merge").argument("<subcommand>",`Merge subcommand: ${MERGE_SUBCOMMAND_VALUES.join(", ")}`).argument("[artifact]",`driver only: artifact class to merge (${MERGE_DRIVER_ARTIFACT_VALUES.join(", ")})`).argument("[base]","driver only: common-ancestor file path (git %O)").argument("[ours]","driver only: current-branch file path (git %A)").argument("[theirs]","driver only: other-branch file path (git %B)").option("--dry-run","install/reconcile: preview changes without writing").option("--message <text>","reconcile only: audit message recorded on repaired history streams").option("--force","reconcile only: permit the underlying audited history ownership override").option("--include-reconciled","report only: include clone-local receipts already recorded in history").option("--output <path>","driver only: write the merged content to this path instead of the ours path").option("--item-path <path>","driver only: original repository-relative path supplied by git as %P").option("--prefer <side>","driver only: side that wins unresolvable conflicts (ours|theirs; default ours)").description("Install merge drivers, reconcile or report post-merge history, or run a field-aware driver.").action(runMergeAction);const schemaCommand=program.command("schema").option("--definition <json>","Policy or proposed fields JSON").option("--policy <id>","Policy id for policy-approve").option("--message <text>","Audit rationale for a policy mutation").argument("[subcommand]","Required; schema verb (list/show, add/remove, rename/remap, policy-*), or custom type shorthand").argument("[name]","Definition/source name or item id; policy-mode: advise|refuse").option("--description <text>","Type, status, or field description").option("--default-status <status>","Default status for this type").option("--folder <dir>","Storage folder for items of this custom type").option("--alias <name>","Alias for the custom type, status, or field flag (repeatable, csv-friendly)",collect).option("--role <value>","Lifecycle role for a custom status (repeatable): draft, active, blocked, terminal, terminal_done, terminal_canceled, default_open, default_close, default_cancel",collect).option("--order <n>","Display/sort order for a custom status").option("--type <type>","Value type for a custom field (add-field): string, number, boolean, string_array, array, object").option("--commands <list>","Field commands (repeatable/csv): create, update, update_many, list, search, calendar, context",collect).option("--cli-flag <flag>","Override the auto-derived CLI flag for a custom field (add-field)").option("--required","Mark a custom field as always required (add-field)").option("--required-on-create","Mark a custom field as required at create time (add-field)").option("--no-allow-unset","Disallow clearing a custom field via --unset (add-field)").option("--required-types <list>","Restrict a custom field's requirement to specific item types (add-field; repeatable, comma-friendly)",collect).option("--infer","Infer custom item types from title-prefix conventions (add-type; preview unless --apply)").option("--min-count <n>","Minimum items sharing a prefix for add-type --infer (default 10)").option("--apply","Register inferred types (add-type --infer); without it the command previews only").option("--to <name>","Target definition name for rename/remap migrations").option("--migration-id <id>","Stable idempotency key for a resumable schema migration").option("--dry-run","Preview schema changes without writes").option("--author <value>","Mutation author").option("--force","Force ownership/lock override").description("Manage types, statuses, fields, presets, and workflow policies.");addHiddenOption(schemaCommand,"--default_status <status>","Alias for --default-status",false);addHiddenOption(schemaCommand,"--migration_id <id>","Alias for --migration-id",false);schemaCommand.action(runSchemaAction);const profileCommand=program.command("profile").argument("[subcommand]","Required; Profile subcommand: list, show, apply, or lint").argument("[name]","Profile name for show/apply/lint: agile, ops, or research").option("--dry-run","Preview the apply diff without writing any files (apply)").option("--author <value>","Mutation author").option("--force","Force ownership/lock override").description("List, show, apply, and lint project profiles \u2014 archetype bundles of item types, statuses, fields, workflows, config, templates, and recommended packages.");profileCommand.action(runProfileAction);registerAnnotationCommands(program,parsePositiveIntOption);const filesCommand=program.command("files").description("Manage files linked to an item.");filesCommand.argument("<id>","Item id").option("--add <value>","Add linked file entry (CSV/markdown pairs or - for stdin)",collect).option("--add-glob <value>","Add linked file entries from a glob (plain glob or pattern=<glob>,scope=<scope>,note=<text>; repeatable)",collect).option("--remove <value>","Remove linked file by path only (path=<value>, path:<value>, plain path, or - for stdin); does not accept note=/scope= \u2014 record removal context with --message",collect).option("--migrate <value>","Migrate linked file paths in-place (from=<prefix>,to=<prefix>; repeatable)",collect).option("--note <value>","Note attached to every link added by --add/--add-glob in this invocation (embedded note= wins)").option("--list","List linked files without mutating").option("--append-stable","Preserve existing linked-file order and append new links without full-array resorting").option("--validate-paths","Validate linked file paths for existence and file shape").option("--author <value>","Mutation author").option("--message <value>","History message").option("--force","Force ownership override").action(runFilesAction);filesCommand.command("discover").argument("<id>","Item id").option("--apply","Add discovered missing files to the item").option("--note <value>","Note to attach to discovered file links").option("--append-stable","Preserve existing linked-file order and append discovered links without full-array resorting").option("--author <value>","Mutation author").option("--message <value>","History message").option("--force","Force ownership override").description("Discover existing file paths referenced in item text and optionally link missing files.").action(runFilesDiscoverAction);registerFilesLookupCommand(filesCommand);program.command("docs").argument("<id>","Item id").option("--add <value>","Add linked doc entry (CSV/markdown pairs or - for stdin)",collect).option("--add-glob <value>","Add linked doc entries from a glob (plain glob or pattern=<glob>,scope=<scope>,note=<text>; repeatable)",collect).option("--remove <value>","Remove linked doc by path only (path=<value>, path:<value>, plain path, or - for stdin); does not accept note=/scope= \u2014 record removal context with --message",collect).option("--migrate <value>","Migrate linked doc paths in-place (from=<prefix>,to=<prefix>; repeatable)",collect).option("--note <value>","Note attached to every link added by --add/--add-glob in this invocation (embedded note= wins)").option("--list","List linked docs without mutating").option("--validate-paths","Validate linked doc paths for existence and file shape").option("--author <value>","Mutation author").option("--message <value>","History message").option("--force","Force ownership override").description("Manage docs linked to an item.").action(runDocsAction);program.command("deps").argument("<id>","Item id").option("--format <value>","Output format (tree, graph, or context)","tree").option("--max-depth <value>","Maximum dependency traversal depth (0 keeps only the root)").option("--collapse <value>","Collapse mode (none or repeated)","none").option("--summary","Return counts only without full tree/graph payload").option("--full","Return the complete dependency row projection").option("--node-limit <value>","Maximum nodes in context output").option("--edge-limit <value>","Maximum edges and missing-reference rows in context output").option("--token-budget <value>","Maximum estimated tokens in context output").option("--cursor <value>","Continue an equivalent context query").option("--direction <value>","Context traversal direction (outgoing, incoming, or both)").option("--kind <value>","Restrict context traversal to registered relationship kinds (repeatable or comma-separated)",collect).description("Show dependency relationships for an item.").action(runDepsAction)}export{looksLikeSchemaSubcommandTypo2 as looksLikeSchemaSubcommandTypo,parsePositiveIntOption,parseSchemaOrderOption2 as parseSchemaOrderOption,registerCommanderOptionContracts,registerMutationCommands};
1893
20
  //# sourceMappingURL=register-mutation.js.map
1894
- //# debugId=c9d736d1-58bf-5088-aaae-0b89ad61d41f