@unbrained/pm-cli 2026.6.12 → 2026.6.16

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 (777) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/README.md +2 -2
  3. package/dist/cli/bootstrap-args.d.ts +29 -0
  4. package/dist/cli/bootstrap-args.js +11 -4
  5. package/dist/cli/bootstrap-args.js.map +1 -1
  6. package/dist/cli/commander-usage.d.ts +12 -0
  7. package/dist/cli/commander-usage.js +18 -7
  8. package/dist/cli/commander-usage.js.map +1 -1
  9. package/dist/cli/commands/activity.d.ts +19 -0
  10. package/dist/cli/commands/activity.js +12 -2
  11. package/dist/cli/commands/activity.js.map +1 -1
  12. package/dist/cli/commands/aggregate.d.ts +58 -0
  13. package/dist/cli/commands/aggregate.js +48 -15
  14. package/dist/cli/commands/aggregate.js.map +1 -1
  15. package/dist/cli/commands/annotation-command.d.ts +6 -1
  16. package/dist/cli/commands/annotation-command.js +72 -2
  17. package/dist/cli/commands/annotation-command.js.map +1 -1
  18. package/dist/cli/commands/append.js +4 -3
  19. package/dist/cli/commands/append.js.map +1 -1
  20. package/dist/cli/commands/close-many.d.ts +20 -0
  21. package/dist/cli/commands/close-many.js +14 -23
  22. package/dist/cli/commands/close-many.js.map +1 -1
  23. package/dist/cli/commands/close.js +37 -4
  24. package/dist/cli/commands/close.js.map +1 -1
  25. package/dist/cli/commands/comments-audit.js +3 -2
  26. package/dist/cli/commands/comments-audit.js.map +1 -1
  27. package/dist/cli/commands/comments.d.ts +2 -0
  28. package/dist/cli/commands/comments.js +49 -23
  29. package/dist/cli/commands/comments.js.map +1 -1
  30. package/dist/cli/commands/completion.js +269 -8
  31. package/dist/cli/commands/completion.js.map +1 -1
  32. package/dist/cli/commands/config.d.ts +51 -1
  33. package/dist/cli/commands/config.js +50 -12
  34. package/dist/cli/commands/config.js.map +1 -1
  35. package/dist/cli/commands/context.d.ts +79 -1
  36. package/dist/cli/commands/context.js +151 -25
  37. package/dist/cli/commands/context.js.map +1 -1
  38. package/dist/cli/commands/contracts.d.ts +80 -1
  39. package/dist/cli/commands/contracts.js +54 -4
  40. package/dist/cli/commands/contracts.js.map +1 -1
  41. package/dist/cli/commands/create.d.ts +49 -0
  42. package/dist/cli/commands/create.js +112 -7
  43. package/dist/cli/commands/create.js.map +1 -1
  44. package/dist/cli/commands/dedupe-audit.d.ts +33 -0
  45. package/dist/cli/commands/dedupe-audit.js +18 -14
  46. package/dist/cli/commands/dedupe-audit.js.map +1 -1
  47. package/dist/cli/commands/deps.js +7 -4
  48. package/dist/cli/commands/deps.js.map +1 -1
  49. package/dist/cli/commands/event-validation-messages.js +3 -3
  50. package/dist/cli/commands/event-validation-messages.js.map +1 -1
  51. package/dist/cli/commands/extension/bundled-catalog.d.ts +7 -0
  52. package/dist/cli/commands/extension/bundled-catalog.js +19 -15
  53. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -1
  54. package/dist/cli/commands/extension/install-sources.d.ts +41 -1
  55. package/dist/cli/commands/extension/install-sources.js +26 -8
  56. package/dist/cli/commands/extension/install-sources.js.map +1 -1
  57. package/dist/cli/commands/extension/shared.d.ts +5 -0
  58. package/dist/cli/commands/extension/shared.js +9 -3
  59. package/dist/cli/commands/extension/shared.js.map +1 -1
  60. package/dist/cli/commands/extension.d.ts +133 -1
  61. package/dist/cli/commands/extension.js +127 -9
  62. package/dist/cli/commands/extension.js.map +1 -1
  63. package/dist/cli/commands/files.d.ts +30 -1
  64. package/dist/cli/commands/files.js +21 -2
  65. package/dist/cli/commands/files.js.map +1 -1
  66. package/dist/cli/commands/focus.d.ts +11 -0
  67. package/dist/cli/commands/focus.js +86 -0
  68. package/dist/cli/commands/focus.js.map +1 -0
  69. package/dist/cli/commands/get.d.ts +9 -2
  70. package/dist/cli/commands/get.js +34 -6
  71. package/dist/cli/commands/get.js.map +1 -1
  72. package/dist/cli/commands/guide.d.ts +5 -0
  73. package/dist/cli/commands/guide.js +6 -3
  74. package/dist/cli/commands/guide.js.map +1 -1
  75. package/dist/cli/commands/health.d.ts +109 -0
  76. package/dist/cli/commands/health.js +87 -35
  77. package/dist/cli/commands/health.js.map +1 -1
  78. package/dist/cli/commands/history-compact.js +27 -36
  79. package/dist/cli/commands/history-compact.js.map +1 -1
  80. package/dist/cli/commands/history-redact.d.ts +46 -0
  81. package/dist/cli/commands/history-redact.js +99 -67
  82. package/dist/cli/commands/history-redact.js.map +1 -1
  83. package/dist/cli/commands/history-repair.js +34 -37
  84. package/dist/cli/commands/history-repair.js.map +1 -1
  85. package/dist/cli/commands/history.js +6 -2
  86. package/dist/cli/commands/history.js.map +1 -1
  87. package/dist/cli/commands/index.d.ts +1 -0
  88. package/dist/cli/commands/index.js +3 -2
  89. package/dist/cli/commands/index.js.map +1 -1
  90. package/dist/cli/commands/init-agent-guidance.d.ts +54 -0
  91. package/dist/cli/commands/init-agent-guidance.js +31 -4
  92. package/dist/cli/commands/init-agent-guidance.js.map +1 -1
  93. package/dist/cli/commands/init.d.ts +36 -1
  94. package/dist/cli/commands/init.js +38 -5
  95. package/dist/cli/commands/init.js.map +1 -1
  96. package/dist/cli/commands/learnings.js +4 -3
  97. package/dist/cli/commands/learnings.js.map +1 -1
  98. package/dist/cli/commands/linked-test-parsers.d.ts +5 -0
  99. package/dist/cli/commands/linked-test-parsers.js +5 -2
  100. package/dist/cli/commands/linked-test-parsers.js.map +1 -1
  101. package/dist/cli/commands/list-filter-shared.d.ts +8 -0
  102. package/dist/cli/commands/list-filter-shared.js +70 -0
  103. package/dist/cli/commands/list-filter-shared.js.map +1 -0
  104. package/dist/cli/commands/list.d.ts +116 -0
  105. package/dist/cli/commands/list.js +194 -6
  106. package/dist/cli/commands/list.js.map +1 -1
  107. package/dist/cli/commands/normalize.js +16 -2
  108. package/dist/cli/commands/normalize.js.map +1 -1
  109. package/dist/cli/commands/notes.js +4 -3
  110. package/dist/cli/commands/notes.js.map +1 -1
  111. package/dist/cli/commands/plan.js +3 -2
  112. package/dist/cli/commands/plan.js.map +1 -1
  113. package/dist/cli/commands/reindex.d.ts +83 -0
  114. package/dist/cli/commands/reindex.js +45 -10
  115. package/dist/cli/commands/reindex.js.map +1 -1
  116. package/dist/cli/commands/restore.d.ts +40 -1
  117. package/dist/cli/commands/restore.js +27 -2
  118. package/dist/cli/commands/restore.js.map +1 -1
  119. package/dist/cli/commands/schema.d.ts +18 -0
  120. package/dist/cli/commands/schema.js +30 -3
  121. package/dist/cli/commands/schema.js.map +1 -1
  122. package/dist/cli/commands/search.d.ts +289 -1
  123. package/dist/cli/commands/search.js +367 -60
  124. package/dist/cli/commands/search.js.map +1 -1
  125. package/dist/cli/commands/stats.d.ts +38 -0
  126. package/dist/cli/commands/stats.js +38 -10
  127. package/dist/cli/commands/stats.js.map +1 -1
  128. package/dist/cli/commands/telemetry.js +5 -3
  129. package/dist/cli/commands/telemetry.js.map +1 -1
  130. package/dist/cli/commands/templates.d.ts +18 -0
  131. package/dist/cli/commands/templates.js +9 -2
  132. package/dist/cli/commands/templates.js.map +1 -1
  133. package/dist/cli/commands/test-all.d.ts +5 -0
  134. package/dist/cli/commands/test-all.js +9 -3
  135. package/dist/cli/commands/test-all.js.map +1 -1
  136. package/dist/cli/commands/test.d.ts +70 -1
  137. package/dist/cli/commands/test.js +84 -3
  138. package/dist/cli/commands/test.js.map +1 -1
  139. package/dist/cli/commands/update-many.d.ts +34 -1
  140. package/dist/cli/commands/update-many.js +60 -31
  141. package/dist/cli/commands/update-many.js.map +1 -1
  142. package/dist/cli/commands/update.d.ts +71 -0
  143. package/dist/cli/commands/update.js +74 -8
  144. package/dist/cli/commands/update.js.map +1 -1
  145. package/dist/cli/commands/upgrade.d.ts +28 -1
  146. package/dist/cli/commands/upgrade.js +17 -4
  147. package/dist/cli/commands/upgrade.js.map +1 -1
  148. package/dist/cli/commands/validate.d.ts +114 -0
  149. package/dist/cli/commands/validate.js +154 -9
  150. package/dist/cli/commands/validate.js.map +1 -1
  151. package/dist/cli/error-guidance.d.ts +30 -0
  152. package/dist/cli/error-guidance.js +68 -6
  153. package/dist/cli/error-guidance.js.map +1 -1
  154. package/dist/cli/extension-command-options.js +9 -7
  155. package/dist/cli/extension-command-options.js.map +1 -1
  156. package/dist/cli/help-content.d.ts +8 -0
  157. package/dist/cli/help-content.js +30 -6
  158. package/dist/cli/help-content.js.map +1 -1
  159. package/dist/cli/help-json-payload.d.ts +19 -1
  160. package/dist/cli/help-json-payload.js +16 -7
  161. package/dist/cli/help-json-payload.js.map +1 -1
  162. package/dist/cli/main.d.ts +223 -0
  163. package/dist/cli/main.js +214 -46
  164. package/dist/cli/main.js.map +1 -1
  165. package/dist/cli/register-list-query.js +62 -5
  166. package/dist/cli/register-list-query.js.map +1 -1
  167. package/dist/cli/register-mutation.d.ts +16 -0
  168. package/dist/cli/register-mutation.js +210 -40
  169. package/dist/cli/register-mutation.js.map +1 -1
  170. package/dist/cli/register-operations.d.ts +8 -0
  171. package/dist/cli/register-operations.js +33 -11
  172. package/dist/cli/register-operations.js.map +1 -1
  173. package/dist/cli/register-setup.js +9 -6
  174. package/dist/cli/register-setup.js.map +1 -1
  175. package/dist/cli/registration-helpers.d.ts +4 -0
  176. package/dist/cli/registration-helpers.js +124 -38
  177. package/dist/cli/registration-helpers.js.map +1 -1
  178. package/dist/cli-bundle/chunks/activity-5P2KQCTH.js +18 -0
  179. package/dist/cli-bundle/chunks/{activity-XADJOG6G.js → activity-MJGTX4LO.js} +13 -11
  180. package/dist/cli-bundle/chunks/{aggregate-OD36DJU5.js → aggregate-MH3GROKB.js} +54 -25
  181. package/dist/cli-bundle/chunks/aggregate-MH3GROKB.js.map +7 -0
  182. package/dist/cli-bundle/chunks/{aggregate-6OTS3AOO.js → aggregate-OUGCDFNC.js} +55 -26
  183. package/dist/cli-bundle/chunks/aggregate-OUGCDFNC.js.map +1 -0
  184. package/dist/cli-bundle/chunks/{append-JYWO4P7W.js → append-2Q4BPUBW.js} +10 -10
  185. package/dist/cli-bundle/chunks/{append-JYWO4P7W.js.map → append-2Q4BPUBW.js.map} +2 -2
  186. package/dist/cli-bundle/chunks/{append-KG55G7S3.js → append-VCRUG2W6.js} +11 -11
  187. package/dist/cli-bundle/chunks/append-VCRUG2W6.js.map +1 -0
  188. package/dist/cli-bundle/chunks/{chunk-IGVJRZ6H.js → chunk-2IUJBMKS.js} +10 -9
  189. package/dist/cli-bundle/chunks/{chunk-IGVJRZ6H.js.map → chunk-2IUJBMKS.js.map} +2 -2
  190. package/dist/cli-bundle/chunks/{chunk-ATEES5SX.js → chunk-2JEGCDYT.js} +2 -2
  191. package/dist/cli-bundle/chunks/{chunk-XUC4C4PT.js → chunk-3WAULYOY.js} +3 -3
  192. package/dist/cli-bundle/chunks/{chunk-UIG4TW2H.js → chunk-3XOXWOGA.js} +359 -19
  193. package/dist/cli-bundle/chunks/chunk-3XOXWOGA.js.map +1 -0
  194. package/dist/cli-bundle/chunks/{chunk-3KLPFWZ4.js → chunk-4KBK4BA3.js} +16 -34
  195. package/dist/cli-bundle/chunks/chunk-4KBK4BA3.js.map +7 -0
  196. package/dist/cli-bundle/chunks/{chunk-OLKBSY4N.js → chunk-4VLB4JH2.js} +51 -8
  197. package/dist/cli-bundle/chunks/chunk-4VLB4JH2.js.map +7 -0
  198. package/dist/cli-bundle/chunks/{chunk-ZMW77VWV.js → chunk-656HPQPO.js} +27 -12
  199. package/dist/cli-bundle/chunks/chunk-656HPQPO.js.map +1 -0
  200. package/dist/cli-bundle/chunks/{chunk-CW6E4NAT.js → chunk-667XI4UJ.js} +309 -20
  201. package/dist/cli-bundle/chunks/chunk-667XI4UJ.js.map +1 -0
  202. package/dist/cli-bundle/chunks/{chunk-5SCT2JCT.js → chunk-6BV7ENQL.js} +9 -8
  203. package/dist/cli-bundle/chunks/chunk-6BV7ENQL.js.map +7 -0
  204. package/dist/cli-bundle/chunks/chunk-6EFCFPNE.js +35 -0
  205. package/dist/cli-bundle/chunks/chunk-6EFCFPNE.js.map +7 -0
  206. package/dist/cli-bundle/chunks/{chunk-VFUZV5EB.js → chunk-6NQXMGYU.js} +19 -8
  207. package/dist/cli-bundle/chunks/chunk-6NQXMGYU.js.map +7 -0
  208. package/dist/cli-bundle/chunks/{chunk-GKIZW7SM.js → chunk-764O7EUA.js} +223 -50
  209. package/dist/cli-bundle/chunks/chunk-764O7EUA.js.map +7 -0
  210. package/dist/cli-bundle/chunks/{chunk-QJMGRZO2.js → chunk-7AGIXLNK.js} +3 -3
  211. package/dist/cli-bundle/chunks/chunk-7EILPFMA.js +404 -0
  212. package/dist/cli-bundle/chunks/chunk-7EILPFMA.js.map +7 -0
  213. package/dist/cli-bundle/chunks/{chunk-HI7STVF2.js → chunk-7K2MXFMX.js} +14 -32
  214. package/dist/cli-bundle/chunks/chunk-7K2MXFMX.js.map +1 -0
  215. package/dist/cli-bundle/chunks/{chunk-TNAP7EJX.js → chunk-7L5VOUYP.js} +6 -17
  216. package/dist/cli-bundle/chunks/chunk-7L5VOUYP.js.map +7 -0
  217. package/dist/cli-bundle/chunks/chunk-7ZGKNHUL.js +61 -0
  218. package/dist/cli-bundle/chunks/chunk-7ZGKNHUL.js.map +7 -0
  219. package/dist/cli-bundle/chunks/{chunk-7IYFN5R7.js → chunk-A576QZDL.js} +223 -50
  220. package/dist/cli-bundle/chunks/chunk-A576QZDL.js.map +1 -0
  221. package/dist/cli-bundle/chunks/{chunk-KBPQHXWG.js → chunk-AERT7KT3.js} +5 -5
  222. package/dist/cli-bundle/chunks/chunk-ASM4DVRW.js +58 -0
  223. package/dist/cli-bundle/chunks/chunk-ASM4DVRW.js.map +1 -0
  224. package/dist/cli-bundle/chunks/{chunk-KWAXVAXX.js → chunk-B5Q7XC4K.js} +117 -37
  225. package/dist/cli-bundle/chunks/chunk-B5Q7XC4K.js.map +7 -0
  226. package/dist/cli-bundle/chunks/{chunk-EWFY7SLA.js → chunk-BJWTFOZM.js} +74 -14
  227. package/dist/cli-bundle/chunks/chunk-BJWTFOZM.js.map +1 -0
  228. package/dist/cli-bundle/chunks/{chunk-XJDGS74Y.js → chunk-CBMETQ2U.js} +105 -31
  229. package/dist/cli-bundle/chunks/chunk-CBMETQ2U.js.map +1 -0
  230. package/dist/cli-bundle/chunks/{chunk-ESANVZF4.js → chunk-E6J2PEK6.js} +3 -3
  231. package/dist/cli-bundle/chunks/{chunk-VSRZRLG3.js → chunk-F2GC6L3N.js} +3 -3
  232. package/dist/cli-bundle/chunks/{chunk-I7NYDZDV.js → chunk-F7WSO5UX.js} +7 -18
  233. package/dist/cli-bundle/chunks/chunk-F7WSO5UX.js.map +1 -0
  234. package/dist/cli-bundle/chunks/{chunk-VAOUX6TK.js → chunk-FTAZLAR7.js} +8 -5
  235. package/dist/cli-bundle/chunks/{chunk-VAOUX6TK.js.map → chunk-FTAZLAR7.js.map} +1 -1
  236. package/dist/cli-bundle/chunks/{chunk-OASDW5UI.js → chunk-FXNT5LPX.js} +77 -9
  237. package/dist/cli-bundle/chunks/chunk-FXNT5LPX.js.map +1 -0
  238. package/dist/cli-bundle/chunks/{chunk-WUNFKP7M.js → chunk-G2YVUY7I.js} +14 -9
  239. package/dist/cli-bundle/chunks/chunk-G2YVUY7I.js.map +1 -0
  240. package/dist/cli-bundle/chunks/{chunk-L5EPZQIC.js → chunk-G3CEIXTV.js} +68 -19
  241. package/dist/cli-bundle/chunks/chunk-G3CEIXTV.js.map +7 -0
  242. package/dist/cli-bundle/chunks/{chunk-UUWGCWBU.js → chunk-GAVE4MYM.js} +37 -63
  243. package/dist/cli-bundle/chunks/chunk-GAVE4MYM.js.map +1 -0
  244. package/dist/cli-bundle/chunks/{chunk-SXKNJPQ7.js → chunk-GQ4JKNMV.js} +4 -4
  245. package/dist/cli-bundle/chunks/{chunk-SXKNJPQ7.js.map → chunk-GQ4JKNMV.js.map} +1 -1
  246. package/dist/cli-bundle/chunks/{chunk-73ZPG2I3.js → chunk-GYMG7AG6.js} +36 -62
  247. package/dist/cli-bundle/chunks/chunk-GYMG7AG6.js.map +7 -0
  248. package/dist/cli-bundle/chunks/{chunk-35P4GT6E.js → chunk-H6EH6ENJ.js} +362 -22
  249. package/dist/cli-bundle/chunks/chunk-H6EH6ENJ.js.map +7 -0
  250. package/dist/cli-bundle/chunks/{chunk-F75JSIOZ.js → chunk-HDIDUME4.js} +45 -13
  251. package/dist/cli-bundle/chunks/chunk-HDIDUME4.js.map +1 -0
  252. package/dist/cli-bundle/chunks/{chunk-XWMF3POR.js → chunk-HPELHUTG.js} +122 -45
  253. package/dist/cli-bundle/chunks/chunk-HPELHUTG.js.map +1 -0
  254. package/dist/cli-bundle/chunks/{chunk-QKW5D45B.js → chunk-II7OGE3V.js} +20 -9
  255. package/dist/cli-bundle/chunks/chunk-II7OGE3V.js.map +1 -0
  256. package/dist/cli-bundle/chunks/{chunk-4HFU4UO2.js → chunk-ILHLIA47.js} +5 -5
  257. package/dist/cli-bundle/chunks/{chunk-4HFU4UO2.js.map → chunk-ILHLIA47.js.map} +1 -1
  258. package/dist/cli-bundle/chunks/{chunk-P5BJOMBB.js → chunk-IMQG4VR3.js} +118 -74
  259. package/dist/cli-bundle/chunks/chunk-IMQG4VR3.js.map +1 -0
  260. package/dist/cli-bundle/chunks/{chunk-AX4GEVQC.js → chunk-IQVB3YDD.js} +88 -22
  261. package/dist/cli-bundle/chunks/chunk-IQVB3YDD.js.map +7 -0
  262. package/dist/cli-bundle/chunks/{chunk-I53JBTJW.js → chunk-KQ3LAMDO.js} +45 -13
  263. package/dist/cli-bundle/chunks/chunk-KQ3LAMDO.js.map +7 -0
  264. package/dist/cli-bundle/chunks/{chunk-A6LXQFO7.js → chunk-KTVETP66.js} +334 -253
  265. package/dist/cli-bundle/chunks/chunk-KTVETP66.js.map +1 -0
  266. package/dist/cli-bundle/chunks/{chunk-DY6C42S6.js → chunk-KZYVTOG5.js} +26 -11
  267. package/dist/cli-bundle/chunks/chunk-KZYVTOG5.js.map +7 -0
  268. package/dist/cli-bundle/chunks/{chunk-HGLC63AU.js → chunk-L6FJPOT4.js} +11 -10
  269. package/dist/cli-bundle/chunks/{chunk-HGLC63AU.js.map → chunk-L6FJPOT4.js.map} +1 -1
  270. package/dist/cli-bundle/chunks/{chunk-FY4SPXSC.js → chunk-LV5FFQ7M.js} +354 -266
  271. package/dist/cli-bundle/chunks/chunk-LV5FFQ7M.js.map +7 -0
  272. package/dist/cli-bundle/chunks/{chunk-PNYAAB4S.js → chunk-LWGMDLQ6.js} +8 -3
  273. package/dist/cli-bundle/chunks/chunk-LWGMDLQ6.js.map +1 -0
  274. package/dist/cli-bundle/chunks/{chunk-XTKJSVWH.js → chunk-M23HXJL3.js} +2 -2
  275. package/dist/cli-bundle/chunks/{chunk-S26FESD4.js → chunk-MJZUZ2QE.js} +3 -3
  276. package/dist/cli-bundle/chunks/{chunk-I2IJY2NL.js → chunk-NCIBNERT.js} +4 -4
  277. package/dist/cli-bundle/chunks/{chunk-I2IJY2NL.js.map → chunk-NCIBNERT.js.map} +1 -1
  278. package/dist/cli-bundle/chunks/{chunk-TK5VZFHY.js → chunk-NIQHNDBZ.js} +76 -8
  279. package/dist/cli-bundle/chunks/chunk-NIQHNDBZ.js.map +7 -0
  280. package/dist/cli-bundle/chunks/{chunk-C6SAP27O.js → chunk-O46LTCXQ.js} +4 -4
  281. package/dist/cli-bundle/chunks/{chunk-YW6Q3RYZ.js → chunk-OCTQJP42.js} +19 -8
  282. package/dist/cli-bundle/chunks/{chunk-YW6Q3RYZ.js.map → chunk-OCTQJP42.js.map} +2 -2
  283. package/dist/cli-bundle/chunks/{chunk-WPDMBIX6.js → chunk-OLTYNVJR.js} +5 -5
  284. package/dist/cli-bundle/chunks/{chunk-IUKD4W6Z.js → chunk-OY3P2I6B.js} +13 -8
  285. package/dist/cli-bundle/chunks/chunk-OY3P2I6B.js.map +7 -0
  286. package/dist/cli-bundle/chunks/{chunk-SO55HRA5.js → chunk-PZD7WPUC.js} +69 -20
  287. package/dist/cli-bundle/chunks/chunk-PZD7WPUC.js.map +1 -0
  288. package/dist/cli-bundle/chunks/{chunk-HHHJ2GI3.js → chunk-Q5RLUCP3.js} +74 -14
  289. package/dist/cli-bundle/chunks/chunk-Q5RLUCP3.js.map +7 -0
  290. package/dist/cli-bundle/chunks/{chunk-S2ZLDYGS.js → chunk-RKKIH2ZQ.js} +116 -36
  291. package/dist/cli-bundle/chunks/chunk-RKKIH2ZQ.js.map +1 -0
  292. package/dist/cli-bundle/chunks/{chunk-GWZSYR6X.js → chunk-SPYPC5CB.js} +3 -3
  293. package/dist/cli-bundle/chunks/{chunk-GWZSYR6X.js.map → chunk-SPYPC5CB.js.map} +1 -1
  294. package/dist/cli-bundle/chunks/{chunk-7AMK6DOW.js → chunk-SY4GKIWT.js} +88 -22
  295. package/dist/cli-bundle/chunks/chunk-SY4GKIWT.js.map +1 -0
  296. package/dist/cli-bundle/chunks/{chunk-ZLMIWZUG.js → chunk-SY4PZWIZ.js} +7 -4
  297. package/dist/cli-bundle/chunks/{chunk-ZLMIWZUG.js.map → chunk-SY4PZWIZ.js.map} +2 -2
  298. package/dist/cli-bundle/chunks/{chunk-R2OUQVBK.js → chunk-T5VU7ROQ.js} +4 -4
  299. package/dist/cli-bundle/chunks/{chunk-37CYVF73.js → chunk-TIRZIQRP.js} +121 -44
  300. package/dist/cli-bundle/chunks/chunk-TIRZIQRP.js.map +7 -0
  301. package/dist/cli-bundle/chunks/{chunk-7UGSRQCL.js → chunk-TUB3DZAZ.js} +107 -33
  302. package/dist/cli-bundle/chunks/chunk-TUB3DZAZ.js.map +7 -0
  303. package/dist/cli-bundle/chunks/chunk-UAR2VNCK.js +394 -0
  304. package/dist/cli-bundle/chunks/chunk-UAR2VNCK.js.map +1 -0
  305. package/dist/cli-bundle/chunks/{chunk-P5U5EOMA.js → chunk-UBMCSJXX.js} +3 -3
  306. package/dist/cli-bundle/chunks/{chunk-ZYNJNPYD.js → chunk-UUKORJSN.js} +4 -4
  307. package/dist/cli-bundle/chunks/{chunk-R4VWYWRN.js → chunk-W3HFLORZ.js} +7 -2
  308. package/dist/cli-bundle/chunks/chunk-W3HFLORZ.js.map +7 -0
  309. package/dist/cli-bundle/chunks/{chunk-VPEAS7PS.js → chunk-WZCQVABQ.js} +2 -2
  310. package/dist/cli-bundle/chunks/chunk-X3W5ESZQ.js +32 -0
  311. package/dist/cli-bundle/chunks/chunk-X3W5ESZQ.js.map +1 -0
  312. package/dist/cli-bundle/chunks/{chunk-4YFAGDRH.js → chunk-XLNNCKTN.js} +322 -19
  313. package/dist/cli-bundle/chunks/chunk-XLNNCKTN.js.map +7 -0
  314. package/dist/cli-bundle/chunks/{chunk-RXAP6JL5.js → chunk-XNOY7TCB.js} +118 -74
  315. package/dist/cli-bundle/chunks/chunk-XNOY7TCB.js.map +7 -0
  316. package/dist/cli-bundle/chunks/{chunk-Y3YKK7CY.js → chunk-YGRPBFMA.js} +2 -2
  317. package/dist/cli-bundle/chunks/{chunk-QNJSITCX.js → chunk-YXTLI4XP.js} +20 -9
  318. package/dist/cli-bundle/chunks/chunk-YXTLI4XP.js.map +1 -0
  319. package/dist/cli-bundle/chunks/{chunk-FDH2X65L.js → chunk-Z3MUNQRV.js} +52 -9
  320. package/dist/cli-bundle/chunks/chunk-Z3MUNQRV.js.map +1 -0
  321. package/dist/cli-bundle/chunks/{chunk-XMBI6TNW.js → chunk-ZJRDVYZI.js} +4 -4
  322. package/dist/cli-bundle/chunks/{chunk-CCX4RSYZ.js → chunk-ZONXMSVB.js} +10 -9
  323. package/dist/cli-bundle/chunks/chunk-ZONXMSVB.js.map +1 -0
  324. package/dist/cli-bundle/chunks/{claim-2RDYMCTP.js → claim-4APLUXJW.js} +10 -10
  325. package/dist/cli-bundle/chunks/{claim-MJ7DZFC3.js → claim-NEO7AGWH.js} +10 -10
  326. package/dist/cli-bundle/chunks/{close-XLEKIQSW.js → close-3QABBNGU.js} +8 -8
  327. package/dist/cli-bundle/chunks/close-ILMZR3D7.js +13 -0
  328. package/dist/cli-bundle/chunks/{close-many-AOD4HSAZ.js → close-many-MIZLTYGL.js} +32 -20
  329. package/dist/cli-bundle/chunks/close-many-MIZLTYGL.js.map +1 -0
  330. package/dist/cli-bundle/chunks/{close-many-XKAQY5CQ.js → close-many-Q7Y5AHQI.js} +31 -19
  331. package/dist/cli-bundle/chunks/close-many-Q7Y5AHQI.js.map +7 -0
  332. package/dist/cli-bundle/chunks/{comments-RN5TG4ZN.js → comments-DAIQPOMU.js} +55 -31
  333. package/dist/cli-bundle/chunks/comments-DAIQPOMU.js.map +1 -0
  334. package/dist/cli-bundle/chunks/{comments-B4RWWDJT.js → comments-IWFSVM4P.js} +54 -30
  335. package/dist/cli-bundle/chunks/comments-IWFSVM4P.js.map +7 -0
  336. package/dist/cli-bundle/chunks/{config-3JXJ3XZ7.js → config-IOJELD6O.js} +45 -19
  337. package/dist/cli-bundle/chunks/config-IOJELD6O.js.map +1 -0
  338. package/dist/cli-bundle/chunks/{config-FZ4UDC4B.js → config-PXTMAYV3.js} +44 -18
  339. package/dist/cli-bundle/chunks/config-PXTMAYV3.js.map +7 -0
  340. package/dist/cli-bundle/chunks/{context-QBPO3BFM.js → context-QHJSCJW4.js} +128 -39
  341. package/dist/cli-bundle/chunks/context-QHJSCJW4.js.map +1 -0
  342. package/dist/cli-bundle/chunks/{context-L36PIN35.js → context-XZS2VFKU.js} +127 -38
  343. package/dist/cli-bundle/chunks/context-XZS2VFKU.js.map +7 -0
  344. package/dist/cli-bundle/chunks/{contracts-2G66IGIA.js → contracts-B7U4OJTV.js} +54 -10
  345. package/dist/cli-bundle/chunks/contracts-B7U4OJTV.js.map +1 -0
  346. package/dist/cli-bundle/chunks/{contracts-PJCHYSO5.js → contracts-NSBVLXQ3.js} +54 -10
  347. package/dist/cli-bundle/chunks/contracts-NSBVLXQ3.js.map +7 -0
  348. package/dist/cli-bundle/chunks/{copy-FWIVTLBO.js → copy-Q64T5FD4.js} +7 -7
  349. package/dist/cli-bundle/chunks/{copy-ALU5WMHA.js → copy-SG34LCMU.js} +7 -7
  350. package/dist/cli-bundle/chunks/create-F5HZX2S4.js +30 -0
  351. package/dist/cli-bundle/chunks/{create-5433DP3G.js → create-IPAX2SNL.js} +16 -13
  352. package/dist/cli-bundle/chunks/{delete-Y2SGJBGY.js → delete-TLXR7LJ2.js} +7 -7
  353. package/dist/cli-bundle/chunks/{delete-IYTIYAJS.js → delete-VH3L7DZ6.js} +7 -7
  354. package/dist/cli-bundle/chunks/{deps-CZ4PTVXU.js → deps-J3HBBLDB.js} +9 -10
  355. package/dist/cli-bundle/chunks/{deps-CZ4PTVXU.js.map → deps-J3HBBLDB.js.map} +2 -2
  356. package/dist/cli-bundle/chunks/{deps-6TSPOSGU.js → deps-XV6JJ6IN.js} +10 -11
  357. package/dist/cli-bundle/chunks/deps-XV6JJ6IN.js.map +1 -0
  358. package/dist/cli-bundle/chunks/{docs-MXLGZUIT.js → docs-GWDEB7JH.js} +9 -9
  359. package/dist/cli-bundle/chunks/{docs-I3BAF5WH.js → docs-RCLNSKID.js} +9 -9
  360. package/dist/cli-bundle/chunks/{extension-Q34OEWO5.js → extension-5RN65LHT.js} +7 -5
  361. package/dist/cli-bundle/chunks/{extension-WH2FOIOZ.js → extension-7KO2NX2A.js} +7 -5
  362. package/dist/cli-bundle/chunks/{files-GUXUM2MB.js → files-3TCQHUHA.js} +25 -11
  363. package/dist/cli-bundle/chunks/files-3TCQHUHA.js.map +1 -0
  364. package/dist/cli-bundle/chunks/{files-FYP3MDPX.js → files-5FDUPSEA.js} +24 -10
  365. package/dist/cli-bundle/chunks/files-5FDUPSEA.js.map +7 -0
  366. package/dist/cli-bundle/chunks/focus-7AQMNRSU.js +109 -0
  367. package/dist/cli-bundle/chunks/focus-7AQMNRSU.js.map +7 -0
  368. package/dist/cli-bundle/chunks/focus-HQXBYPKM.js +106 -0
  369. package/dist/cli-bundle/chunks/focus-HQXBYPKM.js.map +1 -0
  370. package/dist/cli-bundle/chunks/{gc-KGQG66SA.js → gc-2FGKYRJ4.js} +3 -3
  371. package/dist/cli-bundle/chunks/{gc-FENB2ESG.js → gc-5B6ABL3Z.js} +3 -3
  372. package/dist/cli-bundle/chunks/{get-PCHS7RA6.js → get-FUMVOJQD.js} +43 -16
  373. package/dist/cli-bundle/chunks/get-FUMVOJQD.js.map +1 -0
  374. package/dist/cli-bundle/chunks/{get-QARTE6BL.js → get-H5BZTW4A.js} +42 -15
  375. package/dist/cli-bundle/chunks/get-H5BZTW4A.js.map +7 -0
  376. package/dist/cli-bundle/chunks/{health-E4D7KGHD.js → health-JSVOR6B4.js} +75 -49
  377. package/dist/cli-bundle/chunks/health-JSVOR6B4.js.map +1 -0
  378. package/dist/cli-bundle/chunks/{health-7MTXAVR2.js → health-LE2ZQGSM.js} +74 -48
  379. package/dist/cli-bundle/chunks/health-LE2ZQGSM.js.map +7 -0
  380. package/dist/cli-bundle/chunks/{history-7WUAEWHW.js → history-QO4JVJJP.js} +10 -10
  381. package/dist/cli-bundle/chunks/history-SSXGGTVZ.js +20 -0
  382. package/dist/cli-bundle/chunks/{history-compact-LW27IPFK.js → history-compact-ID74DOUI.js} +37 -46
  383. package/dist/cli-bundle/chunks/history-compact-ID74DOUI.js.map +7 -0
  384. package/dist/cli-bundle/chunks/{history-compact-3EJ3L2O7.js → history-compact-SDFRPZ4V.js} +38 -47
  385. package/dist/cli-bundle/chunks/history-compact-SDFRPZ4V.js.map +1 -0
  386. package/dist/cli-bundle/chunks/history-redact-VBH44Y7F.js +21 -0
  387. package/dist/cli-bundle/chunks/{history-redact-G72A4EJ4.js → history-redact-Z4P5MM3G.js} +13 -11
  388. package/dist/cli-bundle/chunks/{history-repair-OSQOKJ3E.js → history-repair-ANHEYWKF.js} +43 -48
  389. package/dist/cli-bundle/chunks/history-repair-ANHEYWKF.js.map +7 -0
  390. package/dist/cli-bundle/chunks/{history-repair-SBK7P34V.js → history-repair-CKE7GLZR.js} +44 -49
  391. package/dist/cli-bundle/chunks/history-repair-CKE7GLZR.js.map +1 -0
  392. package/dist/cli-bundle/chunks/init-7FBQO77A.js +19 -0
  393. package/dist/cli-bundle/chunks/{init-S5WEGUJY.js → init-K6MSMB37.js} +11 -9
  394. package/dist/cli-bundle/chunks/{learnings-XK3P4ZDR.js → learnings-VIS3NOQV.js} +13 -12
  395. package/dist/cli-bundle/chunks/learnings-VIS3NOQV.js.map +7 -0
  396. package/dist/cli-bundle/chunks/{learnings-HQXSSKZ5.js → learnings-YYNB64GN.js} +14 -13
  397. package/dist/cli-bundle/chunks/learnings-YYNB64GN.js.map +1 -0
  398. package/dist/cli-bundle/chunks/list-7UE44A2R.js +29 -0
  399. package/dist/cli-bundle/chunks/list-UHMA3N2K.js +33 -0
  400. package/dist/cli-bundle/chunks/{notes-5T6P7C5V.js → notes-2HRMV67I.js} +14 -13
  401. package/dist/cli-bundle/chunks/notes-2HRMV67I.js.map +1 -0
  402. package/dist/cli-bundle/chunks/{notes-U5FZCSBT.js → notes-IN3UMA7W.js} +13 -12
  403. package/dist/cli-bundle/chunks/notes-IN3UMA7W.js.map +7 -0
  404. package/dist/cli-bundle/chunks/{plan-2YTQYWGM.js → plan-I3SVH7FV.js} +16 -15
  405. package/dist/cli-bundle/chunks/plan-I3SVH7FV.js.map +1 -0
  406. package/dist/cli-bundle/chunks/{plan-7IVSICR6.js → plan-PAWCCAPW.js} +15 -14
  407. package/dist/cli-bundle/chunks/plan-PAWCCAPW.js.map +7 -0
  408. package/dist/cli-bundle/chunks/{register-list-query-4UPMHONX.js → register-list-query-N7Z7RTDM.js} +31 -22
  409. package/dist/cli-bundle/chunks/register-list-query-N7Z7RTDM.js.map +7 -0
  410. package/dist/cli-bundle/chunks/{register-list-query-7VOW2C3W.js → register-list-query-OTIK4DVA.js} +32 -23
  411. package/dist/cli-bundle/chunks/register-list-query-OTIK4DVA.js.map +1 -0
  412. package/dist/cli-bundle/chunks/{register-mutation-FARSGYRD.js → register-mutation-UFZK6Q57.js} +216 -66
  413. package/dist/cli-bundle/chunks/register-mutation-UFZK6Q57.js.map +7 -0
  414. package/dist/cli-bundle/chunks/{register-mutation-LJDNVREU.js → register-mutation-XFORLS6D.js} +210 -67
  415. package/dist/cli-bundle/chunks/register-mutation-XFORLS6D.js.map +1 -0
  416. package/dist/cli-bundle/chunks/{register-operations-HCJKDUA6.js → register-operations-6ZCLKRBG.js} +53 -39
  417. package/dist/cli-bundle/chunks/register-operations-6ZCLKRBG.js.map +7 -0
  418. package/dist/cli-bundle/chunks/{register-operations-FFTYAL42.js → register-operations-ITE7JTH3.js} +54 -40
  419. package/dist/cli-bundle/chunks/register-operations-ITE7JTH3.js.map +1 -0
  420. package/dist/cli-bundle/chunks/{register-setup-6AVIUOCC.js → register-setup-7RKGE4BQ.js} +18 -21
  421. package/dist/cli-bundle/chunks/register-setup-7RKGE4BQ.js.map +1 -0
  422. package/dist/cli-bundle/chunks/{register-setup-KVNLO5OJ.js → register-setup-7UKEFKT6.js} +17 -20
  423. package/dist/cli-bundle/chunks/register-setup-7UKEFKT6.js.map +7 -0
  424. package/dist/cli-bundle/chunks/{restore-M6AFHMV4.js → restore-NNVPBBVJ.js} +13 -11
  425. package/dist/cli-bundle/chunks/restore-XXXLQ2XC.js +19 -0
  426. package/dist/cli-bundle/chunks/{schema-AINZ2IMM.js → schema-3HCLXCFX.js} +27 -9
  427. package/dist/cli-bundle/chunks/schema-3HCLXCFX.js.map +7 -0
  428. package/dist/cli-bundle/chunks/{schema-76HDZJCC.js → schema-3YKCQ3VO.js} +28 -10
  429. package/dist/cli-bundle/chunks/schema-3YKCQ3VO.js.map +1 -0
  430. package/dist/cli-bundle/chunks/{search-JMLFQEPJ.js → search-NQ42NC6A.js} +328 -71
  431. package/dist/cli-bundle/chunks/search-NQ42NC6A.js.map +7 -0
  432. package/dist/cli-bundle/chunks/{search-NL3TSCYB.js → search-V7PZ2ICH.js} +328 -71
  433. package/dist/cli-bundle/chunks/search-V7PZ2ICH.js.map +1 -0
  434. package/dist/cli-bundle/chunks/{stats-BKXCBIGT.js → stats-7KD4PJC5.js} +41 -16
  435. package/dist/cli-bundle/chunks/stats-7KD4PJC5.js.map +7 -0
  436. package/dist/cli-bundle/chunks/{stats-UBD56TGK.js → stats-GRHO6RFB.js} +42 -17
  437. package/dist/cli-bundle/chunks/stats-GRHO6RFB.js.map +1 -0
  438. package/dist/cli-bundle/chunks/{telemetry-ZJXK3H7X.js → telemetry-H5GLXNG5.js} +6 -6
  439. package/dist/cli-bundle/chunks/telemetry-H5GLXNG5.js.map +7 -0
  440. package/dist/cli-bundle/chunks/{telemetry-N454RHG5.js → telemetry-TRRYZXWT.js} +7 -7
  441. package/dist/cli-bundle/chunks/telemetry-TRRYZXWT.js.map +1 -0
  442. package/dist/cli-bundle/chunks/test-6CZNIIGA.js +34 -0
  443. package/dist/cli-bundle/chunks/{test-BQAKIXAT.js → test-7GVQ3VMN.js} +16 -14
  444. package/dist/cli-bundle/chunks/{test-all-7LV3I6S5.js → test-all-3LF2OZD2.js} +23 -16
  445. package/dist/cli-bundle/chunks/test-all-3LF2OZD2.js.map +7 -0
  446. package/dist/cli-bundle/chunks/{test-all-TDYCCBA4.js → test-all-ODVADHV6.js} +24 -17
  447. package/dist/cli-bundle/chunks/test-all-ODVADHV6.js.map +1 -0
  448. package/dist/cli-bundle/chunks/{test-runs-E64M6XS3.js → test-runs-LYT6ZTNQ.js} +62 -65
  449. package/dist/cli-bundle/chunks/test-runs-LYT6ZTNQ.js.map +1 -0
  450. package/dist/cli-bundle/chunks/{test-runs-LXZLULCI.js → test-runs-RVP6VWN7.js} +61 -64
  451. package/dist/cli-bundle/chunks/test-runs-RVP6VWN7.js.map +7 -0
  452. package/dist/cli-bundle/chunks/update-MPGM6SBE.js +28 -0
  453. package/dist/cli-bundle/chunks/update-UN75XW3C.js +24 -0
  454. package/dist/cli-bundle/chunks/{update-many-F4IKDWZB.js → update-many-FCU6RKTO.js} +80 -34
  455. package/dist/cli-bundle/chunks/update-many-FCU6RKTO.js.map +1 -0
  456. package/dist/cli-bundle/chunks/{update-many-NTWZ5YT3.js → update-many-XSEQJ24X.js} +79 -33
  457. package/dist/cli-bundle/chunks/update-many-XSEQJ24X.js.map +7 -0
  458. package/dist/cli-bundle/chunks/{upgrade-37F7JKES.js → upgrade-A6TL3INC.js} +22 -8
  459. package/dist/cli-bundle/chunks/upgrade-A6TL3INC.js.map +7 -0
  460. package/dist/cli-bundle/chunks/{upgrade-L32JA4TZ.js → upgrade-FOB5LHO5.js} +23 -9
  461. package/dist/cli-bundle/chunks/upgrade-FOB5LHO5.js.map +1 -0
  462. package/dist/cli-bundle/chunks/{validate-46KCRHL7.js → validate-7BLDG3AT.js} +222 -31
  463. package/dist/cli-bundle/chunks/validate-7BLDG3AT.js.map +1 -0
  464. package/dist/cli-bundle/chunks/{validate-CRFMPTYD.js → validate-EHL3MI2V.js} +236 -31
  465. package/dist/cli-bundle/chunks/validate-EHL3MI2V.js.map +7 -0
  466. package/dist/cli-bundle/main.js +305 -140
  467. package/dist/cli-bundle/main.js.map +3 -3
  468. package/dist/cli.d.ts +10 -0
  469. package/dist/cli.js +21 -8
  470. package/dist/cli.js.map +1 -1
  471. package/dist/core/diagnostics/remediation.js +7 -2
  472. package/dist/core/diagnostics/remediation.js.map +1 -1
  473. package/dist/core/extensions/extension-capability-aliases.js +7 -33
  474. package/dist/core/extensions/extension-capability-aliases.js.map +1 -1
  475. package/dist/core/extensions/extension-policy.js +14 -15
  476. package/dist/core/extensions/extension-policy.js.map +1 -1
  477. package/dist/core/extensions/item-fields.js +4 -5
  478. package/dist/core/extensions/item-fields.js.map +1 -1
  479. package/dist/core/extensions/loader.d.ts +75 -1
  480. package/dist/core/extensions/loader.js +56 -32
  481. package/dist/core/extensions/loader.js.map +1 -1
  482. package/dist/core/governance/content-fields.d.ts +84 -0
  483. package/dist/core/governance/content-fields.js +182 -0
  484. package/dist/core/governance/content-fields.js.map +1 -0
  485. package/dist/core/governance/issue-codes.d.ts +51 -0
  486. package/dist/core/governance/issue-codes.js +95 -0
  487. package/dist/core/governance/issue-codes.js.map +1 -0
  488. package/dist/core/governance/metadata-coverage.d.ts +168 -0
  489. package/dist/core/governance/metadata-coverage.js +362 -0
  490. package/dist/core/governance/metadata-coverage.js.map +1 -0
  491. package/dist/core/history/history-rewrite.d.ts +22 -0
  492. package/dist/core/history/history-rewrite.js +38 -2
  493. package/dist/core/history/history-rewrite.js.map +1 -1
  494. package/dist/core/history/history.d.ts +7 -0
  495. package/dist/core/history/history.js +6 -2
  496. package/dist/core/history/history.js.map +1 -1
  497. package/dist/core/io/body-file.d.ts +14 -0
  498. package/dist/core/io/body-file.js +47 -0
  499. package/dist/core/io/body-file.js.map +1 -0
  500. package/dist/core/item/item-format.d.ts +46 -1
  501. package/dist/core/item/item-format.js +51 -60
  502. package/dist/core/item/item-format.js.map +1 -1
  503. package/dist/core/item/parse.d.ts +9 -0
  504. package/dist/core/item/parse.js +10 -16
  505. package/dist/core/item/parse.js.map +1 -1
  506. package/dist/core/item/type-registry.d.ts +1 -0
  507. package/dist/core/item/type-registry.js +8 -10
  508. package/dist/core/item/type-registry.js.map +1 -1
  509. package/dist/core/lock/lock.d.ts +26 -0
  510. package/dist/core/lock/lock.js +10 -2
  511. package/dist/core/lock/lock.js.map +1 -1
  512. package/dist/core/output/output.d.ts +7 -0
  513. package/dist/core/output/output.js +6 -2
  514. package/dist/core/output/output.js.map +1 -1
  515. package/dist/core/schema/item-types-file.d.ts +25 -2
  516. package/dist/core/schema/item-types-file.js +78 -6
  517. package/dist/core/schema/item-types-file.js.map +1 -1
  518. package/dist/core/schema/runtime-schema.d.ts +7 -0
  519. package/dist/core/schema/runtime-schema.js +23 -16
  520. package/dist/core/schema/runtime-schema.js.map +1 -1
  521. package/dist/core/search/background-refresh.js +3 -3
  522. package/dist/core/search/background-refresh.js.map +1 -1
  523. package/dist/core/search/cache.d.ts +19 -1
  524. package/dist/core/search/cache.js +11 -3
  525. package/dist/core/search/cache.js.map +1 -1
  526. package/dist/core/search/corpus.d.ts +36 -2
  527. package/dist/core/search/corpus.js +120 -24
  528. package/dist/core/search/corpus.js.map +1 -1
  529. package/dist/core/search/providers.d.ts +19 -0
  530. package/dist/core/search/providers.js +19 -2
  531. package/dist/core/search/providers.js.map +1 -1
  532. package/dist/core/sentry/instrument.d.ts +1 -0
  533. package/dist/core/sentry/instrument.js +6 -2
  534. package/dist/core/sentry/instrument.js.map +1 -1
  535. package/dist/core/session/session-state.d.ts +16 -0
  536. package/dist/core/session/session-state.js +48 -0
  537. package/dist/core/session/session-state.js.map +1 -0
  538. package/dist/core/shared/constants.d.ts +8 -0
  539. package/dist/core/shared/constants.js +11 -2
  540. package/dist/core/shared/constants.js.map +1 -1
  541. package/dist/core/shared/errors.d.ts +3 -0
  542. package/dist/core/shared/errors.js +2 -2
  543. package/dist/core/shared/errors.js.map +1 -1
  544. package/dist/core/shared/text-normalization.js +4 -3
  545. package/dist/core/shared/text-normalization.js.map +1 -1
  546. package/dist/core/shared/time.d.ts +13 -0
  547. package/dist/core/shared/time.js +19 -7
  548. package/dist/core/shared/time.js.map +1 -1
  549. package/dist/core/store/item-store.d.ts +11 -0
  550. package/dist/core/store/item-store.js +16 -23
  551. package/dist/core/store/item-store.js.map +1 -1
  552. package/dist/core/store/settings-validator.d.ts +2 -0
  553. package/dist/core/store/settings-validator.js +25 -2
  554. package/dist/core/store/settings-validator.js.map +1 -1
  555. package/dist/core/store/settings.d.ts +60 -1
  556. package/dist/core/store/settings.js +100 -46
  557. package/dist/core/store/settings.js.map +1 -1
  558. package/dist/core/telemetry/observability.js +10 -8
  559. package/dist/core/telemetry/observability.js.map +1 -1
  560. package/dist/core/telemetry/runtime.d.ts +272 -1
  561. package/dist/core/telemetry/runtime.js +358 -37
  562. package/dist/core/telemetry/runtime.js.map +1 -1
  563. package/dist/core/test/background-runs.d.ts +35 -0
  564. package/dist/core/test/background-runs.js +72 -61
  565. package/dist/core/test/background-runs.js.map +1 -1
  566. package/dist/core/test/run-selectors.js +5 -4
  567. package/dist/core/test/run-selectors.js.map +1 -1
  568. package/dist/core/validate/estimate-defaults.d.ts +39 -0
  569. package/dist/core/validate/estimate-defaults.js +117 -0
  570. package/dist/core/validate/estimate-defaults.js.map +1 -0
  571. package/dist/core/validate/fix-planning.d.ts +21 -3
  572. package/dist/core/validate/fix-planning.js +31 -4
  573. package/dist/core/validate/fix-planning.js.map +1 -1
  574. package/dist/core/validate/missing-link-owners.d.ts +64 -0
  575. package/dist/core/validate/missing-link-owners.js +98 -0
  576. package/dist/core/validate/missing-link-owners.js.map +1 -0
  577. package/dist/mcp/server.d.ts +62 -0
  578. package/dist/mcp/server.js +71 -8
  579. package/dist/mcp/server.js.map +1 -1
  580. package/dist/mcp/tool-definitions.js +17 -4
  581. package/dist/mcp/tool-definitions.js.map +1 -1
  582. package/dist/sdk/cli-contracts/commander-types.js +13 -2
  583. package/dist/sdk/cli-contracts/commander-types.js.map +1 -1
  584. package/dist/sdk/cli-contracts/enum-contracts.d.ts +2 -2
  585. package/dist/sdk/cli-contracts/enum-contracts.js +4 -2
  586. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
  587. package/dist/sdk/cli-contracts/tool-option-contracts.js +110 -2
  588. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
  589. package/dist/sdk/cli-contracts/tool-parameter-tables.js +83 -8
  590. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  591. package/dist/sdk/cli-contracts.d.ts +28 -0
  592. package/dist/sdk/cli-contracts.js +164 -11
  593. package/dist/sdk/cli-contracts.js.map +1 -1
  594. package/dist/types.d.ts +17 -1
  595. package/dist/types.js +3 -3
  596. package/dist/types.js.map +1 -1
  597. package/docs/AGENT_GUIDE.md +15 -3
  598. package/docs/CLAUDE_CODE_PLUGIN.md +2 -2
  599. package/docs/COMMANDS.md +136 -7
  600. package/docs/CONFIGURATION.md +52 -0
  601. package/docs/TESTING.md +6 -4
  602. package/package.json +6 -4
  603. package/packages/pm-calendar/extensions/calendar/runtime.js +6 -0
  604. package/packages/pm-calendar/extensions/calendar/runtime.ts +12 -0
  605. package/packages/pm-todos/extensions/todos/runtime.ts +5 -0
  606. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  607. package/plugins/pm-claude/README.md +6 -14
  608. package/plugins/pm-claude/commands/pm-init.md +1 -1
  609. package/plugins/pm-codex/README.md +1 -1
  610. package/scripts/bundle-cli.mjs +46 -37
  611. package/scripts/finalize-build.mjs +20 -9
  612. package/scripts/prepare-build-cache.mjs +27 -16
  613. package/dist/cli-bundle/chunks/activity-XZIUPGZH.js +0 -16
  614. package/dist/cli-bundle/chunks/aggregate-6OTS3AOO.js.map +0 -1
  615. package/dist/cli-bundle/chunks/aggregate-OD36DJU5.js.map +0 -7
  616. package/dist/cli-bundle/chunks/append-KG55G7S3.js.map +0 -1
  617. package/dist/cli-bundle/chunks/chunk-35P4GT6E.js.map +0 -7
  618. package/dist/cli-bundle/chunks/chunk-37CYVF73.js.map +0 -7
  619. package/dist/cli-bundle/chunks/chunk-3KLPFWZ4.js.map +0 -7
  620. package/dist/cli-bundle/chunks/chunk-4JCSYR6F.js +0 -138
  621. package/dist/cli-bundle/chunks/chunk-4JCSYR6F.js.map +0 -7
  622. package/dist/cli-bundle/chunks/chunk-4YFAGDRH.js.map +0 -7
  623. package/dist/cli-bundle/chunks/chunk-5SCT2JCT.js.map +0 -7
  624. package/dist/cli-bundle/chunks/chunk-73ZPG2I3.js.map +0 -7
  625. package/dist/cli-bundle/chunks/chunk-7AMK6DOW.js.map +0 -1
  626. package/dist/cli-bundle/chunks/chunk-7IYFN5R7.js.map +0 -1
  627. package/dist/cli-bundle/chunks/chunk-7UGSRQCL.js.map +0 -7
  628. package/dist/cli-bundle/chunks/chunk-A6LXQFO7.js.map +0 -1
  629. package/dist/cli-bundle/chunks/chunk-AVGHVVF7.js +0 -128
  630. package/dist/cli-bundle/chunks/chunk-AVGHVVF7.js.map +0 -1
  631. package/dist/cli-bundle/chunks/chunk-AX4GEVQC.js.map +0 -7
  632. package/dist/cli-bundle/chunks/chunk-CCX4RSYZ.js.map +0 -1
  633. package/dist/cli-bundle/chunks/chunk-CW6E4NAT.js.map +0 -1
  634. package/dist/cli-bundle/chunks/chunk-DY6C42S6.js.map +0 -7
  635. package/dist/cli-bundle/chunks/chunk-EWFY7SLA.js.map +0 -1
  636. package/dist/cli-bundle/chunks/chunk-F75JSIOZ.js.map +0 -1
  637. package/dist/cli-bundle/chunks/chunk-FDH2X65L.js.map +0 -1
  638. package/dist/cli-bundle/chunks/chunk-FY4SPXSC.js.map +0 -7
  639. package/dist/cli-bundle/chunks/chunk-GKIZW7SM.js.map +0 -7
  640. package/dist/cli-bundle/chunks/chunk-HHHJ2GI3.js.map +0 -7
  641. package/dist/cli-bundle/chunks/chunk-HI7STVF2.js.map +0 -1
  642. package/dist/cli-bundle/chunks/chunk-I53JBTJW.js.map +0 -7
  643. package/dist/cli-bundle/chunks/chunk-I7NYDZDV.js.map +0 -1
  644. package/dist/cli-bundle/chunks/chunk-IUKD4W6Z.js.map +0 -7
  645. package/dist/cli-bundle/chunks/chunk-KWAXVAXX.js.map +0 -7
  646. package/dist/cli-bundle/chunks/chunk-L5EPZQIC.js.map +0 -7
  647. package/dist/cli-bundle/chunks/chunk-OASDW5UI.js.map +0 -1
  648. package/dist/cli-bundle/chunks/chunk-OLKBSY4N.js.map +0 -7
  649. package/dist/cli-bundle/chunks/chunk-P5BJOMBB.js.map +0 -1
  650. package/dist/cli-bundle/chunks/chunk-PNYAAB4S.js.map +0 -1
  651. package/dist/cli-bundle/chunks/chunk-QKW5D45B.js.map +0 -1
  652. package/dist/cli-bundle/chunks/chunk-QNJSITCX.js.map +0 -1
  653. package/dist/cli-bundle/chunks/chunk-R4VWYWRN.js.map +0 -7
  654. package/dist/cli-bundle/chunks/chunk-RXAP6JL5.js.map +0 -7
  655. package/dist/cli-bundle/chunks/chunk-S2ZLDYGS.js.map +0 -1
  656. package/dist/cli-bundle/chunks/chunk-SO55HRA5.js.map +0 -1
  657. package/dist/cli-bundle/chunks/chunk-TK5VZFHY.js.map +0 -7
  658. package/dist/cli-bundle/chunks/chunk-TNAP7EJX.js.map +0 -7
  659. package/dist/cli-bundle/chunks/chunk-UIG4TW2H.js.map +0 -1
  660. package/dist/cli-bundle/chunks/chunk-UUWGCWBU.js.map +0 -1
  661. package/dist/cli-bundle/chunks/chunk-VFUZV5EB.js.map +0 -7
  662. package/dist/cli-bundle/chunks/chunk-WUNFKP7M.js.map +0 -1
  663. package/dist/cli-bundle/chunks/chunk-XJDGS74Y.js.map +0 -1
  664. package/dist/cli-bundle/chunks/chunk-XWMF3POR.js.map +0 -1
  665. package/dist/cli-bundle/chunks/chunk-ZMW77VWV.js.map +0 -1
  666. package/dist/cli-bundle/chunks/close-4FMAPEMY.js +0 -13
  667. package/dist/cli-bundle/chunks/close-many-AOD4HSAZ.js.map +0 -1
  668. package/dist/cli-bundle/chunks/close-many-XKAQY5CQ.js.map +0 -7
  669. package/dist/cli-bundle/chunks/comments-B4RWWDJT.js.map +0 -7
  670. package/dist/cli-bundle/chunks/comments-RN5TG4ZN.js.map +0 -1
  671. package/dist/cli-bundle/chunks/config-3JXJ3XZ7.js.map +0 -1
  672. package/dist/cli-bundle/chunks/config-FZ4UDC4B.js.map +0 -7
  673. package/dist/cli-bundle/chunks/context-L36PIN35.js.map +0 -7
  674. package/dist/cli-bundle/chunks/context-QBPO3BFM.js.map +0 -1
  675. package/dist/cli-bundle/chunks/contracts-2G66IGIA.js.map +0 -1
  676. package/dist/cli-bundle/chunks/contracts-PJCHYSO5.js.map +0 -7
  677. package/dist/cli-bundle/chunks/create-VWLWS34Z.js +0 -27
  678. package/dist/cli-bundle/chunks/deps-6TSPOSGU.js.map +0 -1
  679. package/dist/cli-bundle/chunks/files-FYP3MDPX.js.map +0 -7
  680. package/dist/cli-bundle/chunks/files-GUXUM2MB.js.map +0 -1
  681. package/dist/cli-bundle/chunks/get-PCHS7RA6.js.map +0 -1
  682. package/dist/cli-bundle/chunks/get-QARTE6BL.js.map +0 -7
  683. package/dist/cli-bundle/chunks/health-7MTXAVR2.js.map +0 -7
  684. package/dist/cli-bundle/chunks/health-E4D7KGHD.js.map +0 -1
  685. package/dist/cli-bundle/chunks/history-L2FQFRTU.js +0 -20
  686. package/dist/cli-bundle/chunks/history-compact-3EJ3L2O7.js.map +0 -1
  687. package/dist/cli-bundle/chunks/history-compact-LW27IPFK.js.map +0 -7
  688. package/dist/cli-bundle/chunks/history-redact-QWQCX5DZ.js +0 -19
  689. package/dist/cli-bundle/chunks/history-repair-OSQOKJ3E.js.map +0 -7
  690. package/dist/cli-bundle/chunks/history-repair-SBK7P34V.js.map +0 -1
  691. package/dist/cli-bundle/chunks/init-4BKRHGWW.js +0 -17
  692. package/dist/cli-bundle/chunks/learnings-HQXSSKZ5.js.map +0 -1
  693. package/dist/cli-bundle/chunks/learnings-XK3P4ZDR.js.map +0 -7
  694. package/dist/cli-bundle/chunks/list-6CL3XFT6.js +0 -23
  695. package/dist/cli-bundle/chunks/list-BYNN4ZEO.js +0 -19
  696. package/dist/cli-bundle/chunks/notes-5T6P7C5V.js.map +0 -1
  697. package/dist/cli-bundle/chunks/notes-U5FZCSBT.js.map +0 -7
  698. package/dist/cli-bundle/chunks/plan-2YTQYWGM.js.map +0 -1
  699. package/dist/cli-bundle/chunks/plan-7IVSICR6.js.map +0 -7
  700. package/dist/cli-bundle/chunks/register-list-query-4UPMHONX.js.map +0 -7
  701. package/dist/cli-bundle/chunks/register-list-query-7VOW2C3W.js.map +0 -1
  702. package/dist/cli-bundle/chunks/register-mutation-FARSGYRD.js.map +0 -7
  703. package/dist/cli-bundle/chunks/register-mutation-LJDNVREU.js.map +0 -1
  704. package/dist/cli-bundle/chunks/register-operations-FFTYAL42.js.map +0 -1
  705. package/dist/cli-bundle/chunks/register-operations-HCJKDUA6.js.map +0 -7
  706. package/dist/cli-bundle/chunks/register-setup-6AVIUOCC.js.map +0 -1
  707. package/dist/cli-bundle/chunks/register-setup-KVNLO5OJ.js.map +0 -7
  708. package/dist/cli-bundle/chunks/restore-CHIOQAQL.js +0 -17
  709. package/dist/cli-bundle/chunks/schema-76HDZJCC.js.map +0 -1
  710. package/dist/cli-bundle/chunks/schema-AINZ2IMM.js.map +0 -7
  711. package/dist/cli-bundle/chunks/search-JMLFQEPJ.js.map +0 -7
  712. package/dist/cli-bundle/chunks/search-NL3TSCYB.js.map +0 -1
  713. package/dist/cli-bundle/chunks/stats-BKXCBIGT.js.map +0 -7
  714. package/dist/cli-bundle/chunks/stats-UBD56TGK.js.map +0 -1
  715. package/dist/cli-bundle/chunks/telemetry-N454RHG5.js.map +0 -1
  716. package/dist/cli-bundle/chunks/telemetry-ZJXK3H7X.js.map +0 -7
  717. package/dist/cli-bundle/chunks/test-O74JFUH5.js +0 -32
  718. package/dist/cli-bundle/chunks/test-all-7LV3I6S5.js.map +0 -7
  719. package/dist/cli-bundle/chunks/test-all-TDYCCBA4.js.map +0 -1
  720. package/dist/cli-bundle/chunks/test-runs-E64M6XS3.js.map +0 -1
  721. package/dist/cli-bundle/chunks/test-runs-LXZLULCI.js.map +0 -7
  722. package/dist/cli-bundle/chunks/update-36JM7YZT.js +0 -21
  723. package/dist/cli-bundle/chunks/update-I246PCLO.js +0 -25
  724. package/dist/cli-bundle/chunks/update-many-F4IKDWZB.js.map +0 -1
  725. package/dist/cli-bundle/chunks/update-many-NTWZ5YT3.js.map +0 -7
  726. package/dist/cli-bundle/chunks/upgrade-37F7JKES.js.map +0 -7
  727. package/dist/cli-bundle/chunks/upgrade-L32JA4TZ.js.map +0 -1
  728. package/dist/cli-bundle/chunks/validate-46KCRHL7.js.map +0 -1
  729. package/dist/cli-bundle/chunks/validate-CRFMPTYD.js.map +0 -7
  730. /package/dist/cli-bundle/chunks/{activity-XZIUPGZH.js.map → activity-5P2KQCTH.js.map} +0 -0
  731. /package/dist/cli-bundle/chunks/{activity-XADJOG6G.js.map → activity-MJGTX4LO.js.map} +0 -0
  732. /package/dist/cli-bundle/chunks/{chunk-ATEES5SX.js.map → chunk-2JEGCDYT.js.map} +0 -0
  733. /package/dist/cli-bundle/chunks/{chunk-XUC4C4PT.js.map → chunk-3WAULYOY.js.map} +0 -0
  734. /package/dist/cli-bundle/chunks/{chunk-QJMGRZO2.js.map → chunk-7AGIXLNK.js.map} +0 -0
  735. /package/dist/cli-bundle/chunks/{chunk-KBPQHXWG.js.map → chunk-AERT7KT3.js.map} +0 -0
  736. /package/dist/cli-bundle/chunks/{chunk-ESANVZF4.js.map → chunk-E6J2PEK6.js.map} +0 -0
  737. /package/dist/cli-bundle/chunks/{chunk-VSRZRLG3.js.map → chunk-F2GC6L3N.js.map} +0 -0
  738. /package/dist/cli-bundle/chunks/{chunk-XTKJSVWH.js.map → chunk-M23HXJL3.js.map} +0 -0
  739. /package/dist/cli-bundle/chunks/{chunk-S26FESD4.js.map → chunk-MJZUZ2QE.js.map} +0 -0
  740. /package/dist/cli-bundle/chunks/{chunk-C6SAP27O.js.map → chunk-O46LTCXQ.js.map} +0 -0
  741. /package/dist/cli-bundle/chunks/{chunk-WPDMBIX6.js.map → chunk-OLTYNVJR.js.map} +0 -0
  742. /package/dist/cli-bundle/chunks/{chunk-R2OUQVBK.js.map → chunk-T5VU7ROQ.js.map} +0 -0
  743. /package/dist/cli-bundle/chunks/{chunk-P5U5EOMA.js.map → chunk-UBMCSJXX.js.map} +0 -0
  744. /package/dist/cli-bundle/chunks/{chunk-ZYNJNPYD.js.map → chunk-UUKORJSN.js.map} +0 -0
  745. /package/dist/cli-bundle/chunks/{chunk-VPEAS7PS.js.map → chunk-WZCQVABQ.js.map} +0 -0
  746. /package/dist/cli-bundle/chunks/{chunk-Y3YKK7CY.js.map → chunk-YGRPBFMA.js.map} +0 -0
  747. /package/dist/cli-bundle/chunks/{chunk-XMBI6TNW.js.map → chunk-ZJRDVYZI.js.map} +0 -0
  748. /package/dist/cli-bundle/chunks/{claim-2RDYMCTP.js.map → claim-4APLUXJW.js.map} +0 -0
  749. /package/dist/cli-bundle/chunks/{claim-MJ7DZFC3.js.map → claim-NEO7AGWH.js.map} +0 -0
  750. /package/dist/cli-bundle/chunks/{close-XLEKIQSW.js.map → close-3QABBNGU.js.map} +0 -0
  751. /package/dist/cli-bundle/chunks/{close-4FMAPEMY.js.map → close-ILMZR3D7.js.map} +0 -0
  752. /package/dist/cli-bundle/chunks/{copy-FWIVTLBO.js.map → copy-Q64T5FD4.js.map} +0 -0
  753. /package/dist/cli-bundle/chunks/{copy-ALU5WMHA.js.map → copy-SG34LCMU.js.map} +0 -0
  754. /package/dist/cli-bundle/chunks/{create-VWLWS34Z.js.map → create-F5HZX2S4.js.map} +0 -0
  755. /package/dist/cli-bundle/chunks/{create-5433DP3G.js.map → create-IPAX2SNL.js.map} +0 -0
  756. /package/dist/cli-bundle/chunks/{delete-Y2SGJBGY.js.map → delete-TLXR7LJ2.js.map} +0 -0
  757. /package/dist/cli-bundle/chunks/{delete-IYTIYAJS.js.map → delete-VH3L7DZ6.js.map} +0 -0
  758. /package/dist/cli-bundle/chunks/{docs-MXLGZUIT.js.map → docs-GWDEB7JH.js.map} +0 -0
  759. /package/dist/cli-bundle/chunks/{docs-I3BAF5WH.js.map → docs-RCLNSKID.js.map} +0 -0
  760. /package/dist/cli-bundle/chunks/{extension-Q34OEWO5.js.map → extension-5RN65LHT.js.map} +0 -0
  761. /package/dist/cli-bundle/chunks/{extension-WH2FOIOZ.js.map → extension-7KO2NX2A.js.map} +0 -0
  762. /package/dist/cli-bundle/chunks/{gc-KGQG66SA.js.map → gc-2FGKYRJ4.js.map} +0 -0
  763. /package/dist/cli-bundle/chunks/{gc-FENB2ESG.js.map → gc-5B6ABL3Z.js.map} +0 -0
  764. /package/dist/cli-bundle/chunks/{history-7WUAEWHW.js.map → history-QO4JVJJP.js.map} +0 -0
  765. /package/dist/cli-bundle/chunks/{history-L2FQFRTU.js.map → history-SSXGGTVZ.js.map} +0 -0
  766. /package/dist/cli-bundle/chunks/{history-redact-QWQCX5DZ.js.map → history-redact-VBH44Y7F.js.map} +0 -0
  767. /package/dist/cli-bundle/chunks/{history-redact-G72A4EJ4.js.map → history-redact-Z4P5MM3G.js.map} +0 -0
  768. /package/dist/cli-bundle/chunks/{init-4BKRHGWW.js.map → init-7FBQO77A.js.map} +0 -0
  769. /package/dist/cli-bundle/chunks/{init-S5WEGUJY.js.map → init-K6MSMB37.js.map} +0 -0
  770. /package/dist/cli-bundle/chunks/{list-BYNN4ZEO.js.map → list-7UE44A2R.js.map} +0 -0
  771. /package/dist/cli-bundle/chunks/{list-6CL3XFT6.js.map → list-UHMA3N2K.js.map} +0 -0
  772. /package/dist/cli-bundle/chunks/{restore-M6AFHMV4.js.map → restore-NNVPBBVJ.js.map} +0 -0
  773. /package/dist/cli-bundle/chunks/{restore-CHIOQAQL.js.map → restore-XXXLQ2XC.js.map} +0 -0
  774. /package/dist/cli-bundle/chunks/{test-O74JFUH5.js.map → test-6CZNIIGA.js.map} +0 -0
  775. /package/dist/cli-bundle/chunks/{test-BQAKIXAT.js.map → test-7GVQ3VMN.js.map} +0 -0
  776. /package/dist/cli-bundle/chunks/{update-I246PCLO.js.map → update-MPGM6SBE.js.map} +0 -0
  777. /package/dist/cli-bundle/chunks/{update-36JM7YZT.js.map → update-UN75XW3C.js.map} +0 -0
