@unbrained/pm-cli 2026.7.1 → 2026.7.3

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 (625) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/CHANGELOG.md +25 -0
  3. package/CONTRIBUTING.md +2 -2
  4. package/README.md +1 -1
  5. package/dist/cli/commander-usage.d.ts +2 -0
  6. package/dist/cli/commander-usage.js +110 -86
  7. package/dist/cli/commander-usage.js.map +1 -1
  8. package/dist/cli/commands/activity.js +79 -57
  9. package/dist/cli/commands/activity.js.map +1 -1
  10. package/dist/cli/commands/aggregate.js +102 -79
  11. package/dist/cli/commands/aggregate.js.map +1 -1
  12. package/dist/cli/commands/calendar.js +278 -243
  13. package/dist/cli/commands/calendar.js.map +1 -1
  14. package/dist/cli/commands/close-many.js +176 -114
  15. package/dist/cli/commands/close-many.js.map +1 -1
  16. package/dist/cli/commands/close.js +157 -129
  17. package/dist/cli/commands/close.js.map +1 -1
  18. package/dist/cli/commands/comments-audit.js +50 -42
  19. package/dist/cli/commands/comments-audit.js.map +1 -1
  20. package/dist/cli/commands/config.d.ts +2 -0
  21. package/dist/cli/commands/config.js +443 -879
  22. package/dist/cli/commands/config.js.map +1 -1
  23. package/dist/cli/commands/context.js +365 -287
  24. package/dist/cli/commands/context.js.map +1 -1
  25. package/dist/cli/commands/contracts.js +352 -238
  26. package/dist/cli/commands/contracts.js.map +1 -1
  27. package/dist/cli/commands/create.js +32 -17
  28. package/dist/cli/commands/create.js.map +1 -1
  29. package/dist/cli/commands/dedupe-audit.js +46 -39
  30. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  31. package/dist/cli/commands/dedupe-merge.js +88 -69
  32. package/dist/cli/commands/dedupe-merge.js.map +1 -1
  33. package/dist/cli/commands/extension/doctor.js +56 -67
  34. package/dist/cli/commands/extension/doctor.js.map +1 -1
  35. package/dist/cli/commands/extension/shared.js +21 -15
  36. package/dist/cli/commands/extension/shared.js.map +1 -1
  37. package/dist/cli/commands/get.js +114 -81
  38. package/dist/cli/commands/get.js.map +1 -1
  39. package/dist/cli/commands/health.d.ts +17 -0
  40. package/dist/cli/commands/health.js +545 -417
  41. package/dist/cli/commands/health.js.map +1 -1
  42. package/dist/cli/commands/history-compact.js +209 -140
  43. package/dist/cli/commands/history-compact.js.map +1 -1
  44. package/dist/cli/commands/history-redact.js +162 -119
  45. package/dist/cli/commands/history-redact.js.map +1 -1
  46. package/dist/cli/commands/history-repair.js +120 -85
  47. package/dist/cli/commands/history-repair.js.map +1 -1
  48. package/dist/cli/commands/init-agent-guidance.js +32 -19
  49. package/dist/cli/commands/init-agent-guidance.js.map +1 -1
  50. package/dist/cli/commands/init.d.ts +8 -2
  51. package/dist/cli/commands/init.js +263 -162
  52. package/dist/cli/commands/init.js.map +1 -1
  53. package/dist/cli/commands/list.js +152 -102
  54. package/dist/cli/commands/list.js.map +1 -1
  55. package/dist/cli/commands/next.js +60 -40
  56. package/dist/cli/commands/next.js.map +1 -1
  57. package/dist/cli/commands/plan.js +373 -298
  58. package/dist/cli/commands/plan.js.map +1 -1
  59. package/dist/cli/commands/profile.js +23 -15
  60. package/dist/cli/commands/profile.js.map +1 -1
  61. package/dist/cli/commands/recurrence-parsers.js +43 -25
  62. package/dist/cli/commands/recurrence-parsers.js.map +1 -1
  63. package/dist/cli/commands/reindex.d.ts +21 -5
  64. package/dist/cli/commands/reindex.js +345 -205
  65. package/dist/cli/commands/reindex.js.map +1 -1
  66. package/dist/cli/commands/restore.d.ts +8 -7
  67. package/dist/cli/commands/restore.js +105 -69
  68. package/dist/cli/commands/restore.js.map +1 -1
  69. package/dist/cli/commands/schema.js +33 -30
  70. package/dist/cli/commands/schema.js.map +1 -1
  71. package/dist/cli/commands/search.d.ts +10 -2
  72. package/dist/cli/commands/search.js +503 -470
  73. package/dist/cli/commands/search.js.map +1 -1
  74. package/dist/cli/commands/telemetry.js +98 -87
  75. package/dist/cli/commands/telemetry.js.map +1 -1
  76. package/dist/cli/commands/test-all.js +237 -168
  77. package/dist/cli/commands/test-all.js.map +1 -1
  78. package/dist/cli/commands/test.d.ts +6 -5
  79. package/dist/cli/commands/test.js +424 -344
  80. package/dist/cli/commands/test.js.map +1 -1
  81. package/dist/cli/commands/update-many.js +57 -42
  82. package/dist/cli/commands/update-many.js.map +1 -1
  83. package/dist/cli/commands/update.d.ts +1 -1
  84. package/dist/cli/commands/update.js +738 -671
  85. package/dist/cli/commands/update.js.map +1 -1
  86. package/dist/cli/commands/validate.d.ts +20 -1
  87. package/dist/cli/commands/validate.js +478 -343
  88. package/dist/cli/commands/validate.js.map +1 -1
  89. package/dist/cli/error-guidance.js +406 -361
  90. package/dist/cli/error-guidance.js.map +1 -1
  91. package/dist/cli/extension-command-help.js +27 -19
  92. package/dist/cli/extension-command-help.js.map +1 -1
  93. package/dist/cli/help-json-payload.js +57 -49
  94. package/dist/cli/help-json-payload.js.map +1 -1
  95. package/dist/cli/main.d.ts +47 -0
  96. package/dist/cli/main.js +474 -371
  97. package/dist/cli/main.js.map +1 -1
  98. package/dist/cli/migration-gates.js +22 -45
  99. package/dist/cli/migration-gates.js.map +1 -1
  100. package/dist/cli/register-list-query.js +299 -310
  101. package/dist/cli/register-list-query.js.map +1 -1
  102. package/dist/cli/register-mutation.js +763 -779
  103. package/dist/cli/register-mutation.js.map +1 -1
  104. package/dist/cli/register-operations.js +386 -362
  105. package/dist/cli/register-operations.js.map +1 -1
  106. package/dist/cli/register-setup.js +120 -101
  107. package/dist/cli/register-setup.js.map +1 -1
  108. package/dist/cli/registration-helpers.d.ts +4 -0
  109. package/dist/cli/registration-helpers.js +45 -56
  110. package/dist/cli/registration-helpers.js.map +1 -1
  111. package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js → activity-5YWLSPGE.js} +9 -9
  112. package/dist/cli-bundle/chunks/activity-BIML7K2D.js +16 -0
  113. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js → aggregate-2V2M3JZU.js} +107 -83
  114. package/dist/cli-bundle/chunks/{aggregate-SDF7DUOD.js.map → aggregate-2V2M3JZU.js.map} +2 -2
  115. package/dist/cli-bundle/chunks/{aggregate-JTEF4BP7.js → aggregate-EK7DXML7.js} +108 -84
  116. package/dist/cli-bundle/chunks/aggregate-EK7DXML7.js.map +1 -0
  117. package/dist/cli-bundle/chunks/{append-LOVPGVPT.js → append-EZESUVJT.js} +8 -8
  118. package/dist/cli-bundle/chunks/{append-QCFJSDFL.js → append-JFG4WQMG.js} +8 -8
  119. package/dist/cli-bundle/chunks/{chunk-TP5Q5ZD3.js → chunk-32IUNTG4.js} +158 -119
  120. package/dist/cli-bundle/chunks/chunk-32IUNTG4.js.map +1 -0
  121. package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js → chunk-3W2HJKJX.js} +3 -3
  122. package/dist/cli-bundle/chunks/{chunk-VARHOHYV.js → chunk-4EXFFP7T.js} +86 -52
  123. package/dist/cli-bundle/chunks/chunk-4EXFFP7T.js.map +7 -0
  124. package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js → chunk-4PFVUUYV.js} +2 -2
  125. package/dist/cli-bundle/chunks/{chunk-JSU5P7VS.js → chunk-4WB6S4YX.js} +308 -184
  126. package/dist/cli-bundle/chunks/chunk-4WB6S4YX.js.map +1 -0
  127. package/dist/cli-bundle/chunks/{chunk-HXTQJXWT.js → chunk-572FKBRL.js} +61 -102
  128. package/dist/cli-bundle/chunks/chunk-572FKBRL.js.map +1 -0
  129. package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js → chunk-5E7N4T2Z.js} +2 -2
  130. package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js → chunk-5IZUBZBR.js} +3 -3
  131. package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js → chunk-5JIWFWOZ.js} +2 -2
  132. package/dist/cli-bundle/chunks/{chunk-FFMQB7WR.js → chunk-67LARBDL.js} +493 -404
  133. package/dist/cli-bundle/chunks/chunk-67LARBDL.js.map +1 -0
  134. package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js → chunk-6CDCWKSX.js} +4 -4
  135. package/dist/cli-bundle/chunks/{chunk-3K2M5OYU.js → chunk-6KRFL33E.js} +308 -184
  136. package/dist/cli-bundle/chunks/chunk-6KRFL33E.js.map +7 -0
  137. package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js → chunk-6NYJGMTY.js} +2 -2
  138. package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js → chunk-7CLLC75T.js} +4 -4
  139. package/dist/cli-bundle/chunks/{chunk-2466X6E4.js → chunk-7LYO6S5A.js} +8 -8
  140. package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js → chunk-A3OQ7TFW.js} +8 -8
  141. package/dist/cli-bundle/chunks/{chunk-5CGRF3L5.js → chunk-AIKU3IIL.js} +153 -90
  142. package/dist/cli-bundle/chunks/chunk-AIKU3IIL.js.map +1 -0
  143. package/dist/cli-bundle/chunks/{chunk-WYDHYJPO.js → chunk-AJHYQCBJ.js} +39 -5
  144. package/dist/cli-bundle/chunks/chunk-AJHYQCBJ.js.map +7 -0
  145. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js → chunk-B4O5S7I3.js} +79 -57
  146. package/dist/cli-bundle/chunks/{chunk-VZDBVEZR.js.map → chunk-B4O5S7I3.js.map} +2 -2
  147. package/dist/cli-bundle/chunks/{chunk-OTUHB4HS.js → chunk-BE2SR6QL.js} +92 -77
  148. package/dist/cli-bundle/chunks/chunk-BE2SR6QL.js.map +1 -0
  149. package/dist/cli-bundle/chunks/{chunk-JLM7BHI7.js → chunk-BI4R7HI2.js} +75 -53
  150. package/dist/cli-bundle/chunks/chunk-BI4R7HI2.js.map +7 -0
  151. package/dist/cli-bundle/chunks/{chunk-AXIDKKAT.js → chunk-CXR3CMBQ.js} +33 -6
  152. package/dist/cli-bundle/chunks/chunk-CXR3CMBQ.js.map +1 -0
  153. package/dist/cli-bundle/chunks/{chunk-ZETXE4SE.js → chunk-ECU6MMTQ.js} +713 -613
  154. package/dist/cli-bundle/chunks/chunk-ECU6MMTQ.js.map +1 -0
  155. package/dist/cli-bundle/chunks/{chunk-2D4HATP2.js → chunk-EJ2OCBHF.js} +54 -30
  156. package/dist/cli-bundle/chunks/chunk-EJ2OCBHF.js.map +1 -0
  157. package/dist/cli-bundle/chunks/{chunk-BDTISOSD.js → chunk-EQURFOMH.js} +41 -26
  158. package/dist/cli-bundle/chunks/chunk-EQURFOMH.js.map +7 -0
  159. package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js → chunk-ER4ME5U2.js} +3 -3
  160. package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js → chunk-ERG65A2L.js} +2 -2
  161. package/dist/cli-bundle/chunks/{chunk-IZBR4NRW.js → chunk-F6WNBITZ.js} +157 -113
  162. package/dist/cli-bundle/chunks/chunk-F6WNBITZ.js.map +7 -0
  163. package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js → chunk-FH2H3CBD.js} +3 -3
  164. package/dist/cli-bundle/chunks/{chunk-JPECA746.js → chunk-FUFFPIYA.js} +2 -2
  165. package/dist/cli-bundle/chunks/{chunk-CF7RL6FR.js → chunk-FZJM2TXF.js} +110 -73
  166. package/dist/cli-bundle/chunks/chunk-FZJM2TXF.js.map +1 -0
  167. package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js → chunk-GUYNUXQT.js} +3 -3
  168. package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js → chunk-GVJE5T7Q.js} +2 -2
  169. package/dist/cli-bundle/chunks/{chunk-3J6JRJ3I.js → chunk-HB4FAT3O.js} +42 -60
  170. package/dist/cli-bundle/chunks/chunk-HB4FAT3O.js.map +7 -0
  171. package/dist/cli-bundle/chunks/{chunk-55SNVXRQ.js → chunk-HQAF23Q2.js} +626 -484
  172. package/dist/cli-bundle/chunks/chunk-HQAF23Q2.js.map +7 -0
  173. package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js → chunk-JBZ2NTKX.js} +2 -2
  174. package/dist/cli-bundle/chunks/{chunk-RMMQ74TG.js → chunk-JPATY4SE.js} +54 -30
  175. package/dist/cli-bundle/chunks/chunk-JPATY4SE.js.map +7 -0
  176. package/dist/cli-bundle/chunks/{chunk-IPYBJWTE.js → chunk-K5DT2YKM.js} +109 -72
  177. package/dist/cli-bundle/chunks/chunk-K5DT2YKM.js.map +7 -0
  178. package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js → chunk-KEZOIPCR.js} +3 -3
  179. package/dist/cli-bundle/chunks/{chunk-RVUALSJF.js → chunk-KHVGM5CS.js} +466 -365
  180. package/dist/cli-bundle/chunks/chunk-KHVGM5CS.js.map +7 -0
  181. package/dist/cli-bundle/chunks/{chunk-YITK2PJ6.js → chunk-KS6ATO47.js} +288 -175
  182. package/dist/cli-bundle/chunks/chunk-KS6ATO47.js.map +7 -0
  183. package/dist/cli-bundle/chunks/{chunk-7R4QEMZZ.js → chunk-L4SLHV6G.js} +463 -362
  184. package/dist/cli-bundle/chunks/chunk-L4SLHV6G.js.map +1 -0
  185. package/dist/cli-bundle/chunks/{chunk-RLDHZHQS.js → chunk-LBE5QFMZ.js} +158 -114
  186. package/dist/cli-bundle/chunks/chunk-LBE5QFMZ.js.map +1 -0
  187. package/dist/cli-bundle/chunks/{chunk-22WKIL3H.js → chunk-LCWQP6NM.js} +76 -54
  188. package/dist/cli-bundle/chunks/chunk-LCWQP6NM.js.map +1 -0
  189. package/dist/cli-bundle/chunks/{chunk-KNPEF7QG.js → chunk-LOWVNZBZ.js} +91 -76
  190. package/dist/cli-bundle/chunks/chunk-LOWVNZBZ.js.map +7 -0
  191. package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js → chunk-MDHWWBNZ.js} +3 -3
  192. package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js → chunk-MEZZZBYX.js} +2 -2
  193. package/dist/cli-bundle/chunks/{chunk-V3NOKJF2.js → chunk-MHRS5FUX.js} +288 -175
  194. package/dist/cli-bundle/chunks/chunk-MHRS5FUX.js.map +1 -0
  195. package/dist/cli-bundle/chunks/{chunk-3XZCOZ5J.js → chunk-NOIEVOK5.js} +391 -313
  196. package/dist/cli-bundle/chunks/chunk-NOIEVOK5.js.map +1 -0
  197. package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js → chunk-NZ7QIUP5.js} +4 -4
  198. package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js → chunk-OGLGI22K.js} +115 -67
  199. package/dist/cli-bundle/chunks/{chunk-UYUYDGIB.js.map → chunk-OGLGI22K.js.map} +1 -1
  200. package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js → chunk-P5L7Z2O6.js} +2 -2
  201. package/dist/cli-bundle/chunks/{chunk-BZCEN4JA.js → chunk-PULUSQAV.js} +492 -403
  202. package/dist/cli-bundle/chunks/chunk-PULUSQAV.js.map +7 -0
  203. package/dist/cli-bundle/chunks/{chunk-3VGN2UWE.js → chunk-QCDTQCMW.js} +22 -30
  204. package/dist/cli-bundle/chunks/chunk-QCDTQCMW.js.map +1 -0
  205. package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js → chunk-QNNQAAZ5.js} +24 -18
  206. package/dist/cli-bundle/chunks/{chunk-4A3BJ675.js.map → chunk-QNNQAAZ5.js.map} +1 -1
  207. package/dist/cli-bundle/chunks/{chunk-MDPEOIGN.js → chunk-RAHINBVP.js} +60 -101
  208. package/dist/cli-bundle/chunks/chunk-RAHINBVP.js.map +7 -0
  209. package/dist/cli-bundle/chunks/{chunk-CWFNTKQJ.js → chunk-RJH5VQHW.js} +43 -61
  210. package/dist/cli-bundle/chunks/chunk-RJH5VQHW.js.map +1 -0
  211. package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js → chunk-SU2E4AWU.js} +6 -6
  212. package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js → chunk-SU3TB4NS.js} +2 -2
  213. package/dist/cli-bundle/chunks/{chunk-JWXRETDF.js → chunk-SYE6WMV6.js} +626 -484
  214. package/dist/cli-bundle/chunks/chunk-SYE6WMV6.js.map +1 -0
  215. package/dist/cli-bundle/chunks/{chunk-NWMZWYYB.js → chunk-T3P7PMZP.js} +42 -27
  216. package/dist/cli-bundle/chunks/chunk-T3P7PMZP.js.map +1 -0
  217. package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js → chunk-T4XBKJ3F.js} +4 -4
  218. package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js → chunk-T6AXEBOP.js} +23 -17
  219. package/dist/cli-bundle/chunks/{chunk-RH5ZBYFD.js.map → chunk-T6AXEBOP.js.map} +2 -2
  220. package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js → chunk-TQ6AX5SQ.js} +58 -69
  221. package/dist/cli-bundle/chunks/{chunk-5QFDBI4F.js.map → chunk-TQ6AX5SQ.js.map} +2 -2
  222. package/dist/cli-bundle/chunks/{chunk-4XOIEKSD.js → chunk-U3S2B7TA.js} +86 -52
  223. package/dist/cli-bundle/chunks/chunk-U3S2B7TA.js.map +1 -0
  224. package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js → chunk-U5TR4N7J.js} +7 -7
  225. package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js → chunk-UMNQZS4H.js} +3 -3
  226. package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js → chunk-WJA3PXW7.js} +7 -7
  227. package/dist/cli-bundle/chunks/{chunk-RGEMWD6Q.js → chunk-WRYERRZX.js} +157 -118
  228. package/dist/cli-bundle/chunks/chunk-WRYERRZX.js.map +7 -0
  229. package/dist/cli-bundle/chunks/{chunk-NUHHPVVS.js → chunk-WYOIIFSE.js} +712 -612
  230. package/dist/cli-bundle/chunks/chunk-WYOIIFSE.js.map +7 -0
  231. package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js → chunk-XRYSCRZR.js} +116 -68
  232. package/dist/cli-bundle/chunks/{chunk-4DSGXSBL.js.map → chunk-XRYSCRZR.js.map} +3 -3
  233. package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js → chunk-YF746GTH.js} +59 -70
  234. package/dist/cli-bundle/chunks/{chunk-NU2UEROZ.js.map → chunk-YF746GTH.js.map} +1 -1
  235. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js → chunk-YPWUSH72.js} +390 -312
  236. package/dist/cli-bundle/chunks/{chunk-JMP4E6D7.js.map → chunk-YPWUSH72.js.map} +2 -2
  237. package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js → chunk-YSDFIY7N.js} +3 -3
  238. package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js → chunk-YSGTMDWC.js} +2 -2
  239. package/dist/cli-bundle/chunks/{chunk-NFDPYAIP.js → chunk-YVKZ3ANP.js} +21 -29
  240. package/dist/cli-bundle/chunks/chunk-YVKZ3ANP.js.map +7 -0
  241. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js → chunk-Z4DGFQDH.js} +80 -58
  242. package/dist/cli-bundle/chunks/{chunk-OKQ22KTH.js.map → chunk-Z4DGFQDH.js.map} +1 -1
  243. package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js → chunk-Z5F6XZXE.js} +6 -6
  244. package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js → chunk-Z7RPDF2Y.js} +3 -3
  245. package/dist/cli-bundle/chunks/{chunk-3S2KT7NG.js → chunk-ZFTKYWIF.js} +152 -89
  246. package/dist/cli-bundle/chunks/chunk-ZFTKYWIF.js.map +7 -0
  247. package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js → claim-2BGBGSVI.js} +8 -8
  248. package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js → claim-5GU7OE67.js} +8 -8
  249. package/dist/cli-bundle/chunks/close-6YODBUIV.js +14 -0
  250. package/dist/cli-bundle/chunks/{close-TQYAAFJP.js → close-AFVKPR57.js} +7 -7
  251. package/dist/cli-bundle/chunks/{close-many-BG5QQIDQ.js → close-many-7KLOSYLP.js} +186 -122
  252. package/dist/cli-bundle/chunks/close-many-7KLOSYLP.js.map +7 -0
  253. package/dist/cli-bundle/chunks/{close-many-LDRVEQY2.js → close-many-JKUJMHLG.js} +187 -123
  254. package/dist/cli-bundle/chunks/close-many-JKUJMHLG.js.map +1 -0
  255. package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js → comments-DNWHEBOS.js} +9 -9
  256. package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js → comments-RW23R3VE.js} +9 -9
  257. package/dist/cli-bundle/chunks/config-AUM5WBYA.js +1072 -0
  258. package/dist/cli-bundle/chunks/config-AUM5WBYA.js.map +7 -0
  259. package/dist/cli-bundle/chunks/config-OZWSA2NP.js +1062 -0
  260. package/dist/cli-bundle/chunks/config-OZWSA2NP.js.map +1 -0
  261. package/dist/cli-bundle/chunks/{context-B6275WPX.js → context-OYXRGY7S.js} +12 -12
  262. package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js → context-PKCEHQY3.js} +12 -12
  263. package/dist/cli-bundle/chunks/{contracts-HN7ABKLP.js → contracts-L6ODXNUM.js} +320 -199
  264. package/dist/cli-bundle/chunks/contracts-L6ODXNUM.js.map +7 -0
  265. package/dist/cli-bundle/chunks/{contracts-W4FZVVD6.js → contracts-X74F2GSM.js} +321 -200
  266. package/dist/cli-bundle/chunks/contracts-X74F2GSM.js.map +1 -0
  267. package/dist/cli-bundle/chunks/{copy-DEM4DATS.js → copy-6XOR3HKN.js} +5 -5
  268. package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js → copy-I4NCLBR4.js} +5 -5
  269. package/dist/cli-bundle/chunks/{create-RLRJMRTM.js → create-PM45M6PE.js} +12 -12
  270. package/dist/cli-bundle/chunks/create-Z7YCH3BE.js +28 -0
  271. package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js → delete-7YXHYG67.js} +5 -5
  272. package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js → delete-LPISP43T.js} +5 -5
  273. package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js → deps-N2T26FME.js} +5 -5
  274. package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js → deps-WATKQDE3.js} +5 -5
  275. package/dist/cli-bundle/chunks/{docs-GYZNVS26.js → docs-6LQ3GLM7.js} +7 -7
  276. package/dist/cli-bundle/chunks/{docs-26S44RXU.js → docs-Z3X6JZLT.js} +7 -7
  277. package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js → eval-6DCLG52D.js} +10 -10
  278. package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js → eval-Y3ZCUTHK.js} +10 -10
  279. package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js → extension-BNINIMT7.js} +11 -11
  280. package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js → extension-QWE4YYK5.js} +11 -11
  281. package/dist/cli-bundle/chunks/{files-NQHEXUZD.js → files-6SGKHS6O.js} +7 -7
  282. package/dist/cli-bundle/chunks/{files-MBNICQFM.js → files-FUYPSOFJ.js} +7 -7
  283. package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js → focus-2Q3K76G2.js} +6 -6
  284. package/dist/cli-bundle/chunks/{focus-XZW5423D.js → focus-ATLBWXXD.js} +6 -6
  285. package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js → gc-RUYEMNRF.js} +3 -3
  286. package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js → gc-TDWSDR66.js} +3 -3
  287. package/dist/cli-bundle/chunks/{get-A7MAOHCU.js → get-2WGLX74N.js} +120 -80
  288. package/dist/cli-bundle/chunks/get-2WGLX74N.js.map +7 -0
  289. package/dist/cli-bundle/chunks/{get-DSDEKJ3L.js → get-LY6M2JIM.js} +121 -81
  290. package/dist/cli-bundle/chunks/get-LY6M2JIM.js.map +1 -0
  291. package/dist/cli-bundle/chunks/{health-3IPFLKXB.js → health-4RKHYS3T.js} +535 -371
  292. package/dist/cli-bundle/chunks/health-4RKHYS3T.js.map +1 -0
  293. package/dist/cli-bundle/chunks/{health-GZXGBZ36.js → health-TMFVNYRA.js} +534 -370
  294. package/dist/cli-bundle/chunks/health-TMFVNYRA.js.map +7 -0
  295. package/dist/cli-bundle/chunks/history-CGNQJXFE.js +18 -0
  296. package/dist/cli-bundle/chunks/{history-NERDJNUB.js → history-SGRRS72R.js} +8 -8
  297. package/dist/cli-bundle/chunks/{history-compact-2WRZ2WK4.js → history-compact-LOED43R3.js} +213 -134
  298. package/dist/cli-bundle/chunks/history-compact-LOED43R3.js.map +7 -0
  299. package/dist/cli-bundle/chunks/{history-compact-HR7BB4LR.js → history-compact-V5DNAQHH.js} +214 -135
  300. package/dist/cli-bundle/chunks/history-compact-V5DNAQHH.js.map +1 -0
  301. package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js → history-redact-IRL7WJ3E.js} +9 -9
  302. package/dist/cli-bundle/chunks/history-redact-N3JK7VBW.js +19 -0
  303. package/dist/cli-bundle/chunks/{history-repair-XA3LC4GA.js → history-repair-4WVBVHFR.js} +124 -84
  304. package/dist/cli-bundle/chunks/history-repair-4WVBVHFR.js.map +1 -0
  305. package/dist/cli-bundle/chunks/{history-repair-LCMOS45X.js → history-repair-PGYQJMGD.js} +123 -83
  306. package/dist/cli-bundle/chunks/history-repair-PGYQJMGD.js.map +7 -0
  307. package/dist/cli-bundle/chunks/{init-64XDLQJB.js → init-4GESW7RM.js} +12 -12
  308. package/dist/cli-bundle/chunks/init-XIDPABA4.js +22 -0
  309. package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js → learnings-4BHWFFUV.js} +9 -9
  310. package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js → learnings-4FJY7WIW.js} +9 -9
  311. package/dist/cli-bundle/chunks/{list-G5Y65VF6.js → list-472TIOVK.js} +8 -8
  312. package/dist/cli-bundle/chunks/{list-DNBJVO3E.js → list-D7BF5CL2.js} +8 -8
  313. package/dist/cli-bundle/chunks/{next-FYTQF6HG.js → next-D5STGWI2.js} +71 -46
  314. package/dist/cli-bundle/chunks/next-D5STGWI2.js.map +1 -0
  315. package/dist/cli-bundle/chunks/{next-BCERKDUR.js → next-SFQZVX2B.js} +70 -45
  316. package/dist/cli-bundle/chunks/next-SFQZVX2B.js.map +7 -0
  317. package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js → notes-6KNOSLIT.js} +9 -9
  318. package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js → notes-W4UEICGF.js} +9 -9
  319. package/dist/cli-bundle/chunks/{plan-RKZHQVXR.js → plan-JO6V7BXO.js} +373 -279
  320. package/dist/cli-bundle/chunks/plan-JO6V7BXO.js.map +1 -0
  321. package/dist/cli-bundle/chunks/{plan-4WXEQCTN.js → plan-MJQW5XK3.js} +372 -278
  322. package/dist/cli-bundle/chunks/plan-MJQW5XK3.js.map +7 -0
  323. package/dist/cli-bundle/chunks/{profile-4OMM32CD.js → profile-3TOTMUR4.js} +27 -19
  324. package/dist/cli-bundle/chunks/profile-3TOTMUR4.js.map +7 -0
  325. package/dist/cli-bundle/chunks/{profile-QLER5ENE.js → profile-WIQY2KCV.js} +28 -20
  326. package/dist/cli-bundle/chunks/profile-WIQY2KCV.js.map +1 -0
  327. package/dist/cli-bundle/chunks/register-list-query-ELBHCCFI.js +416 -0
  328. package/dist/cli-bundle/chunks/register-list-query-ELBHCCFI.js.map +7 -0
  329. package/dist/cli-bundle/chunks/register-list-query-GAPQ6DM3.js +406 -0
  330. package/dist/cli-bundle/chunks/register-list-query-GAPQ6DM3.js.map +1 -0
  331. package/dist/cli-bundle/chunks/{register-mutation-KK7PHYYU.js → register-mutation-ROFE2YPC.js} +729 -702
  332. package/dist/cli-bundle/chunks/register-mutation-ROFE2YPC.js.map +7 -0
  333. package/dist/cli-bundle/chunks/{register-mutation-ENNDUAZG.js → register-mutation-SJWMVIJ2.js} +730 -703
  334. package/dist/cli-bundle/chunks/register-mutation-SJWMVIJ2.js.map +1 -0
  335. package/dist/cli-bundle/chunks/{register-operations-HZ6XERQG.js → register-operations-IADFVH53.js} +389 -365
  336. package/dist/cli-bundle/chunks/register-operations-IADFVH53.js.map +7 -0
  337. package/dist/cli-bundle/chunks/register-operations-MEKU3AKC.js +510 -0
  338. package/dist/cli-bundle/chunks/register-operations-MEKU3AKC.js.map +1 -0
  339. package/dist/cli-bundle/chunks/{register-setup-ZKJ53RS7.js → register-setup-3QJY43CY.js} +128 -103
  340. package/dist/cli-bundle/chunks/register-setup-3QJY43CY.js.map +7 -0
  341. package/dist/cli-bundle/chunks/{register-setup-P67EMBDJ.js → register-setup-AJWUSSQX.js} +129 -104
  342. package/dist/cli-bundle/chunks/register-setup-AJWUSSQX.js.map +1 -0
  343. package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js → restore-44IHMMZZ.js} +9 -9
  344. package/dist/cli-bundle/chunks/restore-EXHU34EU.js +17 -0
  345. package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js → scheduling-shortcuts-OLHNLAZY.js} +12 -12
  346. package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js → scheduling-shortcuts-TSBK4AY5.js} +12 -12
  347. package/dist/cli-bundle/chunks/{schema-73HR2OJW.js → schema-IB2NZZWD.js} +7 -7
  348. package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js → schema-VBCELP5G.js} +7 -7
  349. package/dist/cli-bundle/chunks/{search-AXPXKZER.js → search-7UBETML4.js} +10 -10
  350. package/dist/cli-bundle/chunks/{search-KILGT37L.js → search-R227JOL6.js} +10 -10
  351. package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js → stats-FAG7COEH.js} +6 -6
  352. package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js → stats-MCK7PLYS.js} +6 -6
  353. package/dist/cli-bundle/chunks/{telemetry-GAHHQTOS.js → telemetry-DRPDZMAO.js} +84 -70
  354. package/dist/cli-bundle/chunks/telemetry-DRPDZMAO.js.map +7 -0
  355. package/dist/cli-bundle/chunks/{telemetry-BZUF6H7G.js → telemetry-GVVUQSJQ.js} +85 -71
  356. package/dist/cli-bundle/chunks/telemetry-GVVUQSJQ.js.map +1 -0
  357. package/dist/cli-bundle/chunks/{test-PWDIZ255.js → test-QY44WAMR.js} +15 -15
  358. package/dist/cli-bundle/chunks/{test-ACD52Z3S.js → test-SY76DZTO.js} +15 -15
  359. package/dist/cli-bundle/chunks/test-all-QD6QAEG7.js +430 -0
  360. package/dist/cli-bundle/chunks/test-all-QD6QAEG7.js.map +7 -0
  361. package/dist/cli-bundle/chunks/test-all-USPJHXFR.js +427 -0
  362. package/dist/cli-bundle/chunks/test-all-USPJHXFR.js.map +1 -0
  363. package/dist/cli-bundle/chunks/{test-runs-UXIXPDKU.js → test-runs-MG5VIGSK.js} +185 -147
  364. package/dist/cli-bundle/chunks/test-runs-MG5VIGSK.js.map +1 -0
  365. package/dist/cli-bundle/chunks/{test-runs-PLRAZEFW.js → test-runs-QIR5MJPL.js} +184 -146
  366. package/dist/cli-bundle/chunks/test-runs-QIR5MJPL.js.map +7 -0
  367. package/dist/cli-bundle/chunks/update-A7EICML6.js +24 -0
  368. package/dist/cli-bundle/chunks/{update-KFX2SIAC.js → update-IKJZWLQC.js} +15 -15
  369. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js → update-many-BEMTDA2X.js} +84 -69
  370. package/dist/cli-bundle/chunks/{update-many-RNSBX2TA.js.map → update-many-BEMTDA2X.js.map} +1 -1
  371. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js → update-many-RATAARHU.js} +83 -68
  372. package/dist/cli-bundle/chunks/{update-many-Z5GJS5LC.js.map → update-many-RATAARHU.js.map} +2 -2
  373. package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js → upgrade-NWMR3VQL.js} +11 -11
  374. package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js → upgrade-VU46BLJZ.js} +11 -11
  375. package/dist/cli-bundle/chunks/{validate-X5W76YJL.js → validate-GAJ6FUSI.js} +451 -321
  376. package/dist/cli-bundle/chunks/validate-GAJ6FUSI.js.map +1 -0
  377. package/dist/cli-bundle/chunks/{validate-MTUVL5VC.js → validate-NRY6MFXN.js} +450 -320
  378. package/dist/cli-bundle/chunks/validate-NRY6MFXN.js.map +7 -0
  379. package/dist/cli-bundle/main.js +1107 -916
  380. package/dist/cli-bundle/main.js.map +3 -3
  381. package/dist/core/config/nested-settings.js +89 -67
  382. package/dist/core/config/nested-settings.js.map +1 -1
  383. package/dist/core/governance/metadata-coverage.js +20 -28
  384. package/dist/core/governance/metadata-coverage.js.map +1 -1
  385. package/dist/core/history/drift-scan.js +93 -81
  386. package/dist/core/history/drift-scan.js.map +1 -1
  387. package/dist/core/item/item-type-definition.js +14 -14
  388. package/dist/core/item/item-type-definition.js.map +1 -1
  389. package/dist/core/item/type-registry.js +114 -99
  390. package/dist/core/item/type-registry.js.map +1 -1
  391. package/dist/core/output/mutation-projection.js +42 -26
  392. package/dist/core/output/mutation-projection.js.map +1 -1
  393. package/dist/core/schema/runtime-schema.js +97 -80
  394. package/dist/core/schema/runtime-schema.js.map +1 -1
  395. package/dist/core/schema/status-defs-file.js +26 -3
  396. package/dist/core/schema/status-defs-file.js.map +1 -1
  397. package/dist/core/search/corpus.js +25 -19
  398. package/dist/core/search/corpus.js.map +1 -1
  399. package/dist/core/search/semantic-defaults.js +64 -37
  400. package/dist/core/search/semantic-defaults.js.map +1 -1
  401. package/dist/core/search/vector-stores.js +32 -17
  402. package/dist/core/search/vector-stores.js.map +1 -1
  403. package/dist/core/sentry/helpers.js +31 -28
  404. package/dist/core/sentry/helpers.js.map +1 -1
  405. package/dist/core/sentry/instrument.js +54 -43
  406. package/dist/core/sentry/instrument.js.map +1 -1
  407. package/dist/core/shared/memo.d.ts +12 -0
  408. package/dist/core/shared/memo.js +25 -0
  409. package/dist/core/shared/memo.js.map +1 -0
  410. package/dist/core/shared/serialization.js +24 -14
  411. package/dist/core/shared/serialization.js.map +1 -1
  412. package/dist/core/shared/time.js +26 -4
  413. package/dist/core/shared/time.js.map +1 -1
  414. package/dist/core/store/front-matter-cache.d.ts +5 -0
  415. package/dist/core/store/front-matter-cache.js +316 -171
  416. package/dist/core/store/front-matter-cache.js.map +1 -1
  417. package/dist/core/store/item-store.js +33 -26
  418. package/dist/core/store/item-store.js.map +1 -1
  419. package/dist/core/store/settings.js +247 -203
  420. package/dist/core/store/settings.js.map +1 -1
  421. package/dist/core/test/background-runs.js +189 -160
  422. package/dist/core/test/background-runs.js.map +1 -1
  423. package/dist/sdk/cli-contracts/flag-contracts.js +71 -99
  424. package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
  425. package/dist/sdk/compose.js +51 -42
  426. package/dist/sdk/compose.js.map +1 -1
  427. package/docs/AGENT_GUIDE.md +2 -2
  428. package/docs/ARCHITECTURE.md +2 -2
  429. package/docs/COMMANDS.md +8 -4
  430. package/docs/CONFIGURATION.md +1 -1
  431. package/docs/EXTENSIONS.md +12 -12
  432. package/docs/ONBOARDING.md +4 -2
  433. package/docs/README.md +2 -0
  434. package/docs/examples/starter-extension/README.md +11 -10
  435. package/marketplace.json +3 -3
  436. package/package.json +2 -2
  437. package/packages/pm-beads/extensions/beads/runtime.ts +240 -167
  438. package/packages/pm-guide-shell/extensions/guide-shell/runtime.ts +65 -58
  439. package/packages/pm-todos/extensions/todos/runtime.ts +65 -42
  440. package/plugins/pm-claude/.claude-plugin/plugin.json +2 -2
  441. package/plugins/pm-claude/README.md +6 -3
  442. package/plugins/pm-claude/commands/pm-init.md +1 -1
  443. package/dist/cli-bundle/chunks/activity-AW6XVFH6.js +0 -16
  444. package/dist/cli-bundle/chunks/aggregate-JTEF4BP7.js.map +0 -1
  445. package/dist/cli-bundle/chunks/chunk-22WKIL3H.js.map +0 -1
  446. package/dist/cli-bundle/chunks/chunk-2D4HATP2.js.map +0 -1
  447. package/dist/cli-bundle/chunks/chunk-3J6JRJ3I.js.map +0 -7
  448. package/dist/cli-bundle/chunks/chunk-3K2M5OYU.js.map +0 -7
  449. package/dist/cli-bundle/chunks/chunk-3S2KT7NG.js.map +0 -7
  450. package/dist/cli-bundle/chunks/chunk-3VGN2UWE.js.map +0 -1
  451. package/dist/cli-bundle/chunks/chunk-3XZCOZ5J.js.map +0 -1
  452. package/dist/cli-bundle/chunks/chunk-4XOIEKSD.js.map +0 -1
  453. package/dist/cli-bundle/chunks/chunk-55SNVXRQ.js.map +0 -7
  454. package/dist/cli-bundle/chunks/chunk-5CGRF3L5.js.map +0 -1
  455. package/dist/cli-bundle/chunks/chunk-7R4QEMZZ.js.map +0 -1
  456. package/dist/cli-bundle/chunks/chunk-AXIDKKAT.js.map +0 -1
  457. package/dist/cli-bundle/chunks/chunk-BDTISOSD.js.map +0 -7
  458. package/dist/cli-bundle/chunks/chunk-BZCEN4JA.js.map +0 -7
  459. package/dist/cli-bundle/chunks/chunk-CF7RL6FR.js.map +0 -1
  460. package/dist/cli-bundle/chunks/chunk-CWFNTKQJ.js.map +0 -1
  461. package/dist/cli-bundle/chunks/chunk-FFMQB7WR.js.map +0 -1
  462. package/dist/cli-bundle/chunks/chunk-HXTQJXWT.js.map +0 -1
  463. package/dist/cli-bundle/chunks/chunk-IPYBJWTE.js.map +0 -7
  464. package/dist/cli-bundle/chunks/chunk-IZBR4NRW.js.map +0 -7
  465. package/dist/cli-bundle/chunks/chunk-JLM7BHI7.js.map +0 -7
  466. package/dist/cli-bundle/chunks/chunk-JSU5P7VS.js.map +0 -1
  467. package/dist/cli-bundle/chunks/chunk-JWXRETDF.js.map +0 -1
  468. package/dist/cli-bundle/chunks/chunk-KNPEF7QG.js.map +0 -7
  469. package/dist/cli-bundle/chunks/chunk-MDPEOIGN.js.map +0 -7
  470. package/dist/cli-bundle/chunks/chunk-NFDPYAIP.js.map +0 -7
  471. package/dist/cli-bundle/chunks/chunk-NUHHPVVS.js.map +0 -7
  472. package/dist/cli-bundle/chunks/chunk-NWMZWYYB.js.map +0 -1
  473. package/dist/cli-bundle/chunks/chunk-OTUHB4HS.js.map +0 -1
  474. package/dist/cli-bundle/chunks/chunk-RGEMWD6Q.js.map +0 -7
  475. package/dist/cli-bundle/chunks/chunk-RLDHZHQS.js.map +0 -1
  476. package/dist/cli-bundle/chunks/chunk-RMMQ74TG.js.map +0 -7
  477. package/dist/cli-bundle/chunks/chunk-RVUALSJF.js.map +0 -7
  478. package/dist/cli-bundle/chunks/chunk-TP5Q5ZD3.js.map +0 -1
  479. package/dist/cli-bundle/chunks/chunk-V3NOKJF2.js.map +0 -1
  480. package/dist/cli-bundle/chunks/chunk-VARHOHYV.js.map +0 -7
  481. package/dist/cli-bundle/chunks/chunk-WYDHYJPO.js.map +0 -7
  482. package/dist/cli-bundle/chunks/chunk-YITK2PJ6.js.map +0 -7
  483. package/dist/cli-bundle/chunks/chunk-ZETXE4SE.js.map +0 -1
  484. package/dist/cli-bundle/chunks/close-E6ZZGCJY.js +0 -14
  485. package/dist/cli-bundle/chunks/close-many-BG5QQIDQ.js.map +0 -7
  486. package/dist/cli-bundle/chunks/close-many-LDRVEQY2.js.map +0 -1
  487. package/dist/cli-bundle/chunks/config-DMSU64QO.js +0 -1541
  488. package/dist/cli-bundle/chunks/config-DMSU64QO.js.map +0 -7
  489. package/dist/cli-bundle/chunks/config-QH2DICD6.js +0 -1531
  490. package/dist/cli-bundle/chunks/config-QH2DICD6.js.map +0 -1
  491. package/dist/cli-bundle/chunks/contracts-HN7ABKLP.js.map +0 -7
  492. package/dist/cli-bundle/chunks/contracts-W4FZVVD6.js.map +0 -1
  493. package/dist/cli-bundle/chunks/create-OH3BDGBB.js +0 -28
  494. package/dist/cli-bundle/chunks/get-A7MAOHCU.js.map +0 -7
  495. package/dist/cli-bundle/chunks/get-DSDEKJ3L.js.map +0 -1
  496. package/dist/cli-bundle/chunks/health-3IPFLKXB.js.map +0 -1
  497. package/dist/cli-bundle/chunks/health-GZXGBZ36.js.map +0 -7
  498. package/dist/cli-bundle/chunks/history-WSZHY3PN.js +0 -18
  499. package/dist/cli-bundle/chunks/history-compact-2WRZ2WK4.js.map +0 -7
  500. package/dist/cli-bundle/chunks/history-compact-HR7BB4LR.js.map +0 -1
  501. package/dist/cli-bundle/chunks/history-redact-MP6CH7U5.js +0 -19
  502. package/dist/cli-bundle/chunks/history-repair-LCMOS45X.js.map +0 -7
  503. package/dist/cli-bundle/chunks/history-repair-XA3LC4GA.js.map +0 -1
  504. package/dist/cli-bundle/chunks/init-PAX32BJA.js +0 -22
  505. package/dist/cli-bundle/chunks/next-BCERKDUR.js.map +0 -7
  506. package/dist/cli-bundle/chunks/next-FYTQF6HG.js.map +0 -1
  507. package/dist/cli-bundle/chunks/plan-4WXEQCTN.js.map +0 -7
  508. package/dist/cli-bundle/chunks/plan-RKZHQVXR.js.map +0 -1
  509. package/dist/cli-bundle/chunks/profile-4OMM32CD.js.map +0 -7
  510. package/dist/cli-bundle/chunks/profile-QLER5ENE.js.map +0 -1
  511. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js +0 -400
  512. package/dist/cli-bundle/chunks/register-list-query-7LV46VAU.js.map +0 -1
  513. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js +0 -410
  514. package/dist/cli-bundle/chunks/register-list-query-SNG5PGA4.js.map +0 -7
  515. package/dist/cli-bundle/chunks/register-mutation-ENNDUAZG.js.map +0 -1
  516. package/dist/cli-bundle/chunks/register-mutation-KK7PHYYU.js.map +0 -7
  517. package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js +0 -486
  518. package/dist/cli-bundle/chunks/register-operations-C6OWLDSH.js.map +0 -1
  519. package/dist/cli-bundle/chunks/register-operations-HZ6XERQG.js.map +0 -7
  520. package/dist/cli-bundle/chunks/register-setup-P67EMBDJ.js.map +0 -1
  521. package/dist/cli-bundle/chunks/register-setup-ZKJ53RS7.js.map +0 -7
  522. package/dist/cli-bundle/chunks/restore-YALDGTQR.js +0 -17
  523. package/dist/cli-bundle/chunks/telemetry-BZUF6H7G.js.map +0 -1
  524. package/dist/cli-bundle/chunks/telemetry-GAHHQTOS.js.map +0 -7
  525. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js +0 -358
  526. package/dist/cli-bundle/chunks/test-all-L2MDDUCA.js.map +0 -1
  527. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js +0 -361
  528. package/dist/cli-bundle/chunks/test-all-RBZ6DLU2.js.map +0 -7
  529. package/dist/cli-bundle/chunks/test-runs-PLRAZEFW.js.map +0 -7
  530. package/dist/cli-bundle/chunks/test-runs-UXIXPDKU.js.map +0 -1
  531. package/dist/cli-bundle/chunks/update-AMRSOIWP.js +0 -24
  532. package/dist/cli-bundle/chunks/validate-MTUVL5VC.js.map +0 -7
  533. package/dist/cli-bundle/chunks/validate-X5W76YJL.js.map +0 -1
  534. /package/dist/cli-bundle/chunks/{activity-DBLQVIP6.js.map → activity-5YWLSPGE.js.map} +0 -0
  535. /package/dist/cli-bundle/chunks/{activity-AW6XVFH6.js.map → activity-BIML7K2D.js.map} +0 -0
  536. /package/dist/cli-bundle/chunks/{append-LOVPGVPT.js.map → append-EZESUVJT.js.map} +0 -0
  537. /package/dist/cli-bundle/chunks/{append-QCFJSDFL.js.map → append-JFG4WQMG.js.map} +0 -0
  538. /package/dist/cli-bundle/chunks/{chunk-BHO33VBQ.js.map → chunk-3W2HJKJX.js.map} +0 -0
  539. /package/dist/cli-bundle/chunks/{chunk-4DUVCVLZ.js.map → chunk-4PFVUUYV.js.map} +0 -0
  540. /package/dist/cli-bundle/chunks/{chunk-IJYK2T43.js.map → chunk-5E7N4T2Z.js.map} +0 -0
  541. /package/dist/cli-bundle/chunks/{chunk-NKZAN7BD.js.map → chunk-5IZUBZBR.js.map} +0 -0
  542. /package/dist/cli-bundle/chunks/{chunk-NOLPZMSV.js.map → chunk-5JIWFWOZ.js.map} +0 -0
  543. /package/dist/cli-bundle/chunks/{chunk-6AQZPVHQ.js.map → chunk-6CDCWKSX.js.map} +0 -0
  544. /package/dist/cli-bundle/chunks/{chunk-LB6TP6MC.js.map → chunk-6NYJGMTY.js.map} +0 -0
  545. /package/dist/cli-bundle/chunks/{chunk-SLMUGTK3.js.map → chunk-7CLLC75T.js.map} +0 -0
  546. /package/dist/cli-bundle/chunks/{chunk-2466X6E4.js.map → chunk-7LYO6S5A.js.map} +0 -0
  547. /package/dist/cli-bundle/chunks/{chunk-W4ULYO7Z.js.map → chunk-A3OQ7TFW.js.map} +0 -0
  548. /package/dist/cli-bundle/chunks/{chunk-GJ326ZKX.js.map → chunk-ER4ME5U2.js.map} +0 -0
  549. /package/dist/cli-bundle/chunks/{chunk-HZZEHPRG.js.map → chunk-ERG65A2L.js.map} +0 -0
  550. /package/dist/cli-bundle/chunks/{chunk-L5OEFZQG.js.map → chunk-FH2H3CBD.js.map} +0 -0
  551. /package/dist/cli-bundle/chunks/{chunk-JPECA746.js.map → chunk-FUFFPIYA.js.map} +0 -0
  552. /package/dist/cli-bundle/chunks/{chunk-27BXPBAY.js.map → chunk-GUYNUXQT.js.map} +0 -0
  553. /package/dist/cli-bundle/chunks/{chunk-MAUKX7JC.js.map → chunk-GVJE5T7Q.js.map} +0 -0
  554. /package/dist/cli-bundle/chunks/{chunk-ZRP4VG5U.js.map → chunk-JBZ2NTKX.js.map} +0 -0
  555. /package/dist/cli-bundle/chunks/{chunk-EJUDVUYZ.js.map → chunk-KEZOIPCR.js.map} +0 -0
  556. /package/dist/cli-bundle/chunks/{chunk-HYTGA6GI.js.map → chunk-MDHWWBNZ.js.map} +0 -0
  557. /package/dist/cli-bundle/chunks/{chunk-N74UMG5H.js.map → chunk-MEZZZBYX.js.map} +0 -0
  558. /package/dist/cli-bundle/chunks/{chunk-SDR5J34Q.js.map → chunk-NZ7QIUP5.js.map} +0 -0
  559. /package/dist/cli-bundle/chunks/{chunk-DDPTYJIM.js.map → chunk-P5L7Z2O6.js.map} +0 -0
  560. /package/dist/cli-bundle/chunks/{chunk-OGXLACHC.js.map → chunk-SU2E4AWU.js.map} +0 -0
  561. /package/dist/cli-bundle/chunks/{chunk-HPPFYYOV.js.map → chunk-SU3TB4NS.js.map} +0 -0
  562. /package/dist/cli-bundle/chunks/{chunk-G7I7DEZA.js.map → chunk-T4XBKJ3F.js.map} +0 -0
  563. /package/dist/cli-bundle/chunks/{chunk-VICZWYGZ.js.map → chunk-U5TR4N7J.js.map} +0 -0
  564. /package/dist/cli-bundle/chunks/{chunk-EVMTBV6V.js.map → chunk-UMNQZS4H.js.map} +0 -0
  565. /package/dist/cli-bundle/chunks/{chunk-A7FPBAQS.js.map → chunk-WJA3PXW7.js.map} +0 -0
  566. /package/dist/cli-bundle/chunks/{chunk-QCWF6IYD.js.map → chunk-YSDFIY7N.js.map} +0 -0
  567. /package/dist/cli-bundle/chunks/{chunk-UZIWVBE6.js.map → chunk-YSGTMDWC.js.map} +0 -0
  568. /package/dist/cli-bundle/chunks/{chunk-64HNBBFQ.js.map → chunk-Z5F6XZXE.js.map} +0 -0
  569. /package/dist/cli-bundle/chunks/{chunk-AVEE5EHK.js.map → chunk-Z7RPDF2Y.js.map} +0 -0
  570. /package/dist/cli-bundle/chunks/{claim-T3GCKV7C.js.map → claim-2BGBGSVI.js.map} +0 -0
  571. /package/dist/cli-bundle/chunks/{claim-EMQLYPRW.js.map → claim-5GU7OE67.js.map} +0 -0
  572. /package/dist/cli-bundle/chunks/{close-E6ZZGCJY.js.map → close-6YODBUIV.js.map} +0 -0
  573. /package/dist/cli-bundle/chunks/{close-TQYAAFJP.js.map → close-AFVKPR57.js.map} +0 -0
  574. /package/dist/cli-bundle/chunks/{comments-YUXJRZPQ.js.map → comments-DNWHEBOS.js.map} +0 -0
  575. /package/dist/cli-bundle/chunks/{comments-QCKR2YY2.js.map → comments-RW23R3VE.js.map} +0 -0
  576. /package/dist/cli-bundle/chunks/{context-B6275WPX.js.map → context-OYXRGY7S.js.map} +0 -0
  577. /package/dist/cli-bundle/chunks/{context-OCZ3FJ4Z.js.map → context-PKCEHQY3.js.map} +0 -0
  578. /package/dist/cli-bundle/chunks/{copy-DEM4DATS.js.map → copy-6XOR3HKN.js.map} +0 -0
  579. /package/dist/cli-bundle/chunks/{copy-BTJOSKKT.js.map → copy-I4NCLBR4.js.map} +0 -0
  580. /package/dist/cli-bundle/chunks/{create-RLRJMRTM.js.map → create-PM45M6PE.js.map} +0 -0
  581. /package/dist/cli-bundle/chunks/{create-OH3BDGBB.js.map → create-Z7YCH3BE.js.map} +0 -0
  582. /package/dist/cli-bundle/chunks/{delete-BHK7VB2Z.js.map → delete-7YXHYG67.js.map} +0 -0
  583. /package/dist/cli-bundle/chunks/{delete-LSVHAB4Y.js.map → delete-LPISP43T.js.map} +0 -0
  584. /package/dist/cli-bundle/chunks/{deps-XHYXWEPT.js.map → deps-N2T26FME.js.map} +0 -0
  585. /package/dist/cli-bundle/chunks/{deps-4UDFJRUA.js.map → deps-WATKQDE3.js.map} +0 -0
  586. /package/dist/cli-bundle/chunks/{docs-GYZNVS26.js.map → docs-6LQ3GLM7.js.map} +0 -0
  587. /package/dist/cli-bundle/chunks/{docs-26S44RXU.js.map → docs-Z3X6JZLT.js.map} +0 -0
  588. /package/dist/cli-bundle/chunks/{eval-UYF3ZPVO.js.map → eval-6DCLG52D.js.map} +0 -0
  589. /package/dist/cli-bundle/chunks/{eval-PGRVIJQU.js.map → eval-Y3ZCUTHK.js.map} +0 -0
  590. /package/dist/cli-bundle/chunks/{extension-CPSLJQVE.js.map → extension-BNINIMT7.js.map} +0 -0
  591. /package/dist/cli-bundle/chunks/{extension-CXJ6RELI.js.map → extension-QWE4YYK5.js.map} +0 -0
  592. /package/dist/cli-bundle/chunks/{files-NQHEXUZD.js.map → files-6SGKHS6O.js.map} +0 -0
  593. /package/dist/cli-bundle/chunks/{files-MBNICQFM.js.map → files-FUYPSOFJ.js.map} +0 -0
  594. /package/dist/cli-bundle/chunks/{focus-DWYIG7GU.js.map → focus-2Q3K76G2.js.map} +0 -0
  595. /package/dist/cli-bundle/chunks/{focus-XZW5423D.js.map → focus-ATLBWXXD.js.map} +0 -0
  596. /package/dist/cli-bundle/chunks/{gc-LPVMKJQJ.js.map → gc-RUYEMNRF.js.map} +0 -0
  597. /package/dist/cli-bundle/chunks/{gc-7GQYOS2G.js.map → gc-TDWSDR66.js.map} +0 -0
  598. /package/dist/cli-bundle/chunks/{history-WSZHY3PN.js.map → history-CGNQJXFE.js.map} +0 -0
  599. /package/dist/cli-bundle/chunks/{history-NERDJNUB.js.map → history-SGRRS72R.js.map} +0 -0
  600. /package/dist/cli-bundle/chunks/{history-redact-O3NBCNWC.js.map → history-redact-IRL7WJ3E.js.map} +0 -0
  601. /package/dist/cli-bundle/chunks/{history-redact-MP6CH7U5.js.map → history-redact-N3JK7VBW.js.map} +0 -0
  602. /package/dist/cli-bundle/chunks/{init-64XDLQJB.js.map → init-4GESW7RM.js.map} +0 -0
  603. /package/dist/cli-bundle/chunks/{init-PAX32BJA.js.map → init-XIDPABA4.js.map} +0 -0
  604. /package/dist/cli-bundle/chunks/{learnings-LPKCSJX7.js.map → learnings-4BHWFFUV.js.map} +0 -0
  605. /package/dist/cli-bundle/chunks/{learnings-JR6MA5TI.js.map → learnings-4FJY7WIW.js.map} +0 -0
  606. /package/dist/cli-bundle/chunks/{list-G5Y65VF6.js.map → list-472TIOVK.js.map} +0 -0
  607. /package/dist/cli-bundle/chunks/{list-DNBJVO3E.js.map → list-D7BF5CL2.js.map} +0 -0
  608. /package/dist/cli-bundle/chunks/{notes-2BMU3VVQ.js.map → notes-6KNOSLIT.js.map} +0 -0
  609. /package/dist/cli-bundle/chunks/{notes-6KTGO2OJ.js.map → notes-W4UEICGF.js.map} +0 -0
  610. /package/dist/cli-bundle/chunks/{restore-4MHZFJ2E.js.map → restore-44IHMMZZ.js.map} +0 -0
  611. /package/dist/cli-bundle/chunks/{restore-YALDGTQR.js.map → restore-EXHU34EU.js.map} +0 -0
  612. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-LB6DOLRL.js.map → scheduling-shortcuts-OLHNLAZY.js.map} +0 -0
  613. /package/dist/cli-bundle/chunks/{scheduling-shortcuts-UTOYKLXQ.js.map → scheduling-shortcuts-TSBK4AY5.js.map} +0 -0
  614. /package/dist/cli-bundle/chunks/{schema-73HR2OJW.js.map → schema-IB2NZZWD.js.map} +0 -0
  615. /package/dist/cli-bundle/chunks/{schema-U6LJKSIR.js.map → schema-VBCELP5G.js.map} +0 -0
  616. /package/dist/cli-bundle/chunks/{search-AXPXKZER.js.map → search-7UBETML4.js.map} +0 -0
  617. /package/dist/cli-bundle/chunks/{search-KILGT37L.js.map → search-R227JOL6.js.map} +0 -0
  618. /package/dist/cli-bundle/chunks/{stats-W5KNVJWQ.js.map → stats-FAG7COEH.js.map} +0 -0
  619. /package/dist/cli-bundle/chunks/{stats-PSYVVTNZ.js.map → stats-MCK7PLYS.js.map} +0 -0
  620. /package/dist/cli-bundle/chunks/{test-PWDIZ255.js.map → test-QY44WAMR.js.map} +0 -0
  621. /package/dist/cli-bundle/chunks/{test-ACD52Z3S.js.map → test-SY76DZTO.js.map} +0 -0
  622. /package/dist/cli-bundle/chunks/{update-AMRSOIWP.js.map → update-A7EICML6.js.map} +0 -0
  623. /package/dist/cli-bundle/chunks/{update-KFX2SIAC.js.map → update-IKJZWLQC.js.map} +0 -0
  624. /package/dist/cli-bundle/chunks/{upgrade-BRL6KCOJ.js.map → upgrade-NWMR3VQL.js.map} +0 -0
  625. /package/dist/cli-bundle/chunks/{upgrade-HAK6JG2O.js.map → upgrade-VU46BLJZ.js.map} +0 -0
