@unbrained/pm-cli 2026.5.14 → 2026.5.24

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 (436) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/AGENTS.md +78 -457
  3. package/CHANGELOG.md +71 -0
  4. package/CONTRIBUTING.md +1 -0
  5. package/README.md +8 -6
  6. package/dist/cli/argv-utils.js +4 -1
  7. package/dist/cli/argv-utils.js.map +1 -1
  8. package/dist/cli/bootstrap-args.js +4 -1
  9. package/dist/cli/bootstrap-args.js.map +1 -1
  10. package/dist/cli/commander-usage.js +19 -1
  11. package/dist/cli/commander-usage.js.map +1 -1
  12. package/dist/cli/commands/activity.js +4 -1
  13. package/dist/cli/commands/activity.js.map +1 -1
  14. package/dist/cli/commands/aggregate.js +5 -2
  15. package/dist/cli/commands/aggregate.js.map +1 -1
  16. package/dist/cli/commands/annotation-command.d.ts +49 -0
  17. package/dist/cli/commands/annotation-command.js +135 -0
  18. package/dist/cli/commands/annotation-command.js.map +1 -0
  19. package/dist/cli/commands/append.js +5 -6
  20. package/dist/cli/commands/append.js.map +1 -1
  21. package/dist/cli/commands/calendar.js +5 -5
  22. package/dist/cli/commands/calendar.js.map +1 -1
  23. package/dist/cli/commands/claim.d.ts +3 -0
  24. package/dist/cli/commands/claim.js +29 -23
  25. package/dist/cli/commands/claim.js.map +1 -1
  26. package/dist/cli/commands/close.js +63 -8
  27. package/dist/cli/commands/close.js.map +1 -1
  28. package/dist/cli/commands/comments-audit.js +4 -1
  29. package/dist/cli/commands/comments-audit.js.map +1 -1
  30. package/dist/cli/commands/comments.d.ts +5 -0
  31. package/dist/cli/commands/comments.js +29 -116
  32. package/dist/cli/commands/comments.js.map +1 -1
  33. package/dist/cli/commands/completion.js +198 -15
  34. package/dist/cli/commands/completion.js.map +1 -1
  35. package/dist/cli/commands/config.js +4 -1
  36. package/dist/cli/commands/config.js.map +1 -1
  37. package/dist/cli/commands/context.js +21 -13
  38. package/dist/cli/commands/context.js.map +1 -1
  39. package/dist/cli/commands/contracts.d.ts +9 -0
  40. package/dist/cli/commands/contracts.js +314 -64
  41. package/dist/cli/commands/contracts.js.map +1 -1
  42. package/dist/cli/commands/create.js +77 -48
  43. package/dist/cli/commands/create.js.map +1 -1
  44. package/dist/cli/commands/dedupe-audit.js +9 -3
  45. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  46. package/dist/cli/commands/delete.d.ts +3 -0
  47. package/dist/cli/commands/delete.js +11 -7
  48. package/dist/cli/commands/delete.js.map +1 -1
  49. package/dist/cli/commands/deps.js +4 -1
  50. package/dist/cli/commands/deps.js.map +1 -1
  51. package/dist/cli/commands/docs.d.ts +1 -0
  52. package/dist/cli/commands/docs.js +6 -7
  53. package/dist/cli/commands/docs.js.map +1 -1
  54. package/dist/cli/commands/event-validation-messages.d.ts +3 -0
  55. package/dist/cli/commands/event-validation-messages.js +44 -0
  56. package/dist/cli/commands/event-validation-messages.js.map +1 -0
  57. package/dist/cli/commands/extension.d.ts +3 -1
  58. package/dist/cli/commands/extension.js +259 -52
  59. package/dist/cli/commands/extension.js.map +1 -1
  60. package/dist/cli/commands/files.js +8 -12
  61. package/dist/cli/commands/files.js.map +1 -1
  62. package/dist/cli/commands/gc.js +19 -3
  63. package/dist/cli/commands/gc.js.map +1 -1
  64. package/dist/cli/commands/get.d.ts +10 -5
  65. package/dist/cli/commands/get.js +135 -20
  66. package/dist/cli/commands/get.js.map +1 -1
  67. package/dist/cli/commands/guide.js +6 -8
  68. package/dist/cli/commands/guide.js.map +1 -1
  69. package/dist/cli/commands/health.d.ts +14 -0
  70. package/dist/cli/commands/health.js +269 -67
  71. package/dist/cli/commands/health.js.map +1 -1
  72. package/dist/cli/commands/history-redact.d.ts +50 -0
  73. package/dist/cli/commands/history-redact.js +476 -0
  74. package/dist/cli/commands/history-redact.js.map +1 -0
  75. package/dist/cli/commands/history-repair.d.ts +33 -0
  76. package/dist/cli/commands/history-repair.js +166 -0
  77. package/dist/cli/commands/history-repair.js.map +1 -0
  78. package/dist/cli/commands/history.d.ts +4 -0
  79. package/dist/cli/commands/history.js +12 -79
  80. package/dist/cli/commands/history.js.map +1 -1
  81. package/dist/cli/commands/index.d.ts +5 -1
  82. package/dist/cli/commands/index.js +9 -2
  83. package/dist/cli/commands/index.js.map +1 -1
  84. package/dist/cli/commands/init-agent-guidance.d.ts +31 -0
  85. package/dist/cli/commands/init-agent-guidance.js +336 -0
  86. package/dist/cli/commands/init-agent-guidance.js.map +1 -0
  87. package/dist/cli/commands/init.d.ts +42 -0
  88. package/dist/cli/commands/init.js +96 -1
  89. package/dist/cli/commands/init.js.map +1 -1
  90. package/dist/cli/commands/learnings.js +22 -118
  91. package/dist/cli/commands/learnings.js.map +1 -1
  92. package/dist/cli/commands/linked-test-entry.d.ts +3 -0
  93. package/dist/cli/commands/linked-test-entry.js +62 -0
  94. package/dist/cli/commands/linked-test-entry.js.map +1 -0
  95. package/dist/cli/commands/list.d.ts +1 -0
  96. package/dist/cli/commands/list.js +72 -38
  97. package/dist/cli/commands/list.js.map +1 -1
  98. package/dist/cli/commands/metadata-normalizers.js +4 -1
  99. package/dist/cli/commands/metadata-normalizers.js.map +1 -1
  100. package/dist/cli/commands/normalize.js +4 -1
  101. package/dist/cli/commands/normalize.js.map +1 -1
  102. package/dist/cli/commands/notes.js +22 -118
  103. package/dist/cli/commands/notes.js.map +1 -1
  104. package/dist/cli/commands/plan.d.ts +121 -0
  105. package/dist/cli/commands/plan.js +1137 -0
  106. package/dist/cli/commands/plan.js.map +1 -0
  107. package/dist/cli/commands/reindex.js +4 -1
  108. package/dist/cli/commands/reindex.js.map +1 -1
  109. package/dist/cli/commands/restore.js +9 -49
  110. package/dist/cli/commands/restore.js.map +1 -1
  111. package/dist/cli/commands/schema.d.ts +31 -0
  112. package/dist/cli/commands/schema.js +98 -0
  113. package/dist/cli/commands/schema.js.map +1 -0
  114. package/dist/cli/commands/search.js +156 -40
  115. package/dist/cli/commands/search.js.map +1 -1
  116. package/dist/cli/commands/stats.js +4 -1
  117. package/dist/cli/commands/stats.js.map +1 -1
  118. package/dist/cli/commands/templates.d.ts +4 -0
  119. package/dist/cli/commands/templates.js +91 -16
  120. package/dist/cli/commands/templates.js.map +1 -1
  121. package/dist/cli/commands/test-all.js +6 -7
  122. package/dist/cli/commands/test-all.js.map +1 -1
  123. package/dist/cli/commands/test-runs.js +4 -1
  124. package/dist/cli/commands/test-runs.js.map +1 -1
  125. package/dist/cli/commands/test.d.ts +1 -0
  126. package/dist/cli/commands/test.js +9 -9
  127. package/dist/cli/commands/test.js.map +1 -1
  128. package/dist/cli/commands/update-many.js +6 -7
  129. package/dist/cli/commands/update-many.js.map +1 -1
  130. package/dist/cli/commands/update.js +204 -103
  131. package/dist/cli/commands/update.js.map +1 -1
  132. package/dist/cli/commands/upgrade.js +6 -3
  133. package/dist/cli/commands/upgrade.js.map +1 -1
  134. package/dist/cli/commands/validate.d.ts +3 -1
  135. package/dist/cli/commands/validate.js +44 -64
  136. package/dist/cli/commands/validate.js.map +1 -1
  137. package/dist/cli/error-guidance.js +99 -6
  138. package/dist/cli/error-guidance.js.map +1 -1
  139. package/dist/cli/extension-command-help.d.ts +0 -1
  140. package/dist/cli/extension-command-help.js +4 -12
  141. package/dist/cli/extension-command-help.js.map +1 -1
  142. package/dist/cli/extension-command-options.d.ts +1 -0
  143. package/dist/cli/extension-command-options.js +108 -6
  144. package/dist/cli/extension-command-options.js.map +1 -1
  145. package/dist/cli/guide-topics.js +4 -1
  146. package/dist/cli/guide-topics.js.map +1 -1
  147. package/dist/cli/help-content.d.ts +0 -1
  148. package/dist/cli/help-content.js +46 -22
  149. package/dist/cli/help-content.js.map +1 -1
  150. package/dist/cli/help-json-payload.d.ts +1 -0
  151. package/dist/cli/help-json-payload.js +35 -2
  152. package/dist/cli/help-json-payload.js.map +1 -1
  153. package/dist/cli/main.js +214 -30
  154. package/dist/cli/main.js.map +1 -1
  155. package/dist/cli/migration-gates.js +4 -1
  156. package/dist/cli/migration-gates.js.map +1 -1
  157. package/dist/cli/register-list-query.d.ts +1 -1
  158. package/dist/cli/register-list-query.js +75 -29
  159. package/dist/cli/register-list-query.js.map +1 -1
  160. package/dist/cli/register-mutation.d.ts +1 -1
  161. package/dist/cli/register-mutation.js +430 -38
  162. package/dist/cli/register-mutation.js.map +1 -1
  163. package/dist/cli/register-operations.js +47 -10
  164. package/dist/cli/register-operations.js.map +1 -1
  165. package/dist/cli/register-setup.js +47 -25
  166. package/dist/cli/register-setup.js.map +1 -1
  167. package/dist/cli/registration-helpers.d.ts +0 -2
  168. package/dist/cli/registration-helpers.js +21 -40
  169. package/dist/cli/registration-helpers.js.map +1 -1
  170. package/dist/cli/shared-parsers.js +4 -1
  171. package/dist/cli/shared-parsers.js.map +1 -1
  172. package/dist/cli/telemetry-flush.js +4 -1
  173. package/dist/cli/telemetry-flush.js.map +1 -1
  174. package/dist/cli.js +65 -3
  175. package/dist/cli.js.map +1 -1
  176. package/dist/core/extensions/extension-types.js +4 -1
  177. package/dist/core/extensions/extension-types.js.map +1 -1
  178. package/dist/core/extensions/index.d.ts +0 -1
  179. package/dist/core/extensions/index.js +4 -13
  180. package/dist/core/extensions/index.js.map +1 -1
  181. package/dist/core/extensions/item-fields.js +4 -1
  182. package/dist/core/extensions/item-fields.js.map +1 -1
  183. package/dist/core/extensions/loader.js +78 -60
  184. package/dist/core/extensions/loader.js.map +1 -1
  185. package/dist/core/extensions/runtime-registrations.js +4 -1
  186. package/dist/core/extensions/runtime-registrations.js.map +1 -1
  187. package/dist/core/fs/fs-utils.js +4 -1
  188. package/dist/core/fs/fs-utils.js.map +1 -1
  189. package/dist/core/fs/index.js +4 -1
  190. package/dist/core/fs/index.js.map +1 -1
  191. package/dist/core/fs/path-utils.d.ts +1 -0
  192. package/dist/core/fs/path-utils.js +12 -0
  193. package/dist/core/fs/path-utils.js.map +1 -0
  194. package/dist/core/history/drift-scan.d.ts +11 -0
  195. package/dist/core/history/drift-scan.js +67 -0
  196. package/dist/core/history/drift-scan.js.map +1 -0
  197. package/dist/core/history/history-stream-policy.js +4 -1
  198. package/dist/core/history/history-stream-policy.js.map +1 -1
  199. package/dist/core/history/history.js +4 -1
  200. package/dist/core/history/history.js.map +1 -1
  201. package/dist/core/history/index.js +4 -1
  202. package/dist/core/history/index.js.map +1 -1
  203. package/dist/core/history/replay.d.ts +82 -0
  204. package/dist/core/history/replay.js +249 -0
  205. package/dist/core/history/replay.js.map +1 -0
  206. package/dist/core/item/id.js +4 -1
  207. package/dist/core/item/id.js.map +1 -1
  208. package/dist/core/item/index.js +4 -1
  209. package/dist/core/item/index.js.map +1 -1
  210. package/dist/core/item/item-format.js +250 -8
  211. package/dist/core/item/item-format.js.map +1 -1
  212. package/dist/core/item/item-type-definition.d.ts +52 -0
  213. package/dist/core/item/item-type-definition.js +123 -0
  214. package/dist/core/item/item-type-definition.js.map +1 -0
  215. package/dist/core/item/parent-reference-policy.js +4 -1
  216. package/dist/core/item/parent-reference-policy.js.map +1 -1
  217. package/dist/core/item/parse.js +34 -3
  218. package/dist/core/item/parse.js.map +1 -1
  219. package/dist/core/item/priority.d.ts +23 -0
  220. package/dist/core/item/priority.js +55 -0
  221. package/dist/core/item/priority.js.map +1 -0
  222. package/dist/core/item/sprint-release-format.js +4 -1
  223. package/dist/core/item/sprint-release-format.js.map +1 -1
  224. package/dist/core/item/status.d.ts +14 -1
  225. package/dist/core/item/status.js +24 -1
  226. package/dist/core/item/status.js.map +1 -1
  227. package/dist/core/item/toon-decode.d.ts +19 -0
  228. package/dist/core/item/toon-decode.js +69 -0
  229. package/dist/core/item/toon-decode.js.map +1 -0
  230. package/dist/core/item/type-registry.js +15 -83
  231. package/dist/core/item/type-registry.js.map +1 -1
  232. package/dist/core/lock/index.js +4 -1
  233. package/dist/core/lock/index.js.map +1 -1
  234. package/dist/core/lock/lock.js +4 -1
  235. package/dist/core/lock/lock.js.map +1 -1
  236. package/dist/core/output/output.d.ts +4 -0
  237. package/dist/core/output/output.js +47 -6
  238. package/dist/core/output/output.js.map +1 -1
  239. package/dist/core/packages/manifest.d.ts +1 -0
  240. package/dist/core/packages/manifest.js +6 -8
  241. package/dist/core/packages/manifest.js.map +1 -1
  242. package/dist/core/packages/root.d.ts +3 -0
  243. package/dist/core/packages/root.js +51 -0
  244. package/dist/core/packages/root.js.map +1 -0
  245. package/dist/core/schema/item-types-file.d.ts +85 -0
  246. package/dist/core/schema/item-types-file.js +243 -0
  247. package/dist/core/schema/item-types-file.js.map +1 -0
  248. package/dist/core/schema/runtime-field-filters.js +4 -1
  249. package/dist/core/schema/runtime-field-filters.js.map +1 -1
  250. package/dist/core/schema/runtime-field-values.js +4 -1
  251. package/dist/core/schema/runtime-field-values.js.map +1 -1
  252. package/dist/core/schema/runtime-schema.d.ts +2 -1
  253. package/dist/core/schema/runtime-schema.js +13 -8
  254. package/dist/core/schema/runtime-schema.js.map +1 -1
  255. package/dist/core/search/cache.js +7 -2
  256. package/dist/core/search/cache.js.map +1 -1
  257. package/dist/core/search/corpus.d.ts +2 -0
  258. package/dist/core/search/corpus.js +77 -2
  259. package/dist/core/search/corpus.js.map +1 -1
  260. package/dist/core/search/embedding-batches.js +21 -7
  261. package/dist/core/search/embedding-batches.js.map +1 -1
  262. package/dist/core/search/http-client.js +4 -1
  263. package/dist/core/search/http-client.js.map +1 -1
  264. package/dist/core/search/providers.js +4 -1
  265. package/dist/core/search/providers.js.map +1 -1
  266. package/dist/core/search/semantic-defaults.js +12 -3
  267. package/dist/core/search/semantic-defaults.js.map +1 -1
  268. package/dist/core/search/vector-stores.js +4 -1
  269. package/dist/core/search/vector-stores.js.map +1 -1
  270. package/dist/core/sentry/helpers.js +4 -1
  271. package/dist/core/sentry/helpers.js.map +1 -1
  272. package/dist/core/sentry/instrument.js +10 -13
  273. package/dist/core/sentry/instrument.js.map +1 -1
  274. package/dist/core/shared/author.d.ts +1 -0
  275. package/dist/core/shared/author.js +9 -0
  276. package/dist/core/shared/author.js.map +1 -0
  277. package/dist/core/shared/command-types.js +4 -1
  278. package/dist/core/shared/command-types.js.map +1 -1
  279. package/dist/core/shared/conflict-markers.js +4 -1
  280. package/dist/core/shared/conflict-markers.js.map +1 -1
  281. package/dist/core/shared/constants.d.ts +2 -2
  282. package/dist/core/shared/constants.js +24 -1
  283. package/dist/core/shared/constants.js.map +1 -1
  284. package/dist/core/shared/errors.js +4 -1
  285. package/dist/core/shared/errors.js.map +1 -1
  286. package/dist/core/shared/index.js +4 -1
  287. package/dist/core/shared/index.js.map +1 -1
  288. package/dist/core/shared/lazy-module.d.ts +1 -0
  289. package/dist/core/shared/lazy-module.js +11 -0
  290. package/dist/core/shared/lazy-module.js.map +1 -0
  291. package/dist/core/shared/levenshtein.js +4 -1
  292. package/dist/core/shared/levenshtein.js.map +1 -1
  293. package/dist/core/shared/option-alias-visibility.d.ts +44 -0
  294. package/dist/core/shared/option-alias-visibility.js +76 -0
  295. package/dist/core/shared/option-alias-visibility.js.map +1 -0
  296. package/dist/core/shared/primitives.js +4 -1
  297. package/dist/core/shared/primitives.js.map +1 -1
  298. package/dist/core/shared/serialization.js +4 -1
  299. package/dist/core/shared/serialization.js.map +1 -1
  300. package/dist/core/shared/text-normalization.d.ts +0 -1
  301. package/dist/core/shared/text-normalization.js +4 -4
  302. package/dist/core/shared/text-normalization.js.map +1 -1
  303. package/dist/core/shared/time.js +4 -1
  304. package/dist/core/shared/time.js.map +1 -1
  305. package/dist/core/store/front-matter-cache.js +8 -3
  306. package/dist/core/store/front-matter-cache.js.map +1 -1
  307. package/dist/core/store/index.js +4 -1
  308. package/dist/core/store/index.js.map +1 -1
  309. package/dist/core/store/item-format-migration.js +4 -1
  310. package/dist/core/store/item-format-migration.js.map +1 -1
  311. package/dist/core/store/item-store.d.ts +4 -0
  312. package/dist/core/store/item-store.js +133 -39
  313. package/dist/core/store/item-store.js.map +1 -1
  314. package/dist/core/store/paths.js +4 -1
  315. package/dist/core/store/paths.js.map +1 -1
  316. package/dist/core/store/settings-validator.d.ts +106 -0
  317. package/dist/core/store/settings-validator.js +279 -0
  318. package/dist/core/store/settings-validator.js.map +1 -0
  319. package/dist/core/store/settings.js +32 -331
  320. package/dist/core/store/settings.js.map +1 -1
  321. package/dist/core/telemetry/consent.js +4 -1
  322. package/dist/core/telemetry/consent.js.map +1 -1
  323. package/dist/core/telemetry/observability.d.ts +1 -1
  324. package/dist/core/telemetry/observability.js +11 -2
  325. package/dist/core/telemetry/observability.js.map +1 -1
  326. package/dist/core/telemetry/runtime.js +34 -6
  327. package/dist/core/telemetry/runtime.js.map +1 -1
  328. package/dist/core/test/background-runs.js +4 -1
  329. package/dist/core/test/background-runs.js.map +1 -1
  330. package/dist/core/test/item-test-run-tracking.js +4 -1
  331. package/dist/core/test/item-test-run-tracking.js.map +1 -1
  332. package/dist/mcp/server.js +182 -22
  333. package/dist/mcp/server.js.map +1 -1
  334. package/dist/sdk/cli-contracts/commander-mutation-options.js +10 -3
  335. package/dist/sdk/cli-contracts/commander-mutation-options.js.map +1 -1
  336. package/dist/sdk/cli-contracts/commander-types.js +4 -1
  337. package/dist/sdk/cli-contracts/commander-types.js.map +1 -1
  338. package/dist/sdk/cli-contracts.d.ts +13 -2
  339. package/dist/sdk/cli-contracts.js +410 -26
  340. package/dist/sdk/cli-contracts.js.map +1 -1
  341. package/dist/sdk/index.js +4 -1
  342. package/dist/sdk/index.js.map +1 -1
  343. package/dist/sdk/runtime.d.ts +25 -1
  344. package/dist/sdk/runtime.js +48 -2
  345. package/dist/sdk/runtime.js.map +1 -1
  346. package/dist/types/index.js +4 -1
  347. package/dist/types/index.js.map +1 -1
  348. package/dist/types.d.ts +92 -2
  349. package/dist/types.js +42 -1
  350. package/dist/types.js.map +1 -1
  351. package/docs/AGENT_GUIDE.md +23 -7
  352. package/docs/ARCHITECTURE.md +1 -1
  353. package/docs/CLAUDE_CODE_PLUGIN.md +10 -10
  354. package/docs/CODEX_PLUGIN.md +2 -2
  355. package/docs/COMMANDS.md +117 -12
  356. package/docs/CONFIGURATION.md +5 -2
  357. package/docs/EXTENSIONS.md +158 -814
  358. package/docs/QUICKSTART.md +11 -5
  359. package/docs/README.md +7 -6
  360. package/docs/RELEASING.md +13 -9
  361. package/docs/SDK.md +11 -2
  362. package/docs/TESTING.md +2 -2
  363. package/marketplace.json +3 -3
  364. package/package.json +15 -12
  365. package/packages/pm-beads/package.json +1 -1
  366. package/packages/pm-calendar/README.md +4 -2
  367. package/packages/pm-calendar/extensions/calendar/index.js +22 -3
  368. package/packages/pm-calendar/extensions/calendar/index.ts +22 -3
  369. package/packages/pm-calendar/extensions/calendar/runtime.js +26 -7
  370. package/packages/pm-calendar/extensions/calendar/runtime.ts +26 -7
  371. package/packages/pm-calendar/package.json +1 -1
  372. package/packages/pm-governance-audit/package.json +1 -1
  373. package/packages/pm-guide-shell/extensions/guide-shell/index.js +1 -1
  374. package/packages/pm-guide-shell/extensions/guide-shell/index.ts +1 -1
  375. package/packages/pm-guide-shell/package.json +1 -1
  376. package/packages/pm-linked-test-adapters/package.json +1 -1
  377. package/packages/pm-search-advanced/README.md +8 -0
  378. package/packages/pm-search-advanced/extensions/search-advanced/index.js +74 -0
  379. package/packages/pm-search-advanced/extensions/search-advanced/index.ts +75 -1
  380. package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +67 -9
  381. package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +67 -9
  382. package/packages/pm-search-advanced/package.json +1 -1
  383. package/packages/pm-templates/README.md +1 -1
  384. package/packages/pm-templates/extensions/templates/runtime.js +11 -202
  385. package/packages/pm-templates/extensions/templates/runtime.ts +38 -230
  386. package/packages/pm-templates/package.json +1 -1
  387. package/packages/pm-todos/package.json +1 -1
  388. package/plugins/{pm-cli-claude → pm-claude}/.claude-plugin/plugin.json +2 -2
  389. package/plugins/{pm-cli-claude → pm-claude}/.mcp.json +1 -1
  390. package/plugins/{pm-cli-claude → pm-claude}/README.md +4 -4
  391. package/plugins/{pm-cli-claude → pm-claude}/agents/pm-coordinator.md +1 -1
  392. package/plugins/{pm-cli-claude → pm-claude}/commands/pm-init.md +10 -1
  393. package/plugins/{pm-cli-claude → pm-claude}/commands/pm-planner.md +18 -0
  394. package/plugins/{pm-cli-claude → pm-claude}/skills/pm-planner/SKILL.md +46 -1
  395. package/plugins/{pm-cli-codex → pm-codex}/.codex-plugin/plugin.json +3 -3
  396. package/plugins/{pm-cli-codex → pm-codex}/.mcp.json +1 -1
  397. package/plugins/{pm-cli-codex → pm-codex}/README.md +7 -4
  398. package/plugins/pm-codex/skills/pm-native/SKILL.md +81 -0
  399. package/scripts/finalize-build.mjs +28 -0
  400. package/scripts/prepare-build-cache.mjs +37 -0
  401. package/dist/core/output/command-aware.d.ts +0 -1
  402. package/dist/core/output/command-aware.js +0 -394
  403. package/dist/core/output/command-aware.js.map +0 -1
  404. package/plugins/pm-cli-codex/skills/pm-native/SKILL.md +0 -57
  405. /package/plugins/{pm-cli-claude → pm-claude}/agents/pm-delivery-chain.md +0 -0
  406. /package/plugins/{pm-cli-claude → pm-claude}/agents/pm-triage-agent.md +0 -0
  407. /package/plugins/{pm-cli-claude → pm-claude}/agents/pm-verification-agent.md +0 -0
  408. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-audit.md +0 -0
  409. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-calendar.md +0 -0
  410. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-close-task.md +0 -0
  411. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-developer.md +0 -0
  412. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-list.md +0 -0
  413. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-new.md +0 -0
  414. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-release.md +0 -0
  415. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-search.md +0 -0
  416. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-start-task.md +0 -0
  417. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-status.md +0 -0
  418. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-triage.md +0 -0
  419. /package/plugins/{pm-cli-claude → pm-claude}/commands/pm-workflow.md +0 -0
  420. /package/plugins/{pm-cli-claude → pm-claude}/hooks/hooks.json +0 -0
  421. /package/plugins/{pm-cli-claude → pm-claude}/hooks/session-start.mjs +0 -0
  422. /package/plugins/{pm-cli-claude → pm-claude}/scripts/pm-mcp-server.mjs +0 -0
  423. /package/plugins/{pm-cli-claude → pm-claude}/skills/pm-audit/SKILL.md +0 -0
  424. /package/plugins/{pm-cli-claude → pm-claude}/skills/pm-developer/SKILL.md +0 -0
  425. /package/plugins/{pm-cli-claude → pm-claude}/skills/pm-release/SKILL.md +0 -0
  426. /package/plugins/{pm-cli-claude → pm-claude}/skills/pm-workflow/SKILL.md +0 -0
  427. /package/plugins/{pm-cli-codex → pm-codex}/assets/pm-cli-small.svg +0 -0
  428. /package/plugins/{pm-cli-codex → pm-codex}/commands/pm-audit.md +0 -0
  429. /package/plugins/{pm-cli-codex → pm-codex}/commands/pm-close-task.md +0 -0
  430. /package/plugins/{pm-cli-codex → pm-codex}/commands/pm-start-task.md +0 -0
  431. /package/plugins/{pm-cli-codex → pm-codex}/scripts/pm-mcp-server.mjs +0 -0
  432. /package/plugins/{pm-cli-codex → pm-codex}/skills/pm-auditor/SKILL.md +0 -0
  433. /package/plugins/{pm-cli-codex → pm-codex}/skills/pm-auditor/agents/openai.yaml +0 -0
  434. /package/plugins/{pm-cli-codex → pm-codex}/skills/pm-native/agents/openai.yaml +0 -0
  435. /package/plugins/{pm-cli-codex → pm-codex}/skills/pm-release/SKILL.md +0 -0
  436. /package/plugins/{pm-cli-codex → pm-codex}/skills/pm-release/agents/openai.yaml +0 -0