@@ -0,0 +1,362 @@
1
+ /**
2
+ * Metadata governance & coverage observability primitives.
3
+ *
4
+ * One dependency-light module that powers the whole metadata-governance
5
+ * surface: missing-field selection (pm list / pm update-many), coverage
6
+ * percentages (pm stats --metadata-coverage / pm validate), and grouped
7
+ * lifecycle breakdowns (pm stats --by-assignee/--by-tag/--by-priority,
8
+ * pm aggregate explicit labels).
9
+ *
10
+ * The module is pure: it performs no IO and imports no heavy runtime
11
+ * dependencies. Lifecycle semantics are injected via a {@link LifecycleClassifier}
12
+ * so callers map their runtime status registry to lifecycle buckets while the
13
+ * pure logic here stays trivially testable with a fake classifier.
14
+ */
15
+
16
+ !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]="53dbd46b-5d5b-56ac-9e84-8139d30d84ac")}catch(e){}}();
17
+ import { toNonEmptyStringOrUndefined } from "../shared/primitives.js";
18
+ /** Stable rendering order for lifecycle buckets. */
19
+ export const LIFECYCLE_BUCKET_ORDER = [
20
+ "open",
21
+ "in_progress",
22
+ "blocked",
23
+ "draft",
24
+ "closed",
25
+ "canceled",
26
+ "other",
27
+ ];
28
+ function normalizeStatus(status, registry) {
29
+ const trimmed = status.trim().toLowerCase();
30
+ return registry.alias_to_id.get(trimmed) ?? trimmed;
31
+ }
32
+ /**
33
+ * Adapt a resolved runtime status registry into a {@link LifecycleClassifier}.
34
+ *
35
+ * Precedence is deliberate and disjoint: canceled → closed → blocked → draft →
36
+ * open → in_progress (active but not the default open status) → other.
37
+ */
38
+ export function lifecycleClassifierFromStatusRegistry(registry) {
39
+ return {
40
+ isTerminal(status) {
41
+ return registry.terminal_statuses.has(normalizeStatus(status, registry));
42
+ },
43
+ classify(status) {
44
+ const id = normalizeStatus(status, registry);
45
+ if (registry.terminal_canceled_statuses.has(id)) {
46
+ return "canceled";
47
+ }
48
+ if (registry.terminal_statuses.has(id)) {
49
+ return "closed";
50
+ }
51
+ if (registry.blocked_statuses.has(id)) {
52
+ return "blocked";
53
+ }
54
+ if (registry.draft_statuses.has(id)) {
55
+ return "draft";
56
+ }
57
+ if (id === registry.open_status) {
58
+ return "open";
59
+ }
60
+ if (registry.active_statuses.has(id)) {
61
+ return "in_progress";
62
+ }
63
+ return "other";
64
+ },
65
+ };
66
+ }
67
+ // ---------------------------------------------------------------------------
68
+ // Missing-metadata predicates
69
+ // ---------------------------------------------------------------------------
70
+ /** True when an item has no non-empty acceptance_criteria. */
71
+ export function isAcMissing(item) {
72
+ return toNonEmptyStringOrUndefined(item.acceptance_criteria) === undefined;
73
+ }
74
+ /** True when an item has no finite estimated_minutes. */
75
+ export function isEstimateMissing(item) {
76
+ return !Number.isFinite(item.estimated_minutes);
77
+ }
78
+ /**
79
+ * True when a terminal (closed/canceled) item has no non-empty resolution.
80
+ * Resolution is only expected on terminal items, so open items are never
81
+ * considered "resolution-missing".
82
+ */
83
+ export function isResolutionMissing(item, classifier) {
84
+ if (!classifier.isTerminal(item.status)) {
85
+ return false;
86
+ }
87
+ return toNonEmptyStringOrUndefined(item.resolution) === undefined;
88
+ }
89
+ /** True when an item has no non-empty reviewer. */
90
+ export function isReviewerMissing(item) {
91
+ return toNonEmptyStringOrUndefined(item.reviewer) === undefined;
92
+ }
93
+ /** True when an item has no non-empty risk level. */
94
+ export function isRiskMissing(item) {
95
+ return toNonEmptyStringOrUndefined(item.risk) === undefined;
96
+ }
97
+ /**
98
+ * True when an item has no confidence value. Confidence is a string-like enum
99
+ * or a numeric score depending on workspace, so a finite number counts as
100
+ * present and only blank/absent values are treated as missing.
101
+ */
102
+ export function isConfidenceMissing(item) {
103
+ if (typeof item.confidence === "number") {
104
+ return !Number.isFinite(item.confidence);
105
+ }
106
+ return toNonEmptyStringOrUndefined(item.confidence) === undefined;
107
+ }
108
+ /** True when an item has no non-empty sprint. */
109
+ export function isSprintMissing(item) {
110
+ return toNonEmptyStringOrUndefined(item.sprint) === undefined;
111
+ }
112
+ /** True when an item has no non-empty release. */
113
+ export function isReleaseMissing(item) {
114
+ return toNonEmptyStringOrUndefined(item.release) === undefined;
115
+ }
116
+ /** True when any missing-metadata filter is requested. */
117
+ export function hasMissingMetadataFilter(filters) {
118
+ return Boolean(filters.acMissing ||
119
+ filters.estimatesMissing ||
120
+ filters.resolutionMissing ||
121
+ filters.reviewerMissing ||
122
+ filters.riskMissing ||
123
+ filters.confidenceMissing ||
124
+ filters.sprintMissing ||
125
+ filters.releaseMissing ||
126
+ filters.metadataMissing);
127
+ }
128
+ /**
129
+ * Does a single item satisfy the requested missing-metadata filters?
130
+ *
131
+ * Specific flags (acMissing/estimatesMissing/resolutionMissing plus the
132
+ * governance flags reviewerMissing/riskMissing/confidenceMissing/sprintMissing/
133
+ * releaseMissing) are ANDed together so callers can narrow precisely.
134
+ * `metadataMissing` is ORed in as a union shortcut for "missing any of the
135
+ * core tracked fields" (acceptance_criteria/estimated_minutes/resolution); it
136
+ * deliberately excludes the governance fields so the long-standing flag keeps
137
+ * its original meaning. When no filter is requested the item passes.
138
+ */
139
+ export function itemMatchesMissingMetadata(item, filters, classifier) {
140
+ if (!hasMissingMetadataFilter(filters)) {
141
+ return true;
142
+ }
143
+ if (filters.acMissing && !isAcMissing(item)) {
144
+ return false;
145
+ }
146
+ if (filters.estimatesMissing && !isEstimateMissing(item)) {
147
+ return false;
148
+ }
149
+ if (filters.resolutionMissing && !isResolutionMissing(item, classifier)) {
150
+ return false;
151
+ }
152
+ if (filters.reviewerMissing && !isReviewerMissing(item)) {
153
+ return false;
154
+ }
155
+ if (filters.riskMissing && !isRiskMissing(item)) {
156
+ return false;
157
+ }
158
+ if (filters.confidenceMissing && !isConfidenceMissing(item)) {
159
+ return false;
160
+ }
161
+ if (filters.sprintMissing && !isSprintMissing(item)) {
162
+ return false;
163
+ }
164
+ if (filters.releaseMissing && !isReleaseMissing(item)) {
165
+ return false;
166
+ }
167
+ if (filters.metadataMissing) {
168
+ const anyMissing = isAcMissing(item) || isEstimateMissing(item) || isResolutionMissing(item, classifier);
169
+ if (!anyMissing) {
170
+ return false;
171
+ }
172
+ }
173
+ return true;
174
+ }
175
+ /** Filter a list of items by the requested missing-metadata predicates. */
176
+ export function filterMissingMetadata(items, filters, classifier) {
177
+ if (!hasMissingMetadataFilter(filters)) {
178
+ return [...items];
179
+ }
180
+ return items.filter((item) => itemMatchesMissingMetadata(item, filters, classifier));
181
+ }
182
+ /** Stable ordering of coverage fields for rendering. */
183
+ export const COVERAGE_FIELD_ORDER = [
184
+ "acceptance_criteria",
185
+ "estimated_minutes",
186
+ "resolution",
187
+ "tags",
188
+ "parent",
189
+ ];
190
+ function isFieldPresent(item, field) {
191
+ switch (field) {
192
+ case "acceptance_criteria":
193
+ return !isAcMissing(item);
194
+ case "estimated_minutes":
195
+ return !isEstimateMissing(item);
196
+ case "resolution":
197
+ return toNonEmptyStringOrUndefined(item.resolution) !== undefined;
198
+ case "tags":
199
+ return Array.isArray(item.tags) && item.tags.length > 0;
200
+ default:
201
+ return toNonEmptyStringOrUndefined(item.parent) !== undefined;
202
+ }
203
+ }
204
+ /** Whether a field applies to a given item (resolution only applies to terminal items). */
205
+ function isFieldApplicable(item, field, classifier) {
206
+ if (field === "resolution") {
207
+ return classifier.isTerminal(item.status);
208
+ }
209
+ return true;
210
+ }
211
+ function roundPercent(present, applicable) {
212
+ if (applicable === 0) {
213
+ return 100;
214
+ }
215
+ return Math.round((present / applicable) * 1000) / 10;
216
+ }
217
+ function emptyFieldCoverage() {
218
+ const record = {};
219
+ for (const field of COVERAGE_FIELD_ORDER) {
220
+ record[field] = { present: 0, applicable: 0, percent: 100 };
221
+ }
222
+ return record;
223
+ }
224
+ function accumulateCoverage(target, item, classifier) {
225
+ for (const field of COVERAGE_FIELD_ORDER) {
226
+ if (!isFieldApplicable(item, field, classifier)) {
227
+ continue;
228
+ }
229
+ const entry = target[field];
230
+ entry.applicable += 1;
231
+ if (isFieldPresent(item, field)) {
232
+ entry.present += 1;
233
+ }
234
+ }
235
+ }
236
+ function finalizePercentages(record) {
237
+ for (const field of COVERAGE_FIELD_ORDER) {
238
+ const entry = record[field];
239
+ entry.percent = roundPercent(entry.present, entry.applicable);
240
+ }
241
+ }
242
+ /**
243
+ * Compute metadata coverage overall and per item type. For each tracked field
244
+ * we report present/applicable counts and a rounded percentage. Resolution is
245
+ * scoped to terminal items (its only applicable population).
246
+ */
247
+ export function computeMetadataCoverage(items, classifier) {
248
+ const overall = emptyFieldCoverage();
249
+ const byType = {};
250
+ for (const item of items) {
251
+ accumulateCoverage(overall, item, classifier);
252
+ const typeRecord = byType[item.type] ?? (byType[item.type] = emptyFieldCoverage());
253
+ accumulateCoverage(typeRecord, item, classifier);
254
+ }
255
+ finalizePercentages(overall);
256
+ for (const typeRecord of Object.values(byType)) {
257
+ finalizePercentages(typeRecord);
258
+ }
259
+ return { overall, by_type: byType };
260
+ }
261
+ /** Explicit labels for empty/blank group keys, by dimension. */
262
+ const EMPTY_GROUP_LABELS = {
263
+ assignee: "(unassigned)",
264
+ priority: "(no priority)",
265
+ tag: "(untagged)",
266
+ parent: "(unparented)",
267
+ type: "(untyped)",
268
+ status: "(no status)",
269
+ };
270
+ /** Explicit label for an empty/blank group value for a given dimension. */
271
+ export function emptyGroupLabel(dimension) {
272
+ return EMPTY_GROUP_LABELS[dimension];
273
+ }
274
+ function emptyBuckets() {
275
+ return {
276
+ open: 0,
277
+ in_progress: 0,
278
+ blocked: 0,
279
+ draft: 0,
280
+ closed: 0,
281
+ canceled: 0,
282
+ other: 0,
283
+ };
284
+ }
285
+ /**
286
+ * Resolve the group keys an item belongs to for a dimension. Most dimensions
287
+ * yield exactly one key (possibly null for blank); tag yields one key per
288
+ * matching tag (or [null] when none match), so an item can span multiple rows.
289
+ */
290
+ function groupKeysForItem(item, dimension, options) {
291
+ switch (dimension) {
292
+ case "assignee":
293
+ return [toNonEmptyStringOrUndefined(item.assignee) ?? null];
294
+ case "parent":
295
+ return [toNonEmptyStringOrUndefined(item.parent) ?? null];
296
+ case "type":
297
+ return [toNonEmptyStringOrUndefined(item.type) ?? null];
298
+ case "status":
299
+ return [toNonEmptyStringOrUndefined(item.status) ?? null];
300
+ case "priority":
301
+ return [typeof item.priority === "number" ? `P${item.priority}` : null];
302
+ default: {
303
+ const prefix = options.tagPrefix?.trim();
304
+ const tags = Array.isArray(item.tags) ? item.tags : [];
305
+ const matching = tags.filter((tag) => typeof tag === "string" && tag.length > 0 && (!prefix || tag.startsWith(prefix)));
306
+ return matching.length > 0 ? matching : [null];
307
+ }
308
+ }
309
+ }
310
+ /**
311
+ * Group items by a dimension into lifecycle-bucketed rows. Blank keys render
312
+ * with an explicit "(unassigned)"-style label. Rows are sorted by total
313
+ * descending, then label ascending, with the empty group sorted last on ties.
314
+ */
315
+ export function groupItemsByDimension(items, dimension, classifier, options = {}) {
316
+ const rows = new Map();
317
+ let totalItems = 0;
318
+ for (const item of items) {
319
+ totalItems += 1;
320
+ const bucket = classifier.classify(item.status);
321
+ for (const key of groupKeysForItem(item, dimension, options)) {
322
+ const mapKey = key ?? "empty";
323
+ let row = rows.get(mapKey);
324
+ if (!row) {
325
+ row = {
326
+ label: key ?? emptyGroupLabel(dimension),
327
+ key,
328
+ buckets: emptyBuckets(),
329
+ total: 0,
330
+ };
331
+ rows.set(mapKey, row);
332
+ }
333
+ row.buckets[bucket] += 1;
334
+ row.total += 1;
335
+ }
336
+ }
337
+ const sorted = [...rows.values()].sort((left, right) => {
338
+ if (right.total !== left.total) {
339
+ return right.total - left.total;
340
+ }
341
+ // All blank-key items collapse into a single row per dimension, so at most
342
+ // one row has key === null; it sorts last on ties.
343
+ if (left.key === null) {
344
+ return 1;
345
+ }
346
+ if (right.key === null) {
347
+ return -1;
348
+ }
349
+ return left.label.localeCompare(right.label);
350
+ });
351
+ return { dimension, rows: sorted, total_items: totalItems };
352
+ }
353
+ /** Lifecycle-bucket distribution across all items (for stats lifecycle section). */
354
+ export function computeLifecycleDistribution(items, classifier) {
355
+ const buckets = emptyBuckets();
356
+ for (const item of items) {
357
+ buckets[classifier.classify(item.status)] += 1;
358
+ }
359
+ return buckets;
360
+ }
361
+ //# sourceMappingURL=metadata-coverage.js.map
362
+ //# debugId=53dbd46b-5d5b-56ac-9e84-8139d30d84ac
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata-coverage.js","sources":["core/governance/metadata-coverage.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Metadata governance & coverage observability primitives.\n *\n * One dependency-light module that powers the whole metadata-governance\n * surface: missing-field selection (pm list / pm update-many), coverage\n * percentages (pm stats --metadata-coverage / pm validate), and grouped\n * lifecycle breakdowns (pm stats --by-assignee/--by-tag/--by-priority,\n * pm aggregate explicit labels).\n *\n * The module is pure: it performs no IO and imports no heavy runtime\n * dependencies. Lifecycle semantics are injected via a {@link LifecycleClassifier}\n * so callers map their runtime status registry to lifecycle buckets while the\n * pure logic here stays trivially testable with a fake classifier.\n */\n\nimport { toNonEmptyStringOrUndefined } from \"../shared/primitives.js\";\n\n/** Minimal structural shape this module needs from an item's front matter. */\nexport interface CoverageItem {\n type: string;\n status: string;\n assignee?: string;\n tags?: string[];\n parent?: string;\n priority?: number;\n acceptance_criteria?: string;\n estimated_minutes?: number;\n resolution?: string;\n reviewer?: string;\n risk?: string;\n /** Confidence is a string-like enum or a numeric score depending on workspace. */\n confidence?: string | number;\n sprint?: string;\n release?: string;\n [key: string]: unknown;\n}\n\n/** Lifecycle buckets used by grouped breakdowns and distributions. */\nexport type LifecycleBucket =\n | \"open\"\n | \"in_progress\"\n | \"blocked\"\n | \"draft\"\n | \"closed\"\n | \"canceled\"\n | \"other\";\n\n/** Stable rendering order for lifecycle buckets. */\nexport const LIFECYCLE_BUCKET_ORDER: readonly LifecycleBucket[] = [\n \"open\",\n \"in_progress\",\n \"blocked\",\n \"draft\",\n \"closed\",\n \"canceled\",\n \"other\",\n] as const;\n\n/**\n * Classifies a raw status string into a lifecycle bucket and reports whether a\n * status is terminal (closed/canceled). Callers build this from their resolved\n * runtime status registry via {@link lifecycleClassifierFromStatusRegistry}.\n */\nexport interface LifecycleClassifier {\n classify(status: string): LifecycleBucket;\n isTerminal(status: string): boolean;\n}\n\n/** The subset of a resolved runtime status registry this module consumes. */\nexport interface StatusRegistryLike {\n alias_to_id: Map<string, string>;\n terminal_statuses: Set<string>;\n terminal_canceled_statuses: Set<string>;\n blocked_statuses: Set<string>;\n draft_statuses: Set<string>;\n active_statuses: Set<string>;\n open_status: string;\n}\n\nfunction normalizeStatus(status: string, registry: StatusRegistryLike): string {\n const trimmed = status.trim().toLowerCase();\n return registry.alias_to_id.get(trimmed) ?? trimmed;\n}\n\n/**\n * Adapt a resolved runtime status registry into a {@link LifecycleClassifier}.\n *\n * Precedence is deliberate and disjoint: canceled → closed → blocked → draft →\n * open → in_progress (active but not the default open status) → other.\n */\nexport function lifecycleClassifierFromStatusRegistry(registry: StatusRegistryLike): LifecycleClassifier {\n return {\n isTerminal(status: string): boolean {\n return registry.terminal_statuses.has(normalizeStatus(status, registry));\n },\n classify(status: string): LifecycleBucket {\n const id = normalizeStatus(status, registry);\n if (registry.terminal_canceled_statuses.has(id)) {\n return \"canceled\";\n }\n if (registry.terminal_statuses.has(id)) {\n return \"closed\";\n }\n if (registry.blocked_statuses.has(id)) {\n return \"blocked\";\n }\n if (registry.draft_statuses.has(id)) {\n return \"draft\";\n }\n if (id === registry.open_status) {\n return \"open\";\n }\n if (registry.active_statuses.has(id)) {\n return \"in_progress\";\n }\n return \"other\";\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Missing-metadata predicates\n// ---------------------------------------------------------------------------\n\n/** True when an item has no non-empty acceptance_criteria. */\nexport function isAcMissing(item: CoverageItem): boolean {\n return toNonEmptyStringOrUndefined(item.acceptance_criteria) === undefined;\n}\n\n/** True when an item has no finite estimated_minutes. */\nexport function isEstimateMissing(item: CoverageItem): boolean {\n return !Number.isFinite(item.estimated_minutes);\n}\n\n/**\n * True when a terminal (closed/canceled) item has no non-empty resolution.\n * Resolution is only expected on terminal items, so open items are never\n * considered \"resolution-missing\".\n */\nexport function isResolutionMissing(item: CoverageItem, classifier: LifecycleClassifier): boolean {\n if (!classifier.isTerminal(item.status)) {\n return false;\n }\n return toNonEmptyStringOrUndefined(item.resolution) === undefined;\n}\n\n/** True when an item has no non-empty reviewer. */\nexport function isReviewerMissing(item: CoverageItem): boolean {\n return toNonEmptyStringOrUndefined(item.reviewer) === undefined;\n}\n\n/** True when an item has no non-empty risk level. */\nexport function isRiskMissing(item: CoverageItem): boolean {\n return toNonEmptyStringOrUndefined(item.risk) === undefined;\n}\n\n/**\n * True when an item has no confidence value. Confidence is a string-like enum\n * or a numeric score depending on workspace, so a finite number counts as\n * present and only blank/absent values are treated as missing.\n */\nexport function isConfidenceMissing(item: CoverageItem): boolean {\n if (typeof item.confidence === \"number\") {\n return !Number.isFinite(item.confidence);\n }\n return toNonEmptyStringOrUndefined(item.confidence) === undefined;\n}\n\n/** True when an item has no non-empty sprint. */\nexport function isSprintMissing(item: CoverageItem): boolean {\n return toNonEmptyStringOrUndefined(item.sprint) === undefined;\n}\n\n/** True when an item has no non-empty release. */\nexport function isReleaseMissing(item: CoverageItem): boolean {\n return toNonEmptyStringOrUndefined(item.release) === undefined;\n}\n\n/** Selection flags for {@link filterMissingMetadata}. */\nexport interface MissingMetadataFilters {\n acMissing?: boolean;\n estimatesMissing?: boolean;\n resolutionMissing?: boolean;\n reviewerMissing?: boolean;\n riskMissing?: boolean;\n confidenceMissing?: boolean;\n sprintMissing?: boolean;\n releaseMissing?: boolean;\n /** Match items missing ANY of the tracked metadata fields (union). */\n metadataMissing?: boolean;\n}\n\n/** True when any missing-metadata filter is requested. */\nexport function hasMissingMetadataFilter(filters: MissingMetadataFilters): boolean {\n return Boolean(\n filters.acMissing ||\n filters.estimatesMissing ||\n filters.resolutionMissing ||\n filters.reviewerMissing ||\n filters.riskMissing ||\n filters.confidenceMissing ||\n filters.sprintMissing ||\n filters.releaseMissing ||\n filters.metadataMissing,\n );\n}\n\n/**\n * Does a single item satisfy the requested missing-metadata filters?\n *\n * Specific flags (acMissing/estimatesMissing/resolutionMissing plus the\n * governance flags reviewerMissing/riskMissing/confidenceMissing/sprintMissing/\n * releaseMissing) are ANDed together so callers can narrow precisely.\n * `metadataMissing` is ORed in as a union shortcut for \"missing any of the\n * core tracked fields\" (acceptance_criteria/estimated_minutes/resolution); it\n * deliberately excludes the governance fields so the long-standing flag keeps\n * its original meaning. When no filter is requested the item passes.\n */\nexport function itemMatchesMissingMetadata(\n item: CoverageItem,\n filters: MissingMetadataFilters,\n classifier: LifecycleClassifier,\n): boolean {\n if (!hasMissingMetadataFilter(filters)) {\n return true;\n }\n if (filters.acMissing && !isAcMissing(item)) {\n return false;\n }\n if (filters.estimatesMissing && !isEstimateMissing(item)) {\n return false;\n }\n if (filters.resolutionMissing && !isResolutionMissing(item, classifier)) {\n return false;\n }\n if (filters.reviewerMissing && !isReviewerMissing(item)) {\n return false;\n }\n if (filters.riskMissing && !isRiskMissing(item)) {\n return false;\n }\n if (filters.confidenceMissing && !isConfidenceMissing(item)) {\n return false;\n }\n if (filters.sprintMissing && !isSprintMissing(item)) {\n return false;\n }\n if (filters.releaseMissing && !isReleaseMissing(item)) {\n return false;\n }\n if (filters.metadataMissing) {\n const anyMissing =\n isAcMissing(item) || isEstimateMissing(item) || isResolutionMissing(item, classifier);\n if (!anyMissing) {\n return false;\n }\n }\n return true;\n}\n\n/** Filter a list of items by the requested missing-metadata predicates. */\nexport function filterMissingMetadata<T extends CoverageItem>(\n items: readonly T[],\n filters: MissingMetadataFilters,\n classifier: LifecycleClassifier,\n): T[] {\n if (!hasMissingMetadataFilter(filters)) {\n return [...items];\n }\n return items.filter((item) => itemMatchesMissingMetadata(item, filters, classifier));\n}\n\n// ---------------------------------------------------------------------------\n// Metadata coverage percentages\n// ---------------------------------------------------------------------------\n\n/** Coverage-tracked metadata fields. */\nexport type CoverageField =\n | \"acceptance_criteria\"\n | \"estimated_minutes\"\n | \"resolution\"\n | \"tags\"\n | \"parent\";\n\n/** Stable ordering of coverage fields for rendering. */\nexport const COVERAGE_FIELD_ORDER: readonly CoverageField[] = [\n \"acceptance_criteria\",\n \"estimated_minutes\",\n \"resolution\",\n \"tags\",\n \"parent\",\n] as const;\n\n/** Coverage of a single field: present vs applicable, with a rounded percent. */\nexport interface FieldCoverage {\n present: number;\n /** Items for which the field is expected (all items, except resolution = terminal only). */\n applicable: number;\n /** present/applicable * 100, rounded to one decimal; 100 when applicable is 0. */\n percent: number;\n}\n\nexport interface MetadataCoverageReport {\n overall: Record<CoverageField, FieldCoverage>;\n by_type: Record<string, Record<CoverageField, FieldCoverage>>;\n}\n\nfunction isFieldPresent(item: CoverageItem, field: CoverageField): boolean {\n switch (field) {\n case \"acceptance_criteria\":\n return !isAcMissing(item);\n case \"estimated_minutes\":\n return !isEstimateMissing(item);\n case \"resolution\":\n return toNonEmptyStringOrUndefined(item.resolution) !== undefined;\n case \"tags\":\n return Array.isArray(item.tags) && item.tags.length > 0;\n default:\n return toNonEmptyStringOrUndefined(item.parent) !== undefined;\n }\n}\n\n/** Whether a field applies to a given item (resolution only applies to terminal items). */\nfunction isFieldApplicable(item: CoverageItem, field: CoverageField, classifier: LifecycleClassifier): boolean {\n if (field === \"resolution\") {\n return classifier.isTerminal(item.status);\n }\n return true;\n}\n\nfunction roundPercent(present: number, applicable: number): number {\n if (applicable === 0) {\n return 100;\n }\n return Math.round((present / applicable) * 1000) / 10;\n}\n\nfunction emptyFieldCoverage(): Record<CoverageField, FieldCoverage> {\n const record = {} as Record<CoverageField, FieldCoverage>;\n for (const field of COVERAGE_FIELD_ORDER) {\n record[field] = { present: 0, applicable: 0, percent: 100 };\n }\n return record;\n}\n\nfunction accumulateCoverage(\n target: Record<CoverageField, FieldCoverage>,\n item: CoverageItem,\n classifier: LifecycleClassifier,\n): void {\n for (const field of COVERAGE_FIELD_ORDER) {\n if (!isFieldApplicable(item, field, classifier)) {\n continue;\n }\n const entry = target[field];\n entry.applicable += 1;\n if (isFieldPresent(item, field)) {\n entry.present += 1;\n }\n }\n}\n\nfunction finalizePercentages(record: Record<CoverageField, FieldCoverage>): void {\n for (const field of COVERAGE_FIELD_ORDER) {\n const entry = record[field];\n entry.percent = roundPercent(entry.present, entry.applicable);\n }\n}\n\n/**\n * Compute metadata coverage overall and per item type. For each tracked field\n * we report present/applicable counts and a rounded percentage. Resolution is\n * scoped to terminal items (its only applicable population).\n */\nexport function computeMetadataCoverage(\n items: readonly CoverageItem[],\n classifier: LifecycleClassifier,\n): MetadataCoverageReport {\n const overall = emptyFieldCoverage();\n const byType: Record<string, Record<CoverageField, FieldCoverage>> = {};\n for (const item of items) {\n accumulateCoverage(overall, item, classifier);\n const typeRecord = byType[item.type] ?? (byType[item.type] = emptyFieldCoverage());\n accumulateCoverage(typeRecord, item, classifier);\n }\n finalizePercentages(overall);\n for (const typeRecord of Object.values(byType)) {\n finalizePercentages(typeRecord);\n }\n return { overall, by_type: byType };\n}\n\n// ---------------------------------------------------------------------------\n// Grouped lifecycle breakdowns\n// ---------------------------------------------------------------------------\n\n/** Dimensions a breakdown can group by. */\nexport type GroupDimension = \"assignee\" | \"priority\" | \"tag\" | \"parent\" | \"type\" | \"status\";\n\n/** Explicit labels for empty/blank group keys, by dimension. */\nconst EMPTY_GROUP_LABELS: Record<GroupDimension, string> = {\n assignee: \"(unassigned)\",\n priority: \"(no priority)\",\n tag: \"(untagged)\",\n parent: \"(unparented)\",\n type: \"(untyped)\",\n status: \"(no status)\",\n};\n\n/** Explicit label for an empty/blank group value for a given dimension. */\nexport function emptyGroupLabel(dimension: GroupDimension): string {\n return EMPTY_GROUP_LABELS[dimension];\n}\n\nexport interface GroupRow {\n /** Display label; explicit \"(unassigned)\"-style label for blank keys. */\n label: string;\n /** Stable structured key (null for the empty/blank group). */\n key: string | null;\n buckets: Record<LifecycleBucket, number>;\n total: number;\n}\n\nexport interface GroupedBreakdown {\n dimension: GroupDimension;\n rows: GroupRow[];\n /** Distinct items observed (an item can contribute to multiple tag rows). */\n total_items: number;\n}\n\nexport interface GroupOptions {\n /** For dimension=\"tag\": only consider tags starting with this prefix. */\n tagPrefix?: string;\n}\n\nfunction emptyBuckets(): Record<LifecycleBucket, number> {\n return {\n open: 0,\n in_progress: 0,\n blocked: 0,\n draft: 0,\n closed: 0,\n canceled: 0,\n other: 0,\n };\n}\n\n/**\n * Resolve the group keys an item belongs to for a dimension. Most dimensions\n * yield exactly one key (possibly null for blank); tag yields one key per\n * matching tag (or [null] when none match), so an item can span multiple rows.\n */\nfunction groupKeysForItem(item: CoverageItem, dimension: GroupDimension, options: GroupOptions): (string | null)[] {\n switch (dimension) {\n case \"assignee\":\n return [toNonEmptyStringOrUndefined(item.assignee) ?? null];\n case \"parent\":\n return [toNonEmptyStringOrUndefined(item.parent) ?? null];\n case \"type\":\n return [toNonEmptyStringOrUndefined(item.type) ?? null];\n case \"status\":\n return [toNonEmptyStringOrUndefined(item.status) ?? null];\n case \"priority\":\n return [typeof item.priority === \"number\" ? `P${item.priority}` : null];\n default: {\n const prefix = options.tagPrefix?.trim();\n const tags = Array.isArray(item.tags) ? item.tags : [];\n const matching = tags.filter(\n (tag) => typeof tag === \"string\" && tag.length > 0 && (!prefix || tag.startsWith(prefix)),\n );\n return matching.length > 0 ? matching : [null];\n }\n }\n}\n\n/**\n * Group items by a dimension into lifecycle-bucketed rows. Blank keys render\n * with an explicit \"(unassigned)\"-style label. Rows are sorted by total\n * descending, then label ascending, with the empty group sorted last on ties.\n */\nexport function groupItemsByDimension(\n items: readonly CoverageItem[],\n dimension: GroupDimension,\n classifier: LifecycleClassifier,\n options: GroupOptions = {},\n): GroupedBreakdown {\n const rows = new Map<string, GroupRow>();\n let totalItems = 0;\n for (const item of items) {\n totalItems += 1;\n const bucket = classifier.classify(item.status);\n for (const key of groupKeysForItem(item, dimension, options)) {\n const mapKey = key ?? \"\u0000empty\";\n let row = rows.get(mapKey);\n if (!row) {\n row = {\n label: key ?? emptyGroupLabel(dimension),\n key,\n buckets: emptyBuckets(),\n total: 0,\n };\n rows.set(mapKey, row);\n }\n row.buckets[bucket] += 1;\n row.total += 1;\n }\n }\n const sorted = [...rows.values()].sort((left, right) => {\n if (right.total !== left.total) {\n return right.total - left.total;\n }\n // All blank-key items collapse into a single row per dimension, so at most\n // one row has key === null; it sorts last on ties.\n if (left.key === null) {\n return 1;\n }\n if (right.key === null) {\n return -1;\n }\n return left.label.localeCompare(right.label);\n });\n return { dimension, rows: sorted, total_items: totalItems };\n}\n\n/** Lifecycle-bucket distribution across all items (for stats lifecycle section). */\nexport function computeLifecycleDistribution(\n items: readonly CoverageItem[],\n classifier: LifecycleClassifier,\n): Record<LifecycleBucket, number> {\n const buckets = emptyBuckets();\n for (const item of items) {\n buckets[classifier.classify(item.status)] += 1;\n }\n return buckets;\n}\n"],"names":[],"mappings":"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","debugId":"53dbd46b-5d5b-56ac-9e84-8139d30d84ac"}
@@ -40,4 +40,26 @@ export interface VerifiedHistoryRewriteState {
40
40
  * diverged while waiting for the lock so the caller surfaces an actionable retry.
41
41
  */
42
42
  export declare function verifyHistoryRewriteNoDrift(params: VerifyHistoryRewriteDriftParams): Promise<VerifiedHistoryRewriteState>;
43
+ export interface ExecuteHistoryRewriteParams {
44
+ pmRoot: string;
45
+ subject: HistoryRewriteSubject;
46
+ settings: PmSettings;
47
+ typeRegistry: ItemTypeRegistry;
48
+ historyRawBeforeLock: string | null;
49
+ currentItemRawBeforeLock: string | null;
50
+ /** Short operation name used in conflict guidance (e.g. "history-redact"). */
51
+ operation: string;
52
+ author: string;
53
+ force: boolean | undefined;
54
+ itemDocument: ItemDocument | null;
55
+ applyRewrite: (verified: VerifiedHistoryRewriteState) => Promise<void>;
56
+ applyPostRewrite?: (verified: VerifiedHistoryRewriteState) => Promise<string[]>;
57
+ }
58
+ /**
59
+ * Shared lock/verify/ownership orchestration for history-rewrite commands.
60
+ * Callers provide the operation-specific write/rollback logic and optional
61
+ * post-write hook execution while this helper enforces the common governance +
62
+ * lock sequencing contract.
63
+ */
64
+ export declare function executeHistoryRewrite(params: ExecuteHistoryRewriteParams): Promise<string[]>;
43
65
  export {};
@@ -1,6 +1,7 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6929fbcd-89b7-580d-93fc-f647b086b95f")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="5c9d33cb-2601-55e4-9134-acae94c017c0")}catch(e){}}();
3
3
  import { readFileIfExists } from "../fs/fs-utils.js";
4
+ import { acquireLock } from "../lock/lock.js";
4
5
  import { EXIT_CODE } from "../shared/constants.js";
5
6
  import { PmCliError } from "../shared/errors.js";
6
7
  import { locateItem, readLocatedItem } from "../store/item-store.js";
@@ -44,5 +45,40 @@ export async function verifyHistoryRewriteNoDrift(params) {
44
45
  }
45
46
  return { historyRawUnderLock, locatedUnderLock, loadedItemUnderLock };
46
47
  }