@@ -4,7 +4,7 @@
4
4
  * Provides CLI runtime support for Register Mutation.
5
5
  */
6
6
 
7
- !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]="703247b2-e81d-5a78-999d-6d493a4cf9bf")}catch(e){}}();
7
+ !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]="506e1f95-1444-5306-9a5e-c1fb3726b2df")}catch(e){}}();
8
8
  import { Option } from "commander";
9
9
  import { resolveBodyFileContent } from "../core/io/body-file.js";
10
10
  import { EXIT_CODE } from "../core/shared/constants.js";
@@ -18,7 +18,7 @@ import { BUILTIN_ITEM_TYPE_VALUES } from "../types/index.js";
18
18
  // positional exactly matches a known type AND no --title was given, we throw
19
19
  // instead of silently creating a Task titled with the type name.
20
20
  const BUILTIN_TYPE_NAME_LOOKUP = new Set(BUILTIN_ITEM_TYPE_VALUES.map((value) => value.toLowerCase()));
21
- import { collect, extractUpdateManyMutationOptionSource, formatHookWarnings, getGlobalOptions, invalidateSearchCachesForMutation, normalizeCreateOptions, normalizeUpdateOptions, printError, printResult, writeStdout, } from "./registration-helpers.js";
21
+ import { collect, extractUpdateManyMutationOptionSource, formatHookWarnings, getGlobalOptions, invalidateSearchCachesForMutation, normalizeCreateOptions, normalizeUpdateOptions, printError, printResult, readOptionString, writeStdout, } from "./registration-helpers.js";
22
22
  /**
23
23
  * Register a flag and hide it from `--help` text while keeping it fully
24
24
  * functional as a parse-time alias. The option still appears in
@@ -33,6 +33,11 @@ function addHiddenOption(command, flags, description, repeatable) {
33
33
  }
34
34
  command.addOption(option);
35
35
  }
36
+ function addHiddenOptions(command, aliases, repeatable) {
37
+ for (const [flags, description] of aliases) {
38
+ addHiddenOption(command, flags, description, repeatable);
39
+ }
40
+ }
36
41
  const SCHEMA_SHORTHAND_RESERVED_PREFIXES = ["add-", "apply-", "list-", "remove-", "show-"];
37
42
  const SCHEMA_SHORTHAND_RESERVED_TOKENS = new Set([
38
43
  "field",
@@ -399,6 +404,732 @@ function buildUpdateManyListOptions(options) {
399
404
  includeBody: true,
400
405
  };
401
406
  }
407
+ function pickStringOption(...candidates) {
408
+ for (const candidate of candidates) {
409
+ if (typeof candidate === "string") {
410
+ return candidate;
411
+ }
412
+ }
413
+ return undefined;
414
+ }
415
+ function stringArrayOption(value) {
416
+ if (Array.isArray(value)) {
417
+ return value;
418
+ }
419
+ if (typeof value === "string") {
420
+ return [value];
421
+ }
422
+ return undefined;
423
+ }
424
+ function resolveCreatePositionals(typeOrTitle, secondTitle, options) {
425
+ if (typeof secondTitle === "string" && secondTitle.length > 0) {
426
+ return { positionalType: typeOrTitle, positionalTitle: secondTitle };
427
+ }
428
+ if (typeof typeOrTitle !== "string" || typeOrTitle.length === 0) {
429
+ return { positionalType: undefined, positionalTitle: undefined };
430
+ }
431
+ const explicitTitleProvided = typeof options.title === "string" && options.title.trim().length > 0;
432
+ return explicitTitleProvided && options.type === undefined
433
+ ? { positionalType: typeOrTitle, positionalTitle: undefined }
434
+ : { positionalType: undefined, positionalTitle: typeOrTitle };
435
+ }
436
+ function assertCreatePositionalTypeHasTitle(positionalType, positionalTitle, options) {
437
+ if (positionalType !== undefined ||
438
+ typeof positionalTitle !== "string" ||
439
+ positionalTitle.length === 0 ||
440
+ options.title !== undefined ||
441
+ options.type !== undefined ||
442
+ !BUILTIN_TYPE_NAME_LOOKUP.has(positionalTitle.trim().toLowerCase())) {
443
+ return;
444
+ }
445
+ const matchedType = positionalTitle.trim();
446
+ 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, {
447
+ code: "create_positional_type_without_title",
448
+ 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 \"" + matchedType + "\".",
449
+ examples: [
450
+ `pm create ${matchedType} "Wire up SSO for the agent harness"`,
451
+ `pm create "Wire up SSO for the agent harness" --type ${matchedType}`,
452
+ ],
453
+ nextSteps: [
454
+ `Re-run with both type and title: pm create ${matchedType} "<title>"`,
455
+ ],
456
+ });
457
+ }
458
+ async function runCreateAction(typeOrTitle, secondTitle, options, command) {
459
+ const globalOptions = getGlobalOptions(command);
460
+ const startedAt = Date.now();
461
+ const positionals = resolveCreatePositionals(typeOrTitle, secondTitle, options);
462
+ assertCreatePositionalTypeHasTitle(positionals.positionalType, positionals.positionalTitle, options);
463
+ if (typeof positionals.positionalType === "string" && positionals.positionalType.length > 0 && options.type === undefined) {
464
+ options.type = positionals.positionalType;
465
+ }
466
+ if (typeof positionals.positionalTitle === "string" && positionals.positionalTitle.length > 0 && options.title === undefined) {
467
+ options.title = positionals.positionalTitle;
468
+ }
469
+ if (typeof options.bodyFile === "string") {
470
+ options.body = await resolveBodyFileContent(options.bodyFile, options.body !== undefined ? String(options.body) : undefined);
471
+ delete options.bodyFile;
472
+ }
473
+ const normalized = normalizeCreateOptions(options, { requireType: false });
474
+ const { runCreate } = await import("./commands/create.js");
475
+ const result = await runCreate(normalized, globalOptions);
476
+ await invalidateSearchCachesForMutation(globalOptions, result);
477
+ printResult(result, globalOptions);
478
+ if (globalOptions.profile) {
479
+ printError(`profile:command=create took_ms=${Date.now() - startedAt}`);
480
+ }
481
+ }
482
+ function buildCloseManyListOptions(options) {
483
+ return {
484
+ type: readOptionString(options, "filterType"),
485
+ tag: readOptionString(options, "filterTag"),
486
+ priority: readOptionString(options, "filterPriority"),
487
+ deadlineBefore: readOptionString(options, "filterDeadlineBefore"),
488
+ deadlineAfter: readOptionString(options, "filterDeadlineAfter"),
489
+ updatedAfter: readOptionString(options, "filterUpdatedAfter"),
490
+ updatedBefore: readOptionString(options, "filterUpdatedBefore"),
491
+ createdAfter: readOptionString(options, "filterCreatedAfter"),
492
+ createdBefore: readOptionString(options, "filterCreatedBefore"),
493
+ ids: readOptionString(options, "ids"),
494
+ assignee: readOptionString(options, "filterAssignee"),
495
+ assigneeFilter: pickStringOption(options.filterAssigneeFilter, options.filterAssignee_filter),
496
+ parent: readOptionString(options, "filterParent"),
497
+ sprint: readOptionString(options, "filterSprint"),
498
+ release: readOptionString(options, "filterRelease"),
499
+ ...mapBulkContentAndGovernanceFilters(options),
500
+ limit: readOptionString(options, "limit"),
501
+ offset: readOptionString(options, "offset"),
502
+ };
503
+ }
504
+ async function runCloseManyAction(options, command) {
505
+ const globalOptions = getGlobalOptions(command);
506
+ const startedAt = Date.now();
507
+ const { runCloseMany } = await import("./commands/close-many.js");
508
+ const result = await runCloseMany({
509
+ status: readOptionString(options, "filterStatus"),
510
+ list: buildCloseManyListOptions(options),
511
+ reason: readOptionString(options, "reason"),
512
+ resolution: readOptionString(options, "resolution"),
513
+ expectedResult: pickStringOption(options.expectedResult, options.expected_result, options.expected),
514
+ actualResult: pickStringOption(options.actualResult, options.actual_result, options.actual),
515
+ validateClose: options.validateClose === true
516
+ ? "warn"
517
+ : readOptionString(options, "validateClose"),
518
+ author: readOptionString(options, "author"),
519
+ message: readOptionString(options, "message"),
520
+ force: Boolean(options.force),
521
+ dryRun: options.dryRun === true ? true : undefined,
522
+ rollback: readOptionString(options, "rollback"),
523
+ checkpoint: options.checkpoint === false ? false : undefined,
524
+ }, globalOptions);
525
+ await invalidateSearchCachesForMutation(globalOptions, result);
526
+ printResult(result, globalOptions);
527
+ if (globalOptions.profile) {
528
+ printError(`profile:command=close-many took_ms=${Date.now() - startedAt}`);
529
+ }
530
+ }
531
+ async function runUpdateManyAction(options, command) {
532
+ const globalOptions = getGlobalOptions(command);
533
+ const startedAt = Date.now();
534
+ const { runUpdateMany } = await import("./commands/update-many.js");
535
+ const result = await runUpdateMany({
536
+ status: readOptionString(options, "filterStatus"),
537
+ list: buildUpdateManyListOptions(options),
538
+ update: normalizeUpdateOptions(extractUpdateManyMutationOptionSource(options)),
539
+ dryRun: options.dryRun === true ? true : undefined,
540
+ rollback: readOptionString(options, "rollback"),
541
+ checkpoint: options.checkpoint === false ? false : undefined,
542
+ }, globalOptions);
543
+ await invalidateSearchCachesForMutation(globalOptions, result);
544
+ printResult(result, globalOptions);
545
+ if (globalOptions.profile) {
546
+ printError(`profile:command=update-many took_ms=${Date.now() - startedAt}`);
547
+ }
548
+ }
549
+ async function runCloseAction(id, text, options, command) {
550
+ const globalOptions = getGlobalOptions(command);
551
+ const startedAt = Date.now();
552
+ const { runClose } = await import("./commands/close.js");
553
+ const reasonFromOption = (typeof options.reason === "string" && options.reason.trim().length > 0 && options.reason) ||
554
+ (typeof options.closeReason === "string" && options.closeReason.trim().length > 0 && options.closeReason) ||
555
+ undefined;
556
+ const resolvedText = typeof text === "string" && text.length > 0 ? text : reasonFromOption;
557
+ const result = await runClose(id, resolvedText, {
558
+ author: readOptionString(options, "author"),
559
+ message: readOptionString(options, "message"),
560
+ validateClose: options.validateClose === true
561
+ ? "warn"
562
+ : readOptionString(options, "validateClose"),
563
+ force: Boolean(options.force),
564
+ duplicateOf: readOptionString(options, "duplicateOf"),
565
+ resolution: readOptionString(options, "resolution"),
566
+ expectedResult: pickStringOption(options.expectedResult, options.expected_result, options.expected),
567
+ actualResult: pickStringOption(options.actualResult, options.actual_result, options.actual),
568
+ }, globalOptions);
569
+ await invalidateSearchCachesForMutation(globalOptions, result);
570
+ printResult(result, globalOptions);
571
+ if (globalOptions.profile) {
572
+ printError(`profile:command=close took_ms=${Date.now() - startedAt}`);
573
+ }
574
+ }
575
+ function normalizePlanAliases(options) {
576
+ const planOptions = { ...options };
577
+ const aliasPairs = [
578
+ ["blocked_by", "blockedBy"],
579
+ ["resume_context", "resumeContext"],
580
+ ["from_search", "fromSearch"],
581
+ ["step_title", "stepTitle"],
582
+ ["step_body", "stepBody"],
583
+ ["step_owner", "stepOwner"],
584
+ ["step_status", "stepStatus"],
585
+ ["step_evidence", "stepEvidence"],
586
+ ["step_blocked_reason", "stepBlockedReason"],
587
+ ["step_replacement", "stepReplacement"],
588
+ ["depends_on", "dependsOn"],
589
+ ["link_kind", "linkKind"],
590
+ ["link_note", "linkNote"],
591
+ ["promote_to_item_dep", "promoteToItemDep"],
592
+ ["allow_multiple_active", "allowMultipleActive"],
593
+ ["decision_text", "decisionText"],
594
+ ["decision_rationale", "decisionRationale"],
595
+ ["decision_evidence", "decisionEvidence"],
596
+ ["discovery_text", "discoveryText"],
597
+ ["validation_text", "validationText"],
598
+ ["validation_command", "validationCommand"],
599
+ ["validation_expected", "validationExpected"],
600
+ ["materialize_type", "materializeType"],
601
+ ["materialize_parent", "materializeParent"],
602
+ ["materialize_tags", "materializeTags"],
603
+ ];
604
+ for (const [snake, camel] of aliasPairs) {
605
+ if (planOptions[snake] !== undefined && planOptions[camel] === undefined) {
606
+ planOptions[camel] = planOptions[snake];
607
+ }
608
+ }
609
+ return planOptions;
610
+ }
611
+ function assertKnownPlanSubcommand(subcommand, normalized, allowed) {
612
+ if (!normalized) {
613
+ throw new PmCliError(`pm plan requires a subcommand. Allowed: ${allowed.join(", ")}`, EXIT_CODE.USAGE, {
614
+ code: "missing_required_argument",
615
+ examples: [
616
+ 'pm plan create --title "Refactor lock retry"',
617
+ "pm plan show pm-a1b2 --depth standard",
618
+ 'pm plan add-step pm-a1b2 --step-title "Read lock.ts"',
619
+ ],
620
+ });
621
+ }
622
+ if (allowed.includes(normalized)) {
623
+ return;
624
+ }
625
+ const examples = normalized === "list" || normalized === "ls" ? ['pm list --type Plan', 'pm list-all --type Plan'] : undefined;
626
+ throw new PmCliError(`Unknown pm plan subcommand "${subcommand}". Allowed: ${allowed.join(", ")}`, EXIT_CODE.USAGE, examples ? { code: "unknown_subcommand", examples } : undefined);
627
+ }
628
+ function parsePlanReorderTo(normalizedSubcommand, reorderToken) {
629
+ if (normalizedSubcommand !== "reorder-step" || typeof reorderToken !== "string") {
630
+ return undefined;
631
+ }
632
+ const parsed = Number.parseInt(reorderToken, 10);
633
+ if (!Number.isFinite(parsed)) {
634
+ throw new PmCliError(`reorder-step requires an integer new order, got "${reorderToken}"`, EXIT_CODE.USAGE);
635
+ }
636
+ return parsed;
637
+ }
638
+ async function runPlanAction(subcommand, id, stepRef, reorderToken, options, command) {
639
+ const globalOptions = getGlobalOptions(command);
640
+ const startedAt = Date.now();
641
+ const { runPlan, PLAN_SUBCOMMANDS } = await import("./commands/plan.js");
642
+ const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
643
+ assertKnownPlanSubcommand(subcommand, normalizedSubcommand, PLAN_SUBCOMMANDS);
644
+ const planOptions = normalizePlanAliases(options);
645
+ const reorderTo = parsePlanReorderTo(normalizedSubcommand, reorderToken);
646
+ const planId = normalizedSubcommand === "create" && typeof id === "string" && id.length > 0 && planOptions.title === undefined
647
+ ? undefined
648
+ : id;
649
+ if (planId === undefined && typeof id === "string" && id.length > 0) {
650
+ planOptions.title = id;
651
+ }
652
+ const result = await runPlan({
653
+ subcommand: normalizedSubcommand,
654
+ id: planId,
655
+ stepRef,
656
+ reorderTo,
657
+ options: planOptions,
658
+ global: globalOptions,
659
+ });
660
+ await invalidateSearchCachesForMutation(globalOptions, result);
661
+ printResult(result, globalOptions);
662
+ if (globalOptions.profile) {
663
+ printError(`profile:command=plan took_ms=${Date.now() - startedAt}`);
664
+ }
665
+ }
666
+ function parseNonNegativeIntFlag(raw, flag) {
667
+ if (typeof raw !== "string") {
668
+ return undefined;
669
+ }
670
+ if (!/^\d+$/.test(raw.trim())) {
671
+ throw new PmCliError(`history-compact ${flag} must be a non-negative integer.`, EXIT_CODE.USAGE);
672
+ }
673
+ return Number.parseInt(raw, 10);
674
+ }
675
+ async function runHistoryCompactAction(id, options, command) {
676
+ const globalOptions = getGlobalOptions(command);
677
+ const startedAt = Date.now();
678
+ const { runHistoryCompact, runHistoryCompactBulk, assertHistoryCompactTarget } = await import("./commands/history-compact.js");
679
+ const ids = typeof options.ids === "string" ? splitCommaList(options.ids) : undefined;
680
+ const allOver = parseNonNegativeIntFlag(options.allOver, "--all-over");
681
+ const minEntries = parseNonNegativeIntFlag(options.minEntries, "--min-entries");
682
+ if (options.closed === true && options.allStreams === true) {
683
+ throw new PmCliError("history-compact: --closed and --all-streams are mutually exclusive; pick one lifecycle scope.", EXIT_CODE.USAGE);
684
+ }
685
+ const scope = options.closed === true ? "closed" : options.allStreams === true ? "all-streams" : undefined;
686
+ const isBulk = ids !== undefined || allOver !== undefined || scope !== undefined;
687
+ if (isBulk && typeof options.before === "string") {
688
+ throw new PmCliError("history-compact: --before applies only in single-id mode (bulk mode always compacts full streams).", EXIT_CODE.USAGE);
689
+ }
690
+ assertHistoryCompactTarget(id, { ids, allOver, scope });
691
+ if (id === undefined) {
692
+ const result = await runHistoryCompactBulk({
693
+ ids,
694
+ scope,
695
+ allOver,
696
+ minEntries,
697
+ dryRun: options.dryRun === true,
698
+ author: readOptionString(options, "author"),
699
+ message: readOptionString(options, "message"),
700
+ force: Boolean(options.force),
701
+ }, globalOptions);
702
+ printResult(result, globalOptions);
703
+ if (result.totals.items_errored > 0) {
704
+ process.exitCode = EXIT_CODE.GENERIC_FAILURE;
705
+ }
706
+ }
707
+ else {
708
+ const result = await runHistoryCompact(id, {
709
+ before: readOptionString(options, "before"),
710
+ dryRun: options.dryRun === true,
711
+ author: readOptionString(options, "author"),
712
+ message: readOptionString(options, "message"),
713
+ force: Boolean(options.force),
714
+ }, globalOptions);
715
+ printResult(result, globalOptions);
716
+ }
717
+ if (globalOptions.profile) {
718
+ printError(`profile:command=history-compact took_ms=${Date.now() - startedAt}`);
719
+ }
720
+ }
721
+ function splitCollectedCommaList(raw) {
722
+ if (!Array.isArray(raw)) {
723
+ return undefined;
724
+ }
725
+ return raw
726
+ .flatMap((value) => value.split(","))
727
+ .map((value) => value.trim())
728
+ .filter((value) => value.length > 0);
729
+ }
730
+ async function runSchemaAction(subcommand, name, options, command) {
731
+ const globalOptions = getGlobalOptions(command);
732
+ const startedAt = Date.now();
733
+ const schemaModule = await import("./commands/schema.js");
734
+ const { SCHEMA_SUBCOMMANDS } = schemaModule;
735
+ let normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
736
+ let typeName = name;
737
+ assertSchemaSubcommandPresent(normalizedSubcommand, SCHEMA_SUBCOMMANDS);
738
+ if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand) &&
739
+ typeName === undefined &&
740
+ !looksLikeSchemaSubcommandTypo(normalizedSubcommand)) {
741
+ typeName = subcommand;
742
+ normalizedSubcommand = "add-type";
743
+ }
744
+ if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand)) {
745
+ throw new PmCliError(`Unknown pm schema subcommand "${subcommand}". Allowed: ${SCHEMA_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, { code: "unknown_subcommand" });
746
+ }
747
+ const result = await dispatchSchemaSubcommand(schemaModule, {
748
+ normalizedSubcommand,
749
+ typeName,
750
+ options,
751
+ aliases: stringArrayOption(options.alias),
752
+ roles: stringArrayOption(options.role),
753
+ commands: splitCollectedCommaList(options.commands),
754
+ requiredTypes: splitCollectedCommaList(options.requiredTypes),
755
+ defaultStatus: pickStringOption(options.defaultStatus, options.default_status),
756
+ order: parseSchemaOrderOption(options.order),
757
+ minCount: parseSchemaOrderOption(options.minCount),
758
+ author: readOptionString(options, "author"),
759
+ force: Boolean(options.force),
760
+ description: readOptionString(options, "description"),
761
+ globalOptions,
762
+ });
763
+ if (globalOptions.json === true || globalOptions.defaultOutputFormat === "json") {
764
+ printResult(result, globalOptions);
765
+ }
766
+ else if (!globalOptions.quiet) {
767
+ renderSchemaResultHuman(schemaModule, result);
768
+ }
769
+ if (globalOptions.profile) {
770
+ printError(`profile:command=schema took_ms=${Date.now() - startedAt}`);
771
+ }
772
+ }
773
+ function assertSchemaSubcommandPresent(normalizedSubcommand, allowed) {
774
+ if (normalizedSubcommand) {
775
+ return;
776
+ }
777
+ throw new PmCliError(`pm schema requires a subcommand. Allowed: ${allowed.join(", ")}`, EXIT_CODE.USAGE, {
778
+ code: "missing_required_argument",
779
+ examples: [
780
+ "pm schema list",
781
+ "pm schema show Task",
782
+ "pm schema show-status open",
783
+ 'pm schema add-type Spike --description "Time-boxed investigation" --default-status open',
784
+ "pm schema remove-type Spike",
785
+ "pm schema add-status review --role active --alias in_review",
786
+ "pm schema remove-status review",
787
+ "pm schema add-field severity_level --type string --commands create,update",
788
+ "pm schema list-fields",
789
+ "pm schema apply-preset agile",
790
+ "pm schema add-type --infer --min-count 10",
791
+ ],
792
+ });
793
+ }
794
+ function resolveCommentSources(text, options) {
795
+ const editIndex = typeof options.edit === "number" ? options.edit : undefined;
796
+ const deleteIndex = typeof options.delete === "number" ? options.delete : undefined;
797
+ const addFromOption = readOptionString(options, "add");
798
+ const addFromPositional = typeof text === "string" ? text : undefined;
799
+ const readFromStdin = options.stdin === true;
800
+ const readFromFile = readOptionString(options, "file");
801
+ const sourceCount = Number(addFromOption !== undefined) +
802
+ Number(addFromPositional !== undefined) +
803
+ Number(readFromStdin) +
804
+ Number(readFromFile !== undefined);
805
+ if (sourceCount > 1) {
806
+ if (addFromOption !== undefined && addFromPositional !== undefined && !readFromStdin && readFromFile === undefined) {
807
+ throw new PmCliError("Specify comment text either as positional [text] or with --add, not both", EXIT_CODE.USAGE);
808
+ }
809
+ throw new PmCliError("Specify comment text with exactly one source: positional [text], --add, --stdin, or --file", EXIT_CODE.USAGE);
810
+ }
811
+ const add = addFromOption ?? addFromPositional;
812
+ const isMutation = typeof add === "string" || readFromStdin || readFromFile !== undefined || editIndex !== undefined || deleteIndex !== undefined;
813
+ return { add, readFromStdin, readFromFile, editIndex, deleteIndex, isMutation };
814
+ }
815
+ async function runCommentsAction(id, text, options, command) {
816
+ const globalOptions = getGlobalOptions(command);
817
+ const startedAt = Date.now();
818
+ const sources = resolveCommentSources(text, options);
819
+ const { runComments } = await import("./commands/comments.js");
820
+ const result = await runComments(id, {
821
+ add: sources.add,
822
+ stdin: sources.readFromStdin,
823
+ file: sources.readFromFile,
824
+ edit: sources.editIndex,
825
+ delete: sources.deleteIndex,
826
+ limit: readOptionString(options, "limit"),
827
+ author: readOptionString(options, "author"),
828
+ message: readOptionString(options, "message"),
829
+ allowAuditComment: Boolean(options.allowAuditComment),
830
+ force: Boolean(options.force),
831
+ }, globalOptions);
832
+ if (sources.isMutation) {
833
+ await invalidateSearchCachesForMutation(globalOptions, result);
834
+ }
835
+ printResult(result, globalOptions);
836
+ if (globalOptions.profile) {
837
+ printError(`profile:command=comments took_ms=${Date.now() - startedAt}`);
838
+ }
839
+ }
840
+ async function runCopyAction(id, options, command) {
841
+ const globalOptions = getGlobalOptions(command);
842
+ const startedAt = Date.now();
843
+ const { runCopy } = await import("./commands/copy.js");
844
+ const result = await runCopy(id, {
845
+ title: readOptionString(options, "title"),
846
+ author: readOptionString(options, "author"),
847
+ message: readOptionString(options, "message"),
848
+ }, globalOptions);
849
+ await invalidateSearchCachesForMutation(globalOptions, result);
850
+ printResult(result, globalOptions);
851
+ if (globalOptions.profile) {
852
+ printError(`profile:command=copy took_ms=${Date.now() - startedAt}`);
853
+ }
854
+ }
855
+ async function runFocusAction(id, options, command) {
856
+ const globalOptions = getGlobalOptions(command);
857
+ const startedAt = Date.now();
858
+ const { runFocus } = await import("./commands/focus.js");
859
+ const result = await runFocus(id, { clear: options.clear === true }, globalOptions);
860
+ printResult(result, globalOptions);
861
+ if (globalOptions.profile) {
862
+ printError(`profile:command=focus took_ms=${Date.now() - startedAt}`);
863
+ }
864
+ }
865
+ async function runUpdateAction(id, options, command) {
866
+ const globalOptions = getGlobalOptions(command);
867
+ const startedAt = Date.now();
868
+ // GH-214: resolve --body-file into the existing body field before
869
+ // normalization so the rest of update is unchanged. CLI-only input alias.
870
+ if (typeof options.bodyFile === "string") {
871
+ options.body = await resolveBodyFileContent(options.bodyFile, options.body !== undefined ? String(options.body) : undefined);
872
+ delete options.bodyFile;
873
+ }
874
+ const { runUpdate } = await import("./commands/update.js");
875
+ const result = await runUpdate(id, normalizeUpdateOptions(options), globalOptions);
876
+ await invalidateSearchCachesForMutation(globalOptions, result);
877
+ printResult(result, globalOptions);
878
+ if (globalOptions.profile) {
879
+ printError(`profile:command=update took_ms=${Date.now() - startedAt}`);
880
+ }
881
+ }
882
+ async function runDeleteAction(id, options, command) {
883
+ const globalOptions = getGlobalOptions(command);
884
+ const startedAt = Date.now();
885
+ const { runDelete } = await import("./commands/delete.js");
886
+ const result = await runDelete(id, {
887
+ author: readOptionString(options, "author"),
888
+ message: readOptionString(options, "message"),
889
+ force: Boolean(options.force),
890
+ dryRun: options.dryRun === true,
891
+ }, globalOptions);
892
+ if (result.dry_run !== true) {
893
+ await invalidateSearchCachesForMutation(globalOptions, result);
894
+ }
895
+ printResult(result, globalOptions);
896
+ if (globalOptions.profile) {
897
+ printError(`profile:command=delete took_ms=${Date.now() - startedAt}`);
898
+ }
899
+ }
900
+ function resolveSingleTextSource(label, positional, options) {
901
+ const addFromOption = readOptionString(options, "add");
902
+ const addFromPositional = typeof positional === "string" ? positional : undefined;
903
+ if (addFromOption !== undefined && addFromPositional !== undefined) {
904
+ throw new PmCliError(`Specify ${label} text either as positional [text] or with --add, not both`, EXIT_CODE.USAGE);
905
+ }
906
+ return addFromOption ?? addFromPositional;
907
+ }
908
+ function resolveAppendBody(text, options) {
909
+ const bodyFromOption = readOptionString(options, "body");
910
+ const bodyFromAlias = readOptionString(options, "text");
911
+ const bodyFromPositional = typeof text === "string" ? text : undefined;
912
+ const bodySourceCount = [bodyFromOption, bodyFromAlias, bodyFromPositional].filter((value) => value !== undefined).length;
913
+ if (bodySourceCount > 1) {
914
+ throw new PmCliError("Specify append text with exactly one source: positional [text], --body, or --text", EXIT_CODE.USAGE);
915
+ }
916
+ const resolvedBody = bodyFromOption ?? bodyFromAlias ?? bodyFromPositional;
917
+ if (resolvedBody === undefined) {
918
+ throw new PmCliError("Missing append text. Provide it as positional [text], --body <value>, or --text <value> (use - for stdin).", EXIT_CODE.USAGE);
919
+ }
920
+ return resolvedBody;
921
+ }
922
+ async function runAppendAction(id, text, options, command) {
923
+ const globalOptions = getGlobalOptions(command);
924
+ const startedAt = Date.now();
925
+ const { runAppend } = await import("./commands/append.js");
926
+ const result = await runAppend(id, {
927
+ body: resolveAppendBody(text, options),
928
+ author: readOptionString(options, "author"),
929
+ message: readOptionString(options, "message"),
930
+ force: Boolean(options.force),
931
+ }, globalOptions);
932
+ await invalidateSearchCachesForMutation(globalOptions, result);
933
+ printResult(result, globalOptions);
934
+ if (globalOptions.profile) {
935
+ printError(`profile:command=append took_ms=${Date.now() - startedAt}`);
936
+ }
937
+ }
938
+ async function runRestoreAction(id, target, options, command) {
939
+ const globalOptions = getGlobalOptions(command);
940
+ const startedAt = Date.now();
941
+ const { runRestore } = await import("./commands/restore.js");
942
+ const result = await runRestore(id, target, {
943
+ author: readOptionString(options, "author"),
944
+ message: readOptionString(options, "message"),
945
+ force: Boolean(options.force),
946
+ }, globalOptions);
947
+ await invalidateSearchCachesForMutation(globalOptions, result);
948
+ printResult(result, globalOptions);
949
+ if (globalOptions.profile) {
950
+ printError(`profile:command=restore took_ms=${Date.now() - startedAt}`);
951
+ }
952
+ }
953
+ async function runProfileAction(subcommand, name, options, command) {
954
+ const globalOptions = getGlobalOptions(command);
955
+ const startedAt = Date.now();
956
+ const profileModule = await import("./commands/profile.js");
957
+ const { PROFILE_SUBCOMMANDS } = profileModule;
958
+ const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
959
+ if (!normalizedSubcommand) {
960
+ throw new PmCliError(`pm profile requires a subcommand. Allowed: ${PROFILE_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
961
+ code: "missing_required_argument",
962
+ examples: ["pm profile list", "pm profile show agile", "pm profile apply agile --dry-run", "pm profile lint agile"],
963
+ });
964
+ }
965
+ if (!PROFILE_SUBCOMMANDS.includes(normalizedSubcommand)) {
966
+ throw new PmCliError(`Unknown pm profile subcommand "${subcommand}". Allowed: ${PROFILE_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, { code: "unknown_subcommand" });
967
+ }
968
+ const result = await dispatchProfileSubcommand(profileModule, normalizedSubcommand, name, options, globalOptions);
969
+ // Profile inspection and schema staging do not mutate item content, so search caches stay valid (mirrors pm schema).
970
+ if (globalOptions.json === true || globalOptions.defaultOutputFormat === "json") {
971
+ printResult(result, globalOptions);
972
+ }
973
+ else if (!globalOptions.quiet) {
974
+ renderProfileResultHuman(profileModule, result);
975
+ }
976
+ // `pm profile lint` is a validation gate: exit non-zero when the profile has
977
+ // error-severity findings so shell/CI callers can fail on them. Warnings keep
978
+ // `ok` true and never fail the command.
979
+ if (result.action === "lint" && !result.ok) {
980
+ process.exitCode = EXIT_CODE.GENERIC_FAILURE;
981
+ }
982
+ if (globalOptions.profile) {
983
+ printError(`profile:command=profile took_ms=${Date.now() - startedAt}`);
984
+ }
985
+ }
986
+ async function runNotesAction(id, text, options, command) {
987
+ const globalOptions = getGlobalOptions(command);
988
+ const startedAt = Date.now();
989
+ const add = resolveSingleTextSource("note", text, options);
990
+ const { runNotes } = await import("./commands/notes.js");
991
+ const result = await runNotes(id, {
992
+ add,
993
+ limit: readOptionString(options, "limit"),
994
+ author: readOptionString(options, "author"),
995
+ message: readOptionString(options, "message"),
996
+ allowAuditComment: Boolean(options.allowAuditNote || options.allowAuditComment),
997
+ force: Boolean(options.force),
998
+ }, globalOptions);
999
+ if (typeof add === "string") {
1000
+ await invalidateSearchCachesForMutation(globalOptions, result);
1001
+ }
1002
+ printResult(result, globalOptions);
1003
+ if (globalOptions.profile) {
1004
+ printError(`profile:command=notes took_ms=${Date.now() - startedAt}`);
1005
+ }
1006
+ }
1007
+ async function runLearningsAction(id, text, options, command) {
1008
+ const globalOptions = getGlobalOptions(command);
1009
+ const startedAt = Date.now();
1010
+ const add = resolveSingleTextSource("learning", text, options);
1011
+ const { runLearnings } = await import("./commands/learnings.js");
1012
+ const result = await runLearnings(id, {
1013
+ add,
1014
+ limit: readOptionString(options, "limit"),
1015
+ author: readOptionString(options, "author"),
1016
+ message: readOptionString(options, "message"),
1017
+ allowAuditComment: Boolean(options.allowAuditLearning || options.allowAuditComment),
1018
+ force: Boolean(options.force),
1019
+ }, globalOptions);
1020
+ if (typeof add === "string") {
1021
+ await invalidateSearchCachesForMutation(globalOptions, result);
1022
+ }
1023
+ printResult(result, globalOptions);
1024
+ if (globalOptions.profile) {
1025
+ printError(`profile:command=learnings took_ms=${Date.now() - startedAt}`);
1026
+ }
1027
+ }
1028
+ function readStringArrayOption(options, key) {
1029
+ return stringArrayOption(options[key]) ?? [];
1030
+ }
1031
+ async function runFilesAction(id, options, command) {
1032
+ const globalOptions = getGlobalOptions(command);
1033
+ const startedAt = Date.now();
1034
+ const addValues = readStringArrayOption(options, "add");
1035
+ const addGlobValues = readStringArrayOption(options, "addGlob");
1036
+ const removeValues = readStringArrayOption(options, "remove");
1037
+ const migrateValues = readStringArrayOption(options, "migrate");
1038
+ const { runFiles } = await import("./commands/files.js");
1039
+ const result = await runFiles(id, {
1040
+ add: addValues,
1041
+ addGlob: addGlobValues,
1042
+ remove: removeValues,
1043
+ migrate: migrateValues,
1044
+ note: readOptionString(options, "note"),
1045
+ list: Boolean(options.list),
1046
+ appendStable: Boolean(options.appendStable),
1047
+ validatePaths: Boolean(options.validatePaths),
1048
+ audit: Boolean(options.audit),
1049
+ author: readOptionString(options, "author"),
1050
+ message: readOptionString(options, "message"),
1051
+ force: Boolean(options.force),
1052
+ }, globalOptions);
1053
+ if (addValues.length > 0 || addGlobValues.length > 0 || removeValues.length > 0 || migrateValues.length > 0) {
1054
+ await invalidateSearchCachesForMutation(globalOptions, result);
1055
+ }
1056
+ printResult(result, globalOptions);
1057
+ if (globalOptions.profile) {
1058
+ printError(`profile:command=files took_ms=${Date.now() - startedAt}`);
1059
+ }
1060
+ }
1061
+ async function runFilesDiscoverAction(id, options, command) {
1062
+ const globalOptions = getGlobalOptions(command);
1063
+ const startedAt = Date.now();
1064
+ // Flags also declared on the parent files command (--note/--append-stable/
1065
+ // --author/--message/--force) are consumed by the parent during parse, so
1066
+ // merge ancestor opts back in (own options win) instead of reading opts() alone.
1067
+ const mergedOptions = { ...command.optsWithGlobals(), ...options };
1068
+ const { runFilesDiscover } = await import("./commands/files.js");
1069
+ const result = await runFilesDiscover(id, {
1070
+ apply: Boolean(mergedOptions.apply),
1071
+ note: readOptionString(mergedOptions, "note"),
1072
+ appendStable: Boolean(mergedOptions.appendStable),
1073
+ author: readOptionString(mergedOptions, "author"),
1074
+ message: readOptionString(mergedOptions, "message"),
1075
+ force: Boolean(mergedOptions.force),
1076
+ }, globalOptions);
1077
+ if (result.changed) {
1078
+ await invalidateSearchCachesForMutation(globalOptions, result);
1079
+ }
1080
+ printResult(result, globalOptions);
1081
+ if (globalOptions.profile) {
1082
+ printError(`profile:command=files.discover took_ms=${Date.now() - startedAt}`);
1083
+ }
1084
+ }
1085
+ async function runDocsAction(id, options, command) {
1086
+ const globalOptions = getGlobalOptions(command);
1087
+ const startedAt = Date.now();
1088
+ const addValues = readStringArrayOption(options, "add");
1089
+ const addGlobValues = readStringArrayOption(options, "addGlob");
1090
+ const removeValues = readStringArrayOption(options, "remove");
1091
+ const migrateValues = readStringArrayOption(options, "migrate");
1092
+ const { runDocs } = await import("./commands/docs.js");
1093
+ const result = await runDocs(id, {
1094
+ add: addValues,
1095
+ addGlob: addGlobValues,
1096
+ remove: removeValues,
1097
+ migrate: migrateValues,
1098
+ note: readOptionString(options, "note"),
1099
+ list: Boolean(options.list),
1100
+ validatePaths: Boolean(options.validatePaths),
1101
+ audit: Boolean(options.audit),
1102
+ author: readOptionString(options, "author"),
1103
+ message: readOptionString(options, "message"),
1104
+ force: Boolean(options.force),
1105
+ }, globalOptions);
1106
+ if (addValues.length > 0 || addGlobValues.length > 0 || removeValues.length > 0 || migrateValues.length > 0) {
1107
+ await invalidateSearchCachesForMutation(globalOptions, result);
1108
+ }
1109
+ printResult(result, globalOptions);
1110
+ if (globalOptions.profile) {
1111
+ printError(`profile:command=docs took_ms=${Date.now() - startedAt}`);
1112
+ }
1113
+ }
1114
+ async function runDepsAction(id, options, command) {
1115
+ const globalOptions = getGlobalOptions(command);
1116
+ const startedAt = Date.now();
1117
+ const { runDeps } = await import("./commands/deps.js");
1118
+ // --format and --collapse carry commander defaults ("tree"/"none"), so
1119
+ // they are always strings by the time the action runs; --maxDepth has no
1120
+ // default and may be unset. Use `as string` rather than String(...) so an
1121
+ // omitted option stays undefined instead of becoming the literal "undefined".
1122
+ const result = await runDeps(id, {
1123
+ format: options.format,
1124
+ maxDepth: readOptionString(options, "maxDepth"),
1125
+ collapse: options.collapse,
1126
+ summary: options.summary === true,
1127
+ }, globalOptions);
1128
+ printResult(result, globalOptions);
1129
+ if (globalOptions.profile) {
1130
+ printError(`profile:command=deps took_ms=${Date.now() - startedAt}`);
1131
+ }
1132
+ }
402
1133
  /**
403
1134
  * Implements register mutation commands for the public runtime surface of this module.
404
1135
  */