@@ -1,11 +1,26 @@
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]="634fa316-811c-5a12-a391-225313b2c754")}catch(e){}}();
3
+ import { Option } from "commander";
1
4
  import { EXIT_CODE } from "../core/shared/constants.js";
2
5
  import { PmCliError } from "../core/shared/errors.js";
6
+ import { isPureSnakeCaseAlias } from "../core/shared/option-alias-visibility.js";
3
7
  import { CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS, UPDATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS, } from "../sdk/cli-contracts.js";
4
- import { collect, extractUpdateManyMutationOptionSource, getGlobalOptions, invalidateSearchCachesForMutation, normalizeCreateOptions, normalizeUpdateOptions, printError, printResult, } from "./registration-helpers.js";
5
- let mutationCommandsModulePromise = null;
6
- async function loadMutationCommandsModule() {
7
- mutationCommandsModulePromise ??= import("./commands/index.js");
8
- return mutationCommandsModulePromise;
8
+ import { collect, extractUpdateManyMutationOptionSource, formatHookWarnings, getGlobalOptions, invalidateSearchCachesForMutation, normalizeCreateOptions, normalizeUpdateOptions, printError, printResult, writeStdout, } from "./registration-helpers.js";
9
+ import { createLazyModule } from "../core/shared/lazy-module.js";
10
+ const loadMutationCommandsModule = createLazyModule(() => import("./commands/index.js"));
11
+ /**
12
+ * Register a flag and hide it from `--help` text while keeping it fully
13
+ * functional as a parse-time alias. The option still appears in
14
+ * `command.options`, so the JSON help payload and shell completion (which read
15
+ * from the contracts/commander option list, not the rendered text) are
16
+ * unchanged — only commander's text `--help` omits it.
17
+ */
18
+ function addHiddenOption(command, flags, description, repeatable) {
19
+ const option = new Option(flags, description).hideHelp();
20
+ if (repeatable) {
21
+ option.argParser(collect);
22
+ }
23
+ command.addOption(option);
9
24
  }
10
25
  function registerCommanderOptionContracts(command, contracts) {
11
26
  for (const contract of contracts) {
@@ -19,7 +34,13 @@ function registerCommanderOptionContracts(command, contracts) {
19
34
  command.option(contract.option, contract.description);
20
35
  }
21
36
  for (const aliasContract of contract.aliasOptions ?? []) {
22
- if (contract.repeatable) {
37
+ // Hide pure snake_case underscore-duplicate aliases (e.g. --create_mode
38
+ // for --create-mode) from --help, but keep semantically-distinct aliases
39
+ // (e.g. --ac for --acceptance-criteria) visible.
40
+ if (isPureSnakeCaseAlias(contract.option, aliasContract.option)) {
41
+ addHiddenOption(command, aliasContract.option, aliasContract.description, contract.repeatable === true);
42
+ }
43
+ else if (contract.repeatable) {
23
44
  command.option(aliasContract.option, aliasContract.description, collect);
24
45
  }
25
46
  else {
@@ -31,6 +52,8 @@ function registerCommanderOptionContracts(command, contracts) {
31
52
  export function registerMutationCommands(program) {
32
53
  const createCommand = program
33
54
  .command("create")
55
+ .argument("[typeOrTitle]", "Item title, or item type when a title follows (e.g. `pm create task \"Fix bug\"`)")
56
+ .argument("[title]", "Item title when the first argument is an item type")
34
57
  .description("Create a new project management item.");
35
58
  registerCommanderOptionContracts(createCommand, CREATE_COMMANDER_OPTION_REGISTRATION_CONTRACTS);
36
59
  createCommand
@@ -44,9 +67,27 @@ export function registerMutationCommands(program) {
44
67
  .option("--clear-reminders", "Clear reminders")
45
68
  .option("--clear-events", "Clear events")
46
69
  .option("--clear-type-options", "Clear type options")
47
- .action(async (options, command) => {
70
+ .action(async (typeOrTitle, secondTitle, options, command) => {
48
71
  const globalOptions = getGlobalOptions(command);
49
72
  const startedAt = Date.now();
73
+ // Support both `pm create "<title>"` and the natural subcommand-style
74
+ // `pm create <type> "<title>"` so agents are never blocked by argument
75
+ // count. When two positionals are given, the first is the item type.
76
+ let positionalType;
77
+ let positionalTitle;
78
+ if (typeof secondTitle === "string" && secondTitle.length > 0) {
79
+ positionalType = typeOrTitle;
80
+ positionalTitle = secondTitle;
81
+ }
82
+ else if (typeof typeOrTitle === "string" && typeOrTitle.length > 0) {
83
+ positionalTitle = typeOrTitle;
84
+ }
85
+ if (typeof positionalType === "string" && positionalType.length > 0 && options.type === undefined) {
86
+ options.type = positionalType;
87
+ }
88
+ if (typeof positionalTitle === "string" && positionalTitle.length > 0 && options.title === undefined) {
89
+ options.title = positionalTitle;
90
+ }
50
91
  const normalized = normalizeCreateOptions(options, { requireType: false });
51
92
  const { runCreate } = await loadMutationCommandsModule();
52
93
  const result = await runCreate(normalized, globalOptions);
@@ -75,10 +116,11 @@ export function registerMutationCommands(program) {
75
116
  .option("--clear-events", "Clear events")
76
117
  .option("--clear-type-options", "Clear type options")
77
118
  .option("--allow-audit-update", "Allow non-owner metadata-only audit updates without requiring --force")
78
- .option("--allow_audit_update", "Alias for --allow-audit-update")
79
119
  .option("--allow-audit-dep-update", "Allow non-owner append-only dependency updates without requiring --force")
80
- .option("--allow_audit_dep_update", "Alias for --allow-audit-dep-update")
81
- .option("--force", "Force ownership override")
120
+ .option("--force", "Force ownership override");
121
+ addHiddenOption(updateCommand, "--allow_audit_update", "Alias for --allow-audit-update", false);
122
+ addHiddenOption(updateCommand, "--allow_audit_dep_update", "Alias for --allow-audit-dep-update", false);
123
+ updateCommand
82
124
  .action(async (id, options, command) => {
83
125
  const globalOptions = getGlobalOptions(command);
84
126
  const startedAt = Date.now();
@@ -90,7 +132,7 @@ export function registerMutationCommands(program) {
90
132
  printError(`profile:command=update took_ms=${Date.now() - startedAt}`);
91
133
  }
92
134
  });
93
- program
135
+ const updateManyCommand = program
94
136
  .command("update-many")
95
137
  .description("Bulk-update matched items with dry-run plans and rollback checkpoints.")
96
138
  .option("--filter-status <value>", "Filter by status before applying updates")
@@ -101,7 +143,6 @@ export function registerMutationCommands(program) {
101
143
  .option("--filter-deadline-after <value>", "Filter by deadline lower bound before applying updates")
102
144
  .option("--filter-assignee <value>", "Filter by assignee before applying updates")
103
145
  .option("--filter-assignee-filter <value>", "Filter assignee presence: assigned|unassigned before applying updates")
104
- .option("--filter-assignee_filter <value>", "Alias for --filter-assignee-filter")
105
146
  .option("--filter-parent <value>", "Filter by parent item ID before applying updates")
106
147
  .option("--filter-sprint <value>", "Filter by sprint before applying updates")
107
148
  .option("--filter-release <value>", "Filter by release before applying updates")
@@ -119,12 +160,9 @@ export function registerMutationCommands(program) {
119
160
  .option("--tags <value>", "Set comma-separated tags")
120
161
  .option("--deadline <value>", "Set deadline (ISO/date string or relative)")
121
162
  .option("--estimate, --estimated-minutes <value>", "Set estimated minutes")
122
- .option("--estimated_minutes <value>", "Alias for --estimated-minutes")
123
163
  .option("--acceptance-criteria <value>", "Set acceptance criteria")
124
- .option("--acceptance_criteria <value>", "Alias for --acceptance-criteria")
125
164
  .option("--ac <value>", "Alias for --acceptance-criteria")
126
165
  .option("--definition-of-ready <value>", "Set definition of ready")
127
- .option("--definition_of_ready <value>", "Alias for --definition-of-ready")
128
166
  .option("--order <value>", "Set planning order/rank integer")
129
167
  .option("--rank <value>", "Alias for --order")
130
168
  .option("--goal <value>", "Set goal identifier")
@@ -133,7 +171,6 @@ export function registerMutationCommands(program) {
133
171
  .option("--impact <value>", "Set business impact summary")
134
172
  .option("--outcome <value>", "Set expected outcome summary")
135
173
  .option("--why-now <value>", "Set why-now rationale")
136
- .option("--why_now <value>", "Alias for --why-now")
137
174
  .option("--assignee <value>", "Set assignee")
138
175
  .option("--parent <value>", "Set parent item ID")
139
176
  .option("--reviewer <value>", "Set reviewer")
@@ -142,32 +179,22 @@ export function registerMutationCommands(program) {
142
179
  .option("--sprint <value>", "Set sprint identifier")
143
180
  .option("--release <value>", "Set release identifier")
144
181
  .option("--blocked-by <value>", "Set blocked-by item ID or reason")
145
- .option("--blocked_by <value>", "Alias for --blocked-by")
146
182
  .option("--blocked-reason <value>", "Set blocked reason")
147
- .option("--blocked_reason <value>", "Alias for --blocked-reason")
148
183
  .option("--unblock-note <value>", "Set unblock rationale note")
149
- .option("--unblock_note <value>", "Alias for --unblock-note")
150
184
  .option("--reporter <value>", "Set issue reporter")
151
185
  .option("--severity <value>", "Set issue severity")
152
186
  .option("--environment <value>", "Set issue environment context")
153
187
  .option("--repro-steps <value>", "Set issue reproduction steps")
154
- .option("--repro_steps <value>", "Alias for --repro-steps")
155
188
  .option("--resolution <value>", "Set issue resolution summary")
156
189
  .option("--expected-result <value>", "Set issue expected behavior")
157
- .option("--expected_result <value>", "Alias for --expected-result")
158
190
  .option("--actual-result <value>", "Set issue observed behavior")
159
- .option("--actual_result <value>", "Alias for --actual-result")
160
191
  .option("--affected-version <value>", "Set affected version identifier")
161
- .option("--affected_version <value>", "Alias for --affected-version")
162
192
  .option("--fixed-version <value>", "Set fixed version identifier")
163
- .option("--fixed_version <value>", "Alias for --fixed-version")
164
193
  .option("--component <value>", "Set issue component ownership")
165
194
  .option("--regression <value>", "Set regression marker: true|false|1|0")
166
195
  .option("--customer-impact <value>", "Set customer impact summary")
167
- .option("--customer_impact <value>", "Alias for --customer-impact")
168
196
  .option("--dep <value>", "Add dependency entry id=<id>,kind=<kind>,author=<author>,created_at=<timestamp>", collect)
169
197
  .option("--dep-remove <value>", "Remove dependency entries by id/kind/author/timestamp signature", collect)
170
- .option("--dep_remove <value>", "Alias for --dep-remove", collect)
171
198
  .option("--replace-deps", "Atomically replace dependency entries with provided --dep values")
172
199
  .option("--replace-tests", "Atomically replace linked tests with provided --test values")
173
200
  .option("--comment <value>", "Add comment seed author=<value>,created_at=<iso|now>,text=<value>", collect)
@@ -176,10 +203,9 @@ export function registerMutationCommands(program) {
176
203
  .option("--file <value>", "Add linked file path=<value>,scope=<project|global>,note=<text>", collect)
177
204
  .option("--test <value>", "Add linked test command=<value>,path=<value>,scope=<project|global>", collect)
178
205
  .option("--doc <value>", "Add linked doc path=<value>,scope=<project|global>,note=<text>", collect)
179
- .option("--reminder <value>", "Add reminder entry at=<iso|relative>,text=<text>", collect)
206
+ .option("--reminder <value>", "Add reminder entry at=<iso|relative>|date=<iso|relative>,text=<text>|title=<text>", collect)
180
207
  .option("--event <value>", "Add event entry start=<iso|relative>,end=<iso|relative>,recur_*", collect)
181
208
  .option("--type-option <value>", "Set type options key=value (repeatable)", collect)
182
- .option("--type_option <value>", "Alias for --type-option", collect)
183
209
  .option("--unset <field>", "Clear scalar metadata field by name (repeatable)", collect)
184
210
  .option("--clear-deps", "Clear dependency entries")
185
211
  .option("--clear-comments", "Clear comments")
@@ -192,12 +218,39 @@ export function registerMutationCommands(program) {
192
218
  .option("--clear-events", "Clear events")
193
219
  .option("--clear-type-options", "Clear type options")
194
220
  .option("--allow-audit-update", "Allow non-owner metadata-only audit updates without requiring --force")
195
- .option("--allow_audit_update", "Alias for --allow-audit-update")
196
221
  .option("--allow-audit-dep-update", "Allow non-owner append-only dependency updates without requiring --force")
197
- .option("--allow_audit_dep_update", "Alias for --allow-audit-dep-update")
198
222
  .option("--author <value>", "Mutation author")
199
223
  .option("--message <value>", "Mutation message")
200
- .option("--force", "Force ownership override")
224
+ .option("--force", "Force ownership override");
225
+ // Hidden pure snake_case underscore-duplicate aliases (kept parse-functional,
226
+ // omitted from --help to save agent context).
227
+ for (const [flags, description] of [
228
+ ["--filter-assignee_filter <value>", "Alias for --filter-assignee-filter"],
229
+ ["--estimated_minutes <value>", "Alias for --estimated-minutes"],
230
+ ["--acceptance_criteria <value>", "Alias for --acceptance-criteria"],
231
+ ["--definition_of_ready <value>", "Alias for --definition-of-ready"],
232
+ ["--why_now <value>", "Alias for --why-now"],
233
+ ["--blocked_by <value>", "Alias for --blocked-by"],
234
+ ["--blocked_reason <value>", "Alias for --blocked-reason"],
235
+ ["--unblock_note <value>", "Alias for --unblock-note"],
236
+ ["--repro_steps <value>", "Alias for --repro-steps"],
237
+ ["--expected_result <value>", "Alias for --expected-result"],
238
+ ["--actual_result <value>", "Alias for --actual-result"],
239
+ ["--affected_version <value>", "Alias for --affected-version"],
240
+ ["--fixed_version <value>", "Alias for --fixed-version"],
241
+ ["--customer_impact <value>", "Alias for --customer-impact"],
242
+ ["--allow_audit_update", "Alias for --allow-audit-update"],
243
+ ["--allow_audit_dep_update", "Alias for --allow-audit-dep-update"],
244
+ ]) {
245
+ addHiddenOption(updateManyCommand, flags, description, false);
246
+ }
247
+ for (const [flags, description] of [
248
+ ["--dep_remove <value>", "Alias for --dep-remove"],
249
+ ["--type_option <value>", "Alias for --type-option"],
250
+ ]) {
251
+ addHiddenOption(updateManyCommand, flags, description, true);
252
+ }
253
+ updateManyCommand
201
254
  .action(async (options, command) => {
202
255
  const globalOptions = getGlobalOptions(command);
203
256
  const startedAt = Date.now();
@@ -237,7 +290,9 @@ export function registerMutationCommands(program) {
237
290
  program
238
291
  .command("close")
239
292
  .argument("<id>", "Item id")
240
- .argument("<text>", "Close reason text")
293
+ .argument("[text]", "Close reason text (alias: --reason)")
294
+ .option("--reason <value>", "Close reason text (alias for positional <text>)")
295
+ .option("--close-reason <value>", "Close reason text (alias for positional <text>)")
241
296
  .option("--author <value>", "Mutation author")
242
297
  .option("--message <value>", "History message")
243
298
  .option("--validate-close [mode]", 'Validate closure metadata before close: "off", "warn", or "strict" (default: settings governance preset)')
@@ -247,7 +302,24 @@ export function registerMutationCommands(program) {
247
302
  const globalOptions = getGlobalOptions(command);
248
303
  const startedAt = Date.now();
249
304
  const { runClose } = await loadMutationCommandsModule();
250
- const result = await runClose(id, text, {
305
+ const reasonFromOption = (typeof options.reason === "string" && options.reason.trim().length > 0 && options.reason) ||
306
+ (typeof options.closeReason === "string" && options.closeReason.trim().length > 0 && options.closeReason) ||
307
+ undefined;
308
+ const resolvedText = typeof text === "string" && text.length > 0 ? text : reasonFromOption;
309
+ if (typeof resolvedText !== "string" || resolvedText.length === 0) {
310
+ throw new PmCliError("pm close requires a close reason as the second positional argument or via --reason.", EXIT_CODE.USAGE, {
311
+ code: "missing_required_argument",
312
+ why: "Close mutations are auditable; a reason is mandatory for the history record.",
313
+ examples: [
314
+ `pm close ${id} "All acceptance criteria met"`,
315
+ `pm close ${id} --reason "Verified by integration test"`,
316
+ ],
317
+ nextSteps: [
318
+ "Re-run with the close reason as the second positional argument, or pass --reason \"<text>\".",
319
+ ],
320
+ });
321
+ }
322
+ const result = await runClose(id, resolvedText, {
251
323
  author: typeof options.author === "string" ? options.author : undefined,
252
324
  message: typeof options.message === "string" ? options.message : undefined,
253
325
  validateClose: options.validateClose === true
@@ -269,6 +341,7 @@ export function registerMutationCommands(program) {
269
341
  .option("--author <value>", "Mutation author")
270
342
  .option("--message <value>", "History message")
271
343
  .option("--force", "Force ownership override")
344
+ .option("--dry-run", "Preview the item file that would be deleted without mutating")
272
345
  .description("Delete an item and record the change in history.")
273
346
  .action(async (id, options, command) => {
274
347
  const globalOptions = getGlobalOptions(command);
@@ -278,8 +351,11 @@ export function registerMutationCommands(program) {
278
351
  author: typeof options.author === "string" ? options.author : undefined,
279
352
  message: typeof options.message === "string" ? options.message : undefined,
280
353
  force: Boolean(options.force),
354
+ dryRun: options.dryRun === true,
281
355
  }, globalOptions);
282
- await invalidateSearchCachesForMutation(globalOptions, result);
356
+ if (result.dry_run !== true) {
357
+ await invalidateSearchCachesForMutation(globalOptions, result);
358
+ }
283
359
  printResult(result, globalOptions);
284
360
  if (globalOptions.profile) {
285
361
  printError(`profile:command=delete took_ms=${Date.now() - startedAt}`);
@@ -288,17 +364,30 @@ export function registerMutationCommands(program) {
288
364
  program
289
365
  .command("append")
290
366
  .argument("<id>", "Item id")
291
- .requiredOption("--body <value>", "Text to append to body (or - for stdin)")
367
+ .argument("[text]", "Optional body text shorthand (equivalent to --body; use - for stdin)")
368
+ .option("--body <value>", "Text to append to body (or - for stdin)")
369
+ .option("--text <value>", "Alias for --body")
292
370
  .option("--author <value>", "Mutation author")
293
371
  .option("--message <value>", "Mutation message")
294
372
  .option("--force", "Force ownership override")
295
373
  .description("Append text to an item's body.")
296
- .action(async (id, options, command) => {
374
+ .action(async (id, text, options, command) => {
297
375
  const globalOptions = getGlobalOptions(command);
298
376
  const startedAt = Date.now();
377
+ const bodyFromOption = typeof options.body === "string" ? options.body : undefined;
378
+ const bodyFromAlias = typeof options.text === "string" ? options.text : undefined;
379
+ const bodyFromPositional = typeof text === "string" ? text : undefined;
380
+ const bodySourceCount = [bodyFromOption, bodyFromAlias, bodyFromPositional].filter((value) => value !== undefined).length;
381
+ if (bodySourceCount > 1) {
382
+ throw new PmCliError("Specify append text with exactly one source: positional [text], --body, or --text", EXIT_CODE.USAGE);
383
+ }
384
+ const resolvedBody = bodyFromOption ?? bodyFromAlias ?? bodyFromPositional;
385
+ if (resolvedBody === undefined) {
386
+ throw new PmCliError("Missing append text. Provide it as positional [text], --body <value>, or --text <value> (use - for stdin).", EXIT_CODE.USAGE);
387
+ }
299
388
  const { runAppend } = await loadMutationCommandsModule();
300
389
  const result = await runAppend(id, {
301
- body: typeof options.body === "string" ? options.body : "",
390
+ body: resolvedBody,
302
391
  author: typeof options.author === "string" ? options.author : undefined,
303
392
  message: typeof options.message === "string" ? options.message : undefined,
304
393
  force: Boolean(options.force),
@@ -332,6 +421,306 @@ export function registerMutationCommands(program) {
332
421
  printError(`profile:command=restore took_ms=${Date.now() - startedAt}`);
333
422
  }
334
423
  });
424
+ const planCommand = program
425
+ .command("plan")
426
+ .description("Agent-optimized Plan item workflow: create, manage steps, link dependencies, approve, and materialize.")
427
+ .argument("[subcommand]", "Plan subcommand: create|show|add-step|update-step|complete-step|block-step|reorder-step|remove-step|link|unlink|decision|discovery|validation|resume|approve|materialize")
428
+ .argument("[id]", "Plan id (required for non-create subcommands); for create this may be the positional title")
429
+ .argument("[stepRef]", "Step reference: stable id (plan-step-001) or order integer")
430
+ .argument("[reorderTo]", "New order integer for reorder-step")
431
+ .option("--title <value>", "Plan title")
432
+ .option("--description <value>", "Plan description")
433
+ .option("--scope <value>", "Short scope statement of the target change or investigation")
434
+ .option("--parent <value>", "Parent pm item id")
435
+ .option("--related <value>", "Related pm item ids (repeatable, csv-friendly)", collect)
436
+ .option("--blocks <value>", "Pm item ids this plan blocks (repeatable, csv-friendly)", collect)
437
+ .option("--blocked-by <value>", "Pm item ids that block this plan (repeatable, csv-friendly)", collect)
438
+ .option("--harness <value>", "Plan harness provenance: codex|claude-code|cursor|generic")
439
+ .option("--mode <value>", "Plan mode: draft|research|review|approved|executing|paused|completed|superseded")
440
+ .option("--resume-context <value>", "Compact context summary for a future stateless agent")
441
+ .option("--tags <value>", "Comma-separated tags")
442
+ .option("--priority <value>", "Priority 0-4")
443
+ .option("--body <value>", "Plan item body")
444
+ .option("--claim", "Claim the plan on create for the author")
445
+ .option("--from-search <value>", "Record the search query that led to plan creation")
446
+ .option("--step-title <value>", "Step title for add-step / update-step")
447
+ .option("--step <value>", "Alias for --step-title")
448
+ .option("--step-body <value>", "Step body text")
449
+ .option("--step-owner <value>", "Step owner")
450
+ .option("--step-status <value>", "Step status: pending|in_progress|completed|blocked|skipped|superseded")
451
+ .option("--step-evidence <value>", "Step evidence text (used by update-step/complete-step)")
452
+ .option("--step-blocked-reason <value>", "Step blocked reason (required when blocking)")
453
+ .option("--step-replacement <value>", "Replacement reference for a superseded step")
454
+ .option("--depends-on <value>", "Pm item ids the step depends on (repeatable, csv-friendly)", collect)
455
+ .option("--link <value>", "Pm item id to link (repeatable, csv-friendly)", collect)
456
+ .option("--link-kind <value>", "Link kind: related|blocks|blocked_by|depends_on|discovered_from|implements|verifies|supersedes")
457
+ .option("--link-note <value>", "Optional note for the link")
458
+ .option("--promote-to-item-dep", "Also add the linked id as a top-level item dependency when linking")
459
+ .option("--allow-multiple-active", "Allow multiple steps to be in_progress at once")
460
+ .option("--file <value>", "Step linked file path=<value>[,scope=project|global,note=<text>] (repeatable)", collect)
461
+ .option("--test <value>", "Step linked test command=<value>[,path=<value>,note=<text>] (repeatable)", collect)
462
+ .option("--doc <value>", "Step linked doc path=<value>[,scope=project|global,note=<text>] (repeatable)", collect)
463
+ .option("--decision-text <value>", "Decision log entry text")
464
+ .option("--decision <value>", "Alias for --decision-text")
465
+ .option("--decision-rationale <value>", "Decision log entry rationale")
466
+ .option("--decision-evidence <value>", "Decision log entry evidence")
467
+ .option("--discovery-text <value>", "Discovery log entry text")
468
+ .option("--discovery <value>", "Alias for --discovery-text")
469
+ .option("--validation-text <value>", "Validation log entry text")
470
+ .option("--validation <value>", "Alias for --validation-text")
471
+ .option("--validation-command <value>", "Validation log entry command")
472
+ .option("--validation-expected <value>", "Validation log entry expected outcome")
473
+ .option("--depth <value>", "Show depth: brief|standard|deep (default: brief)")
474
+ .option("--fields <value>", "Comma-separated field projection for show output")
475
+ .option("--steps <value>", "Comma-separated step ids/orders for materialize")
476
+ .option("--materialize-type <value>", "Item type for materialized steps (default: Task)")
477
+ .option("--materialize-parent <value>", "Parent item id for materialized children (default: the plan)")
478
+ .option("--materialize-tags <value>", "Comma-separated tags for materialized children")
479
+ .option("--author <value>", "Mutation author")
480
+ .option("--message <value>", "Mutation message")
481
+ .option("--force", "Force ownership override");
482
+ // Hidden pure snake_case underscore-duplicate aliases (kept parse-functional,
483
+ // omitted from --help to save agent context).
484
+ for (const [flags, description] of [
485
+ ["--resume_context <value>", "Alias for --resume-context"],
486
+ ["--from_search <value>", "Alias for --from-search"],
487
+ ["--step_title <value>", "Alias for --step-title"],
488
+ ["--step_body <value>", "Alias for --step-body"],
489
+ ["--step_owner <value>", "Alias for --step-owner"],
490
+ ["--step_status <value>", "Alias for --step-status"],
491
+ ["--step_evidence <value>", "Alias for --step-evidence"],
492
+ ["--step_blocked_reason <value>", "Alias for --step-blocked-reason"],
493
+ ["--step_replacement <value>", "Alias for --step-replacement"],
494
+ ["--link_kind <value>", "Alias for --link-kind"],
495
+ ["--link_note <value>", "Alias for --link-note"],
496
+ ["--promote_to_item_dep", "Alias for --promote-to-item-dep"],
497
+ ["--allow_multiple_active", "Alias for --allow-multiple-active"],
498
+ ["--decision_text <value>", "Alias for --decision-text"],
499
+ ["--decision_rationale <value>", "Alias for --decision-rationale"],
500
+ ["--decision_evidence <value>", "Alias for --decision-evidence"],
501
+ ["--discovery_text <value>", "Alias for --discovery-text"],
502
+ ["--validation_text <value>", "Alias for --validation-text"],
503
+ ["--validation_command <value>", "Alias for --validation-command"],
504
+ ["--validation_expected <value>", "Alias for --validation-expected"],
505
+ ["--materialize_type <value>", "Alias for --materialize-type"],
506
+ ["--materialize_parent <value>", "Alias for --materialize-parent"],
507
+ ["--materialize_tags <value>", "Alias for --materialize-tags"],
508
+ ]) {
509
+ addHiddenOption(planCommand, flags, description, false);
510
+ }
511
+ for (const [flags, description] of [
512
+ ["--blocked_by <value>", "Alias for --blocked-by"],
513
+ ["--depends_on <value>", "Alias for --depends-on"],
514
+ ]) {
515
+ addHiddenOption(planCommand, flags, description, true);
516
+ }
517
+ planCommand
518
+ .action(async (subcommand, id, stepRef, reorderToken, options, command) => {
519
+ const globalOptions = getGlobalOptions(command);
520
+ const startedAt = Date.now();
521
+ const { runPlan, PLAN_SUBCOMMANDS } = await loadMutationCommandsModule();
522
+ const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
523
+ if (!normalizedSubcommand) {
524
+ throw new PmCliError(`pm plan requires a subcommand. Allowed: ${PLAN_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
525
+ code: "missing_required_argument",
526
+ examples: [
527
+ 'pm plan create --title "Refactor lock retry"',
528
+ "pm plan show pm-a1b2 --depth standard",
529
+ 'pm plan add-step pm-a1b2 --step-title "Read lock.ts"',
530
+ ],
531
+ });
532
+ }
533
+ if (!PLAN_SUBCOMMANDS.includes(normalizedSubcommand)) {
534
+ const didYouMean = normalizedSubcommand === "list" || normalizedSubcommand === "ls"
535
+ ? ['pm list --type Plan', 'pm list-all --type Plan']
536
+ : undefined;
537
+ throw new PmCliError(`Unknown pm plan subcommand "${subcommand}". Allowed: ${PLAN_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, didYouMean ? { code: "unknown_subcommand", examples: didYouMean } : undefined);
538
+ }
539
+ const planOptions = { ...options };
540
+ // Normalize alternate-snake/camel aliases that Commander parses as different keys.
541
+ const aliasPairs = [
542
+ ["blocked_by", "blockedBy"],
543
+ ["resume_context", "resumeContext"],
544
+ ["from_search", "fromSearch"],
545
+ ["step", "stepTitle"],
546
+ ["step_title", "stepTitle"],
547
+ ["step_body", "stepBody"],
548
+ ["step_owner", "stepOwner"],
549
+ ["step_status", "stepStatus"],
550
+ ["step_evidence", "stepEvidence"],
551
+ ["step_blocked_reason", "stepBlockedReason"],
552
+ ["step_replacement", "stepReplacement"],
553
+ ["depends_on", "dependsOn"],
554
+ ["link_kind", "linkKind"],
555
+ ["link_note", "linkNote"],
556
+ ["promote_to_item_dep", "promoteToItemDep"],
557
+ ["allow_multiple_active", "allowMultipleActive"],
558
+ ["decision_text", "decisionText"],
559
+ ["decision_rationale", "decisionRationale"],
560
+ ["decision_evidence", "decisionEvidence"],
561
+ ["discovery_text", "discoveryText"],
562
+ ["validation_text", "validationText"],
563
+ ["validation_command", "validationCommand"],
564
+ ["validation_expected", "validationExpected"],
565
+ ["materialize_type", "materializeType"],
566
+ ["materialize_parent", "materializeParent"],
567
+ ["materialize_tags", "materializeTags"],
568
+ ];
569
+ for (const [snake, camel] of aliasPairs) {
570
+ if (planOptions[snake] !== undefined && planOptions[camel] === undefined) {
571
+ planOptions[camel] = planOptions[snake];
572
+ }
573
+ }
574
+ let reorderTo;
575
+ if (normalizedSubcommand === "reorder-step" && typeof reorderToken === "string") {
576
+ const parsed = Number.parseInt(reorderToken, 10);
577
+ if (!Number.isFinite(parsed)) {
578
+ throw new PmCliError(`reorder-step requires an integer new order, got "${reorderToken}"`, EXIT_CODE.USAGE);
579
+ }
580
+ reorderTo = parsed;
581
+ }
582
+ // Allow positional title for `pm plan create "Title"` (mirrors pm create UX).
583
+ // Plan create never takes an id positional; the second token is the title.
584
+ let planId = id;
585
+ if (normalizedSubcommand === "create" && typeof id === "string" && id.length > 0 && planOptions.title === undefined) {
586
+ planOptions.title = id;
587
+ planId = undefined;
588
+ }
589
+ const result = await runPlan({
590
+ subcommand: normalizedSubcommand,
591
+ id: planId,
592
+ stepRef,
593
+ reorderTo,
594
+ options: planOptions,
595
+ global: globalOptions,
596
+ });
597
+ await invalidateSearchCachesForMutation(globalOptions, result);
598
+ printResult(result, globalOptions);
599
+ if (globalOptions.profile) {
600
+ printError(`profile:command=plan took_ms=${Date.now() - startedAt}`);
601
+ }
602
+ });
603
+ void planCommand;
604
+ program
605
+ .command("history-redact")
606
+ .argument("<id>", "Item id")
607
+ .option("--literal <value>", "Literal string to redact (repeatable)", collect)
608
+ .option("--regex <value>", "Regex pattern to redact (repeatable; accepts /pattern/flags or raw pattern)", collect)
609
+ .option("--replacement <value>", 'Replacement string (default: "[redacted]")')
610
+ .option("--dry-run", "Preview redaction impact without writing item/history files")
611
+ .option("--author <value>", "Mutation author")
612
+ .option("--message <value>", "Audit history message for the redaction marker entry")
613
+ .option("--force", "Force ownership/lock override")
614
+ .description("Redact sensitive literals/patterns from an item history stream and recompute hashes.")
615
+ .action(async (id, options, command) => {
616
+ const globalOptions = getGlobalOptions(command);
617
+ const startedAt = Date.now();
618
+ const { runHistoryRedact } = await loadMutationCommandsModule();
619
+ const literal = Array.isArray(options.literal) ? options.literal : undefined;
620
+ const regex = Array.isArray(options.regex) ? options.regex : undefined;
621
+ const result = await runHistoryRedact(id, {
622
+ literal,
623
+ regex,
624
+ replacement: typeof options.replacement === "string" ? options.replacement : undefined,
625
+ dryRun: options.dryRun === true,
626
+ author: typeof options.author === "string" ? options.author : undefined,
627
+ message: typeof options.message === "string" ? options.message : undefined,
628
+ force: Boolean(options.force),
629
+ }, globalOptions);
630
+ if (result.changed && !result.dry_run) {
631
+ await invalidateSearchCachesForMutation(globalOptions, result);
632
+ }
633
+ printResult(result, globalOptions);
634
+ if (globalOptions.profile) {
635
+ printError(`profile:command=history-redact took_ms=${Date.now() - startedAt}`);
636
+ }
637
+ });
638
+ program
639
+ .command("history-repair")
640
+ .argument("<id>", "Item id")
641
+ .option("--dry-run", "Preview the re-anchor impact without writing the history file")
642
+ .option("--author <value>", "Mutation author")
643
+ .option("--message <value>", "Audit history message for the repair marker entry")
644
+ .option("--force", "Force ownership/lock override")
645
+ .description("Re-anchor a drifted item history chain (recompute hashes, reconcile with the on-disk item) and record an audit marker.")
646
+ .action(async (id, options, command) => {
647
+ const globalOptions = getGlobalOptions(command);
648
+ const startedAt = Date.now();
649
+ const { runHistoryRepair } = await loadMutationCommandsModule();
650
+ const result = await runHistoryRepair(id, {
651
+ dryRun: options.dryRun === true,
652
+ author: typeof options.author === "string" ? options.author : undefined,
653
+ message: typeof options.message === "string" ? options.message : undefined,
654
+ force: Boolean(options.force),
655
+ }, globalOptions);
656
+ // history-repair only re-anchors the audit stream; item content is untouched,
657
+ // so search caches do not need invalidation.
658
+ printResult(result, globalOptions);
659
+ if (globalOptions.profile) {
660
+ printError(`profile:command=history-repair took_ms=${Date.now() - startedAt}`);
661
+ }
662
+ });
663
+ const schemaCommand = program
664
+ .command("schema")
665
+ .argument("[subcommand]", "Schema subcommand: add-type")
666
+ .argument("[name]", "Custom item type name (for add-type)")
667
+ .option("--description <text>", "Human description for the custom item type")
668
+ .option("--default-status <status>", "Default status hint recorded for the custom item type")
669
+ .option("--folder <dir>", "Storage folder for items of this custom type")
670
+ .option("--alias <name>", "Alias for the custom type (repeatable, csv-friendly)", collect)
671
+ .option("--author <value>", "Mutation author")
672
+ .option("--force", "Force ownership/lock override")
673
+ .description("Manage config-driven runtime schema: register custom item types into .agents/pm/schema/types.json.");
674
+ // Hidden pure snake_case underscore-duplicate alias.
675
+ addHiddenOption(schemaCommand, "--default_status <status>", "Alias for --default-status", false);
676
+ schemaCommand
677
+ .action(async (subcommand, name, options, command) => {
678
+ const globalOptions = getGlobalOptions(command);
679
+ const startedAt = Date.now();
680
+ const { runSchemaAddType, formatSchemaAddTypeHuman, SCHEMA_SUBCOMMANDS } = await loadMutationCommandsModule();
681
+ const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
682
+ if (!normalizedSubcommand) {
683
+ throw new PmCliError(`pm schema requires a subcommand. Allowed: ${SCHEMA_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
684
+ code: "missing_required_argument",
685
+ examples: [
686
+ 'pm schema add-type Spike --description "Time-boxed investigation" --default-status open',
687
+ 'pm schema add-type Spike --alias spike --alias research',
688
+ ],
689
+ });
690
+ }
691
+ if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand)) {
692
+ throw new PmCliError(`Unknown pm schema subcommand "${subcommand}". Allowed: ${SCHEMA_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, { code: "unknown_subcommand" });
693
+ }
694
+ const aliases = Array.isArray(options.alias) ? options.alias : undefined;
695
+ const defaultStatus = typeof options.defaultStatus === "string"
696
+ ? options.defaultStatus
697
+ : typeof options.default_status === "string"
698
+ ? options.default_status
699
+ : undefined;
700
+ const result = await runSchemaAddType(name, {
701
+ description: typeof options.description === "string" ? options.description : undefined,
702
+ defaultStatus,
703
+ folder: typeof options.folder === "string" ? options.folder : undefined,
704
+ alias: aliases,
705
+ author: typeof options.author === "string" ? options.author : undefined,
706
+ force: Boolean(options.force),
707
+ }, globalOptions);
708
+ // Registering a type does not touch item content, so search caches stay valid.
709
+ if (globalOptions.json === true || globalOptions.defaultOutputFormat === "json") {
710
+ printResult(result, globalOptions);
711
+ }
712
+ else if (!globalOptions.quiet) {
713
+ writeStdout(`${formatSchemaAddTypeHuman(result)}\n`);
714
+ // Surface extension on-write hook diagnostics so policy/enforcement
715
+ // warnings are visible without forcing --json.
716
+ if (result.warnings.length > 0) {
717
+ printError(`schema add-type warnings: ${formatHookWarnings(result.warnings)}`);
718
+ }
719
+ }
720
+ if (globalOptions.profile) {
721
+ printError(`profile:command=schema took_ms=${Date.now() - startedAt}`);
722
+ }
723
+ });
335
724
  program
336
725
  .command("comments")
337
726
  .argument("<id>", "Item id")
@@ -540,6 +929,7 @@ export function registerMutationCommands(program) {
540
929
  .option("--add-glob <value>", "Add linked doc entries from a glob (plain glob or pattern=<glob>,scope=<scope>,note=<text>; repeatable)", collect)
541
930
  .option("--remove <value>", "Remove linked doc by path (path=<value>, path:<value>, plain path, or - for stdin)", collect)
542
931
  .option("--migrate <value>", "Migrate linked doc paths in-place (from=<prefix>,to=<prefix>; repeatable)", collect)
932
+ .option("--list", "List linked docs without mutating")
543
933
  .option("--validate-paths", "Validate linked doc paths for existence and file shape")
544
934
  .option("--audit", "Audit linked doc usage across all items for this item's linked paths")
545
935
  .option("--author <value>", "Mutation author")
@@ -559,6 +949,7 @@ export function registerMutationCommands(program) {
559
949
  addGlob: addGlobValues,
560
950
  remove: removeValues,
561
951
  migrate: migrateValues,
952
+ list: Boolean(options.list),
562
953
  validatePaths: Boolean(options.validatePaths),
563
954
  audit: Boolean(options.audit),
564
955
  author: typeof options.author === "string" ? options.author : undefined,
@@ -597,4 +988,5 @@ export function registerMutationCommands(program) {
597
988
  }
598
989
  });
599
990
  }
600
- //# sourceMappingURL=register-mutation.js.map
991
+ //# sourceMappingURL=register-mutation.js.map
992
+ //# debugId=634fa316-811c-5a12-a391-225313b2c754