48
+ /**
49
+ * Shared lock/verify/ownership orchestration for history-rewrite commands.
50
+ * Callers provide the operation-specific write/rollback logic and optional
51
+ * post-write hook execution while this helper enforces the common governance +
52
+ * lock sequencing contract.
53
+ */
54
+ export async function executeHistoryRewrite(params) {
55
+ const warnings = [...checkHistoryRewriteOwnership({
56
+ itemDocument: params.itemDocument,
57
+ subjectId: params.subject.id,
58
+ author: params.author,
59
+ force: params.force,
60
+ settings: params.settings,
61
+ })];
62
+ const releaseLock = await acquireLock(params.pmRoot, params.subject.id, params.settings.locks.ttl_seconds, params.author, Boolean(params.force), params.settings.governance.force_required_for_stale_lock);
63
+ try {
64
+ const verified = await verifyHistoryRewriteNoDrift({
65
+ pmRoot: params.pmRoot,
66
+ subject: params.subject,
67
+ settings: params.settings,
68
+ typeRegistry: params.typeRegistry,
69
+ historyRawBeforeLock: params.historyRawBeforeLock,
70
+ currentItemRawBeforeLock: params.currentItemRawBeforeLock,
71
+ operation: params.operation,
72
+ });
73
+ await params.applyRewrite(verified);
74
+ if (params.applyPostRewrite) {
75
+ warnings.push(...(await params.applyPostRewrite(verified)));
76
+ }
77
+ return warnings;
78
+ }
79
+ finally {
80
+ await releaseLock();
81
+ }
82
+ }
47
83
  //# sourceMappingURL=history-rewrite.js.map