@@ -421,75 +1152,7 @@ export function registerMutationCommands(program) {
421
1152
  .option("--clear-reminders", "Clear reminders")
422
1153
  .option("--clear-events", "Clear events")
423
1154
  .option("--clear-type-options", "Clear type options")
424
- .action(async (typeOrTitle, secondTitle, options, command) => {
425
- const globalOptions = getGlobalOptions(command);
426
- const startedAt = Date.now();
427
- // Support both `pm create "<title>"` and the natural subcommand-style
428
- // `pm create <type> "<title>"` so agents are never blocked by argument
429
- // count. When two positionals are given, the first is the item type.
430
- let positionalType;
431
- let positionalTitle;
432
- if (typeof secondTitle === "string" && secondTitle.length > 0) {
433
- positionalType = typeOrTitle;
434
- positionalTitle = secondTitle;
435
- }
436
- else if (typeof typeOrTitle === "string" && typeOrTitle.length > 0) {
437
- // Honor `pm create <type> --title ...` by treating the lone positional as
438
- // type when an explicit --title is already present.
439
- const explicitTitleProvided = typeof options.title === "string" && options.title.trim().length > 0;
440
- if (explicitTitleProvided && options.type === undefined) {
441
- positionalType = typeOrTitle;
442
- }
443
- else {
444
- positionalTitle = typeOrTitle;
445
- }
446
- }
447
- // pm-edge #1 (2026-05-28): when the sole positional matches a known
448
- // item type AND no --title was supplied, refuse early instead of
449
- // silently creating a Task titled with the type name (e.g. `pm create
450
- // Epic` would previously produce a Task literally titled "Epic"). The
451
- // guard fires only for the ambiguous single-positional case so the
452
- // documented `pm create <type> <title>` flow stays a never-block.
453
- if (positionalType === undefined &&
454
- typeof positionalTitle === "string" &&
455
- positionalTitle.length > 0 &&
456
- options.title === undefined &&
457
- options.type === undefined &&
458
- BUILTIN_TYPE_NAME_LOOKUP.has(positionalTitle.trim().toLowerCase())) {
459
- const matchedType = positionalTitle.trim();
460
- 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, {
461
- code: "create_positional_type_without_title",
462
- 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 \"" + matchedType + "\".",
463
- examples: [
464
- `pm create ${matchedType} "Wire up SSO for the agent harness"`,
465
- `pm create "Wire up SSO for the agent harness" --type ${matchedType}`,
466
- ],
467
- nextSteps: [
468
- `Re-run with both type and title: pm create ${matchedType} "<title>"`,
469
- ],
470
- });
471
- }
472
- if (typeof positionalType === "string" && positionalType.length > 0 && options.type === undefined) {
473
- options.type = positionalType;
474
- }
475
- if (typeof positionalTitle === "string" && positionalTitle.length > 0 && options.title === undefined) {
476
- options.title = positionalTitle;
477
- }
478
- // GH-214: resolve --body-file into the existing body field before
479
- // normalization so the rest of create is unchanged. CLI-only input alias.
480
- if (typeof options.bodyFile === "string") {
481
- options.body = await resolveBodyFileContent(options.bodyFile, options.body !== undefined ? String(options.body) : undefined);
482
- delete options.bodyFile;
483
- }
484
- const normalized = normalizeCreateOptions(options, { requireType: false });
485
- const { runCreate } = await import("./commands/create.js");
486
- const result = await runCreate(normalized, globalOptions);
487
- await invalidateSearchCachesForMutation(globalOptions, result);
488
- printResult(result, globalOptions);
489
- if (globalOptions.profile) {
490
- printError(`profile:command=create took_ms=${Date.now() - startedAt}`);
491
- }
492
- });
1155
+ .action(runCreateAction);
493
1156
  program