48
- //# debugId=6929fbcd-89b7-580d-93fc-f647b086b95f
84
+ //# debugId=5c9d33cb-2601-55e4-9134-acae94c017c0
@@ -1 +1 @@
1
- {"version":3,"file":"history-rewrite.js","sources":["core/history/history-rewrite.ts"],"sourceRoot":"/","sourcesContent":["import { readFileIfExists } from \"../fs/fs-utils.js\";\nimport type { ItemTypeRegistry } from \"../item/type-registry.js\";\nimport { EXIT_CODE } from \"../shared/constants.js\";\nimport { PmCliError } from \"../shared/errors.js\";\nimport { locateItem, readLocatedItem } from \"../store/item-store.js\";\nimport { resolveGovernanceKnobs } from \"../store/settings.js\";\nimport type { ItemDocument, PmSettings } from \"../../types/index.js\";\n\ntype LoadedItem = Awaited<ReturnType<typeof readLocatedItem>>;\n\nexport interface HistoryRewriteSubject {\n id: string;\n historyPath: string;\n}\n\nexport interface HistoryRewriteOwnershipParams {\n itemDocument: ItemDocument | null;\n subjectId: string;\n author: string;\n force: boolean | undefined;\n settings: PmSettings;\n}\n\n/**\n * Apply ownership_enforcement governance to a history-rewriting operation.\n * Returns the warning(s) the caller should append (empty when no conflict or strict-throws).\n * Throws PmCliError(CONFLICT) in strict mode when the assignee conflicts and --force is not set.\n */\nexport function checkHistoryRewriteOwnership(params: HistoryRewriteOwnershipParams): string[] {\n if (!params.itemDocument) return [];\n const assigned = params.itemDocument.metadata?.assignee?.trim();\n if (!assigned || assigned === params.author || params.force) return [];\n\n const governance = resolveGovernanceKnobs(params.settings);\n if (governance.ownership_enforcement === \"strict\") {\n throw new PmCliError(\n `Item ${params.subjectId} is assigned to ${assigned}. Use --force to override.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (governance.ownership_enforcement === \"warn\") {\n return [`ownership_warning:assignee_conflict:${params.subjectId}:${assigned}`];\n }\n return [];\n}\n\nexport interface VerifyHistoryRewriteDriftParams {\n pmRoot: string;\n subject: HistoryRewriteSubject;\n settings: PmSettings;\n typeRegistry: ItemTypeRegistry;\n historyRawBeforeLock: string | null;\n currentItemRawBeforeLock: string | null;\n /** Short operation name used in the conflict message (e.g. \"history-redact\"). */\n operation: string;\n}\n\nexport interface VerifiedHistoryRewriteState {\n historyRawUnderLock: string | null;\n locatedUnderLock: Awaited<ReturnType<typeof locateItem>>;\n loadedItemUnderLock: LoadedItem | null;\n}\n\n/**\n * Re-read the history stream and the located item document under the acquired lock and\n * compare both with the pre-lock raw snapshots. Throws PmCliError(CONFLICT) if either\n * diverged while waiting for the lock so the caller surfaces an actionable retry.\n */\nexport async function verifyHistoryRewriteNoDrift(\n params: VerifyHistoryRewriteDriftParams,\n): Promise<VerifiedHistoryRewriteState> {\n const historyRawUnderLock = await readFileIfExists(params.subject.historyPath);\n if (historyRawUnderLock !== params.historyRawBeforeLock) {\n throw new PmCliError(\n `History for ${params.subject.id} changed while waiting for lock; retry ${params.operation}.`,\n EXIT_CODE.CONFLICT,\n );\n }\n const locatedUnderLock = await locateItem(\n params.pmRoot,\n params.subject.id,\n params.settings.id_prefix,\n params.settings.item_format,\n params.typeRegistry.type_to_folder,\n );\n const loadedItemUnderLock = locatedUnderLock\n ? await readLocatedItem(locatedUnderLock, { schema: params.settings.schema })\n : null;\n if ((loadedItemUnderLock?.raw ?? null) !== (params.currentItemRawBeforeLock ?? null)) {\n throw new PmCliError(\n `Item ${params.subject.id} changed while waiting for lock; retry ${params.operation}.`,\n EXIT_CODE.CONFLICT,\n );\n }\n return { historyRawUnderLock, locatedUnderLock, loadedItemUnderLock };\n}\n"],"names":[],"mappings":";;AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAkB9D;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAqC;IAChF,IAAI,CAAC,MAAM,CAAC,YAAY;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAChE,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEvE,MAAM,UAAU,GAAG,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,qBAAqB,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,UAAU,CAClB,QAAQ,MAAM,CAAC,SAAS,mBAAmB,QAAQ,4BAA4B,EAC/E,SAAS,CAAC,QAAQ,CACnB,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,CAAC,qBAAqB,KAAK,MAAM,EAAE,CAAC;QAChD,OAAO,CAAC,uCAAuC,MAAM,CAAC,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAmBD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,MAAuC;IAEvC,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/E,IAAI,mBAAmB,KAAK,MAAM,CAAC,oBAAoB,EAAE,CAAC;QACxD,MAAM,IAAI,UAAU,CAClB,eAAe,MAAM,CAAC,OAAO,CAAC,EAAE,0CAA0C,MAAM,CAAC,SAAS,GAAG,EAC7F,SAAS,CAAC,QAAQ,CACnB,CAAC;IACJ,CAAC;IACD,MAAM,gBAAgB,GAAG,MAAM,UAAU,CACvC,MAAM,CAAC,MAAM,EACb,MAAM,CAAC,OAAO,CAAC,EAAE,EACjB,MAAM,CAAC,QAAQ,CAAC,SAAS,EACzB,MAAM,CAAC,QAAQ,CAAC,WAAW,EAC3B,MAAM,CAAC,YAAY,CAAC,cAAc,CACnC,CAAC;IACF,MAAM,mBAAmB,GAAG,gBAAgB;QAC1C,CAAC,CAAC,MAAM,eAAe,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC7E,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,CAAC,mBAAmB,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,IAAI,IAAI,CAAC,EAAE,CAAC;QACrF,MAAM,IAAI,UAAU,CAClB,QAAQ,MAAM,CAAC,OAAO,CAAC,EAAE,0CAA0C,MAAM,CAAC,SAAS,GAAG,EACtF,SAAS,CAAC,QAAQ,CACnB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;AACxE,CAAC","debugId":"6929fbcd-89b7-580d-93fc-f647b086b95f"}
1
+ {"version":3,"file":"history-rewrite.js","sources":["core/history/history-rewrite.ts"],"sourceRoot":"/","sourcesContent":["import { readFileIfExists } from \"../fs/fs-utils.js\";\nimport type { ItemTypeRegistry } from \"../item/type-registry.js\";\nimport { acquireLock } from \"../lock/lock.js\";\nimport { EXIT_CODE } from \"../shared/constants.js\";\nimport { PmCliError } from \"../shared/errors.js\";\nimport { locateItem, readLocatedItem } from \"../store/item-store.js\";\nimport { resolveGovernanceKnobs } from \"../store/settings.js\";\nimport type { ItemDocument, PmSettings } from \"../../types/index.js\";\n\ntype LoadedItem = Awaited<ReturnType<typeof readLocatedItem>>;\n\nexport interface HistoryRewriteSubject {\n id: string;\n historyPath: string;\n}\n\nexport interface HistoryRewriteOwnershipParams {\n itemDocument: ItemDocument | null;\n subjectId: string;\n author: string;\n force: boolean | undefined;\n settings: PmSettings;\n}\n\n/**\n * Apply ownership_enforcement governance to a history-rewriting operation.\n * Returns the warning(s) the caller should append (empty when no conflict or strict-throws).\n * Throws PmCliError(CONFLICT) in strict mode when the assignee conflicts and --force is not set.\n */\nexport function checkHistoryRewriteOwnership(params: HistoryRewriteOwnershipParams): string[] {\n if (!params.itemDocument) return [];\n const assigned = params.itemDocument.metadata?.assignee?.trim();\n if (!assigned || assigned === params.author || params.force) return [];\n\n const governance = resolveGovernanceKnobs(params.settings);\n if (governance.ownership_enforcement === \"strict\") {\n throw new PmCliError(\n `Item ${params.subjectId} is assigned to ${assigned}. Use --force to override.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (governance.ownership_enforcement === \"warn\") {\n return [`ownership_warning:assignee_conflict:${params.subjectId}:${assigned}`];\n }\n return [];\n}\n\nexport interface VerifyHistoryRewriteDriftParams {\n pmRoot: string;\n subject: HistoryRewriteSubject;\n settings: PmSettings;\n typeRegistry: ItemTypeRegistry;\n historyRawBeforeLock: string | null;\n currentItemRawBeforeLock: string | null;\n /** Short operation name used in the conflict message (e.g. \"history-redact\"). */\n operation: string;\n}\n\nexport interface VerifiedHistoryRewriteState {\n historyRawUnderLock: string | null;\n locatedUnderLock: Awaited<ReturnType<typeof locateItem>>;\n loadedItemUnderLock: LoadedItem | null;\n}\n\n/**\n * Re-read the history stream and the located item document under the acquired lock and\n * compare both with the pre-lock raw snapshots. Throws PmCliError(CONFLICT) if either\n * diverged while waiting for the lock so the caller surfaces an actionable retry.\n */\nexport async function verifyHistoryRewriteNoDrift(\n params: VerifyHistoryRewriteDriftParams,\n): Promise<VerifiedHistoryRewriteState> {\n const historyRawUnderLock = await readFileIfExists(params.subject.historyPath);\n if (historyRawUnderLock !== params.historyRawBeforeLock) {\n throw new PmCliError(\n `History for ${params.subject.id} changed while waiting for lock; retry ${params.operation}.`,\n EXIT_CODE.CONFLICT,\n );\n }\n const locatedUnderLock = await locateItem(\n params.pmRoot,\n params.subject.id,\n params.settings.id_prefix,\n params.settings.item_format,\n params.typeRegistry.type_to_folder,\n );\n const loadedItemUnderLock = locatedUnderLock\n ? await readLocatedItem(locatedUnderLock, { schema: params.settings.schema })\n : null;\n if ((loadedItemUnderLock?.raw ?? null) !== (params.currentItemRawBeforeLock ?? null)) {\n throw new PmCliError(\n `Item ${params.subject.id} changed while waiting for lock; retry ${params.operation}.`,\n EXIT_CODE.CONFLICT,\n );\n }\n return { historyRawUnderLock, locatedUnderLock, loadedItemUnderLock };\n}\n\nexport interface ExecuteHistoryRewriteParams {\n pmRoot: string;\n subject: HistoryRewriteSubject;\n settings: PmSettings;\n typeRegistry: ItemTypeRegistry;\n historyRawBeforeLock: string | null;\n currentItemRawBeforeLock: string | null;\n /** Short operation name used in conflict guidance (e.g. \"history-redact\"). */\n operation: string;\n author: string;\n force: boolean | undefined;\n itemDocument: ItemDocument | null;\n applyRewrite: (verified: VerifiedHistoryRewriteState) => Promise<void>;\n applyPostRewrite?: (verified: VerifiedHistoryRewriteState) => Promise<string[]>;\n}\n\n/**\n * Shared lock/verify/ownership orchestration for history-rewrite commands.\n * Callers provide the operation-specific write/rollback logic and optional\n * post-write hook execution while this helper enforces the common governance +\n * lock sequencing contract.\n */\nexport async function executeHistoryRewrite(params: ExecuteHistoryRewriteParams): Promise<string[]> {\n const warnings = [...checkHistoryRewriteOwnership({\n itemDocument: params.itemDocument,\n subjectId: params.subject.id,\n author: params.author,\n force: params.force,\n settings: params.settings,\n })];\n const releaseLock = await acquireLock(\n params.pmRoot,\n params.subject.id,\n params.settings.locks.ttl_seconds,\n params.author,\n Boolean(params.force),\n params.settings.governance.force_required_for_stale_lock,\n );\n try {\n const verified = await verifyHistoryRewriteNoDrift({\n pmRoot: params.pmRoot,\n subject: params.subject,\n settings: params.settings,\n typeRegistry: params.typeRegistry,\n historyRawBeforeLock: params.historyRawBeforeLock,\n currentItemRawBeforeLock: params.currentItemRawBeforeLock,\n operation: params.operation,\n });\n await params.applyRewrite(verified);\n if (params.applyPostRewrite) {\n warnings.push(...(await params.applyPostRewrite(verified)));\n }\n return warnings;\n } finally {\n await releaseLock();\n }\n}\n"],"names":[],"mappings":"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","debugId":"5c9d33cb-2601-55e4-9134-acae94c017c0"}
@@ -1,4 +1,6 @@
1
1
  import type { HistoryEntry, ItemDocument } from "../../types/index.js";
2
+ declare function decodeJsonPointer(path: string): string[];
3
+ declare function isDefinedPointerPath(document: unknown, path: string): boolean;
2
4
  export declare function hashDocument(document: ItemDocument): string;
3
5
  export declare function hashEmptyDocument(): string;
4
6
  export declare function createHistoryEntry(params: {
@@ -10,3 +12,8 @@ export declare function createHistoryEntry(params: {
10
12
  message?: string;
11
13
  }): HistoryEntry;
12
14
  export declare function appendHistoryEntry(historyPath: string, entry: HistoryEntry): Promise<void>;
15
+ export declare const _testOnly: {
16
+ decodeJsonPointer: typeof decodeJsonPointer;
17
+ isDefinedPointerPath: typeof isDefinedPointerPath;
18
+ };
19
+ export {};
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9a356560-3dec-5529-a2b5-1b4224116c14")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b165ab2e-26f4-5ccd-83f4-39b5cf86c2cf")}catch(e){}}();
3
3
  import jsonPatch from "fast-json-patch";
4
4
  import { FRONT_MATTER_KEY_ORDER } from "../shared/constants.js";
5
5
  import { runActiveServiceOverride } from "../extensions/index.js";
@@ -154,5 +154,9 @@ export async function appendHistoryEntry(historyPath, entry) {
154
154
  }