494
1157
  .command("copy")
495
1158
  .argument("<id>", "Source item id")
@@ -497,36 +1160,13 @@ export function registerMutationCommands(program) {
497
1160
  .option("--author <value>", "Mutation author")
498
1161
  .option("--message <value>", "History message")
499
1162
  .description("Copy an item into a new item id while resetting lifecycle fields.")
500
- .action(async (id, options, command) => {
501
- const globalOptions = getGlobalOptions(command);
502
- const startedAt = Date.now();
503
- const { runCopy } = await import("./commands/copy.js");
504
- const result = await runCopy(id, {
505
- title: typeof options.title === "string" ? options.title : undefined,
506
- author: typeof options.author === "string" ? options.author : undefined,
507
- message: typeof options.message === "string" ? options.message : undefined,
508
- }, globalOptions);
509
- await invalidateSearchCachesForMutation(globalOptions, result);
510
- printResult(result, globalOptions);
511
- if (globalOptions.profile) {
512
- printError(`profile:command=copy took_ms=${Date.now() - startedAt}`);
513
- }
514
- });
1163
+ .action(runCopyAction);
515
1164
  program
516
1165
  .command("focus")
517
1166
  .argument("[id]", "Item id to focus (omit to show current focus)")
518
1167
  .option("--clear", "Clear the focused item")
519
1168
  .description("Set/clear/show the session focused item that new items default --parent to.")
520
- .action(async (id, options, command) => {
521
- const globalOptions = getGlobalOptions(command);
522
- const startedAt = Date.now();
523
- const { runFocus } = await import("./commands/focus.js");
524
- const result = await runFocus(id, { clear: options.clear === true }, globalOptions);
525
- printResult(result, globalOptions);
526
- if (globalOptions.profile) {
527
- printError(`profile:command=focus took_ms=${Date.now() - startedAt}`);
528
- }
529
- });
1169
+ .action(runFocusAction);
530
1170
  const updateCommand = program
531
1171
  .command("update")
532
1172
  .argument("<id>", "Item id")
@@ -551,24 +1191,7 @@ export function registerMutationCommands(program) {
551
1191
  .option("--force", "Force ownership override");
552
1192
  addHiddenOption(updateCommand, "--allow_audit_update", "Alias for --allow-audit-update", false);
553
1193
  addHiddenOption(updateCommand, "--allow_audit_dep_update", "Alias for --allow-audit-dep-update", false);
554
- updateCommand
555
- .action(async (id, options, command) => {
556
- const globalOptions = getGlobalOptions(command);
557
- const startedAt = Date.now();
558
- // GH-214: resolve --body-file into the existing body field before
559
- // normalization so the rest of update is unchanged. CLI-only input alias.
560
- if (typeof options.bodyFile === "string") {
561
- options.body = await resolveBodyFileContent(options.bodyFile, options.body !== undefined ? String(options.body) : undefined);
562
- delete options.bodyFile;
563
- }
564
- const { runUpdate } = await import("./commands/update.js");
565
- const result = await runUpdate(id, normalizeUpdateOptions(options), globalOptions);
566
- await invalidateSearchCachesForMutation(globalOptions, result);
567
- printResult(result, globalOptions);
568
- if (globalOptions.profile) {
569
- printError(`profile:command=update took_ms=${Date.now() - startedAt}`);
570
- }
571
- });
1194
+ updateCommand.action(runUpdateAction);
572
1195
  const updateManyCommand = program
573
1196
  .command("update-many")
574
1197
  .description("Bulk-update matched items with dry-run plans and rollback checkpoints.")
@@ -676,7 +1299,7 @@ export function registerMutationCommands(program) {
676
1299
  .option("--force", "Force ownership override");
677
1300
  // Hidden pure snake_case underscore-duplicate aliases (kept parse-functional,
678
1301
  // omitted from --help to save agent context).
679
- for (const [flags, description] of [
1302
+ addHiddenOptions(updateManyCommand, [
680
1303
  ["--filter-assignee_filter <value>", "Alias for --filter-assignee-filter"],
681
1304
  ["--estimated_minutes <value>", "Alias for --estimated-minutes"],
682
1305
  ["--acceptance_criteria <value>", "Alias for --acceptance-criteria"],
@@ -694,36 +1317,14 @@ export function registerMutationCommands(program) {
694
1317
  ["--allow_audit_update", "Alias for --allow-audit-update"],
695
1318
  ["--allow_audit_dep_update", "Alias for --allow-audit-dep-update"],
696
1319
  ["--filter-estimate-missing", "Alias for --filter-estimates-missing"],
697
- ]) {
698
- addHiddenOption(updateManyCommand, flags, description, false);
699
- }
700
- for (const [flags, description] of [
1320
+ ], false);
1321
+ addHiddenOptions(updateManyCommand, [
701
1322
  ["--dep_remove <value>", "Alias for --dep-remove"],
702
1323
  ["--type_option <value>", "Alias for --type-option"],
703
1324
  ["--add_tags <value>", "Alias for --add-tags"],
704
1325
  ["--remove_tags <value>", "Alias for --remove-tags"],
705
- ]) {
706
- addHiddenOption(updateManyCommand, flags, description, true);
707
- }
708
- updateManyCommand
709
- .action(async (options, command) => {
710
- const globalOptions = getGlobalOptions(command);
711
- const startedAt = Date.now();
712
- const { runUpdateMany } = await import("./commands/update-many.js");
713
- const result = await runUpdateMany({
714
- status: typeof options.filterStatus === "string" ? options.filterStatus : undefined,
715
- list: buildUpdateManyListOptions(options),
716
- update: normalizeUpdateOptions(extractUpdateManyMutationOptionSource(options)),
717
- dryRun: options.dryRun === true ? true : undefined,
718
- rollback: typeof options.rollback === "string" ? options.rollback : undefined,
719
- checkpoint: options.checkpoint === false ? false : undefined,
720
- }, globalOptions);
721
- await invalidateSearchCachesForMutation(globalOptions, result);
722
- printResult(result, globalOptions);
723
- if (globalOptions.profile) {
724
- printError(`profile:command=update-many took_ms=${Date.now() - startedAt}`);
725
- }
726
- });
1326
+ ], true);
1327
+ updateManyCommand.action(runUpdateManyAction);
727
1328
  const closeCommand = program
728
1329
  .command("close")
729
1330
  .argument("<id>", "Item id")
@@ -746,43 +1347,7 @@ export function registerMutationCommands(program) {
746
1347
  // Unknown option error; the rendered help stays clean (aliases hidden).
747
1348
  addHiddenOption(closeCommand, "--expected_result <value>", "Alias for --expected-result", false);
748
1349
  addHiddenOption(closeCommand, "--actual_result <value>", "Alias for --actual-result", false);
749
- closeCommand
750
- .action(async (id, text, options, command) => {
751
- const globalOptions = getGlobalOptions(command);
752
- const startedAt = Date.now();
753
- const { runClose } = await import("./commands/close.js");
754
- const reasonFromOption = (typeof options.reason === "string" && options.reason.trim().length > 0 && options.reason) ||
755
- (typeof options.closeReason === "string" && options.closeReason.trim().length > 0 && options.closeReason) ||
756
- undefined;
757
- const resolvedText = typeof text === "string" && text.length > 0 ? text : reasonFromOption;
758
- const pickInlineString = (...candidates) => {
759
- for (const candidate of candidates) {
760
- if (typeof candidate === "string") {
761
- return candidate;
762
- }
763
- }
764
- return undefined;
765
- };
766
- const result = await runClose(id, resolvedText, {
767
- author: typeof options.author === "string" ? options.author : undefined,
768
- message: typeof options.message === "string" ? options.message : undefined,
769
- validateClose: options.validateClose === true
770
- ? "warn"
771
- : typeof options.validateClose === "string"
772
- ? options.validateClose
773
- : undefined,
774
- force: Boolean(options.force),
775
- duplicateOf: typeof options.duplicateOf === "string" ? options.duplicateOf : undefined,
776
- resolution: typeof options.resolution === "string" ? options.resolution : undefined,
777
- expectedResult: pickInlineString(options.expectedResult, options.expected_result, options.expected),
778
- actualResult: pickInlineString(options.actualResult, options.actual_result, options.actual),
779
- }, globalOptions);
780
- await invalidateSearchCachesForMutation(globalOptions, result);
781
- printResult(result, globalOptions);
782
- if (globalOptions.profile) {
783
- printError(`profile:command=close took_ms=${Date.now() - startedAt}`);
784
- }
785
- });
1350
+ closeCommand.action(runCloseAction);
786
1351
  const closeManyCommand = program
787
1352
  .command("close-many")
788
1353
  .description("Bulk-close matched items with a shared reason and full runClose semantics (dry-run + rollback checkpoint).")
@@ -822,62 +1387,7 @@ export function registerMutationCommands(program) {
822
1387
  addHiddenOption(closeManyCommand, "--filter-assignee_filter <value>", "Alias for --filter-assignee-filter", false);
823
1388
  addHiddenOption(closeManyCommand, "--expected_result <value>", "Alias for --expected-result", false);
824
1389
  addHiddenOption(closeManyCommand, "--actual_result <value>", "Alias for --actual-result", false);
825
- closeManyCommand.action(async (options, command) => {
826
- const globalOptions = getGlobalOptions(command);
827
- const startedAt = Date.now();
828
- const pickString = (...candidates) => {
829
- for (const candidate of candidates) {
830
- if (typeof candidate === "string") {
831
- return candidate;
832
- }
833
- }
834
- return undefined;
835
- };
836
- const { runCloseMany } = await import("./commands/close-many.js");
837
- const result = await runCloseMany({
838
- status: typeof options.filterStatus === "string" ? options.filterStatus : undefined,
839
- list: {
840
- type: typeof options.filterType === "string" ? options.filterType : undefined,
841
- tag: typeof options.filterTag === "string" ? options.filterTag : undefined,
842
- priority: typeof options.filterPriority === "string" ? options.filterPriority : undefined,
843
- deadlineBefore: typeof options.filterDeadlineBefore === "string" ? options.filterDeadlineBefore : undefined,
844
- deadlineAfter: typeof options.filterDeadlineAfter === "string" ? options.filterDeadlineAfter : undefined,
845
- updatedAfter: typeof options.filterUpdatedAfter === "string" ? options.filterUpdatedAfter : undefined,
846
- updatedBefore: typeof options.filterUpdatedBefore === "string" ? options.filterUpdatedBefore : undefined,
847
- createdAfter: typeof options.filterCreatedAfter === "string" ? options.filterCreatedAfter : undefined,
848
- createdBefore: typeof options.filterCreatedBefore === "string" ? options.filterCreatedBefore : undefined,
849
- ids: typeof options.ids === "string" ? options.ids : undefined,
850
- assignee: typeof options.filterAssignee === "string" ? options.filterAssignee : undefined,
851
- assigneeFilter: pickString(options.filterAssigneeFilter, options.filterAssignee_filter),
852
- parent: typeof options.filterParent === "string" ? options.filterParent : undefined,
853
- sprint: typeof options.filterSprint === "string" ? options.filterSprint : undefined,
854
- release: typeof options.filterRelease === "string" ? options.filterRelease : undefined,
855
- ...mapBulkContentAndGovernanceFilters(options),
856
- limit: typeof options.limit === "string" ? options.limit : undefined,
857
- offset: typeof options.offset === "string" ? options.offset : undefined,
858
- },
859
- reason: typeof options.reason === "string" ? options.reason : undefined,
860
- resolution: typeof options.resolution === "string" ? options.resolution : undefined,
861
- expectedResult: pickString(options.expectedResult, options.expected_result, options.expected),
862
- actualResult: pickString(options.actualResult, options.actual_result, options.actual),
863
- validateClose: options.validateClose === true
864
- ? "warn"
865
- : typeof options.validateClose === "string"
866
- ? options.validateClose
867
- : undefined,
868
- author: typeof options.author === "string" ? options.author : undefined,
869
- message: typeof options.message === "string" ? options.message : undefined,
870
- force: Boolean(options.force),
871
- dryRun: options.dryRun === true ? true : undefined,
872
- rollback: typeof options.rollback === "string" ? options.rollback : undefined,
873
- checkpoint: options.checkpoint === false ? false : undefined,
874
- }, globalOptions);
875
- await invalidateSearchCachesForMutation(globalOptions, result);
876
- printResult(result, globalOptions);
877
- if (globalOptions.profile) {
878
- printError(`profile:command=close-many took_ms=${Date.now() - startedAt}`);
879
- }
880
- });
1390
+ closeManyCommand.action(runCloseManyAction);
881
1391
  program
882
1392
  .command("delete")
883
1393
  .argument("<id>", "Item id")
@@ -886,24 +1396,7 @@ export function registerMutationCommands(program) {
886
1396
  .option("--force", "Force ownership override")
887
1397
  .option("--dry-run", "Preview the item file that would be deleted without mutating")
888
1398
  .description("Delete an item and record the change in history.")
889
- .action(async (id, options, command) => {
890
- const globalOptions = getGlobalOptions(command);
891
- const startedAt = Date.now();
892
- const { runDelete } = await import("./commands/delete.js");
893
- const result = await runDelete(id, {
894
- author: typeof options.author === "string" ? options.author : undefined,
895
- message: typeof options.message === "string" ? options.message : undefined,
896
- force: Boolean(options.force),
897
- dryRun: options.dryRun === true,
898
- }, globalOptions);
899
- if (result.dry_run !== true) {
900
- await invalidateSearchCachesForMutation(globalOptions, result);
901
- }
902
- printResult(result, globalOptions);
903
- if (globalOptions.profile) {
904
- printError(`profile:command=delete took_ms=${Date.now() - startedAt}`);
905
- }
906
- });
1399
+ .action(runDeleteAction);
907
1400
  program
908
1401
  .command("append")
909
1402
  .argument("<id>", "Item id")
@@ -914,33 +1407,7 @@ export function registerMutationCommands(program) {
914
1407
  .option("--message <value>", "Mutation message")
915
1408
  .option("--force", "Force ownership override")
916
1409
  .description("Append text to an item's body.")
917
- .action(async (id, text, options, command) => {
918
- const globalOptions = getGlobalOptions(command);
919
- const startedAt = Date.now();
920
- const bodyFromOption = typeof options.body === "string" ? options.body : undefined;
921
- const bodyFromAlias = typeof options.text === "string" ? options.text : undefined;
922
- const bodyFromPositional = typeof text === "string" ? text : undefined;
923
- const bodySourceCount = [bodyFromOption, bodyFromAlias, bodyFromPositional].filter((value) => value !== undefined).length;
924
- if (bodySourceCount > 1) {
925
- throw new PmCliError("Specify append text with exactly one source: positional [text], --body, or --text", EXIT_CODE.USAGE);
926
- }
927
- const resolvedBody = bodyFromOption ?? bodyFromAlias ?? bodyFromPositional;
928
- if (resolvedBody === undefined) {
929
- throw new PmCliError("Missing append text. Provide it as positional [text], --body <value>, or --text <value> (use - for stdin).", EXIT_CODE.USAGE);
930
- }
931
- const { runAppend } = await import("./commands/append.js");
932
- const result = await runAppend(id, {
933
- body: resolvedBody,
934
- author: typeof options.author === "string" ? options.author : undefined,
935
- message: typeof options.message === "string" ? options.message : undefined,
936
- force: Boolean(options.force),
937
- }, globalOptions);
938
- await invalidateSearchCachesForMutation(globalOptions, result);
939
- printResult(result, globalOptions);
940
- if (globalOptions.profile) {
941
- printError(`profile:command=append took_ms=${Date.now() - startedAt}`);
942
- }
943
- });
1410
+ .action(runAppendAction);
944
1411
  program
945
1412
  .command("restore")
946
1413
  .argument("<id>", "Item id")
@@ -949,21 +1416,7 @@ export function registerMutationCommands(program) {
949
1416
  .option("--message <value>", "History message")
950
1417
  .option("--force", "Force ownership/lock override")
951
1418
  .description("Restore an item to an earlier timestamp or version.")
952
- .action(async (id, target, options, command) => {
953
- const globalOptions = getGlobalOptions(command);
954
- const startedAt = Date.now();
955
- const { runRestore } = await import("./commands/restore.js");
956
- const result = await runRestore(id, target, {
957
- author: typeof options.author === "string" ? options.author : undefined,
958
- message: typeof options.message === "string" ? options.message : undefined,
959
- force: Boolean(options.force),
960
- }, globalOptions);
961
- await invalidateSearchCachesForMutation(globalOptions, result);
962
- printResult(result, globalOptions);
963
- if (globalOptions.profile) {
964
- printError(`profile:command=restore took_ms=${Date.now() - startedAt}`);
965
- }
966
- });
1419
+ .action(runRestoreAction);
967
1420
  const planCommand = program
968
1421
  .command("plan")
969
1422
  .description("Agent-optimized Plan item workflow: create, manage steps, link dependencies, approve, and materialize.")
@@ -1030,7 +1483,7 @@ export function registerMutationCommands(program) {
1030
1483
  .option("--force", "Force ownership override");
1031
1484
  // Hidden pure snake_case underscore-duplicate aliases (kept parse-functional,
1032
1485
  // omitted from --help to save agent context).
1033
- for (const [flags, description] of [
1486
+ addHiddenOptions(planCommand, [
1034
1487
  ["--resume_context <value>", "Alias for --resume-context"],
1035
1488
  ["--from_search <value>", "Alias for --from-search"],
1036
1489
  ["--step_title <value>", "Alias for --step-title"],
@@ -1054,104 +1507,12 @@ export function registerMutationCommands(program) {
1054
1507
  ["--materialize_type <value>", "Alias for --materialize-type"],
1055
1508
  ["--materialize_parent <value>", "Alias for --materialize-parent"],
1056
1509
  ["--materialize_tags <value>", "Alias for --materialize-tags"],
1057
- ]) {
1058
- addHiddenOption(planCommand, flags, description, false);
1059
- }
1060
- for (const [flags, description] of [
1510
+ ], false);
1511
+ addHiddenOptions(planCommand, [
1061
1512
  ["--blocked_by <value>", "Alias for --blocked-by"],
1062
1513
  ["--depends_on <value>", "Alias for --depends-on"],
1063
- ]) {
1064
- addHiddenOption(planCommand, flags, description, true);
1065
- }
1066
- planCommand
1067
- .action(async (subcommand, id, stepRef, reorderToken, options, command) => {
1068
- const globalOptions = getGlobalOptions(command);
1069
- const startedAt = Date.now();
1070
- const { runPlan, PLAN_SUBCOMMANDS } = await import("./commands/plan.js");
1071
- const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
1072
- if (!normalizedSubcommand) {
1073
- throw new PmCliError(`pm plan requires a subcommand. Allowed: ${PLAN_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
1074
- code: "missing_required_argument",
1075
- examples: [
1076
- 'pm plan create --title "Refactor lock retry"',
1077
- "pm plan show pm-a1b2 --depth standard",
1078
- 'pm plan add-step pm-a1b2 --step-title "Read lock.ts"',
1079
- ],
1080
- });
1081
- }
1082
- if (!PLAN_SUBCOMMANDS.includes(normalizedSubcommand)) {
1083
- const didYouMean = normalizedSubcommand === "list" || normalizedSubcommand === "ls"
1084
- ? ['pm list --type Plan', 'pm list-all --type Plan']
1085
- : undefined;
1086
- throw new PmCliError(`Unknown pm plan subcommand "${subcommand}". Allowed: ${PLAN_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, didYouMean ? { code: "unknown_subcommand", examples: didYouMean } : undefined);
1087
- }
1088
- const planOptions = { ...options };
1089
- // Normalize alternate-snake/camel aliases that Commander parses as different keys.
1090
- const aliasPairs = [
1091
- ["blocked_by", "blockedBy"],
1092
- ["resume_context", "resumeContext"],
1093
- ["from_search", "fromSearch"],
1094
- // pm-6mit: "step" is no longer folded into stepTitle here — it is a
1095
- // first-class repeatable option normalized inside runPlan (create
1096
- // accumulates ordered steps; other subcommands accept a single value
1097
- // as a stepTitle alias).
1098
- ["step_title", "stepTitle"],
1099
- ["step_body", "stepBody"],
1100
- ["step_owner", "stepOwner"],
1101
- ["step_status", "stepStatus"],
1102
- ["step_evidence", "stepEvidence"],
1103
- ["step_blocked_reason", "stepBlockedReason"],
1104
- ["step_replacement", "stepReplacement"],
1105
- ["depends_on", "dependsOn"],
1106
- ["link_kind", "linkKind"],
1107
- ["link_note", "linkNote"],
1108
- ["promote_to_item_dep", "promoteToItemDep"],
1109
- ["allow_multiple_active", "allowMultipleActive"],
1110
- ["decision_text", "decisionText"],
1111
- ["decision_rationale", "decisionRationale"],
1112
- ["decision_evidence", "decisionEvidence"],
1113
- ["discovery_text", "discoveryText"],
1114
- ["validation_text", "validationText"],
1115
- ["validation_command", "validationCommand"],
1116
- ["validation_expected", "validationExpected"],
1117
- ["materialize_type", "materializeType"],
1118
- ["materialize_parent", "materializeParent"],
1119
- ["materialize_tags", "materializeTags"],
1120
- ];
1121
- for (const [snake, camel] of aliasPairs) {
1122
- if (planOptions[snake] !== undefined && planOptions[camel] === undefined) {
1123
- planOptions[camel] = planOptions[snake];
1124
- }
1125
- }
1126
- let reorderTo;
1127
- if (normalizedSubcommand === "reorder-step" && typeof reorderToken === "string") {
1128
- const parsed = Number.parseInt(reorderToken, 10);
1129
- if (!Number.isFinite(parsed)) {
1130
- throw new PmCliError(`reorder-step requires an integer new order, got "${reorderToken}"`, EXIT_CODE.USAGE);
1131
- }
1132
- reorderTo = parsed;
1133
- }
1134
- // Allow positional title for `pm plan create "Title"` (mirrors pm create UX).
1135
- // Plan create never takes an id positional; the second token is the title.
1136
- let planId = id;
1137
- if (normalizedSubcommand === "create" && typeof id === "string" && id.length > 0 && planOptions.title === undefined) {
1138
- planOptions.title = id;
1139
- planId = undefined;
1140
- }
1141
- const result = await runPlan({
1142
- subcommand: normalizedSubcommand,
1143
- id: planId,
1144
- stepRef,
1145
- reorderTo,
1146
- options: planOptions,
1147
- global: globalOptions,
1148
- });
1149
- await invalidateSearchCachesForMutation(globalOptions, result);
1150
- printResult(result, globalOptions);
1151
- if (globalOptions.profile) {
1152
- printError(`profile:command=plan took_ms=${Date.now() - startedAt}`);
1153
- }
1154
- });
1514
+ ], true);
1515
+ planCommand.action(runPlanAction);
1155
1516
  void planCommand;
1156
1517
  program
1157
1518
  .command("history-redact")
@@ -1241,65 +1602,7 @@ export function registerMutationCommands(program) {
1241
1602
  .option("--message <value>", "Audit history message for the compaction marker entry")
1242
1603
  .option("--force", "Force ownership/lock override")
1243
1604
  .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.")
1244
- .action(async (id, options, command) => {
1245
- const globalOptions = getGlobalOptions(command);
1246
- const startedAt = Date.now();
1247
- const { runHistoryCompact, runHistoryCompactBulk, assertHistoryCompactTarget } = await import("./commands/history-compact.js");
1248
- const parseNonNegativeIntFlag = (raw, flag) => {
1249
- if (typeof raw !== "string") {
1250
- return undefined;
1251
- }
1252
- // Strict: reject "10abc"/"3.5"/"-3" that Number.parseInt would silently truncate.
1253
- if (!/^\d+$/.test(raw.trim())) {
1254
- throw new PmCliError(`history-compact ${flag} must be a non-negative integer.`, EXIT_CODE.USAGE);
1255
- }
1256
- return Number.parseInt(raw, 10);
1257
- };
1258
- const ids = typeof options.ids === "string" ? splitCommaList(options.ids) : undefined;
1259
- const allOver = parseNonNegativeIntFlag(options.allOver, "--all-over");
1260
- const minEntries = parseNonNegativeIntFlag(options.minEntries, "--min-entries");
1261
- if (options.closed === true && options.allStreams === true) {
1262
- throw new PmCliError("history-compact: --closed and --all-streams are mutually exclusive; pick one lifecycle scope.", EXIT_CODE.USAGE);
1263
- }
1264
- const scope = options.closed === true ? "closed" : options.allStreams === true ? "all-streams" : undefined;
1265
- const isBulk = ids !== undefined || allOver !== undefined || scope !== undefined;
1266
- if (isBulk && typeof options.before === "string") {
1267
- throw new PmCliError("history-compact: --before applies only in single-id mode (bulk mode always compacts full streams).", EXIT_CODE.USAGE);
1268
- }
1269
- assertHistoryCompactTarget(id, { ids, allOver, scope });
1270
- if (id === undefined) {
1271
- const result = await runHistoryCompactBulk({
1272
- ids,
1273
- scope,
1274
- allOver,
1275
- minEntries,
1276
- dryRun: options.dryRun === true,
1277
- author: typeof options.author === "string" ? options.author : undefined,
1278
- message: typeof options.message === "string" ? options.message : undefined,
1279
- force: Boolean(options.force),
1280
- }, globalOptions);
1281
- printResult(result, globalOptions);
1282
- if (result.totals.items_errored > 0) {
1283
- // One failing stream never aborts the pass, but the command must still
1284
- // fail for gating callers.
1285
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
1286
- }
1287
- }
1288
- else {
1289
- const result = await runHistoryCompact(id, {
1290
- before: typeof options.before === "string" ? options.before : undefined,
1291
- dryRun: options.dryRun === true,
1292
- author: typeof options.author === "string" ? options.author : undefined,
1293
- message: typeof options.message === "string" ? options.message : undefined,
1294
- force: Boolean(options.force),
1295
- }, globalOptions);
1296
- printResult(result, globalOptions);
1297
- }
1298
- // history-compact only rewrites the history stream; item content is untouched.
1299
- if (globalOptions.profile) {
1300
- printError(`profile:command=history-compact took_ms=${Date.now() - startedAt}`);
1301
- }
1302
- });
1605
+ .action(runHistoryCompactAction);
1303
1606
  const schemaCommand = program
1304
1607
  .command("schema")
1305
1608
  .argument("[subcommand]", "Schema subcommand: list, show, show-status, add-type, remove-type, add-status, remove-status, or a custom item type name shorthand")
@@ -1326,105 +1629,7 @@ export function registerMutationCommands(program) {
1326
1629
  // Hidden pure snake_case underscore-duplicate alias.
1327
1630
  addHiddenOption(schemaCommand, "--default_status <status>", "Alias for --default-status", false);
1328
1631
  schemaCommand
1329
- .action(async (subcommand, name, options, command) => {
1330
- const globalOptions = getGlobalOptions(command);
1331
- const startedAt = Date.now();
1332
- const schemaModule = await import("./commands/schema.js");
1333
- const { SCHEMA_SUBCOMMANDS } = schemaModule;
1334
- let normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
1335
- let typeName = name;
1336
- if (!normalizedSubcommand) {
1337
- throw new PmCliError(`pm schema requires a subcommand. Allowed: ${SCHEMA_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
1338
- code: "missing_required_argument",
1339
- examples: [
1340
- "pm schema list",
1341
- "pm schema show Task",
1342
- "pm schema show-status open",
1343
- 'pm schema add-type Spike --description "Time-boxed investigation" --default-status open',
1344
- "pm schema remove-type Spike",
1345
- "pm schema add-status review --role active --alias in_review",
1346
- "pm schema remove-status review",
1347
- "pm schema add-field severity_level --type string --commands create,update",
1348
- "pm schema list-fields",
1349
- "pm schema apply-preset agile",
1350
- "pm schema add-type --infer --min-count 10",
1351
- ],
1352
- });
1353
- }
1354
- const aliases =
1355
- /* c8 ignore next -- --alias is registered with commander `collect`, so it is always an array here; the string arm is a defensive guard for non-CLI (programmatic) callers */
1356
- typeof options.alias === "string"
1357
- ? [options.alias]
1358
- : Array.isArray(options.alias)
1359
- ? options.alias
1360
- : undefined;
1361
- const roles =
1362
- /* c8 ignore next -- --role is registered with commander `collect`, so it is always an array here; the string arm is a defensive guard for non-CLI (programmatic) callers */
1363
- typeof options.role === "string"
1364
- ? [options.role]
1365
- : Array.isArray(options.role)
1366
- ? options.role
1367
- : undefined;
1368
- const defaultStatus = typeof options.defaultStatus === "string"
1369
- ? options.defaultStatus
1370
- : typeof options.default_status === "string"
1371
- ? options.default_status
1372
- : undefined;
1373
- const order = parseSchemaOrderOption(options.order);
1374
- // --commands/--required-types are repeatable Commander `collect` flags, so
1375
- // their value is always a string[] (or undefined when omitted); each entry
1376
- // may itself be a comma-list, which we split and flatten here.
1377
- const splitCollectedCommaList = (raw) => {
1378
- if (!Array.isArray(raw)) {
1379
- return undefined;
1380
- }
1381
- return raw
1382
- .flatMap((value) => value.split(","))
1383
- .map((value) => value.trim())
1384
- .filter((value) => value.length > 0);
1385
- };
1386
- const commands = splitCollectedCommaList(options.commands);
1387
- const requiredTypes = splitCollectedCommaList(options.requiredTypes);
1388
- const minCount = parseSchemaOrderOption(options.minCount);
1389
- if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand) &&
1390
- typeName === undefined &&
1391
- !looksLikeSchemaSubcommandTypo(normalizedSubcommand)) {
1392
- typeName = subcommand;
1393
- normalizedSubcommand = "add-type";
1394
- }
1395
- if (!SCHEMA_SUBCOMMANDS.includes(normalizedSubcommand)) {
1396
- throw new PmCliError(`Unknown pm schema subcommand "${subcommand}". Allowed: ${SCHEMA_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, { code: "unknown_subcommand" });
1397
- }
1398
- const author = typeof options.author === "string" ? options.author : undefined;
1399
- const force = Boolean(options.force);
1400
- const description = typeof options.description === "string" ? options.description : undefined;
1401
- const result = await dispatchSchemaSubcommand(schemaModule, {
1402
- normalizedSubcommand,
1403
- typeName,
1404
- options,
1405
- aliases,
1406
- roles,
1407
- commands,
1408
- requiredTypes,
1409
- defaultStatus,
1410
- order,
1411
- minCount,
1412
- author,
1413
- force,
1414
- description,
1415
- globalOptions,
1416
- });
1417
- // Schema inspection and type registration do not touch item content, so search caches stay valid.
1418
- if (globalOptions.json === true || globalOptions.defaultOutputFormat === "json") {
1419
- printResult(result, globalOptions);
1420
- }
1421
- else if (!globalOptions.quiet) {
1422
- renderSchemaResultHuman(schemaModule, result);
1423
- }
1424
- if (globalOptions.profile) {
1425
- printError(`profile:command=schema took_ms=${Date.now() - startedAt}`);
1426
- }
1427
- });
1632
+ .action(runSchemaAction);
1428
1633
  const profileCommand = program
1429
1634
  .command("profile")
1430
1635
  .argument("[subcommand]", "Profile subcommand: list, show, apply, or lint")
@@ -1433,39 +1638,7 @@ export function registerMutationCommands(program) {
1433
1638
  .option("--author <value>", "Mutation author")
1434
1639
  .option("--force", "Force ownership/lock override")
1435
1640
  .description("List, show, apply, and lint project profiles — archetype bundles of item types, statuses, fields, workflows, config, templates, and recommended packages.");
1436
- profileCommand.action(async (subcommand, name, options, command) => {
1437
- const globalOptions = getGlobalOptions(command);
1438
- const startedAt = Date.now();
1439
- const profileModule = await import("./commands/profile.js");
1440
- const { PROFILE_SUBCOMMANDS } = profileModule;
1441
- const normalizedSubcommand = (subcommand ?? "").trim().toLowerCase();
1442
- if (!normalizedSubcommand) {
1443
- throw new PmCliError(`pm profile requires a subcommand. Allowed: ${PROFILE_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, {
1444
- code: "missing_required_argument",
1445
- examples: ["pm profile list", "pm profile show agile", "pm profile apply agile --dry-run", "pm profile lint agile"],
1446
- });
1447
- }
1448
- if (!PROFILE_SUBCOMMANDS.includes(normalizedSubcommand)) {
1449
- throw new PmCliError(`Unknown pm profile subcommand "${subcommand}". Allowed: ${PROFILE_SUBCOMMANDS.join(", ")}`, EXIT_CODE.USAGE, { code: "unknown_subcommand" });
1450
- }
1451
- const result = await dispatchProfileSubcommand(profileModule, normalizedSubcommand, name, options, globalOptions);
1452
- // Profile inspection and schema staging do not mutate item content, so search caches stay valid (mirrors pm schema).
1453
- if (globalOptions.json === true || globalOptions.defaultOutputFormat === "json") {
1454
- printResult(result, globalOptions);
1455
- }
1456
- else if (!globalOptions.quiet) {
1457
- renderProfileResultHuman(profileModule, result);
1458
- }
1459
- // `pm profile lint` is a validation gate: exit non-zero when the profile has
1460
- // error-severity findings so shell/CI callers can fail on them. Warnings keep
1461
- // `ok` true and never fail the command.
1462
- if (result.action === "lint" && !result.ok) {
1463
- process.exitCode = EXIT_CODE.GENERIC_FAILURE;
1464
- }
1465
- if (globalOptions.profile) {
1466
- printError(`profile:command=profile took_ms=${Date.now() - startedAt}`);
1467
- }
1468
- });
1641
+ profileCommand.action(runProfileAction);
1469
1642
  program
1470
1643
  .command("comments")
1471
1644
  .argument("<id>", "Item id")
@@ -1481,48 +1654,7 @@ export function registerMutationCommands(program) {
1481
1654
  .option("--allow-audit-comment", "Allow non-owner append-only comment audits (add/edit/delete) without requiring --force")
1482
1655
  .option("--force", "Force ownership override")
1483
1656
  .description("List, add, edit, or delete comments for an item.")
1484
- .action(async (id, text, options, command) => {
1485
- const globalOptions = getGlobalOptions(command);
1486
- const startedAt = Date.now();
1487
- const editIndex = typeof options.edit === "number" ? options.edit : undefined;
1488
- const deleteIndex = typeof options.delete === "number" ? options.delete : undefined;
1489
- const addFromOption = typeof options.add === "string" ? options.add : undefined;
1490
- const addFromPositional = typeof text === "string" ? text : undefined;
1491
- const readFromStdin = options.stdin === true;
1492
- const readFromFile = typeof options.file === "string" ? options.file : undefined;
1493
- const sourceCount = Number(addFromOption !== undefined) +
1494
- Number(addFromPositional !== undefined) +
1495
- Number(readFromStdin) +
1496
- Number(readFromFile !== undefined);
1497
- if (sourceCount > 1) {
1498
- if (addFromOption !== undefined && addFromPositional !== undefined && !readFromStdin && readFromFile === undefined) {
1499
- throw new PmCliError("Specify comment text either as positional [text] or with --add, not both", EXIT_CODE.USAGE);
1500
- }
1501
- throw new PmCliError("Specify comment text with exactly one source: positional [text], --add, --stdin, or --file", EXIT_CODE.USAGE);
1502
- }
1503
- const add = addFromOption ?? addFromPositional;
1504
- const { runComments } = await import("./commands/comments.js");
1505
- const result = await runComments(id, {
1506
- add,
1507
- stdin: readFromStdin,
1508
- file: readFromFile,
1509
- edit: editIndex,
1510
- delete: deleteIndex,
1511
- limit: typeof options.limit === "string" ? options.limit : undefined,
1512
- author: typeof options.author === "string" ? options.author : undefined,
1513
- message: typeof options.message === "string" ? options.message : undefined,
1514
- allowAuditComment: Boolean(options.allowAuditComment),
1515
- force: Boolean(options.force),
1516
- }, globalOptions);
1517
- const isMutation = typeof add === "string" || readFromStdin || readFromFile !== undefined || editIndex !== undefined || deleteIndex !== undefined;
1518
- if (isMutation) {
1519
- await invalidateSearchCachesForMutation(globalOptions, result);
1520
- }
1521
- printResult(result, globalOptions);
1522
- if (globalOptions.profile) {
1523
- printError(`profile:command=comments took_ms=${Date.now() - startedAt}`);
1524
- }
1525
- });
1657
+ .action(runCommentsAction);
1526
1658
  program
1527
1659
  .command("notes")
1528
1660
  .argument("<id>", "Item id")
@@ -1535,32 +1667,7 @@ export function registerMutationCommands(program) {
1535
1667
  .option("--allow-audit-comment", "Backward-compatible alias for --allow-audit-note")
1536
1668
  .option("--force", "Force ownership override")
1537
1669
  .description("List or add notes for an item.")
1538
- .action(async (id, text, options, command) => {
1539
- const globalOptions = getGlobalOptions(command);
1540
- const startedAt = Date.now();
1541
- const addFromOption = typeof options.add === "string" ? options.add : undefined;
1542
- const addFromPositional = typeof text === "string" ? text : undefined;
1543
- if (addFromOption !== undefined && addFromPositional !== undefined) {
1544
- throw new PmCliError("Specify note text either as positional [text] or with --add, not both", EXIT_CODE.USAGE);
1545
- }
1546
- const add = addFromOption ?? addFromPositional;
1547
- const { runNotes } = await import("./commands/notes.js");
1548
- const result = await runNotes(id, {
1549
- add,
1550
- limit: typeof options.limit === "string" ? options.limit : undefined,
1551
- author: typeof options.author === "string" ? options.author : undefined,
1552
- message: typeof options.message === "string" ? options.message : undefined,
1553
- allowAuditComment: Boolean(options.allowAuditNote || options.allowAuditComment),
1554
- force: Boolean(options.force),
1555
- }, globalOptions);
1556
- if (typeof add === "string") {
1557
- await invalidateSearchCachesForMutation(globalOptions, result);
1558
- }
1559
- printResult(result, globalOptions);
1560
- if (globalOptions.profile) {
1561
- printError(`profile:command=notes took_ms=${Date.now() - startedAt}`);
1562
- }
1563
- });
1670
+ .action(runNotesAction);
1564
1671
  program
1565
1672
  .command("learnings")
1566
1673
  .argument("<id>", "Item id")
@@ -1573,32 +1680,7 @@ export function registerMutationCommands(program) {
1573
1680
  .option("--allow-audit-comment", "Backward-compatible alias for --allow-audit-learning")
1574
1681
  .option("--force", "Force ownership override")
1575
1682
  .description("List or add learnings for an item.")
1576
- .action(async (id, text, options, command) => {
1577
- const globalOptions = getGlobalOptions(command);
1578
- const startedAt = Date.now();
1579
- const addFromOption = typeof options.add === "string" ? options.add : undefined;
1580
- const addFromPositional = typeof text === "string" ? text : undefined;
1581
- if (addFromOption !== undefined && addFromPositional !== undefined) {
1582
- throw new PmCliError("Specify learning text either as positional [text] or with --add, not both", EXIT_CODE.USAGE);
1583
- }
1584
- const add = addFromOption ?? addFromPositional;
1585
- const { runLearnings } = await import("./commands/learnings.js");
1586
- const result = await runLearnings(id, {
1587
- add,
1588
- limit: typeof options.limit === "string" ? options.limit : undefined,
1589
- author: typeof options.author === "string" ? options.author : undefined,
1590
- message: typeof options.message === "string" ? options.message : undefined,
1591
- allowAuditComment: Boolean(options.allowAuditLearning || options.allowAuditComment),
1592
- force: Boolean(options.force),
1593
- }, globalOptions);
1594
- if (typeof add === "string") {
1595
- await invalidateSearchCachesForMutation(globalOptions, result);
1596
- }
1597
- printResult(result, globalOptions);
1598
- if (globalOptions.profile) {
1599
- printError(`profile:command=learnings took_ms=${Date.now() - startedAt}`);
1600
- }
1601
- });
1683
+ .action(runLearningsAction);
1602
1684
  const filesCommand = program
1603
1685
  .command("files")
1604
1686
  .description("Manage files linked to an item.");
@@ -1616,36 +1698,7 @@ export function registerMutationCommands(program) {
1616
1698
  .option("--author <value>", "Mutation author")
1617
1699
  .option("--message <value>", "History message")
1618
1700
  .option("--force", "Force ownership override")
1619
- .action(async (id, options, command) => {
1620
- const globalOptions = getGlobalOptions(command);
1621
- const startedAt = Date.now();
1622
- const addValues = Array.isArray(options.add) ? options.add : [];
1623
- const addGlobValues = Array.isArray(options.addGlob) ? options.addGlob : [];
1624
- const removeValues = Array.isArray(options.remove) ? options.remove : [];
1625
- const migrateValues = Array.isArray(options.migrate) ? options.migrate : [];
1626
- const { runFiles } = await import("./commands/files.js");
1627
- const result = await runFiles(id, {
1628
- add: addValues,
1629
- addGlob: addGlobValues,
1630
- remove: removeValues,
1631
- migrate: migrateValues,
1632
- note: typeof options.note === "string" ? options.note : undefined,
1633
- list: Boolean(options.list),
1634
- appendStable: Boolean(options.appendStable),
1635
- validatePaths: Boolean(options.validatePaths),
1636
- audit: Boolean(options.audit),
1637
- author: typeof options.author === "string" ? options.author : undefined,
1638
- message: typeof options.message === "string" ? options.message : undefined,
1639
- force: Boolean(options.force),
1640
- }, globalOptions);
1641
- if (addValues.length > 0 || addGlobValues.length > 0 || removeValues.length > 0 || migrateValues.length > 0) {
1642
- await invalidateSearchCachesForMutation(globalOptions, result);
1643
- }
1644
- printResult(result, globalOptions);
1645
- if (globalOptions.profile) {
1646
- printError(`profile:command=files took_ms=${Date.now() - startedAt}`);
1647
- }
1648
- });
1701
+ .action(runFilesAction);
1649
1702
  filesCommand
1650
1703
  .command("discover")
1651
1704
  .argument("<id>", "Item id")
@@ -1656,30 +1709,7 @@ export function registerMutationCommands(program) {
1656
1709
  .option("--message <value>", "History message")
1657
1710
  .option("--force", "Force ownership override")
1658
1711
  .description("Discover existing file paths referenced in item text and optionally link missing files.")
1659
- .action(async (id, options, command) => {
1660
- const globalOptions = getGlobalOptions(command);
1661
- const startedAt = Date.now();
1662
- // Flags also declared on the parent files command (--note/--append-stable/
1663
- // --author/--message/--force) are consumed by the parent during parse, so
1664
- // merge ancestor opts back in (own options win) instead of reading opts() alone.
1665
- const mergedOptions = { ...command.optsWithGlobals(), ...options };
1666
- const { runFilesDiscover } = await import("./commands/files.js");
1667
- const result = await runFilesDiscover(id, {
1668
- apply: Boolean(mergedOptions.apply),
1669
- note: typeof mergedOptions.note === "string" ? mergedOptions.note : undefined,
1670
- appendStable: Boolean(mergedOptions.appendStable),
1671
- author: typeof mergedOptions.author === "string" ? mergedOptions.author : undefined,
1672
- message: typeof mergedOptions.message === "string" ? mergedOptions.message : undefined,
1673
- force: Boolean(mergedOptions.force),
1674
- }, globalOptions);
1675
- if (result.changed) {
1676
- await invalidateSearchCachesForMutation(globalOptions, result);
1677
- }
1678
- printResult(result, globalOptions);
1679
- if (globalOptions.profile) {
1680
- printError(`profile:command=files.discover took_ms=${Date.now() - startedAt}`);
1681
- }
1682
- });
1712
+ .action(runFilesDiscoverAction);
1683
1713
  program
1684
1714
  .command("docs")
1685
1715
  .argument("<id>", "Item id")
@@ -1695,35 +1725,7 @@ export function registerMutationCommands(program) {
1695
1725
  .option("--message <value>", "History message")
1696
1726
  .option("--force", "Force ownership override")
1697
1727
  .description("Manage docs linked to an item.")
1698
- .action(async (id, options, command) => {
1699
- const globalOptions = getGlobalOptions(command);
1700
- const startedAt = Date.now();
1701
- const addValues = Array.isArray(options.add) ? options.add : [];
1702
- const addGlobValues = Array.isArray(options.addGlob) ? options.addGlob : [];
1703
- const removeValues = Array.isArray(options.remove) ? options.remove : [];
1704
- const migrateValues = Array.isArray(options.migrate) ? options.migrate : [];
1705
- const { runDocs } = await import("./commands/docs.js");
1706
- const result = await runDocs(id, {
1707
- add: addValues,
1708
- addGlob: addGlobValues,
1709
- remove: removeValues,
1710
- migrate: migrateValues,
1711
- note: typeof options.note === "string" ? options.note : undefined,
1712
- list: Boolean(options.list),
1713
- validatePaths: Boolean(options.validatePaths),
1714
- audit: Boolean(options.audit),
1715
- author: typeof options.author === "string" ? options.author : undefined,
1716
- message: typeof options.message === "string" ? options.message : undefined,
1717
- force: Boolean(options.force),
1718
- }, globalOptions);
1719
- if (addValues.length > 0 || addGlobValues.length > 0 || removeValues.length > 0 || migrateValues.length > 0) {
1720
- await invalidateSearchCachesForMutation(globalOptions, result);
1721
- }
1722
- printResult(result, globalOptions);
1723
- if (globalOptions.profile) {
1724
- printError(`profile:command=docs took_ms=${Date.now() - startedAt}`);
1725
- }
1726
- });
1728
+ .action(runDocsAction);
1727
1729
  program
1728
1730
  .command("deps")
1729
1731
  .argument("<id>", "Item id")
@@ -1732,25 +1734,7 @@ export function registerMutationCommands(program) {
1732
1734
  .option("--collapse <value>", "Collapse mode (none or repeated)", "none")
1733
1735
  .option("--summary", "Return counts only without full tree/graph payload")
1734
1736
  .description("Show dependency relationships for an item.")
1735
- .action(async (id, options, command) => {
1736
- const globalOptions = getGlobalOptions(command);
1737
- const startedAt = Date.now();
1738
- const { runDeps } = await import("./commands/deps.js");
1739
- // --format and --collapse carry commander defaults ("tree"/"none"), so
1740
- // they are always strings by the time the action runs; --maxDepth has no
1741
- // default and may be unset. Use `as string` rather than String(...) so an
1742
- // omitted option stays undefined instead of becoming the literal "undefined".
1743
- const result = await runDeps(id, {
1744
- format: options.format,
1745
- maxDepth: typeof options.maxDepth === "string" ? options.maxDepth : undefined,
1746
- collapse: options.collapse,
1747
- summary: options.summary === true,
1748
- }, globalOptions);
1749
- printResult(result, globalOptions);
1750
- if (globalOptions.profile) {
1751
- printError(`profile:command=deps took_ms=${Date.now() - startedAt}`);
1752
- }
1753
- });
1737
+ .action(runDepsAction);
1754
1738
  }
1755
1739
  //# sourceMappingURL=register-mutation.js.map
1756
- //# debugId=703247b2-e81d-5a78-999d-6d493a4cf9bf
1740
+ //# debugId=506e1f95-1444-5306-9a5e-c1fb3726b2df