155
155
  await appendLineAtomic(historyPath, JSON.stringify(entry));
156
156
  }
157
+ export const _testOnly = {
158
+ decodeJsonPointer,
159
+ isDefinedPointerPath,
160
+ };
157
161
  //# sourceMappingURL=history.js.map
158
- //# debugId=9a356560-3dec-5529-a2b5-1b4224116c14
162
+ //# debugId=b165ab2e-26f4-5ccd-83f4-39b5cf86c2cf
@@ -1 +1 @@
1
- {"version":3,"file":"history.js","sources":["core/history/history.ts"],"sourceRoot":"/","sourcesContent":["import jsonPatch from \"fast-json-patch\";\nimport { FRONT_MATTER_KEY_ORDER } from \"../shared/constants.js\";\nimport { runActiveServiceOverride } from \"../extensions/index.js\";\nimport { appendLineAtomic } from \"../fs/fs-utils.js\";\nimport { canonicalDocument } from \"../item/item-format.js\";\nimport { toItemRecord } from \"../item/item-record.js\";\nimport { orderObject, sha256Hex, stableStringify } from \"../shared/serialization.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument } from \"../../types/index.js\";\n\nconst EMPTY_LEGACY_HASH_DOCUMENT = {\n front_matter: {},\n body: \"\",\n};\n\nfunction decodeJsonPointer(path: string): string[] {\n if (!path || path === \"/\") {\n return [];\n }\n if (!path.startsWith(\"/\")) {\n return [];\n }\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n}\n\nfunction isDefinedPointerPath(document: unknown, path: string): boolean {\n const segments = decodeJsonPointer(path);\n if (segments.length === 0) {\n return true;\n }\n let cursor: unknown = document;\n for (const segment of segments) {\n if (Array.isArray(cursor)) {\n if (segment === \"-\" || !/^(0|[1-9]\\d*)$/.test(segment)) {\n return false;\n }\n const index = Number(segment);\n if (!Number.isInteger(index) || index < 0 || index >= cursor.length) {\n return false;\n }\n const next = cursor[index];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n continue;\n }\n if (typeof cursor !== \"object\" || cursor === null) {\n return false;\n }\n if (!Object.prototype.hasOwnProperty.call(cursor, segment)) {\n return false;\n }\n const next = (cursor as Record<string, unknown>)[segment];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n }\n return true;\n}\n\nfunction normalizeHistoryPatchOps(\n beforeDocument: { metadata: Record<string, unknown>; body: string },\n patch: HistoryPatchOp[],\n): HistoryPatchOp[] {\n const normalized: HistoryPatchOp[] = [];\n let replayCursor: unknown = structuredClone(beforeDocument);\n for (const operation of patch) {\n const normalizedOperation =\n operation.op === \"replace\" && !isDefinedPointerPath(replayCursor, operation.path)\n ? ({ ...operation, op: \"add\" } as HistoryPatchOp)\n : operation;\n normalized.push(normalizedOperation);\n replayCursor = jsonPatch.applyPatch(\n replayCursor,\n [normalizedOperation as jsonPatch.Operation],\n true,\n true,\n ).newDocument as unknown;\n }\n return normalized;\n}\n\nfunction canonicalHashDocument(document: ItemDocument): { front_matter: Record<string, unknown>; body: string } {\n const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;\n if (!hasMetadata) {\n return {\n front_matter: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedFrontMatter = orderObject(toItemRecord(canonical.metadata), FRONT_MATTER_KEY_ORDER);\n return {\n front_matter: orderedFrontMatter,\n body: canonical.body,\n };\n}\n\nfunction canonicalPatchDocument(document: ItemDocument): { metadata: Record<string, unknown>; body: string } {\n const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;\n if (!hasMetadata) {\n return {\n metadata: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedMetadata = orderObject(toItemRecord(canonical.metadata), FRONT_MATTER_KEY_ORDER);\n return {\n metadata: orderedMetadata,\n body: canonical.body,\n };\n}\n\nexport function hashDocument(document: ItemDocument): string {\n return sha256Hex(stableStringify(canonicalHashDocument(document)));\n}\n\nexport function hashEmptyDocument(): string {\n return sha256Hex(stableStringify(EMPTY_LEGACY_HASH_DOCUMENT));\n}\n\nexport function createHistoryEntry(params: {\n nowIso: string;\n author: string;\n op: string;\n before: ItemDocument;\n after: ItemDocument;\n message?: string;\n}): HistoryEntry {\n const beforeHashCanonical = canonicalHashDocument(params.before);\n const afterHashCanonical = canonicalHashDocument(params.after);\n const beforePatchCanonical = canonicalPatchDocument(params.before);\n const afterPatchCanonical = canonicalPatchDocument(params.after);\n const rawPatch = jsonPatch.compare(beforePatchCanonical, afterPatchCanonical) as HistoryPatchOp[];\n const patch = normalizeHistoryPatchOps(beforePatchCanonical, rawPatch);\n\n return {\n ts: params.nowIso,\n author: params.author,\n op: params.op,\n patch,\n before_hash: sha256Hex(stableStringify(beforeHashCanonical)),\n after_hash: sha256Hex(stableStringify(afterHashCanonical)),\n message: params.message === undefined ? undefined : params.message,\n };\n}\n\nexport async function appendHistoryEntry(historyPath: string, entry: HistoryEntry): Promise<void> {\n const override = await runActiveServiceOverride(\"history_append\", {\n history_path: historyPath,\n entry,\n });\n if (override.handled) {\n if (override.result === false) {\n return;\n }\n if (typeof override.result === \"string\") {\n await appendLineAtomic(historyPath, override.result);\n return;\n }\n if (typeof override.result === \"object\" && override.result !== null) {\n const record = override.result as {\n history_path?: unknown;\n entry?: unknown;\n line?: unknown;\n skip?: unknown;\n };\n if (record.skip === true) {\n return;\n }\n const nextHistoryPath = typeof record.history_path === \"string\" ? record.history_path : historyPath;\n if (typeof record.line === \"string\") {\n await appendLineAtomic(nextHistoryPath, record.line);\n return;\n }\n const nextEntry = (record.entry ?? entry) as HistoryEntry;\n await appendLineAtomic(nextHistoryPath, JSON.stringify(nextEntry));\n return;\n }\n }\n await appendLineAtomic(historyPath, JSON.stringify(entry));\n}\n"],"names":[],"mappings":"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","debugId":"9a356560-3dec-5529-a2b5-1b4224116c14"}
1
+ {"version":3,"file":"history.js","sources":["core/history/history.ts"],"sourceRoot":"/","sourcesContent":["import jsonPatch from \"fast-json-patch\";\nimport { FRONT_MATTER_KEY_ORDER } from \"../shared/constants.js\";\nimport { runActiveServiceOverride } from \"../extensions/index.js\";\nimport { appendLineAtomic } from \"../fs/fs-utils.js\";\nimport { canonicalDocument } from \"../item/item-format.js\";\nimport { toItemRecord } from \"../item/item-record.js\";\nimport { orderObject, sha256Hex, stableStringify } from \"../shared/serialization.js\";\nimport type { HistoryEntry, HistoryPatchOp, ItemDocument } from \"../../types/index.js\";\n\nconst EMPTY_LEGACY_HASH_DOCUMENT = {\n front_matter: {},\n body: \"\",\n};\n\nfunction decodeJsonPointer(path: string): string[] {\n if (!path || path === \"/\") {\n return [];\n }\n if (!path.startsWith(\"/\")) {\n return [];\n }\n return path\n .slice(1)\n .split(\"/\")\n .map((segment) => segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\"));\n}\n\nfunction isDefinedPointerPath(document: unknown, path: string): boolean {\n const segments = decodeJsonPointer(path);\n if (segments.length === 0) {\n return true;\n }\n let cursor: unknown = document;\n for (const segment of segments) {\n if (Array.isArray(cursor)) {\n if (segment === \"-\" || !/^(0|[1-9]\\d*)$/.test(segment)) {\n return false;\n }\n const index = Number(segment);\n if (!Number.isInteger(index) || index < 0 || index >= cursor.length) {\n return false;\n }\n const next = cursor[index];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n continue;\n }\n if (typeof cursor !== \"object\" || cursor === null) {\n return false;\n }\n if (!Object.prototype.hasOwnProperty.call(cursor, segment)) {\n return false;\n }\n const next = (cursor as Record<string, unknown>)[segment];\n if (next === undefined) {\n return false;\n }\n cursor = next;\n }\n return true;\n}\n\nfunction normalizeHistoryPatchOps(\n beforeDocument: { metadata: Record<string, unknown>; body: string },\n patch: HistoryPatchOp[],\n): HistoryPatchOp[] {\n const normalized: HistoryPatchOp[] = [];\n let replayCursor: unknown = structuredClone(beforeDocument);\n for (const operation of patch) {\n const normalizedOperation =\n operation.op === \"replace\" && !isDefinedPointerPath(replayCursor, operation.path)\n ? ({ ...operation, op: \"add\" } as HistoryPatchOp)\n : operation;\n normalized.push(normalizedOperation);\n replayCursor = jsonPatch.applyPatch(\n replayCursor,\n [normalizedOperation as jsonPatch.Operation],\n true,\n true,\n ).newDocument as unknown;\n }\n return normalized;\n}\n\nfunction canonicalHashDocument(document: ItemDocument): { front_matter: Record<string, unknown>; body: string } {\n const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;\n if (!hasMetadata) {\n return {\n front_matter: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedFrontMatter = orderObject(toItemRecord(canonical.metadata), FRONT_MATTER_KEY_ORDER);\n return {\n front_matter: orderedFrontMatter,\n body: canonical.body,\n };\n}\n\nfunction canonicalPatchDocument(document: ItemDocument): { metadata: Record<string, unknown>; body: string } {\n const hasMetadata = document.metadata && Object.keys(document.metadata).length > 0;\n if (!hasMetadata) {\n return {\n metadata: {},\n body: document.body ?? \"\",\n };\n }\n const canonical = canonicalDocument(document);\n const orderedMetadata = orderObject(toItemRecord(canonical.metadata), FRONT_MATTER_KEY_ORDER);\n return {\n metadata: orderedMetadata,\n body: canonical.body,\n };\n}\n\nexport function hashDocument(document: ItemDocument): string {\n return sha256Hex(stableStringify(canonicalHashDocument(document)));\n}\n\nexport function hashEmptyDocument(): string {\n return sha256Hex(stableStringify(EMPTY_LEGACY_HASH_DOCUMENT));\n}\n\nexport function createHistoryEntry(params: {\n nowIso: string;\n author: string;\n op: string;\n before: ItemDocument;\n after: ItemDocument;\n message?: string;\n}): HistoryEntry {\n const beforeHashCanonical = canonicalHashDocument(params.before);\n const afterHashCanonical = canonicalHashDocument(params.after);\n const beforePatchCanonical = canonicalPatchDocument(params.before);\n const afterPatchCanonical = canonicalPatchDocument(params.after);\n const rawPatch = jsonPatch.compare(beforePatchCanonical, afterPatchCanonical) as HistoryPatchOp[];\n const patch = normalizeHistoryPatchOps(beforePatchCanonical, rawPatch);\n\n return {\n ts: params.nowIso,\n author: params.author,\n op: params.op,\n patch,\n before_hash: sha256Hex(stableStringify(beforeHashCanonical)),\n after_hash: sha256Hex(stableStringify(afterHashCanonical)),\n message: params.message === undefined ? undefined : params.message,\n };\n}\n\nexport async function appendHistoryEntry(historyPath: string, entry: HistoryEntry): Promise<void> {\n const override = await runActiveServiceOverride(\"history_append\", {\n history_path: historyPath,\n entry,\n });\n if (override.handled) {\n if (override.result === false) {\n return;\n }\n if (typeof override.result === \"string\") {\n await appendLineAtomic(historyPath, override.result);\n return;\n }\n if (typeof override.result === \"object\" && override.result !== null) {\n const record = override.result as {\n history_path?: unknown;\n entry?: unknown;\n line?: unknown;\n skip?: unknown;\n };\n if (record.skip === true) {\n return;\n }\n const nextHistoryPath = typeof record.history_path === \"string\" ? record.history_path : historyPath;\n if (typeof record.line === \"string\") {\n await appendLineAtomic(nextHistoryPath, record.line);\n return;\n }\n const nextEntry = (record.entry ?? entry) as HistoryEntry;\n await appendLineAtomic(nextHistoryPath, JSON.stringify(nextEntry));\n return;\n }\n }\n await appendLineAtomic(historyPath, JSON.stringify(entry));\n}\n\nexport const _testOnly = {\n decodeJsonPointer,\n isDefinedPointerPath,\n};\n"],"names":[],"mappings":"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","debugId":"b165ab2e-26f4-5ccd-83f4-39b5cf86c2cf"}