@unbrained/pm-cli 2026.7.5 → 2026.7.7

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 (597) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/cli/commands/annotation-command.d.ts +1 -0
  3. package/dist/cli/commands/annotation-command.js +29 -2
  4. package/dist/cli/commands/annotation-command.js.map +1 -1
  5. package/dist/cli/commands/comments.js +3 -4
  6. package/dist/cli/commands/comments.js.map +1 -1
  7. package/dist/cli/commands/extension/bundled-catalog.d.ts +3 -0
  8. package/dist/cli/commands/extension/bundled-catalog.js +38 -28
  9. package/dist/cli/commands/extension/bundled-catalog.js.map +1 -1
  10. package/dist/cli/commands/extension/install-sources.js +81 -18
  11. package/dist/cli/commands/extension/install-sources.js.map +1 -1
  12. package/dist/cli/commands/health.js +9 -5
  13. package/dist/cli/commands/health.js.map +1 -1
  14. package/dist/cli/commands/learnings.js +5 -3
  15. package/dist/cli/commands/learnings.js.map +1 -1
  16. package/dist/cli/commands/notes.js +5 -3
  17. package/dist/cli/commands/notes.js.map +1 -1
  18. package/dist/cli/commands/reindex.js +4 -3
  19. package/dist/cli/commands/reindex.js.map +1 -1
  20. package/dist/cli/commands/search.js +3 -3
  21. package/dist/cli/commands/search.js.map +1 -1
  22. package/dist/cli/commands/test.d.ts +9 -0
  23. package/dist/cli/commands/test.js +144 -105
  24. package/dist/cli/commands/test.js.map +1 -1
  25. package/dist/cli/extension-command-help.js +10 -2
  26. package/dist/cli/extension-command-help.js.map +1 -1
  27. package/dist/cli/register-list-query.d.ts +1 -1
  28. package/dist/cli/register-list-query.js +18 -27
  29. package/dist/cli/register-list-query.js.map +1 -1
  30. package/dist/cli/register-operations.d.ts +0 -8
  31. package/dist/cli/register-operations.js +41 -46
  32. package/dist/cli/register-operations.js.map +1 -1
  33. package/dist/cli/register-setup.js +113 -13
  34. package/dist/cli/register-setup.js.map +1 -1
  35. package/dist/cli/registration-helpers.d.ts +5 -1
  36. package/dist/cli/registration-helpers.js +14 -2
  37. package/dist/cli/registration-helpers.js.map +1 -1
  38. package/dist/cli-bundle/chunks/append-F7WPGIQL.js +11 -0
  39. package/dist/cli-bundle/chunks/{contracts-OJEXMKVW.js → append-PVCTBVJG.js} +8 -9
  40. package/dist/cli-bundle/chunks/{chunk-PPE4YUQM.js → chunk-2APXX4TZ.js} +17 -28
  41. package/dist/cli-bundle/chunks/chunk-2APXX4TZ.js.map +1 -0
  42. package/dist/cli-bundle/chunks/{docs-S6UTOTO5.js → chunk-2LEJGRQ7.js} +3 -12
  43. package/dist/cli-bundle/chunks/{docs-S6UTOTO5.js.map → chunk-2LEJGRQ7.js.map} +1 -1
  44. package/dist/cli-bundle/chunks/{chunk-T3ABIMGW.js → chunk-2TILG6F2.js} +3 -3
  45. package/dist/cli-bundle/chunks/{chunk-S5AYOUT5.js → chunk-3G6UMXT3.js} +6 -8
  46. package/dist/cli-bundle/chunks/{chunk-S5AYOUT5.js.map → chunk-3G6UMXT3.js.map} +1 -1
  47. package/dist/cli-bundle/chunks/{chunk-RCT3YJOK.js → chunk-3TYOW6RR.js} +8 -8
  48. package/dist/cli-bundle/chunks/{chunk-3JZNEQBA.js → chunk-3X542TEY.js} +7 -7
  49. package/dist/cli-bundle/chunks/{history-repair-EVTO6LIH.js → chunk-42LXP4VO.js} +14 -21
  50. package/dist/cli-bundle/chunks/{history-repair-EVTO6LIH.js.map → chunk-42LXP4VO.js.map} +1 -1
  51. package/dist/cli-bundle/chunks/{chunk-5J2XPTAD.js → chunk-43SIHQND.js} +36 -15
  52. package/dist/cli-bundle/chunks/chunk-43SIHQND.js.map +7 -0
  53. package/dist/cli-bundle/chunks/{history-repair-4N6SDVHK.js → chunk-43UQN754.js} +12 -19
  54. package/dist/cli-bundle/chunks/{history-repair-4N6SDVHK.js.map → chunk-43UQN754.js.map} +1 -1
  55. package/dist/cli-bundle/chunks/{chunk-OWTIRHX4.js → chunk-43YSKY75.js} +4 -6
  56. package/dist/cli-bundle/chunks/{chunk-OWTIRHX4.js.map → chunk-43YSKY75.js.map} +1 -1
  57. package/dist/cli-bundle/chunks/{notes-72YXN5JX.js → chunk-4BKDAEDF.js} +6 -13
  58. package/dist/cli-bundle/chunks/{notes-72YXN5JX.js.map → chunk-4BKDAEDF.js.map} +2 -2
  59. package/dist/cli-bundle/chunks/{close-many-AP4MWU36.js → chunk-4IQKDKGE.js} +18 -32
  60. package/dist/cli-bundle/chunks/{close-many-AP4MWU36.js.map → chunk-4IQKDKGE.js.map} +1 -1
  61. package/dist/cli-bundle/chunks/{chunk-ZCJAA3JK.js → chunk-4MZOKTI2.js} +6 -8
  62. package/dist/cli-bundle/chunks/{chunk-ZCJAA3JK.js.map → chunk-4MZOKTI2.js.map} +1 -1
  63. package/dist/cli-bundle/chunks/{chunk-IJ6CO3JV.js → chunk-52NS7JDP.js} +14 -20
  64. package/dist/cli-bundle/chunks/{chunk-IJ6CO3JV.js.map → chunk-52NS7JDP.js.map} +1 -1
  65. package/dist/cli-bundle/chunks/{chunk-T3F4DF23.js → chunk-565WYS5W.js} +12 -16
  66. package/dist/cli-bundle/chunks/{chunk-T3F4DF23.js.map → chunk-565WYS5W.js.map} +1 -1
  67. package/dist/cli-bundle/chunks/{copy-OTJOWFL6.js → chunk-5FIQ4EX3.js} +13 -19
  68. package/dist/cli-bundle/chunks/{copy-OTJOWFL6.js.map → chunk-5FIQ4EX3.js.map} +1 -1
  69. package/dist/cli-bundle/chunks/{config-V57QD47V.js → chunk-6G6O3OPQ.js} +259 -41
  70. package/dist/cli-bundle/chunks/chunk-6G6O3OPQ.js.map +1 -0
  71. package/dist/cli-bundle/chunks/{chunk-K3AGVXSF.js → chunk-6LCJRGPD.js} +9 -13
  72. package/dist/cli-bundle/chunks/{chunk-K3AGVXSF.js.map → chunk-6LCJRGPD.js.map} +1 -1
  73. package/dist/cli-bundle/chunks/{chunk-7MDXZAZS.js → chunk-6UQCNWFV.js} +6 -8
  74. package/dist/cli-bundle/chunks/{chunk-7MDXZAZS.js.map → chunk-6UQCNWFV.js.map} +1 -1
  75. package/dist/cli-bundle/chunks/{chunk-LEKT4K7I.js → chunk-6XTSYPPO.js} +1216 -387
  76. package/dist/cli-bundle/chunks/chunk-6XTSYPPO.js.map +7 -0
  77. package/dist/cli-bundle/chunks/chunk-7ML7JONU.js +5434 -0
  78. package/dist/cli-bundle/chunks/chunk-7ML7JONU.js.map +1 -0
  79. package/dist/cli-bundle/chunks/{chunk-TSPKZRRW.js → chunk-7PNQA24K.js} +30 -36
  80. package/dist/cli-bundle/chunks/{chunk-TSPKZRRW.js.map → chunk-7PNQA24K.js.map} +1 -1
  81. package/dist/cli-bundle/chunks/{chunk-YOF5VPKM.js → chunk-7VQ3JJN5.js} +2 -2
  82. package/dist/cli-bundle/chunks/{chunk-BFVHCAOO.js → chunk-7Y5N34HX.js} +8 -12
  83. package/dist/cli-bundle/chunks/{chunk-BFVHCAOO.js.map → chunk-7Y5N34HX.js.map} +1 -1
  84. package/dist/cli-bundle/chunks/{chunk-P5TFTLWW.js → chunk-AGAVEDIE.js} +7 -7
  85. package/dist/cli-bundle/chunks/{chunk-YFIE7YK6.js → chunk-AJUON7E6.js} +3 -3
  86. package/dist/cli-bundle/chunks/{close-many-OMZIGZB4.js → chunk-ARKHKYYS.js} +16 -30
  87. package/dist/cli-bundle/chunks/{close-many-OMZIGZB4.js.map → chunk-ARKHKYYS.js.map} +1 -1
  88. package/dist/cli-bundle/chunks/{chunk-7EQNAZX2.js → chunk-C5ACVMOI.js} +99 -51
  89. package/dist/cli-bundle/chunks/chunk-C5ACVMOI.js.map +7 -0
  90. package/dist/cli-bundle/chunks/{chunk-PJ3A56YF.js → chunk-CJQM7O7R.js} +16 -20
  91. package/dist/cli-bundle/chunks/{chunk-PJ3A56YF.js.map → chunk-CJQM7O7R.js.map} +1 -1
  92. package/dist/cli-bundle/chunks/{chunk-WISPVC2E.js → chunk-D2DCTFTL.js} +7 -9
  93. package/dist/cli-bundle/chunks/{chunk-WISPVC2E.js.map → chunk-D2DCTFTL.js.map} +1 -1
  94. package/dist/cli-bundle/chunks/{append-CZGUZ45Q.js → chunk-DDDWVPID.js} +7 -11
  95. package/dist/cli-bundle/chunks/{append-CZGUZ45Q.js.map → chunk-DDDWVPID.js.map} +1 -1
  96. package/dist/cli-bundle/chunks/{learnings-2HTPZNGZ.js → chunk-DG6BSXZ7.js} +6 -13
  97. package/dist/cli-bundle/chunks/{learnings-2HTPZNGZ.js.map → chunk-DG6BSXZ7.js.map} +2 -2
  98. package/dist/cli-bundle/chunks/{chunk-7WYXBPYQ.js → chunk-DR2V5OIV.js} +3 -3
  99. package/dist/cli-bundle/chunks/{chunk-YQMMMONE.js → chunk-E3LWJUGF.js} +4 -6
  100. package/dist/cli-bundle/chunks/{chunk-YQMMMONE.js.map → chunk-E3LWJUGF.js.map} +1 -1
  101. package/dist/cli-bundle/chunks/{chunk-D3UCE7RW.js → chunk-E3YQFSFE.js} +6 -10
  102. package/dist/cli-bundle/chunks/{chunk-D3UCE7RW.js.map → chunk-E3YQFSFE.js.map} +1 -1
  103. package/dist/cli-bundle/chunks/{chunk-PDXT6Q55.js → chunk-EDO7VXSO.js} +2 -2
  104. package/dist/cli-bundle/chunks/{chunk-FDBARR33.js → chunk-EIUBK2LT.js} +12 -18
  105. package/dist/cli-bundle/chunks/{chunk-FDBARR33.js.map → chunk-EIUBK2LT.js.map} +1 -1
  106. package/dist/cli-bundle/chunks/{chunk-HBYZDSK5.js → chunk-EMXPI36L.js} +14 -20
  107. package/dist/cli-bundle/chunks/{chunk-HBYZDSK5.js.map → chunk-EMXPI36L.js.map} +1 -1
  108. package/dist/cli-bundle/chunks/{chunk-4OFLJHX6.js → chunk-EOUVR7JN.js} +13 -8
  109. package/dist/cli-bundle/chunks/chunk-EOUVR7JN.js.map +1 -0
  110. package/dist/cli-bundle/chunks/{chunk-FUM6UMY4.js → chunk-EVEPHNXJ.js} +4 -4
  111. package/dist/cli-bundle/chunks/{deps-L2FPIAD3.js → chunk-F6MT7KKE.js} +6 -10
  112. package/dist/cli-bundle/chunks/{deps-L2FPIAD3.js.map → chunk-F6MT7KKE.js.map} +1 -1
  113. package/dist/cli-bundle/chunks/{chunk-FGQKEDE4.js → chunk-F6YC2A6X.js} +7 -11
  114. package/dist/cli-bundle/chunks/{chunk-FGQKEDE4.js.map → chunk-F6YC2A6X.js.map} +1 -1
  115. package/dist/cli-bundle/chunks/chunk-FILL6BB2.js +5514 -0
  116. package/dist/cli-bundle/chunks/chunk-FILL6BB2.js.map +7 -0
  117. package/dist/cli-bundle/chunks/{chunk-RX3HQSYG.js → chunk-FN6SB4HU.js} +2 -2
  118. package/dist/cli-bundle/chunks/chunk-GH73UOSJ.js +5359 -0
  119. package/dist/cli-bundle/chunks/chunk-GH73UOSJ.js.map +1 -0
  120. package/dist/cli-bundle/chunks/{chunk-JLA7EVYV.js → chunk-GLS6VMWI.js} +37 -16
  121. package/dist/cli-bundle/chunks/chunk-GLS6VMWI.js.map +1 -0
  122. package/dist/cli-bundle/chunks/{files-JPU3FNJ7.js → chunk-GPIDUMMN.js} +10 -17
  123. package/dist/cli-bundle/chunks/{files-JPU3FNJ7.js.map → chunk-GPIDUMMN.js.map} +1 -1
  124. package/dist/cli-bundle/chunks/{history-compact-3F6VELO7.js → chunk-GTM5HQL4.js} +15 -21
  125. package/dist/cli-bundle/chunks/{history-compact-3F6VELO7.js.map → chunk-GTM5HQL4.js.map} +1 -1
  126. package/dist/cli-bundle/chunks/{chunk-DLQ4ZTCU.js → chunk-H2SMKL2N.js} +8 -8
  127. package/dist/cli-bundle/chunks/{chunk-S4APD35C.js → chunk-HHEWQXPD.js} +6 -6
  128. package/dist/cli-bundle/chunks/chunk-HHEWQXPD.js.map +7 -0
  129. package/dist/cli-bundle/chunks/{chunk-C3PMDWGX.js → chunk-HX6QXV5P.js} +2 -2
  130. package/dist/cli-bundle/chunks/{copy-LEE6P6EM.js → chunk-I74FMIWA.js} +11 -17
  131. package/dist/cli-bundle/chunks/{copy-LEE6P6EM.js.map → chunk-I74FMIWA.js.map} +1 -1
  132. package/dist/cli-bundle/chunks/chunk-IDIBF4E2.js +804 -0
  133. package/dist/cli-bundle/chunks/chunk-IDIBF4E2.js.map +7 -0
  134. package/dist/cli-bundle/chunks/{comments-SAG5LSKL.js → chunk-II7R6KD4.js} +9 -13
  135. package/dist/cli-bundle/chunks/{comments-SAG5LSKL.js.map → chunk-II7R6KD4.js.map} +1 -1
  136. package/dist/cli-bundle/chunks/chunk-J2VGADNG.js +10320 -0
  137. package/dist/cli-bundle/chunks/chunk-J2VGADNG.js.map +1 -0
  138. package/dist/cli-bundle/chunks/{chunk-Y76TWC45.js → chunk-J7BOLHAV.js} +5 -7
  139. package/dist/cli-bundle/chunks/{chunk-Y76TWC45.js.map → chunk-J7BOLHAV.js.map} +1 -1
  140. package/dist/cli-bundle/chunks/{chunk-QHZO65XW.js → chunk-KTGJ2CBU.js} +4 -6
  141. package/dist/cli-bundle/chunks/{chunk-QHZO65XW.js.map → chunk-KTGJ2CBU.js.map} +1 -1
  142. package/dist/cli-bundle/chunks/{chunk-5VVUKE3U.js → chunk-LCFJ7XAM.js} +32 -2
  143. package/dist/cli-bundle/chunks/{chunk-5VVUKE3U.js.map → chunk-LCFJ7XAM.js.map} +3 -3
  144. package/dist/cli-bundle/chunks/{chunk-YMABYTNG.js → chunk-LZQU6XJG.js} +28 -34
  145. package/dist/cli-bundle/chunks/{chunk-YMABYTNG.js.map → chunk-LZQU6XJG.js.map} +1 -1
  146. package/dist/cli-bundle/chunks/{chunk-3Y4OESPP.js → chunk-M62RO3XK.js} +10 -14
  147. package/dist/cli-bundle/chunks/{chunk-3Y4OESPP.js.map → chunk-M62RO3XK.js.map} +1 -1
  148. package/dist/cli-bundle/chunks/{chunk-YPPVU5GX.js → chunk-MCEUKJKW.js} +9 -11
  149. package/dist/cli-bundle/chunks/{chunk-YPPVU5GX.js.map → chunk-MCEUKJKW.js.map} +1 -1
  150. package/dist/cli-bundle/chunks/{chunk-T5Y3QSNF.js → chunk-MHNMCDWR.js} +1447 -86
  151. package/dist/cli-bundle/chunks/chunk-MHNMCDWR.js.map +1 -0
  152. package/dist/cli-bundle/chunks/{chunk-HJE4JTKQ.js → chunk-MRFWUSVA.js} +4 -6
  153. package/dist/cli-bundle/chunks/{chunk-HJE4JTKQ.js.map → chunk-MRFWUSVA.js.map} +1 -1
  154. package/dist/cli-bundle/chunks/{chunk-P3VRG72Q.js → chunk-N6ZHDLUY.js} +6 -8
  155. package/dist/cli-bundle/chunks/{chunk-P3VRG72Q.js.map → chunk-N6ZHDLUY.js.map} +1 -1
  156. package/dist/cli-bundle/chunks/{delete-HQKGRNRZ.js → chunk-NWWL22C7.js} +8 -12
  157. package/dist/cli-bundle/chunks/{delete-HQKGRNRZ.js.map → chunk-NWWL22C7.js.map} +1 -1
  158. package/dist/cli-bundle/chunks/{chunk-N6DNM2FA.js → chunk-P3MJJW7P.js} +2 -2
  159. package/dist/cli-bundle/chunks/{chunk-5JE6SMYS.js → chunk-PDXJXEZJ.js} +2 -2
  160. package/dist/cli-bundle/chunks/{append-NSQBCXZJ.js → chunk-Q64AYQYW.js} +9 -13
  161. package/dist/cli-bundle/chunks/{append-NSQBCXZJ.js.map → chunk-Q64AYQYW.js.map} +1 -1
  162. package/dist/cli-bundle/chunks/{update-many-SLLAMHT7.js → chunk-QDABF2RB.js} +26 -47
  163. package/dist/cli-bundle/chunks/{update-many-SLLAMHT7.js.map → chunk-QDABF2RB.js.map} +1 -1
  164. package/dist/cli-bundle/chunks/{chunk-NBFCNJ7Q.js → chunk-QFBSP3NI.js} +529 -46
  165. package/dist/cli-bundle/chunks/chunk-QFBSP3NI.js.map +1 -0
  166. package/dist/cli-bundle/chunks/{focus-LFZ6IDBR.js → chunk-RB3KLPAH.js} +11 -16
  167. package/dist/cli-bundle/chunks/{focus-LFZ6IDBR.js.map → chunk-RB3KLPAH.js.map} +1 -1
  168. package/dist/cli-bundle/chunks/{chunk-YSAH5FY5.js → chunk-RY7PTTUB.js} +94 -53
  169. package/dist/cli-bundle/chunks/chunk-RY7PTTUB.js.map +1 -0
  170. package/dist/cli-bundle/chunks/{chunk-WVSGSZ6J.js → chunk-S547WBYG.js} +1477 -86
  171. package/dist/cli-bundle/chunks/chunk-S547WBYG.js.map +7 -0
  172. package/dist/cli-bundle/chunks/{update-many-DC7X3EWM.js → chunk-S5BNGFN5.js} +24 -45
  173. package/dist/cli-bundle/chunks/{update-many-DC7X3EWM.js.map → chunk-S5BNGFN5.js.map} +1 -1
  174. package/dist/cli-bundle/chunks/{focus-WNMYCVYA.js → chunk-S6VC2A2K.js} +9 -14
  175. package/dist/cli-bundle/chunks/{focus-WNMYCVYA.js.map → chunk-S6VC2A2K.js.map} +1 -1
  176. package/dist/cli-bundle/chunks/{learnings-YBIHY3D6.js → chunk-SIM5JDON.js} +7 -14
  177. package/dist/cli-bundle/chunks/{learnings-YBIHY3D6.js.map → chunk-SIM5JDON.js.map} +1 -1
  178. package/dist/cli-bundle/chunks/{chunk-ZD34OFFQ.js → chunk-SY75LYXR.js} +12 -7
  179. package/dist/cli-bundle/chunks/chunk-SY75LYXR.js.map +7 -0
  180. package/dist/cli-bundle/chunks/{chunk-TT42JUMF.js → chunk-TEISGNSH.js} +7 -7
  181. package/dist/cli-bundle/chunks/chunk-TEISGNSH.js.map +1 -0
  182. package/dist/cli-bundle/chunks/{chunk-AAEQMOC6.js → chunk-TEKZOS7M.js} +2 -2
  183. package/dist/cli-bundle/chunks/{chunk-4QQ6PM7M.js → chunk-TGUK6XN6.js} +14 -18
  184. package/dist/cli-bundle/chunks/{chunk-4QQ6PM7M.js.map → chunk-TGUK6XN6.js.map} +1 -1
  185. package/dist/cli-bundle/chunks/{plan-R4NDQ27E.js → chunk-TNC6MZUD.js} +10 -21
  186. package/dist/cli-bundle/chunks/{plan-R4NDQ27E.js.map → chunk-TNC6MZUD.js.map} +1 -1
  187. package/dist/cli-bundle/chunks/chunk-TZLYO4PP.js +10498 -0
  188. package/dist/cli-bundle/chunks/chunk-TZLYO4PP.js.map +7 -0
  189. package/dist/cli-bundle/chunks/{chunk-YD5FML7K.js → chunk-UO7XAZK6.js} +27 -4
  190. package/dist/cli-bundle/chunks/chunk-UO7XAZK6.js.map +1 -0
  191. package/dist/cli-bundle/chunks/{docs-6CRCSVKK.js → chunk-V5ZWKJNY.js} +5 -14
  192. package/dist/cli-bundle/chunks/{docs-6CRCSVKK.js.map → chunk-V5ZWKJNY.js.map} +1 -1
  193. package/dist/cli-bundle/chunks/{notes-NJ7IQJX4.js → chunk-VGO73OCK.js} +7 -14
  194. package/dist/cli-bundle/chunks/{notes-NJ7IQJX4.js.map → chunk-VGO73OCK.js.map} +1 -1
  195. package/dist/cli-bundle/chunks/{chunk-NER3KUUS.js → chunk-VLEA2UTQ.js} +2 -2
  196. package/dist/cli-bundle/chunks/{files-6P57MRKL.js → chunk-W5HXHC7C.js} +8 -15
  197. package/dist/cli-bundle/chunks/{files-6P57MRKL.js.map → chunk-W5HXHC7C.js.map} +1 -1
  198. package/dist/cli-bundle/chunks/{chunk-ZMD35NYG.js → chunk-WCWVEXGA.js} +2 -2
  199. package/dist/cli-bundle/chunks/chunk-X47MKQXU.js +6690 -0
  200. package/dist/cli-bundle/chunks/chunk-X47MKQXU.js.map +7 -0
  201. package/dist/cli-bundle/chunks/{delete-62JQTYT4.js → chunk-XBX5CBRQ.js} +6 -10
  202. package/dist/cli-bundle/chunks/{delete-62JQTYT4.js.map → chunk-XBX5CBRQ.js.map} +1 -1
  203. package/dist/cli-bundle/chunks/{chunk-MTTXDAK4.js → chunk-XC3X7BQR.js} +541 -44
  204. package/dist/cli-bundle/chunks/chunk-XC3X7BQR.js.map +7 -0
  205. package/dist/cli-bundle/chunks/{history-compact-656Y2TN4.js → chunk-XHCVAZGM.js} +17 -23
  206. package/dist/cli-bundle/chunks/{history-compact-656Y2TN4.js.map → chunk-XHCVAZGM.js.map} +1 -1
  207. package/dist/cli-bundle/chunks/{chunk-ZAHXPXVY.js → chunk-XPMXPR7K.js} +7 -9
  208. package/dist/cli-bundle/chunks/{chunk-ZAHXPXVY.js.map → chunk-XPMXPR7K.js.map} +1 -1
  209. package/dist/cli-bundle/chunks/{deps-55FTG6Z5.js → chunk-XS2TMNXR.js} +8 -12
  210. package/dist/cli-bundle/chunks/{deps-55FTG6Z5.js.map → chunk-XS2TMNXR.js.map} +1 -1
  211. package/dist/cli-bundle/chunks/{plan-XWY5T67S.js → chunk-XXIYUTLK.js} +12 -23
  212. package/dist/cli-bundle/chunks/{plan-XWY5T67S.js.map → chunk-XXIYUTLK.js.map} +1 -1
  213. package/dist/cli-bundle/chunks/{chunk-7QH7DHUB.js → chunk-XZWL7VNE.js} +1220 -398
  214. package/dist/cli-bundle/chunks/chunk-XZWL7VNE.js.map +1 -0
  215. package/dist/cli-bundle/chunks/chunk-Y5IKRUEM.js +6624 -0
  216. package/dist/cli-bundle/chunks/chunk-Y5IKRUEM.js.map +1 -0
  217. package/dist/cli-bundle/chunks/{chunk-ABRA3BHY.js → chunk-Y7KYVCZM.js} +12 -18
  218. package/dist/cli-bundle/chunks/{chunk-ABRA3BHY.js.map → chunk-Y7KYVCZM.js.map} +1 -1
  219. package/dist/cli-bundle/chunks/{chunk-UI5BJ6DO.js → chunk-YCVWWIKY.js} +17 -28
  220. package/dist/cli-bundle/chunks/chunk-YCVWWIKY.js.map +7 -0
  221. package/dist/cli-bundle/chunks/chunk-YH5NBDFA.js +780 -0
  222. package/dist/cli-bundle/chunks/chunk-YH5NBDFA.js.map +1 -0
  223. package/dist/cli-bundle/chunks/chunk-YNCFP5AR.js +5509 -0
  224. package/dist/cli-bundle/chunks/chunk-YNCFP5AR.js.map +7 -0
  225. package/dist/cli-bundle/chunks/{comments-MIW5MZOX.js → chunk-YPD7SQ5P.js} +8 -12
  226. package/dist/cli-bundle/chunks/{comments-MIW5MZOX.js.map → chunk-YPD7SQ5P.js.map} +2 -2
  227. package/dist/cli-bundle/chunks/{chunk-T35XLYZF.js → chunk-YPMZMKN7.js} +2 -2
  228. package/dist/cli-bundle/chunks/{chunk-R3ZBLGTC.js → chunk-YTD5GICJ.js} +4 -4
  229. package/dist/cli-bundle/chunks/{config-DJJKZB5R.js → chunk-ZNEG2UDO.js} +264 -39
  230. package/dist/cli-bundle/chunks/{config-DJJKZB5R.js.map → chunk-ZNEG2UDO.js.map} +4 -4
  231. package/dist/cli-bundle/chunks/{chunk-EEY54JMF.js → chunk-ZO7CLOY2.js} +3 -3
  232. package/dist/cli-bundle/chunks/{close-3YRR3XY6.js → close-3YYQ5OG2.js} +5 -9
  233. package/dist/cli-bundle/chunks/close-Z3Q4U7TS.js +12 -0
  234. package/dist/cli-bundle/chunks/close-many-3L2RXH3M.js +22 -0
  235. package/dist/cli-bundle/chunks/close-many-D366FTIG.js +26 -0
  236. package/dist/cli-bundle/chunks/comments-54XDJNFE.js +17 -0
  237. package/dist/cli-bundle/chunks/comments-HGHC2PN6.js +13 -0
  238. package/dist/cli-bundle/chunks/copy-44RT5GDW.js +13 -0
  239. package/dist/cli-bundle/chunks/copy-UGMUGHZA.js +9 -0
  240. package/dist/cli-bundle/chunks/{create-XWWQFQ6S.js → create-4GWJWPXG.js} +9 -14
  241. package/dist/cli-bundle/chunks/create-AZXCUYKP.js +25 -0
  242. package/dist/cli-bundle/chunks/delete-Y6SXIQ4X.js +10 -0
  243. package/dist/cli-bundle/chunks/delete-YQ2VPXNF.js +14 -0
  244. package/dist/cli-bundle/chunks/deps-BU5EBJDU.js +17 -0
  245. package/dist/cli-bundle/chunks/deps-FMANWFRP.js +13 -0
  246. package/dist/cli-bundle/chunks/docs-OQBSJNIA.js +18 -0
  247. package/dist/cli-bundle/chunks/docs-VNPBZXEL.js +14 -0
  248. package/dist/cli-bundle/chunks/files-72HZEBOE.js +18 -0
  249. package/dist/cli-bundle/chunks/{activity-YKAKZTZ4.js → files-HTSB2KJG.js} +13 -13
  250. package/dist/cli-bundle/chunks/focus-FOG4ALC2.js +14 -0
  251. package/dist/cli-bundle/chunks/focus-SUTMKXGX.js +10 -0
  252. package/dist/cli-bundle/chunks/history-compact-M6IFAMBP.js +25 -0
  253. package/dist/cli-bundle/chunks/history-compact-NEXRPP2O.js +21 -0
  254. package/dist/cli-bundle/chunks/{history-redact-54ICFKXM.js → history-redact-NQX3OGZP.js} +7 -11
  255. package/dist/cli-bundle/chunks/history-redact-WQJBZ3PX.js +17 -0
  256. package/dist/cli-bundle/chunks/history-repair-CBHMHAJO.js +19 -0
  257. package/dist/cli-bundle/chunks/history-repair-NHOJG7WO.js +23 -0
  258. package/dist/cli-bundle/chunks/learnings-M64NTSOR.js +13 -0
  259. package/dist/cli-bundle/chunks/learnings-T63JGKKN.js +17 -0
  260. package/dist/cli-bundle/chunks/notes-73WE2UV2.js +13 -0
  261. package/dist/cli-bundle/chunks/notes-U7L6HQQ2.js +17 -0
  262. package/dist/cli-bundle/chunks/plan-OSCNYFGC.js +24 -0
  263. package/dist/cli-bundle/chunks/plan-OSCNYFGC.js.map +7 -0
  264. package/dist/cli-bundle/chunks/plan-TN537L24.js +28 -0
  265. package/dist/cli-bundle/chunks/plan-TN537L24.js.map +1 -0
  266. package/dist/cli-bundle/chunks/profile-MHAMXMHQ.js +37 -0
  267. package/dist/cli-bundle/chunks/profile-MHAMXMHQ.js.map +1 -0
  268. package/dist/cli-bundle/chunks/profile-TIGLAKJ7.js +33 -0
  269. package/dist/cli-bundle/chunks/profile-TIGLAKJ7.js.map +7 -0
  270. package/dist/cli-bundle/chunks/{register-list-query-5H66WFYF.js → register-list-query-OHXD7G5N.js} +41 -33
  271. package/dist/cli-bundle/chunks/register-list-query-OHXD7G5N.js.map +7 -0
  272. package/dist/cli-bundle/chunks/{register-list-query-FB3FNDLZ.js → register-list-query-ZCRABAPN.js} +42 -34
  273. package/dist/cli-bundle/chunks/register-list-query-ZCRABAPN.js.map +1 -0
  274. package/dist/cli-bundle/chunks/{register-mutation-UJO23C7R.js → register-mutation-P3G4XP6Q.js} +36 -41
  275. package/dist/cli-bundle/chunks/{register-mutation-UJO23C7R.js.map → register-mutation-P3G4XP6Q.js.map} +1 -1
  276. package/dist/cli-bundle/chunks/{register-mutation-Z2ETYHKS.js → register-mutation-XX4H56PE.js} +34 -39
  277. package/dist/cli-bundle/chunks/{register-mutation-Z2ETYHKS.js.map → register-mutation-XX4H56PE.js.map} +1 -1
  278. package/dist/cli-bundle/chunks/{register-operations-A3XAM5J7.js → register-operations-V6PIYEDU.js} +80 -52
  279. package/dist/cli-bundle/chunks/register-operations-V6PIYEDU.js.map +1 -0
  280. package/dist/cli-bundle/chunks/{register-operations-SG7HBSUP.js → register-operations-V6VKTG54.js} +79 -51
  281. package/dist/cli-bundle/chunks/register-operations-V6VKTG54.js.map +7 -0
  282. package/dist/cli-bundle/chunks/{register-setup-K6U3NVY5.js → register-setup-6RVAWT6W.js} +129 -31
  283. package/dist/cli-bundle/chunks/register-setup-6RVAWT6W.js.map +7 -0
  284. package/dist/cli-bundle/chunks/{register-setup-I45OGJUV.js → register-setup-6YVUSQYD.js} +130 -32
  285. package/dist/cli-bundle/chunks/register-setup-6YVUSQYD.js.map +1 -0
  286. package/dist/cli-bundle/chunks/{restore-YJ2ET6AT.js → restore-HC3YSWF7.js} +7 -11
  287. package/dist/cli-bundle/chunks/restore-HC3YSWF7.js.map +1 -0
  288. package/dist/cli-bundle/chunks/restore-LFAMMRYZ.js +15 -0
  289. package/dist/cli-bundle/chunks/restore-LFAMMRYZ.js.map +7 -0
  290. package/dist/cli-bundle/chunks/{schema-2PUXCZ25.js → schema-DAGSYO6E.js} +6 -10
  291. package/dist/cli-bundle/chunks/schema-DAGSYO6E.js.map +7 -0
  292. package/dist/cli-bundle/chunks/{schema-Y6DXXK2F.js → schema-UBXJCQAC.js} +6 -10
  293. package/dist/cli-bundle/chunks/schema-UBXJCQAC.js.map +1 -0
  294. package/dist/cli-bundle/chunks/update-CJGG5WMV.js +21 -0
  295. package/dist/cli-bundle/chunks/update-CJGG5WMV.js.map +7 -0
  296. package/dist/cli-bundle/chunks/update-LKD64AFP.js +25 -0
  297. package/dist/cli-bundle/chunks/update-LKD64AFP.js.map +1 -0
  298. package/dist/cli-bundle/chunks/update-many-G4SM7BHC.js +31 -0
  299. package/dist/cli-bundle/chunks/update-many-G4SM7BHC.js.map +7 -0
  300. package/dist/cli-bundle/chunks/update-many-VLIV3D7R.js +35 -0
  301. package/dist/cli-bundle/chunks/update-many-VLIV3D7R.js.map +1 -0
  302. package/dist/cli-bundle/main.js +29 -31
  303. package/dist/cli-bundle/main.js.map +2 -2
  304. package/dist/cli-bundle/sdk-runtime.js +136 -54
  305. package/dist/cli-bundle/sdk-testing.js +7 -8
  306. package/dist/cli-bundle/sdk.js +132 -84
  307. package/dist/cli-bundle/sdk.js.map +2 -2
  308. package/dist/core/history/drift-scan.js +3 -8
  309. package/dist/core/history/drift-scan.js.map +1 -1
  310. package/dist/core/output/mutation-projection.js +11 -5
  311. package/dist/core/output/mutation-projection.js.map +1 -1
  312. package/dist/core/search/cache.js +3 -3
  313. package/dist/core/search/cache.js.map +1 -1
  314. package/dist/core/search/semantic-defaults.d.ts +2 -0
  315. package/dist/core/search/semantic-defaults.js +11 -4
  316. package/dist/core/search/semantic-defaults.js.map +1 -1
  317. package/dist/core/search/vector-stores.d.ts +1 -1
  318. package/dist/core/search/vector-stores.js +33 -7
  319. package/dist/core/search/vector-stores.js.map +1 -1
  320. package/dist/mcp/server.d.ts +22 -50
  321. package/dist/mcp/server.js +62 -916
  322. package/dist/mcp/server.js.map +1 -1
  323. package/dist/sdk/cli-contracts/flag-contracts.js +7 -7
  324. package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
  325. package/dist/sdk/cli-contracts/tool-schema.js +9 -7
  326. package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
  327. package/dist/sdk/index.d.ts +4 -2
  328. package/dist/sdk/index.js +4 -4
  329. package/dist/sdk/index.js.map +1 -1
  330. package/dist/sdk/runtime.d.ts +312 -5
  331. package/dist/sdk/runtime.js +1391 -26
  332. package/dist/sdk/runtime.js.map +1 -1
  333. package/dist/sdk/start-task-status.d.ts +13 -0
  334. package/dist/sdk/start-task-status.js +19 -0
  335. package/dist/sdk/start-task-status.js.map +1 -0
  336. package/dist/sdk/workspace-contracts-cache.d.ts +17 -0
  337. package/dist/sdk/workspace-contracts-cache.js +36 -0
  338. package/dist/sdk/workspace-contracts-cache.js.map +1 -0
  339. package/docs/COMMANDS.md +10 -1
  340. package/docs/RELEASING.md +3 -1
  341. package/docs/SDK.md +81 -0
  342. package/docs/TESTING.md +3 -0
  343. package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +16 -2
  344. package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +16 -1
  345. package/package.json +1 -1
  346. package/dist/cli-bundle/chunks/activity-4XQIDNM5.js +0 -18
  347. package/dist/cli-bundle/chunks/aggregate-EQX2RGB7.js +0 -375
  348. package/dist/cli-bundle/chunks/aggregate-EQX2RGB7.js.map +0 -7
  349. package/dist/cli-bundle/chunks/aggregate-PEGZGJXD.js +0 -372
  350. package/dist/cli-bundle/chunks/aggregate-PEGZGJXD.js.map +0 -1
  351. package/dist/cli-bundle/chunks/chunk-37E72CNS.js +0 -217
  352. package/dist/cli-bundle/chunks/chunk-37E72CNS.js.map +0 -1
  353. package/dist/cli-bundle/chunks/chunk-3PL6LEKP.js +0 -1961
  354. package/dist/cli-bundle/chunks/chunk-3PL6LEKP.js.map +0 -1
  355. package/dist/cli-bundle/chunks/chunk-3U3VEWK6.js +0 -1749
  356. package/dist/cli-bundle/chunks/chunk-3U3VEWK6.js.map +0 -7
  357. package/dist/cli-bundle/chunks/chunk-4BU75MF4.js +0 -87
  358. package/dist/cli-bundle/chunks/chunk-4BU75MF4.js.map +0 -7
  359. package/dist/cli-bundle/chunks/chunk-4LRVSBO6.js +0 -822
  360. package/dist/cli-bundle/chunks/chunk-4LRVSBO6.js.map +0 -7
  361. package/dist/cli-bundle/chunks/chunk-4OFLJHX6.js.map +0 -1
  362. package/dist/cli-bundle/chunks/chunk-53BTLLAF.js +0 -2181
  363. package/dist/cli-bundle/chunks/chunk-53BTLLAF.js.map +0 -1
  364. package/dist/cli-bundle/chunks/chunk-57C2RLW5.js +0 -1704
  365. package/dist/cli-bundle/chunks/chunk-57C2RLW5.js.map +0 -1
  366. package/dist/cli-bundle/chunks/chunk-5B3X4Y22.js +0 -2330
  367. package/dist/cli-bundle/chunks/chunk-5B3X4Y22.js.map +0 -7
  368. package/dist/cli-bundle/chunks/chunk-5J2XPTAD.js.map +0 -7
  369. package/dist/cli-bundle/chunks/chunk-5JZ7APJU.js +0 -995
  370. package/dist/cli-bundle/chunks/chunk-5JZ7APJU.js.map +0 -1
  371. package/dist/cli-bundle/chunks/chunk-75U6M5ZD.js +0 -819
  372. package/dist/cli-bundle/chunks/chunk-75U6M5ZD.js.map +0 -1
  373. package/dist/cli-bundle/chunks/chunk-7C2O74AE.js +0 -23
  374. package/dist/cli-bundle/chunks/chunk-7C2O74AE.js.map +0 -7
  375. package/dist/cli-bundle/chunks/chunk-7EQNAZX2.js.map +0 -7
  376. package/dist/cli-bundle/chunks/chunk-7QH7DHUB.js.map +0 -1
  377. package/dist/cli-bundle/chunks/chunk-BVEUCSH2.js +0 -530
  378. package/dist/cli-bundle/chunks/chunk-BVEUCSH2.js.map +0 -7
  379. package/dist/cli-bundle/chunks/chunk-DC3QJQWI.js +0 -275
  380. package/dist/cli-bundle/chunks/chunk-DC3QJQWI.js.map +0 -7
  381. package/dist/cli-bundle/chunks/chunk-DRBV5UC2.js +0 -231
  382. package/dist/cli-bundle/chunks/chunk-DRBV5UC2.js.map +0 -7
  383. package/dist/cli-bundle/chunks/chunk-E2FUG6GD.js +0 -2184
  384. package/dist/cli-bundle/chunks/chunk-E2FUG6GD.js.map +0 -7
  385. package/dist/cli-bundle/chunks/chunk-EZFKWSC7.js +0 -1615
  386. package/dist/cli-bundle/chunks/chunk-EZFKWSC7.js.map +0 -7
  387. package/dist/cli-bundle/chunks/chunk-FJRKQREY.js +0 -228
  388. package/dist/cli-bundle/chunks/chunk-FJRKQREY.js.map +0 -1
  389. package/dist/cli-bundle/chunks/chunk-GIWXVMZ3.js +0 -3237
  390. package/dist/cli-bundle/chunks/chunk-GIWXVMZ3.js.map +0 -7
  391. package/dist/cli-bundle/chunks/chunk-HK72NWAD.js +0 -1570
  392. package/dist/cli-bundle/chunks/chunk-HK72NWAD.js.map +0 -1
  393. package/dist/cli-bundle/chunks/chunk-JFCVQXZX.js +0 -3206
  394. package/dist/cli-bundle/chunks/chunk-JFCVQXZX.js.map +0 -1
  395. package/dist/cli-bundle/chunks/chunk-JINYH2DB.js +0 -371
  396. package/dist/cli-bundle/chunks/chunk-JINYH2DB.js.map +0 -7
  397. package/dist/cli-bundle/chunks/chunk-JLA7EVYV.js.map +0 -1
  398. package/dist/cli-bundle/chunks/chunk-K32L7HZO.js +0 -76
  399. package/dist/cli-bundle/chunks/chunk-K32L7HZO.js.map +0 -1
  400. package/dist/cli-bundle/chunks/chunk-KDZ6K25I.js +0 -79
  401. package/dist/cli-bundle/chunks/chunk-KDZ6K25I.js.map +0 -7
  402. package/dist/cli-bundle/chunks/chunk-KL22PY6L.js +0 -915
  403. package/dist/cli-bundle/chunks/chunk-KL22PY6L.js.map +0 -1
  404. package/dist/cli-bundle/chunks/chunk-KLG4ZULO.js +0 -218
  405. package/dist/cli-bundle/chunks/chunk-KLG4ZULO.js.map +0 -7
  406. package/dist/cli-bundle/chunks/chunk-LEKT4K7I.js.map +0 -7
  407. package/dist/cli-bundle/chunks/chunk-MNZ7DRNC.js +0 -1858
  408. package/dist/cli-bundle/chunks/chunk-MNZ7DRNC.js.map +0 -1
  409. package/dist/cli-bundle/chunks/chunk-MTTXDAK4.js.map +0 -7
  410. package/dist/cli-bundle/chunks/chunk-MZ7VNEVY.js +0 -520
  411. package/dist/cli-bundle/chunks/chunk-MZ7VNEVY.js.map +0 -1
  412. package/dist/cli-bundle/chunks/chunk-N7X4WP6L.js +0 -1041
  413. package/dist/cli-bundle/chunks/chunk-N7X4WP6L.js.map +0 -7
  414. package/dist/cli-bundle/chunks/chunk-NBFCNJ7Q.js.map +0 -1
  415. package/dist/cli-bundle/chunks/chunk-NNHHXJB2.js +0 -20
  416. package/dist/cli-bundle/chunks/chunk-NNHHXJB2.js.map +0 -1
  417. package/dist/cli-bundle/chunks/chunk-OBA2WH65.js +0 -918
  418. package/dist/cli-bundle/chunks/chunk-OBA2WH65.js.map +0 -7
  419. package/dist/cli-bundle/chunks/chunk-OESSOFJ4.js +0 -1985
  420. package/dist/cli-bundle/chunks/chunk-OESSOFJ4.js.map +0 -7
  421. package/dist/cli-bundle/chunks/chunk-OK5NXCZB.js +0 -238
  422. package/dist/cli-bundle/chunks/chunk-OK5NXCZB.js.map +0 -1
  423. package/dist/cli-bundle/chunks/chunk-P5YORJRH.js +0 -1977
  424. package/dist/cli-bundle/chunks/chunk-P5YORJRH.js.map +0 -7
  425. package/dist/cli-bundle/chunks/chunk-PPAJG4GB.js +0 -1031
  426. package/dist/cli-bundle/chunks/chunk-PPAJG4GB.js.map +0 -1
  427. package/dist/cli-bundle/chunks/chunk-PPE4YUQM.js.map +0 -1
  428. package/dist/cli-bundle/chunks/chunk-QZ342C63.js +0 -220
  429. package/dist/cli-bundle/chunks/chunk-QZ342C63.js.map +0 -7
  430. package/dist/cli-bundle/chunks/chunk-R2EMWY7Q.js +0 -368
  431. package/dist/cli-bundle/chunks/chunk-R2EMWY7Q.js.map +0 -1
  432. package/dist/cli-bundle/chunks/chunk-S4APD35C.js.map +0 -7
  433. package/dist/cli-bundle/chunks/chunk-STPSZ2XY.js +0 -1149
  434. package/dist/cli-bundle/chunks/chunk-STPSZ2XY.js.map +0 -1
  435. package/dist/cli-bundle/chunks/chunk-T4MX77AK.js +0 -272
  436. package/dist/cli-bundle/chunks/chunk-T4MX77AK.js.map +0 -1
  437. package/dist/cli-bundle/chunks/chunk-T5Y3QSNF.js.map +0 -1
  438. package/dist/cli-bundle/chunks/chunk-TT42JUMF.js.map +0 -1
  439. package/dist/cli-bundle/chunks/chunk-UHKX7I75.js +0 -165
  440. package/dist/cli-bundle/chunks/chunk-UHKX7I75.js.map +0 -1
  441. package/dist/cli-bundle/chunks/chunk-UI5BJ6DO.js.map +0 -7
  442. package/dist/cli-bundle/chunks/chunk-US3T3W5J.js +0 -1932
  443. package/dist/cli-bundle/chunks/chunk-US3T3W5J.js.map +0 -1
  444. package/dist/cli-bundle/chunks/chunk-UZRDBL6W.js +0 -175
  445. package/dist/cli-bundle/chunks/chunk-UZRDBL6W.js.map +0 -7
  446. package/dist/cli-bundle/chunks/chunk-VY3VQ22F.js +0 -84
  447. package/dist/cli-bundle/chunks/chunk-VY3VQ22F.js.map +0 -1
  448. package/dist/cli-bundle/chunks/chunk-VZIYHZDX.js +0 -1868
  449. package/dist/cli-bundle/chunks/chunk-VZIYHZDX.js.map +0 -7
  450. package/dist/cli-bundle/chunks/chunk-WVSGSZ6J.js.map +0 -7
  451. package/dist/cli-bundle/chunks/chunk-XQCG2JGW.js +0 -1152
  452. package/dist/cli-bundle/chunks/chunk-XQCG2JGW.js.map +0 -7
  453. package/dist/cli-bundle/chunks/chunk-YD5FML7K.js.map +0 -1
  454. package/dist/cli-bundle/chunks/chunk-YSAH5FY5.js.map +0 -1
  455. package/dist/cli-bundle/chunks/chunk-YZIR4R3U.js +0 -1005
  456. package/dist/cli-bundle/chunks/chunk-YZIR4R3U.js.map +0 -7
  457. package/dist/cli-bundle/chunks/chunk-Z2CRRZYF.js +0 -215
  458. package/dist/cli-bundle/chunks/chunk-Z2CRRZYF.js.map +0 -1
  459. package/dist/cli-bundle/chunks/chunk-ZD34OFFQ.js.map +0 -7
  460. package/dist/cli-bundle/chunks/chunk-ZJB3UV5U.js +0 -2306
  461. package/dist/cli-bundle/chunks/chunk-ZJB3UV5U.js.map +0 -1
  462. package/dist/cli-bundle/chunks/chunk-ZVDL32GJ.js +0 -241
  463. package/dist/cli-bundle/chunks/chunk-ZVDL32GJ.js.map +0 -7
  464. package/dist/cli-bundle/chunks/claim-4DROPSIS.js +0 -144
  465. package/dist/cli-bundle/chunks/claim-4DROPSIS.js.map +0 -1
  466. package/dist/cli-bundle/chunks/claim-VX54TV5U.js +0 -147
  467. package/dist/cli-bundle/chunks/claim-VX54TV5U.js.map +0 -7
  468. package/dist/cli-bundle/chunks/close-OB2Y4QP5.js +0 -16
  469. package/dist/cli-bundle/chunks/config-V57QD47V.js.map +0 -1
  470. package/dist/cli-bundle/chunks/context-4OQGIPSO.js +0 -45
  471. package/dist/cli-bundle/chunks/context-WLA6IAWE.js +0 -49
  472. package/dist/cli-bundle/chunks/contracts-HXJLKCRI.js +0 -12
  473. package/dist/cli-bundle/chunks/create-WKOZKPQR.js +0 -30
  474. package/dist/cli-bundle/chunks/eval-N6UHFWVO.js +0 -288
  475. package/dist/cli-bundle/chunks/eval-N6UHFWVO.js.map +0 -7
  476. package/dist/cli-bundle/chunks/eval-PHOTWYHI.js +0 -278
  477. package/dist/cli-bundle/chunks/eval-PHOTWYHI.js.map +0 -1
  478. package/dist/cli-bundle/chunks/extension-NBAH62ML.js +0 -40
  479. package/dist/cli-bundle/chunks/extension-ZF6ZZPOU.js +0 -44
  480. package/dist/cli-bundle/chunks/gc-AETFKZ44.js +0 -398
  481. package/dist/cli-bundle/chunks/gc-AETFKZ44.js.map +0 -7
  482. package/dist/cli-bundle/chunks/gc-RLBP4QVN.js +0 -388
  483. package/dist/cli-bundle/chunks/gc-RLBP4QVN.js.map +0 -1
  484. package/dist/cli-bundle/chunks/get-NH2MPBCI.js +0 -283
  485. package/dist/cli-bundle/chunks/get-NH2MPBCI.js.map +0 -1
  486. package/dist/cli-bundle/chunks/get-P4ZQXCPZ.js +0 -286
  487. package/dist/cli-bundle/chunks/get-P4ZQXCPZ.js.map +0 -7
  488. package/dist/cli-bundle/chunks/health-3GVPMQBL.js +0 -1612
  489. package/dist/cli-bundle/chunks/health-3GVPMQBL.js.map +0 -1
  490. package/dist/cli-bundle/chunks/health-DNTM72GJ.js +0 -1615
  491. package/dist/cli-bundle/chunks/health-DNTM72GJ.js.map +0 -7
  492. package/dist/cli-bundle/chunks/history-RYKLC72X.js +0 -20
  493. package/dist/cli-bundle/chunks/history-SGPYRAFT.js +0 -24
  494. package/dist/cli-bundle/chunks/history-redact-4H3FCKF3.js +0 -21
  495. package/dist/cli-bundle/chunks/init-RPIPQUNV.js +0 -32
  496. package/dist/cli-bundle/chunks/init-SKQAESQS.js +0 -28
  497. package/dist/cli-bundle/chunks/list-64LHZ3HM.js +0 -32
  498. package/dist/cli-bundle/chunks/list-7LXBTEKI.js +0 -36
  499. package/dist/cli-bundle/chunks/next-7ODPAQ4U.js +0 -306
  500. package/dist/cli-bundle/chunks/next-7ODPAQ4U.js.map +0 -7
  501. package/dist/cli-bundle/chunks/next-ODJUM4ZM.js +0 -303
  502. package/dist/cli-bundle/chunks/next-ODJUM4ZM.js.map +0 -1
  503. package/dist/cli-bundle/chunks/profile-XQWEQKS3.js +0 -397
  504. package/dist/cli-bundle/chunks/profile-XQWEQKS3.js.map +0 -1
  505. package/dist/cli-bundle/chunks/profile-YRDHLMRO.js +0 -400
  506. package/dist/cli-bundle/chunks/profile-YRDHLMRO.js.map +0 -7
  507. package/dist/cli-bundle/chunks/register-list-query-5H66WFYF.js.map +0 -7
  508. package/dist/cli-bundle/chunks/register-list-query-FB3FNDLZ.js.map +0 -1
  509. package/dist/cli-bundle/chunks/register-operations-A3XAM5J7.js.map +0 -1
  510. package/dist/cli-bundle/chunks/register-operations-SG7HBSUP.js.map +0 -7
  511. package/dist/cli-bundle/chunks/register-setup-I45OGJUV.js.map +0 -1
  512. package/dist/cli-bundle/chunks/register-setup-K6U3NVY5.js.map +0 -7
  513. package/dist/cli-bundle/chunks/restore-PXOFL6AM.js +0 -19
  514. package/dist/cli-bundle/chunks/scheduling-shortcuts-SSC4MYWQ.js +0 -91
  515. package/dist/cli-bundle/chunks/scheduling-shortcuts-SSC4MYWQ.js.map +0 -7
  516. package/dist/cli-bundle/chunks/scheduling-shortcuts-ULRG7MNP.js +0 -88
  517. package/dist/cli-bundle/chunks/scheduling-shortcuts-ULRG7MNP.js.map +0 -1
  518. package/dist/cli-bundle/chunks/search-3S72CTD6.js +0 -38
  519. package/dist/cli-bundle/chunks/search-WNUNBQXO.js +0 -34
  520. package/dist/cli-bundle/chunks/stats-IJYTRQGV.js +0 -250
  521. package/dist/cli-bundle/chunks/stats-IJYTRQGV.js.map +0 -7
  522. package/dist/cli-bundle/chunks/stats-L2D5Y2O5.js +0 -240
  523. package/dist/cli-bundle/chunks/stats-L2D5Y2O5.js.map +0 -1
  524. package/dist/cli-bundle/chunks/telemetry-L2CVOKVN.js +0 -309
  525. package/dist/cli-bundle/chunks/telemetry-L2CVOKVN.js.map +0 -7
  526. package/dist/cli-bundle/chunks/telemetry-QBYWQA76.js +0 -306
  527. package/dist/cli-bundle/chunks/telemetry-QBYWQA76.js.map +0 -1
  528. package/dist/cli-bundle/chunks/test-DQ2QFJ7W.js +0 -45
  529. package/dist/cli-bundle/chunks/test-W7QBLVJS.js +0 -41
  530. package/dist/cli-bundle/chunks/test-all-636NTRTT.js +0 -434
  531. package/dist/cli-bundle/chunks/test-all-636NTRTT.js.map +0 -1
  532. package/dist/cli-bundle/chunks/test-all-DWYK3RG6.js +0 -437
  533. package/dist/cli-bundle/chunks/test-all-DWYK3RG6.js.map +0 -7
  534. package/dist/cli-bundle/chunks/test-runs-245OINZR.js +0 -28
  535. package/dist/cli-bundle/chunks/test-runs-ZRD4GCTT.js +0 -24
  536. package/dist/cli-bundle/chunks/update-SFLZPJXX.js +0 -30
  537. package/dist/cli-bundle/chunks/update-SJZ6S77U.js +0 -26
  538. package/dist/cli-bundle/chunks/upgrade-HFFXLZJA.js +0 -290
  539. package/dist/cli-bundle/chunks/upgrade-HFFXLZJA.js.map +0 -7
  540. package/dist/cli-bundle/chunks/upgrade-UYQKM7RF.js +0 -287
  541. package/dist/cli-bundle/chunks/upgrade-UYQKM7RF.js.map +0 -1
  542. package/dist/cli-bundle/chunks/validate-PA4FDTOV.js +0 -2143
  543. package/dist/cli-bundle/chunks/validate-PA4FDTOV.js.map +0 -7
  544. package/dist/cli-bundle/chunks/validate-Z7L75YEJ.js +0 -2105
  545. package/dist/cli-bundle/chunks/validate-Z7L75YEJ.js.map +0 -1
  546. /package/dist/cli-bundle/chunks/{activity-4XQIDNM5.js.map → append-F7WPGIQL.js.map} +0 -0
  547. /package/dist/cli-bundle/chunks/{activity-YKAKZTZ4.js.map → append-PVCTBVJG.js.map} +0 -0
  548. /package/dist/cli-bundle/chunks/{chunk-T3ABIMGW.js.map → chunk-2TILG6F2.js.map} +0 -0
  549. /package/dist/cli-bundle/chunks/{chunk-RCT3YJOK.js.map → chunk-3TYOW6RR.js.map} +0 -0
  550. /package/dist/cli-bundle/chunks/{chunk-3JZNEQBA.js.map → chunk-3X542TEY.js.map} +0 -0
  551. /package/dist/cli-bundle/chunks/{chunk-YOF5VPKM.js.map → chunk-7VQ3JJN5.js.map} +0 -0
  552. /package/dist/cli-bundle/chunks/{chunk-P5TFTLWW.js.map → chunk-AGAVEDIE.js.map} +0 -0
  553. /package/dist/cli-bundle/chunks/{chunk-YFIE7YK6.js.map → chunk-AJUON7E6.js.map} +0 -0
  554. /package/dist/cli-bundle/chunks/{chunk-7WYXBPYQ.js.map → chunk-DR2V5OIV.js.map} +0 -0
  555. /package/dist/cli-bundle/chunks/{chunk-PDXT6Q55.js.map → chunk-EDO7VXSO.js.map} +0 -0
  556. /package/dist/cli-bundle/chunks/{chunk-FUM6UMY4.js.map → chunk-EVEPHNXJ.js.map} +0 -0
  557. /package/dist/cli-bundle/chunks/{chunk-RX3HQSYG.js.map → chunk-FN6SB4HU.js.map} +0 -0
  558. /package/dist/cli-bundle/chunks/{chunk-DLQ4ZTCU.js.map → chunk-H2SMKL2N.js.map} +0 -0
  559. /package/dist/cli-bundle/chunks/{chunk-C3PMDWGX.js.map → chunk-HX6QXV5P.js.map} +0 -0
  560. /package/dist/cli-bundle/chunks/{chunk-N6DNM2FA.js.map → chunk-P3MJJW7P.js.map} +0 -0
  561. /package/dist/cli-bundle/chunks/{chunk-5JE6SMYS.js.map → chunk-PDXJXEZJ.js.map} +0 -0
  562. /package/dist/cli-bundle/chunks/{chunk-AAEQMOC6.js.map → chunk-TEKZOS7M.js.map} +0 -0
  563. /package/dist/cli-bundle/chunks/{chunk-NER3KUUS.js.map → chunk-VLEA2UTQ.js.map} +0 -0
  564. /package/dist/cli-bundle/chunks/{chunk-ZMD35NYG.js.map → chunk-WCWVEXGA.js.map} +0 -0
  565. /package/dist/cli-bundle/chunks/{chunk-T35XLYZF.js.map → chunk-YPMZMKN7.js.map} +0 -0
  566. /package/dist/cli-bundle/chunks/{chunk-R3ZBLGTC.js.map → chunk-YTD5GICJ.js.map} +0 -0
  567. /package/dist/cli-bundle/chunks/{chunk-EEY54JMF.js.map → chunk-ZO7CLOY2.js.map} +0 -0
  568. /package/dist/cli-bundle/chunks/{close-3YRR3XY6.js.map → close-3YYQ5OG2.js.map} +0 -0
  569. /package/dist/cli-bundle/chunks/{close-OB2Y4QP5.js.map → close-Z3Q4U7TS.js.map} +0 -0
  570. /package/dist/cli-bundle/chunks/{context-4OQGIPSO.js.map → close-many-3L2RXH3M.js.map} +0 -0
  571. /package/dist/cli-bundle/chunks/{context-WLA6IAWE.js.map → close-many-D366FTIG.js.map} +0 -0
  572. /package/dist/cli-bundle/chunks/{contracts-OJEXMKVW.js.map → comments-54XDJNFE.js.map} +0 -0
  573. /package/dist/cli-bundle/chunks/{contracts-HXJLKCRI.js.map → comments-HGHC2PN6.js.map} +0 -0
  574. /package/dist/cli-bundle/chunks/{create-XWWQFQ6S.js.map → copy-44RT5GDW.js.map} +0 -0
  575. /package/dist/cli-bundle/chunks/{create-WKOZKPQR.js.map → copy-UGMUGHZA.js.map} +0 -0
  576. /package/dist/cli-bundle/chunks/{extension-ZF6ZZPOU.js.map → create-4GWJWPXG.js.map} +0 -0
  577. /package/dist/cli-bundle/chunks/{extension-NBAH62ML.js.map → create-AZXCUYKP.js.map} +0 -0
  578. /package/dist/cli-bundle/chunks/{history-RYKLC72X.js.map → delete-Y6SXIQ4X.js.map} +0 -0
  579. /package/dist/cli-bundle/chunks/{history-SGPYRAFT.js.map → delete-YQ2VPXNF.js.map} +0 -0
  580. /package/dist/cli-bundle/chunks/{history-redact-54ICFKXM.js.map → deps-BU5EBJDU.js.map} +0 -0
  581. /package/dist/cli-bundle/chunks/{history-redact-4H3FCKF3.js.map → deps-FMANWFRP.js.map} +0 -0
  582. /package/dist/cli-bundle/chunks/{init-RPIPQUNV.js.map → docs-OQBSJNIA.js.map} +0 -0
  583. /package/dist/cli-bundle/chunks/{init-SKQAESQS.js.map → docs-VNPBZXEL.js.map} +0 -0
  584. /package/dist/cli-bundle/chunks/{list-64LHZ3HM.js.map → files-72HZEBOE.js.map} +0 -0
  585. /package/dist/cli-bundle/chunks/{list-7LXBTEKI.js.map → files-HTSB2KJG.js.map} +0 -0
  586. /package/dist/cli-bundle/chunks/{restore-YJ2ET6AT.js.map → focus-FOG4ALC2.js.map} +0 -0
  587. /package/dist/cli-bundle/chunks/{restore-PXOFL6AM.js.map → focus-SUTMKXGX.js.map} +0 -0
  588. /package/dist/cli-bundle/chunks/{schema-Y6DXXK2F.js.map → history-compact-M6IFAMBP.js.map} +0 -0
  589. /package/dist/cli-bundle/chunks/{schema-2PUXCZ25.js.map → history-compact-NEXRPP2O.js.map} +0 -0
  590. /package/dist/cli-bundle/chunks/{search-3S72CTD6.js.map → history-redact-NQX3OGZP.js.map} +0 -0
  591. /package/dist/cli-bundle/chunks/{search-WNUNBQXO.js.map → history-redact-WQJBZ3PX.js.map} +0 -0
  592. /package/dist/cli-bundle/chunks/{test-W7QBLVJS.js.map → history-repair-CBHMHAJO.js.map} +0 -0
  593. /package/dist/cli-bundle/chunks/{test-DQ2QFJ7W.js.map → history-repair-NHOJG7WO.js.map} +0 -0
  594. /package/dist/cli-bundle/chunks/{test-runs-ZRD4GCTT.js.map → learnings-M64NTSOR.js.map} +0 -0
  595. /package/dist/cli-bundle/chunks/{test-runs-245OINZR.js.map → learnings-T63JGKKN.js.map} +0 -0
  596. /package/dist/cli-bundle/chunks/{update-SJZ6S77U.js.map → notes-73WE2UV2.js.map} +0 -0
  597. /package/dist/cli-bundle/chunks/{update-SFLZPJXX.js.map → notes-U7L6HQQ2.js.map} +0 -0
@@ -1,2105 +0,0 @@
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]="7b42ea6d-c9b5-5d22-b82e-64af26f3173c")}catch(e){}}();
3
- import {
4
- extractReferencedPmItemIdsFromCommand
5
- } from "./chunk-3PL6LEKP.js";
6
- import {
7
- buildRemediationCommands
8
- } from "./chunk-R2EMWY7Q.js";
9
- import {
10
- scanHistoryDrift
11
- } from "./chunk-TT42JUMF.js";
12
- import {
13
- isRemoteLinkedArtifactReference
14
- } from "./chunk-IBMFIKVS.js";
15
- import "./chunk-BFVHCAOO.js";
16
- import "./chunk-MZ7VNEVY.js";
17
- import "./chunk-7WYXBPYQ.js";
18
- import "./chunk-5JZ7APJU.js";
19
- import "./chunk-JFCVQXZX.js";
20
- import "./chunk-K32L7HZO.js";
21
- import "./chunk-OK5NXCZB.js";
22
- import "./chunk-53BTLLAF.js";
23
- import "./chunk-P4SESZGT.js";
24
- import "./chunk-FUM6UMY4.js";
25
- import "./chunk-PPE4YUQM.js";
26
- import "./chunk-AAEQMOC6.js";
27
- import "./chunk-PJ3A56YF.js";
28
- import {
29
- listAllFrontMatterWithBody
30
- } from "./chunk-57C2RLW5.js";
31
- import "./chunk-ZAHXPXVY.js";
32
- import {
33
- CURRENT_ITEM_FORMAT_VERSION,
34
- effectiveItemFormatVersion,
35
- normalizeStatusInput,
36
- scanItemFormatVersions
37
- } from "./chunk-HK72NWAD.js";
38
- import {
39
- nowIso
40
- } from "./chunk-FJRKQREY.js";
41
- import {
42
- PmCliError,
43
- getActiveExtensionRegistrations,
44
- readSettings,
45
- resolveEstimateDefaultMinutes
46
- } from "./chunk-US3T3W5J.js";
47
- import "./chunk-NER3KUUS.js";
48
- import "./chunk-NNHHXJB2.js";
49
- import {
50
- DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS,
51
- DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS,
52
- EXIT_CODE,
53
- PM_DIRNAME,
54
- getSettingsPath,
55
- pathExists,
56
- resolveItemTypeRegistry,
57
- resolvePmRoot,
58
- resolveRuntimeStatusRegistry,
59
- toNonEmptyStringOrUndefined
60
- } from "./chunk-YD5FML7K.js";
61
-
62
- // dist/cli/commands/validate.js
63
- import fs from "node:fs/promises";
64
- import { realpathSync } from "node:fs";
65
- import { execFile } from "node:child_process";
66
- import path from "node:path";
67
- import { promisify } from "node:util";
68
-
69
- // dist/core/validate/fix-planning.js
70
- var DEFAULT_GRANTED_FIX_SCOPES = ["metadata", "resolution"];
71
- var SUPPORTED_FIX_SCOPES = ["metadata", "resolution", "estimates", "lifecycle"];
72
- var DEFAULT_RESOLUTION_BACKFILL_VALUE = "completed";
73
- function quoteForCommand(value) {
74
- return `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"`;
75
- }
76
- function toMeaningfulValue(value) {
77
- const trimmed = value?.trim();
78
- return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
79
- }
80
- function planResolutionBackfillFixes(rows) {
81
- const fixes = [];
82
- for (const row of rows) {
83
- if (!row.missing_fields.includes("resolution")) {
84
- continue;
85
- }
86
- const value = toMeaningfulValue(row.close_reason) ?? DEFAULT_RESOLUTION_BACKFILL_VALUE;
87
- fixes.push({
88
- item_id: row.id,
89
- check: "resolution",
90
- field: "resolution",
91
- kind: "set_resolution",
92
- value,
93
- command: `pm update ${row.id} --resolution ${quoteForCommand(value)}`,
94
- gate: "resolution"
95
- });
96
- }
97
- return fixes;
98
- }
99
- function planCloseReasonBackfillFixes(rows) {
100
- const fixes = [];
101
- for (const row of rows) {
102
- const value = toMeaningfulValue(row.resolution);
103
- if (value === void 0) {
104
- continue;
105
- }
106
- fixes.push({
107
- item_id: row.id,
108
- check: "metadata",
109
- field: "close_reason",
110
- kind: "set_close_reason",
111
- value,
112
- command: `pm update ${row.id} --close-reason ${quoteForCommand(value)}`,
113
- gate: "metadata"
114
- });
115
- }
116
- return fixes;
117
- }
118
- function planEstimateBackfillFixes(rows, overrides) {
119
- return rows.map((row) => {
120
- const minutes = resolveEstimateDefaultMinutes(row.type, overrides);
121
- return {
122
- item_id: row.id,
123
- check: "metadata",
124
- field: "estimated_minutes",
125
- kind: "set_estimate",
126
- value: String(minutes),
127
- command: `pm update ${row.id} --estimate ${minutes}`,
128
- gate: "estimates"
129
- };
130
- });
131
- }
132
- function planTerminalParentFixes(rows) {
133
- return rows.map((row) => {
134
- if (row.grandparent_id !== void 0 && row.grandparent_active === true) {
135
- return {
136
- item_id: row.id,
137
- check: "lifecycle",
138
- field: "parent",
139
- kind: "reparent",
140
- parent_id: row.grandparent_id,
141
- command: `pm update ${row.id} --parent ${row.grandparent_id}`,
142
- gate: "lifecycle"
143
- };
144
- }
145
- return {
146
- item_id: row.id,
147
- check: "lifecycle",
148
- field: "parent",
149
- kind: "unset_parent",
150
- command: `pm update ${row.id} --unset parent`,
151
- gate: "lifecycle"
152
- };
153
- });
154
- }
155
- function planStaleLinkPruneFixes(rows) {
156
- const fixes = [];
157
- for (const row of rows) {
158
- if (row.classification !== "deleted") {
159
- continue;
160
- }
161
- const noun = row.link_kind === "files" ? "files" : "docs";
162
- fixes.push({
163
- item_id: row.item_id,
164
- check: "files",
165
- field: row.link_kind,
166
- kind: row.link_kind === "files" ? "prune_file_link" : "prune_doc_link",
167
- path: row.path,
168
- command: `pm ${noun} ${row.item_id} --remove ${quoteForCommand(row.path)}`
169
- });
170
- }
171
- return fixes;
172
- }
173
- function resolveGrantedFixScopes(rawScopes) {
174
- const tokens = (rawScopes ?? []).flatMap((raw) => raw.split(",")).map((raw) => raw.trim()).filter((raw) => raw.length > 0);
175
- if (tokens.length === 0) {
176
- if (rawScopes !== void 0 && rawScopes.length > 0) {
177
- throw new PmCliError(`--fix-scope values must not be empty. Supported values: ${SUPPORTED_FIX_SCOPES.join(", ")}.`, EXIT_CODE.USAGE);
178
- }
179
- return new Set(DEFAULT_GRANTED_FIX_SCOPES);
180
- }
181
- const granted = /* @__PURE__ */ new Set();
182
- for (const raw of tokens) {
183
- const normalized = raw.toLowerCase().replaceAll("-", "_");
184
- if (SUPPORTED_FIX_SCOPES.includes(normalized)) {
185
- granted.add(normalized);
186
- continue;
187
- }
188
- throw new PmCliError(`Unknown --fix-scope value "${raw}". Supported values: ${SUPPORTED_FIX_SCOPES.join(", ")}.`, EXIT_CODE.USAGE);
189
- }
190
- return granted;
191
- }
192
- function partitionFixesByGrant(fixes, granted) {
193
- const applicable = [];
194
- const gated = [];
195
- for (const fix of fixes) {
196
- if (fix.gate !== void 0 && !granted.has(fix.gate)) {
197
- gated.push(fix);
198
- } else {
199
- applicable.push(fix);
200
- }
201
- }
202
- return { applicable, gated };
203
- }
204
- function toFixOutputRow(fix) {
205
- return {
206
- item_id: fix.item_id,
207
- check: fix.check,
208
- field: fix.field,
209
- command: fix.command,
210
- ...fix.gate !== void 0 ? { gate: fix.gate } : {}
211
- };
212
- }
213
-
214
- // dist/core/governance/issue-codes.js
215
- var ISSUE_CODE_PATTERN = /^([A-Z][A-Z0-9]*-\d+)\b/;
216
- function extractIssueCode(title) {
217
- if (typeof title !== "string") {
218
- return null;
219
- }
220
- const normalized = title.trim().toUpperCase();
221
- if (normalized.length === 0) {
222
- return null;
223
- }
224
- const match = ISSUE_CODE_PATTERN.exec(normalized);
225
- return match ? match[1] : null;
226
- }
227
- function isNonEmptyIdReference(value) {
228
- return typeof value === "string" && value.trim().length > 0;
229
- }
230
- function findDuplicateIssueCodes(items) {
231
- const byCode = /* @__PURE__ */ new Map();
232
- for (const item of items) {
233
- if (typeof item.title !== "string") {
234
- continue;
235
- }
236
- if (isNonEmptyIdReference(item.duplicate_of)) {
237
- continue;
238
- }
239
- const code = extractIssueCode(item.title);
240
- if (code === null) {
241
- continue;
242
- }
243
- let entries = byCode.get(code);
244
- if (!entries) {
245
- entries = [];
246
- byCode.set(code, entries);
247
- }
248
- if (!entries.some((entry) => entry.id === item.id)) {
249
- entries.push({ id: item.id, title: item.title, parent: isNonEmptyIdReference(item.parent) ? item.parent.trim() : null });
250
- }
251
- }
252
- const duplicates = [];
253
- for (const [code, entries] of byCode) {
254
- if (entries.length < 2) {
255
- continue;
256
- }
257
- const idsInGroup = new Set(entries.map((entry) => entry.id.toLowerCase()));
258
- const collisionEntries = entries.filter((entry) => entry.parent === null || !idsInGroup.has(entry.parent.toLowerCase()));
259
- if (collisionEntries.length < 2) {
260
- continue;
261
- }
262
- const sorted = [...collisionEntries].sort((left, right) => left.id.localeCompare(right.id));
263
- duplicates.push({
264
- code,
265
- count: sorted.length,
266
- ids: sorted.map((entry) => entry.id),
267
- titles: sorted.map((entry) => entry.title)
268
- });
269
- }
270
- return duplicates.sort((left, right) => left.code.localeCompare(right.code));
271
- }
272
-
273
- // dist/core/validate/missing-by-type.js
274
- function buildMissingByTypeCounts(occurrences) {
275
- const countsByType = /* @__PURE__ */ new Map();
276
- for (const occurrence of occurrences) {
277
- let fieldCounts = countsByType.get(occurrence.item_type);
278
- if (!fieldCounts) {
279
- fieldCounts = /* @__PURE__ */ new Map();
280
- countsByType.set(occurrence.item_type, fieldCounts);
281
- }
282
- fieldCounts.set(occurrence.field, (fieldCounts.get(occurrence.field) ?? 0) + 1);
283
- }
284
- const result = {};
285
- for (const type of [...countsByType.keys()].sort((left, right) => left.localeCompare(right))) {
286
- const fieldCounts = countsByType.get(type);
287
- const fields = {};
288
- for (const field of [...fieldCounts.keys()].sort((left, right) => left.localeCompare(right))) {
289
- fields[field] = fieldCounts.get(field);
290
- }
291
- result[type] = fields;
292
- }
293
- return result;
294
- }
295
-
296
- // dist/core/validate/stale-file-classification.js
297
- var DEFAULT_STALE_PATH_CANDIDATE_LIMIT = 3;
298
- function basenameOf(relativePath) {
299
- const lastSlash = Math.max(relativePath.lastIndexOf("/"), relativePath.lastIndexOf("\\"));
300
- return lastSlash === -1 ? relativePath : relativePath.slice(lastSlash + 1);
301
- }
302
- function classifyStaleLinkedPaths(stalePaths, candidateFiles, candidateLimit = DEFAULT_STALE_PATH_CANDIDATE_LIMIT) {
303
- const limit = Number.isFinite(candidateLimit) && candidateLimit >= 1 ? Math.floor(candidateLimit) : DEFAULT_STALE_PATH_CANDIDATE_LIMIT;
304
- const candidatesByBasename = /* @__PURE__ */ new Map();
305
- for (const candidate of candidateFiles) {
306
- const basename = basenameOf(candidate);
307
- if (basename.length === 0) {
308
- continue;
309
- }
310
- const bucket = candidatesByBasename.get(basename);
311
- if (bucket) {
312
- bucket.push(candidate);
313
- } else {
314
- candidatesByBasename.set(basename, [candidate]);
315
- }
316
- }
317
- return stalePaths.map((stalePath) => {
318
- const matches = (candidatesByBasename.get(basenameOf(stalePath)) ?? []).filter((candidate) => candidate !== stalePath).sort((left, right) => left.localeCompare(right));
319
- if (matches.length === 0) {
320
- return {
321
- path: stalePath,
322
- classification: "deleted",
323
- candidates: [],
324
- candidates_truncated: false
325
- };
326
- }
327
- return {
328
- path: stalePath,
329
- classification: "moved",
330
- candidates: matches.slice(0, limit),
331
- candidates_truncated: matches.length > limit
332
- };
333
- });
334
- }
335
- function summarizeStaleLinkedPathClassifications(classified) {
336
- return classified.map((entry) => entry.classification === "moved" ? `${entry.path}:moved:${entry.candidates[0]}` : `${entry.path}:deleted`);
337
- }
338
-
339
- // dist/core/validate/missing-link-owners.js
340
- function preferClassification(current, next) {
341
- return current === "moved" || next === "moved" ? "moved" : "deleted";
342
- }
343
- function ownerKey(input) {
344
- return `${input.item_id} ${input.link_kind}`;
345
- }
346
- function buildMissingLinkedPathRows(rows, lookup) {
347
- const buckets = /* @__PURE__ */ new Map();
348
- for (const row of rows) {
349
- const bucket = buckets.get(row.path);
350
- if (bucket) {
351
- bucket.classification = preferClassification(bucket.classification, row.classification);
352
- bucket.owners.set(ownerKey(row), row);
353
- } else {
354
- buckets.set(row.path, {
355
- classification: row.classification,
356
- owners: /* @__PURE__ */ new Map([[ownerKey(row), row]])
357
- });
358
- }
359
- }
360
- return [...buckets.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([path2, bucket]) => ({
361
- path: path2,
362
- classification: bucket.classification,
363
- items: [...bucket.owners.values()].map((owner) => {
364
- const metadata = lookup(owner.item_id);
365
- return {
366
- id: owner.item_id,
367
- type: metadata?.type ?? "Unknown",
368
- title: metadata?.title ?? "",
369
- status: metadata?.status ?? "",
370
- field: owner.link_kind
371
- };
372
- }).sort((leftOwner, rightOwner) => {
373
- const byId = leftOwner.id.localeCompare(rightOwner.id);
374
- return byId !== 0 ? byId : leftOwner.field.localeCompare(rightOwner.field);
375
- })
376
- }));
377
- }
378
- function escapeTitle(title) {
379
- return title.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
380
- }
381
- function summarizeMissingLinkedPathRows(rows) {
382
- const lines = [];
383
- for (const row of rows) {
384
- for (const owner of row.items) {
385
- lines.push(`${row.path}:${row.classification} owner=${owner.id} status=${owner.status} field=${owner.field} title="${escapeTitle(owner.title)}"`);
386
- }
387
- }
388
- return lines;
389
- }
390
-
391
- // dist/cli/commands/validate.js
392
- var FILE_SCAN_DIRECTORIES = ["src", "tests", "docs"];
393
- var FILE_SCAN_ROOT_FILES = [
394
- "README.md",
395
- "PRD.md",
396
- "CHANGELOG.md",
397
- "AGENTS.md",
398
- "CONTRIBUTING.md",
399
- "SECURITY.md",
400
- "CODE_OF_CONDUCT.md",
401
- "LICENSE"
402
- ];
403
- var DIRECTORY_IGNORE_SET = /* @__PURE__ */ new Set(["node_modules", ".git", ".cursor", ".agents", "dist", "coverage"]);
404
- var RESOLUTION_FIELD_KEYS = ["resolution", "expected_result", "actual_result"];
405
- var VALIDATE_FILE_SCAN_MODES = ["default", "tracked-all", "tracked-all-strict"];
406
- var VALIDATE_METADATA_PROFILE_VALUES = ["core", "strict", "custom"];
407
- var VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES = ["off", "warn", "error"];
408
- var CORE_METADATA_REQUIRED_FIELDS = ["author", "acceptance_criteria", "estimated_minutes", "close_reason"];
409
- var STRICT_METADATA_REQUIRED_FIELDS = [
410
- ...CORE_METADATA_REQUIRED_FIELDS,
411
- "reviewer",
412
- "risk",
413
- "confidence",
414
- "sprint",
415
- "release"
416
- ];
417
- var SUPPORTED_METADATA_REQUIRED_FIELDS = Array.from(new Set(STRICT_METADATA_REQUIRED_FIELDS));
418
- var METADATA_REQUIRED_FIELD_ALIASES = {
419
- author: "author",
420
- acceptance_criteria: "acceptance_criteria",
421
- "acceptance-criteria": "acceptance_criteria",
422
- estimated_minutes: "estimated_minutes",
423
- "estimated-minutes": "estimated_minutes",
424
- estimate: "estimated_minutes",
425
- close_reason: "close_reason",
426
- "close-reason": "close_reason",
427
- reviewer: "reviewer",
428
- risk: "risk",
429
- confidence: "confidence",
430
- sprint: "sprint",
431
- release: "release"
432
- };
433
- var METADATA_WARNING_TOKEN_BY_FIELD = {
434
- author: "validate_metadata_missing_author",
435
- acceptance_criteria: "validate_metadata_missing_acceptance_criteria",
436
- estimated_minutes: "validate_metadata_missing_estimate",
437
- close_reason: "validate_metadata_missing_close_reason",
438
- reviewer: "validate_metadata_missing_reviewer",
439
- risk: "validate_metadata_missing_risk",
440
- confidence: "validate_metadata_missing_confidence",
441
- sprint: "validate_metadata_missing_sprint",
442
- release: "validate_metadata_missing_release"
443
- };
444
- var METADATA_COUNT_KEY_BY_FIELD = {
445
- author: "missing_author",
446
- acceptance_criteria: "missing_acceptance_criteria",
447
- estimated_minutes: "missing_estimated_minutes",
448
- close_reason: "closed_missing_close_reason",
449
- reviewer: "missing_reviewer",
450
- risk: "missing_risk",
451
- confidence: "missing_confidence",
452
- sprint: "missing_sprint",
453
- release: "missing_release"
454
- };
455
- var METADATA_ITEM_IDS_KEY_BY_FIELD = {
456
- author: "missing_author_item_ids",
457
- acceptance_criteria: "missing_acceptance_criteria_item_ids",
458
- estimated_minutes: "missing_estimated_minutes_item_ids",
459
- close_reason: "closed_missing_close_reason_item_ids",
460
- reviewer: "missing_reviewer_item_ids",
461
- risk: "missing_risk_item_ids",
462
- confidence: "missing_confidence_item_ids",
463
- sprint: "missing_sprint_item_ids",
464
- release: "missing_release_item_ids"
465
- };
466
- var METADATA_TRUNCATED_KEY_BY_FIELD = {
467
- author: "missing_author_truncated",
468
- acceptance_criteria: "missing_acceptance_criteria_truncated",
469
- estimated_minutes: "missing_estimated_minutes_truncated",
470
- close_reason: "closed_missing_close_reason_truncated",
471
- reviewer: "missing_reviewer_truncated",
472
- risk: "missing_risk_truncated",
473
- confidence: "missing_confidence_truncated",
474
- sprint: "missing_sprint_truncated",
475
- release: "missing_release_truncated"
476
- };
477
- var GIT_LS_FILES_MAX_BUFFER = 32 * 1024 * 1024;
478
- var FILE_LIST_SUMMARY_LIMIT = 40;
479
- var DIAGNOSTIC_LIST_SUMMARY_LIMIT = 5;
480
- var LINKED_ARTIFACT_MAX_PATH_LENGTH = 4096;
481
- var LINKED_ARTIFACT_MAX_SEGMENT_LENGTH = 255;
482
- var execFileAsync = promisify(execFile);
483
- function normalizeRelativePath(value) {
484
- return value.replaceAll("\\", "/").replace(/^\.\/+/, "").replace(/^\/+/, "");
485
- }
486
- function normalizeRelativeDirectoryPath(value) {
487
- const normalized = normalizeRelativePath(value);
488
- return normalized.replace(/\/+$/, "");
489
- }
490
- function toMeaningfulString(value) {
491
- const normalized = toNonEmptyStringOrUndefined(value);
492
- if (!normalized) {
493
- return void 0;
494
- }
495
- const lowered = normalized.toLowerCase();
496
- if (lowered === "none" || lowered === "null" || lowered === "n/a" || lowered === "na") {
497
- return void 0;
498
- }
499
- return normalized;
500
- }
501
- function normalizeStatusForRegistry(status, statusRegistry) {
502
- return normalizeStatusInput(status, statusRegistry) ?? status;
503
- }
504
- function isTerminalStatus(status, statusRegistry) {
505
- return statusRegistry.terminal_statuses.has(normalizeStatusForRegistry(status, statusRegistry));
506
- }
507
- function normalizeLifecyclePatternList(values) {
508
- return [...new Set((values ?? []).map((value) => value.trim().toLowerCase()).filter((value) => value.length > 0))].sort((left, right) => left.localeCompare(right));
509
- }
510
- function areSortedStringListsEqual(left, right) {
511
- if (left.length !== right.length) {
512
- return false;
513
- }
514
- return left.every((value, index) => value === right[index]);
515
- }
516
- function resolveLifecyclePatternPolicy(settings) {
517
- const defaultStalePatterns = normalizeLifecyclePatternList(DEFAULT_VALIDATE_STALE_BLOCKER_REASON_PATTERNS);
518
- const defaultClosureLikePatterns = {
519
- blocked_reason: normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.blocked_reason),
520
- resolution: normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.resolution),
521
- actual_result: normalizeLifecyclePatternList(DEFAULT_VALIDATE_CLOSURE_LIKE_METADATA_FIELD_PATTERNS.actual_result)
522
- };
523
- const staleBlockerReasonPatterns = normalizeLifecyclePatternList(settings.validation.lifecycle_stale_blocker_reason_patterns);
524
- const closureLikePatterns = {
525
- blocked_reason: normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_blocked_reason_patterns),
526
- resolution: normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_resolution_patterns),
527
- actual_result: normalizeLifecyclePatternList(settings.validation.lifecycle_closure_like_actual_result_patterns)
528
- };
529
- return {
530
- stale_blocker_reason_patterns: staleBlockerReasonPatterns,
531
- stale_blocker_reason_pattern_source: areSortedStringListsEqual(staleBlockerReasonPatterns, defaultStalePatterns) ? "default" : "settings",
532
- closure_like_metadata_field_patterns: closureLikePatterns,
533
- closure_like_metadata_field_pattern_sources: {
534
- blocked_reason: areSortedStringListsEqual(closureLikePatterns.blocked_reason, defaultClosureLikePatterns.blocked_reason) ? "default" : "settings",
535
- resolution: areSortedStringListsEqual(closureLikePatterns.resolution, defaultClosureLikePatterns.resolution) ? "default" : "settings",
536
- actual_result: areSortedStringListsEqual(closureLikePatterns.actual_result, defaultClosureLikePatterns.actual_result) ? "default" : "settings"
537
- }
538
- };
539
- }
540
- function resolveValidateMetadataProfile(value) {
541
- const normalized = value?.trim().toLowerCase();
542
- if (!normalized || normalized.length === 0) {
543
- return "core";
544
- }
545
- if (VALIDATE_METADATA_PROFILE_VALUES.includes(normalized)) {
546
- return normalized;
547
- }
548
- throw new PmCliError(`Unknown --metadata-profile value "${value}". Supported values: ${VALIDATE_METADATA_PROFILE_VALUES.join(", ")}.`, EXIT_CODE.USAGE);
549
- }
550
- function resolveDependencyCycleSeverity(value) {
551
- const normalized = value?.trim().toLowerCase();
552
- if (!normalized || normalized.length === 0) {
553
- return "warn";
554
- }
555
- if (VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.includes(normalized)) {
556
- return normalized;
557
- }
558
- throw new PmCliError(`Unknown --dependency-cycle-severity value "${value}". Supported values: ${VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.join(", ")}.`, EXIT_CODE.USAGE);
559
- }
560
- function resolveParentCycleSeverity(value) {
561
- const normalized = value?.trim().toLowerCase();
562
- if (!normalized || normalized.length === 0) {
563
- return "warn";
564
- }
565
- if (VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.includes(normalized)) {
566
- return normalized;
567
- }
568
- throw new PmCliError(`Unknown --parent-cycle-severity value "${value}". Supported values: ${VALIDATE_DEPENDENCY_CYCLE_SEVERITY_VALUES.join(", ")}.`, EXIT_CODE.USAGE);
569
- }
570
- function normalizeMetadataRequiredFieldsFromSettings(values) {
571
- const normalized = [...new Set((values ?? []).map((value) => value.trim().toLowerCase().replaceAll("-", "_")))];
572
- return normalized.map((value) => METADATA_REQUIRED_FIELD_ALIASES[value]).filter((value) => value !== void 0).sort((left, right) => left.localeCompare(right));
573
- }
574
- function resolveValidateMetadataPolicy(profile, profileSource, configuredCustomFields) {
575
- const normalizedCustomFields = normalizeMetadataRequiredFieldsFromSettings(configuredCustomFields);
576
- if (profile === "core") {
577
- return {
578
- profile,
579
- profile_source: profileSource,
580
- required_fields: [...CORE_METADATA_REQUIRED_FIELDS],
581
- configured_custom_fields: normalizedCustomFields,
582
- fallback_to_core: false,
583
- warnings: []
584
- };
585
- }
586
- if (profile === "strict") {
587
- return {
588
- profile,
589
- profile_source: profileSource,
590
- required_fields: [...STRICT_METADATA_REQUIRED_FIELDS],
591
- configured_custom_fields: normalizedCustomFields,
592
- fallback_to_core: false,
593
- warnings: []
594
- };
595
- }
596
- if (normalizedCustomFields.length > 0) {
597
- return {
598
- profile,
599
- profile_source: profileSource,
600
- required_fields: normalizedCustomFields,
601
- configured_custom_fields: normalizedCustomFields,
602
- fallback_to_core: false,
603
- warnings: []
604
- };
605
- }
606
- return {
607
- profile,
608
- profile_source: profileSource,
609
- required_fields: [...CORE_METADATA_REQUIRED_FIELDS],
610
- configured_custom_fields: normalizedCustomFields,
611
- fallback_to_core: true,
612
- warnings: ["validate_metadata_custom_profile_missing_required_fields:0"]
613
- };
614
- }
615
- var TERMINAL_EXEMPT_PLANNING_FIELDS = /* @__PURE__ */ new Set([
616
- "acceptance_criteria",
617
- "estimated_minutes"
618
- ]);
619
- function isMetadataFieldMissing(item, field, statusRegistry, enforcePlanningFieldsOnTerminal) {
620
- if (!enforcePlanningFieldsOnTerminal && TERMINAL_EXEMPT_PLANNING_FIELDS.has(field) && isTerminalStatus(item.status, statusRegistry)) {
621
- return false;
622
- }
623
- if (field === "author") {
624
- return !toNonEmptyStringOrUndefined(item.author);
625
- }
626
- if (field === "acceptance_criteria") {
627
- return !toNonEmptyStringOrUndefined(item.acceptance_criteria);
628
- }
629
- if (field === "estimated_minutes") {
630
- return !Number.isFinite(item.estimated_minutes);
631
- }
632
- if (field === "close_reason") {
633
- return normalizeStatusForRegistry(item.status, statusRegistry) === statusRegistry.close_status && !toNonEmptyStringOrUndefined(item.close_reason);
634
- }
635
- if (field === "reviewer") {
636
- return !toNonEmptyStringOrUndefined(item.reviewer);
637
- }
638
- if (field === "risk") {
639
- return !toNonEmptyStringOrUndefined(item.risk);
640
- }
641
- if (field === "confidence") {
642
- if (typeof item.confidence === "number") {
643
- return !Number.isFinite(item.confidence);
644
- }
645
- return !toNonEmptyStringOrUndefined(item.confidence);
646
- }
647
- if (field === "sprint") {
648
- return !toNonEmptyStringOrUndefined(item.sprint);
649
- }
650
- return !toNonEmptyStringOrUndefined(item.release);
651
- }
652
- function resolveFileScanMode(scanMode) {
653
- if (scanMode === void 0) {
654
- return "default";
655
- }
656
- const normalized = scanMode.trim().toLowerCase();
657
- if (normalized.length === 0) {
658
- return "default";
659
- }
660
- if (normalized === "default") {
661
- return "default";
662
- }
663
- if (normalized === "tracked-all" || normalized === "tracked_all") {
664
- return "tracked-all";
665
- }
666
- if (normalized === "tracked-all-strict" || normalized === "tracked_all_strict") {
667
- return "tracked-all-strict";
668
- }
669
- throw new PmCliError(`Unknown --scan-mode value "${scanMode}". Supported values: ${VALIDATE_FILE_SCAN_MODES.join(", ")}.`, EXIT_CODE.USAGE);
670
- }
671
- function resolveWorkspaceRoot(pmRoot) {
672
- const resolvedPmRoot = path.resolve(pmRoot);
673
- const normalizedPmRoot = resolvedPmRoot.replaceAll("\\", "/");
674
- if (normalizedPmRoot.endsWith("/.agents/pm")) {
675
- return path.dirname(path.dirname(resolvedPmRoot));
676
- }
677
- const resolvedCwd = path.resolve(process.cwd());
678
- const canonicalPmRoot = realpathForWorkspaceRoot(resolvedPmRoot);
679
- const canonicalCwd = realpathForWorkspaceRoot(resolvedCwd);
680
- const relativeFromPmRoot = path.relative(canonicalPmRoot, canonicalCwd);
681
- const cwdInsidePmRoot = relativeFromPmRoot.length === 0 || !relativeFromPmRoot.startsWith("..") && !path.isAbsolute(relativeFromPmRoot);
682
- if (cwdInsidePmRoot) {
683
- return resolvedPmRoot;
684
- }
685
- return resolvedCwd;
686
- }
687
- function realpathForWorkspaceRoot(inputPath) {
688
- try {
689
- return realpathSync.native(inputPath);
690
- } catch {
691
- return path.resolve(inputPath);
692
- }
693
- }
694
- async function listFilesRecursive(basePath, relativePath, output) {
695
- const targetDirectory = relativePath.length > 0 ? path.join(basePath, relativePath) : basePath;
696
- let entries;
697
- try {
698
- entries = await fs.readdir(targetDirectory, { withFileTypes: true });
699
- } catch (error) {
700
- if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
701
- return;
702
- }
703
- throw error;
704
- }
705
- for (const entry of entries) {
706
- if (entry.name.startsWith(".")) {
707
- continue;
708
- }
709
- const childRelative = relativePath.length > 0 ? path.join(relativePath, entry.name) : entry.name;
710
- if (entry.isDirectory()) {
711
- if (DIRECTORY_IGNORE_SET.has(entry.name)) {
712
- continue;
713
- }
714
- await listFilesRecursive(basePath, childRelative, output);
715
- continue;
716
- }
717
- if (!entry.isFile()) {
718
- continue;
719
- }
720
- output.push(normalizeRelativePath(childRelative));
721
- }
722
- }
723
- async function collectDefaultProjectFileCandidates(workspaceRoot) {
724
- const discovered = [];
725
- for (const directory of FILE_SCAN_DIRECTORIES) {
726
- await listFilesRecursive(workspaceRoot, directory, discovered);
727
- }
728
- for (const candidate of FILE_SCAN_ROOT_FILES) {
729
- const absolute = path.join(workspaceRoot, candidate);
730
- try {
731
- const stats = await fs.stat(absolute);
732
- if (stats.isFile()) {
733
- discovered.push(normalizeRelativePath(candidate));
734
- }
735
- } catch {
736
- }
737
- }
738
- return [...new Set(discovered)].sort((left, right) => left.localeCompare(right));
739
- }
740
- async function collectTrackedGitFileCandidates(workspaceRoot) {
741
- try {
742
- const { stdout } = await execFileAsync("git", ["ls-files", "-z"], {
743
- cwd: workspaceRoot,
744
- encoding: "utf8",
745
- maxBuffer: GIT_LS_FILES_MAX_BUFFER,
746
- windowsHide: true
747
- });
748
- const discovered = stdout.split("\0").map((value) => normalizeRelativePath(value)).filter((value) => value.length > 0);
749
- return [...new Set(discovered)].sort((left, right) => left.localeCompare(right));
750
- } catch {
751
- return null;
752
- }
753
- }
754
- function resolvePmInternalCandidatePrefixes(pmRoot, workspaceRoot) {
755
- const prefixes = /* @__PURE__ */ new Set();
756
- const configuredDefault = normalizeRelativeDirectoryPath(PM_DIRNAME);
757
- if (configuredDefault.length > 0) {
758
- prefixes.add(configuredDefault);
759
- }
760
- const relativePmRoot = normalizeRelativeDirectoryPath(path.relative(workspaceRoot, pmRoot));
761
- if (relativePmRoot.length > 0 && !relativePmRoot.startsWith("..")) {
762
- prefixes.add(relativePmRoot);
763
- }
764
- return [...prefixes].sort((left, right) => left.localeCompare(right));
765
- }
766
- function hasPathPrefix(candidate, prefixes) {
767
- for (const prefix of prefixes) {
768
- if (candidate === prefix || candidate.startsWith(`${prefix}/`)) {
769
- return true;
770
- }
771
- }
772
- return false;
773
- }
774
- async function collectProjectFileCandidates(workspaceRoot, scanMode) {
775
- if (scanMode === "tracked-all" || scanMode === "tracked-all-strict") {
776
- const trackedCandidates = await collectTrackedGitFileCandidates(workspaceRoot);
777
- if (trackedCandidates) {
778
- return {
779
- requestedMode: scanMode,
780
- appliedMode: scanMode,
781
- source: "tracked-git",
782
- candidateFiles: trackedCandidates,
783
- candidateTotal: trackedCandidates.length,
784
- candidateScanned: trackedCandidates.length
785
- };
786
- }
787
- const fallbackCandidates = await collectDefaultProjectFileCandidates(workspaceRoot);
788
- return {
789
- requestedMode: scanMode,
790
- appliedMode: "default",
791
- source: "tracked-all-fallback-default",
792
- candidateFiles: fallbackCandidates,
793
- candidateTotal: fallbackCandidates.length,
794
- candidateScanned: fallbackCandidates.length
795
- };
796
- }
797
- const defaultCandidates = await collectDefaultProjectFileCandidates(workspaceRoot);
798
- return {
799
- requestedMode: scanMode,
800
- appliedMode: "default",
801
- source: "default-curated",
802
- candidateFiles: defaultCandidates,
803
- candidateTotal: defaultCandidates.length,
804
- candidateScanned: defaultCandidates.length
805
- };
806
- }
807
- function summarizeList(values, limit = DIAGNOSTIC_LIST_SUMMARY_LIMIT) {
808
- if (values.length <= limit) {
809
- return { values, truncated: false };
810
- }
811
- return {
812
- values: values.slice(0, limit),
813
- truncated: true
814
- };
815
- }
816
- function summarizeFileList(values, verboseFileLists) {
817
- if (verboseFileLists) {
818
- return {
819
- values,
820
- truncated: false,
821
- total: values.length
822
- };
823
- }
824
- const summary = summarizeList(values, FILE_LIST_SUMMARY_LIMIT);
825
- return {
826
- values: summary.values,
827
- truncated: summary.truncated,
828
- total: values.length
829
- };
830
- }
831
- var RESOLUTION_REMEDIATION_FLAG_BY_FIELD = {
832
- resolution: "--resolution",
833
- expected_result: "--expected-result",
834
- actual_result: "--actual-result"
835
- };
836
- var RESOLUTION_REMEDIATION_PLACEHOLDER_BY_FIELD = {
837
- resolution: "Describe how this item was resolved",
838
- expected_result: "Describe the expected result",
839
- actual_result: "Describe the actual result"
840
- };
841
- function buildResolutionRemediationCommand(row) {
842
- const fieldArguments = row.missing_fields.map((field) => `${RESOLUTION_REMEDIATION_FLAG_BY_FIELD[field]} "${RESOLUTION_REMEDIATION_PLACEHOLDER_BY_FIELD[field]}"`).join(" ");
843
- return `pm update ${row.id} ${fieldArguments} --message "Backfill resolution metadata"`;
844
- }
845
- function attachValidateFixHints(check, checkWarnings) {
846
- const existingResolutionHints = check.details?.missing_resolution_remediation_hints;
847
- const aliasedResolution = Array.isArray(existingResolutionHints) && existingResolutionHints.length > 0;
848
- const fixHints = aliasedResolution ? existingResolutionHints.filter((hint) => typeof hint === "string") : buildRemediationCommands(checkWarnings);
849
- if (fixHints.length === 0) {
850
- return;
851
- }
852
- const truncated = aliasedResolution && check.details?.missing_resolution_remediation_hints_truncated === true;
853
- check.details = {
854
- ...check.details,
855
- fix_hints: fixHints,
856
- ...truncated ? { fix_hints_truncated: true } : {}
857
- };
858
- }
859
- function resolveRequestedChecks(options) {
860
- const requested = /* @__PURE__ */ new Set();
861
- if (options.checkMetadata) {
862
- requested.add("metadata");
863
- }
864
- if (options.checkResolution) {
865
- requested.add("resolution");
866
- }
867
- if (options.checkLifecycle || options.checkStaleBlockers) {
868
- requested.add("lifecycle");
869
- }
870
- if (options.checkFiles) {
871
- requested.add("files");
872
- }
873
- if (options.checkHistoryDrift) {
874
- requested.add("history_drift");
875
- }
876
- if (options.checkCommandReferences) {
877
- requested.add("command_references");
878
- }
879
- if (requested.size === 0) {
880
- if (options.autoFix) {
881
- requested.add("metadata");
882
- requested.add("resolution");
883
- requested.add("lifecycle");
884
- }
885
- if (options.pruneMissing) {
886
- requested.add("files");
887
- }
888
- if (requested.size === 0) {
889
- requested.add("metadata");
890
- requested.add("resolution");
891
- requested.add("lifecycle");
892
- requested.add("files");
893
- requested.add("command_references");
894
- requested.add("history_drift");
895
- requested.add("format_version");
896
- }
897
- return requested;
898
- }
899
- if (options.pruneMissing) {
900
- requested.add("files");
901
- }
902
- return requested;
903
- }
904
- var DUPLICATE_ISSUE_CODE_WARNING_TOKEN = "validate_metadata_duplicate_issue_codes";
905
- function summarizeDuplicateIssueCodes(duplicates, verboseDiagnostics) {
906
- if (duplicates.length === 0) {
907
- return { rows: [], truncated: false, warnings: [] };
908
- }
909
- const limit = verboseDiagnostics ? duplicates.length : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
910
- const shown = duplicates.slice(0, limit);
911
- const rows = shown.map((duplicate) => ({
912
- code: duplicate.code,
913
- count: duplicate.count,
914
- ids: duplicate.ids,
915
- titles: duplicate.titles,
916
- remediation_hint: `Items ${duplicate.ids.join(", ")} share issue code "${duplicate.code}"; rename or merge so each logical code maps to one item.`
917
- }));
918
- return {
919
- rows,
920
- truncated: shown.length < duplicates.length,
921
- warnings: [`${DUPLICATE_ISSUE_CODE_WARNING_TOKEN}:${duplicates.length}`]
922
- };
923
- }
924
- function initializeMissingMetadataByField() {
925
- return Object.fromEntries(SUPPORTED_METADATA_REQUIRED_FIELDS.map((field) => [field, []]));
926
- }
927
- function collectMissingMetadataByField(items, statusRegistry, enforcePlanningFieldsOnTerminal) {
928
- const missingByField = initializeMissingMetadataByField();
929
- for (const item of items) {
930
- for (const field of SUPPORTED_METADATA_REQUIRED_FIELDS) {
931
- if (isMetadataFieldMissing(item, field, statusRegistry, enforcePlanningFieldsOnTerminal)) {
932
- missingByField[field].push(item.id);
933
- }
934
- }
935
- }
936
- return missingByField;
937
- }
938
- function buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateWarnings) {
939
- const warningTokens = [...metadataPolicy.warnings];
940
- for (const field of metadataPolicy.required_fields) {
941
- const missingItems = missingByField[field];
942
- if (missingItems.length > 0) {
943
- warningTokens.push(`${METADATA_WARNING_TOKEN_BY_FIELD[field]}:${missingItems.length}`);
944
- }
945
- }
946
- warningTokens.push(...duplicateWarnings);
947
- return warningTokens;
948
- }
949
- function buildMetadataCounts(metadataPolicy, missingByField) {
950
- const counts = {};
951
- for (const field of metadataPolicy.required_fields) {
952
- const missing = missingByField[field];
953
- const value = missing ? missing.length : 0;
954
- const countKey = METADATA_COUNT_KEY_BY_FIELD[field];
955
- if (value > 0 && countKey) {
956
- counts[countKey] = value;
957
- }
958
- }
959
- return counts;
960
- }
961
- function buildMissingFieldOccurrences(metadataPolicy, missingByField, itemsById) {
962
- const occurrences = [];
963
- for (const field of metadataPolicy.required_fields) {
964
- const missing = missingByField[field];
965
- if (!missing) {
966
- continue;
967
- }
968
- for (const itemId of missing) {
969
- const itemType = itemsById.get(itemId)?.type;
970
- const normalizedItemType = typeof itemType === "string" && itemType.length > 0 ? itemType : "Unknown";
971
- occurrences.push({ item_type: normalizedItemType, field });
972
- }
973
- }
974
- return occurrences;
975
- }
976
- function attachMissingMetadataItemIds(details, metadataPolicy, missingByField, verboseDiagnostics) {
977
- for (const field of metadataPolicy.required_fields) {
978
- const missing = missingByField[field];
979
- if (!missing || missing.length === 0) {
980
- continue;
981
- }
982
- const idsKey = METADATA_ITEM_IDS_KEY_BY_FIELD[field];
983
- const truncatedKey = METADATA_TRUNCATED_KEY_BY_FIELD[field];
984
- if (!idsKey || !truncatedKey) {
985
- continue;
986
- }
987
- const summarized = summarizeList(missing, verboseDiagnostics ? missing.length : DIAGNOSTIC_LIST_SUMMARY_LIMIT);
988
- details[idsKey] = summarized.values;
989
- details[truncatedKey] = summarized.truncated;
990
- }
991
- }
992
- function buildCloseReasonBackfillRows(metadataPolicy, missingByField, itemsById) {
993
- if (!metadataPolicy.required_fields.includes("close_reason")) {
994
- return [];
995
- }
996
- const missing = missingByField.close_reason;
997
- if (!missing) {
998
- return [];
999
- }
1000
- return missing.map((itemId) => ({
1001
- id: itemId,
1002
- resolution: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.resolution)
1003
- }));
1004
- }
1005
- function buildEstimateBackfillRows(metadataPolicy, missingByField, itemsById) {
1006
- if (!metadataPolicy.required_fields.includes("estimated_minutes")) {
1007
- return [];
1008
- }
1009
- const missing = missingByField.estimated_minutes;
1010
- if (!missing) {
1011
- return [];
1012
- }
1013
- return missing.map((itemId) => ({
1014
- id: itemId,
1015
- type: toNonEmptyStringOrUndefined(itemsById.get(itemId)?.type)
1016
- }));
1017
- }
1018
- function buildMetadataCheck(items, metadataPolicy, statusRegistry, verboseDiagnostics) {
1019
- const itemsById = new Map(items.map((item) => [item.id, item]));
1020
- const enforcePlanningFieldsOnTerminal = metadataPolicy.profile === "strict";
1021
- const missingByField = collectMissingMetadataByField(items, statusRegistry, enforcePlanningFieldsOnTerminal);
1022
- const duplicateIssueCodes = findDuplicateIssueCodes(items);
1023
- const duplicateIssueCodeSummary = summarizeDuplicateIssueCodes(duplicateIssueCodes, verboseDiagnostics);
1024
- const warningTokens = buildMetadataWarningTokens(metadataPolicy, missingByField, duplicateIssueCodeSummary.warnings);
1025
- const counts = buildMetadataCounts(metadataPolicy, missingByField);
1026
- const missingFieldOccurrences = buildMissingFieldOccurrences(metadataPolicy, missingByField, itemsById);
1027
- const missingByType = buildMissingByTypeCounts(missingFieldOccurrences);
1028
- const details = {
1029
- checked_items: items.length,
1030
- metadata_profile: metadataPolicy.profile,
1031
- metadata_profile_source: metadataPolicy.profile_source,
1032
- metadata_profile_fallback_to_core: metadataPolicy.fallback_to_core,
1033
- required_fields: [...metadataPolicy.required_fields],
1034
- supported_required_fields: [...SUPPORTED_METADATA_REQUIRED_FIELDS],
1035
- counts,
1036
- missing_by_type: missingByType,
1037
- duplicate_issue_codes_count: duplicateIssueCodes.length,
1038
- duplicate_issue_codes: duplicateIssueCodeSummary.rows,
1039
- duplicate_issue_codes_truncated: duplicateIssueCodeSummary.truncated
1040
- };
1041
- if (metadataPolicy.configured_custom_fields.length > 0) {
1042
- details.configured_custom_required_fields = [...metadataPolicy.configured_custom_fields];
1043
- }
1044
- attachMissingMetadataItemIds(details, metadataPolicy, missingByField, verboseDiagnostics);
1045
- const closeReasonBackfillRows = buildCloseReasonBackfillRows(metadataPolicy, missingByField, itemsById);
1046
- const estimateBackfillRows = buildEstimateBackfillRows(metadataPolicy, missingByField, itemsById);
1047
- return {
1048
- check: {
1049
- name: "metadata",
1050
- status: warningTokens.length === 0 ? "ok" : "warn",
1051
- details
1052
- },
1053
- warnings: warningTokens,
1054
- closeReasonBackfillRows,
1055
- estimateBackfillRows
1056
- };
1057
- }
1058
- function buildResolutionCheck(items, statusRegistry, verboseDiagnostics) {
1059
- const terminalDoneStatuses = new Set(statusRegistry.terminal_done_statuses);
1060
- terminalDoneStatuses.add(statusRegistry.close_status);
1061
- const closedItems = items.filter((item) => terminalDoneStatuses.has(normalizeStatusForRegistry(item.status, statusRegistry)));
1062
- const missingResolutionRows = [];
1063
- const resolutionBackfillRows = [];
1064
- for (const item of closedItems) {
1065
- const missingFields = RESOLUTION_FIELD_KEYS.filter((field) => !toNonEmptyStringOrUndefined(item[field]));
1066
- if (missingFields.length === 0) {
1067
- continue;
1068
- }
1069
- missingResolutionRows.push({
1070
- id: item.id,
1071
- missing_fields: missingFields
1072
- });
1073
- resolutionBackfillRows.push({
1074
- id: item.id,
1075
- missing_fields: missingFields,
1076
- close_reason: toNonEmptyStringOrUndefined(item.close_reason)
1077
- });
1078
- }
1079
- const warnings = missingResolutionRows.length > 0 ? [`validate_resolution_missing_fields:${missingResolutionRows.length}`] : [];
1080
- const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1081
- const summarizedRows = summarizeList(missingResolutionRows.map((row) => `${row.id}:${row.missing_fields.join(",")}`), diagnosticLimit);
1082
- const remediationHints = missingResolutionRows.map((row) => buildResolutionRemediationCommand(row));
1083
- const summarizedHints = summarizeList(remediationHints, diagnosticLimit);
1084
- return {
1085
- check: {
1086
- name: "resolution",
1087
- status: warnings.length === 0 ? "ok" : "warn",
1088
- details: {
1089
- checked_closed_items: closedItems.length,
1090
- missing_resolution_items: missingResolutionRows.length,
1091
- missing_resolution_rows: summarizedRows.values,
1092
- missing_resolution_rows_truncated: summarizedRows.truncated,
1093
- missing_resolution_remediation_hints: summarizedHints.values,
1094
- missing_resolution_remediation_hints_truncated: summarizedHints.truncated
1095
- }
1096
- },
1097
- warnings,
1098
- resolutionBackfillRows
1099
- };
1100
- }
1101
- function escapeRegExp(value) {
1102
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1103
- }
1104
- function buildLifecycleDependencyGraph(activeItems, idPrefix = "pm") {
1105
- const activeItemIds = new Set(activeItems.map((item) => item.id));
1106
- const graph = /* @__PURE__ */ new Map();
1107
- const sortedItems = [...activeItems].sort((left, right) => left.id.localeCompare(right.id));
1108
- for (const item of sortedItems) {
1109
- const edges = /* @__PURE__ */ new Set();
1110
- const blockedBy = toMeaningfulString(item.blocked_by);
1111
- if (blockedBy && activeItemIds.has(blockedBy)) {
1112
- edges.add(blockedBy);
1113
- }
1114
- for (const dependency of item.dependencies ?? []) {
1115
- const dependencyId = toMeaningfulString(dependency.id);
1116
- if (!dependencyId || !activeItemIds.has(dependencyId)) {
1117
- continue;
1118
- }
1119
- edges.add(dependencyId);
1120
- }
1121
- const definitionOfReady = toMeaningfulString(item.definition_of_ready);
1122
- if (definitionOfReady) {
1123
- for (const referencedId of extractItemIds(definitionOfReady, idPrefix)) {
1124
- if (activeItemIds.has(referencedId)) {
1125
- edges.add(referencedId);
1126
- }
1127
- }
1128
- }
1129
- graph.set(item.id, [...edges].sort((left, right) => left.localeCompare(right)));
1130
- }
1131
- return graph;
1132
- }
1133
- function extractItemIds(value, idPrefix = "pm") {
1134
- const normalizedPrefix = (idPrefix.trim().toLowerCase() || "pm").replace(/-+$/g, "");
1135
- const pattern = new RegExp(`(?:^|[^a-z0-9-])(${escapeRegExp(normalizedPrefix)}-[a-z0-9][a-z0-9-]*)`, "gi");
1136
- return [...new Set([...value.matchAll(pattern)].map((match) => match[1].toLowerCase()))].sort((left, right) => left.localeCompare(right));
1137
- }
1138
- function findLifecycleDependencyCycleComponents(graph) {
1139
- let nextIndex = 0;
1140
- const indexById = /* @__PURE__ */ new Map();
1141
- const lowLinkById = /* @__PURE__ */ new Map();
1142
- const stack = [];
1143
- const inStack = /* @__PURE__ */ new Set();
1144
- const components = [];
1145
- const visit = (id) => {
1146
- indexById.set(id, nextIndex);
1147
- lowLinkById.set(id, nextIndex);
1148
- nextIndex += 1;
1149
- stack.push(id);
1150
- inStack.add(id);
1151
- for (const dependencyId of graph.get(id) ?? []) {
1152
- if (!indexById.has(dependencyId)) {
1153
- visit(dependencyId);
1154
- lowLinkById.set(id, Math.min(lowLinkById.get(id), lowLinkById.get(dependencyId)));
1155
- } else if (inStack.has(dependencyId)) {
1156
- lowLinkById.set(id, Math.min(lowLinkById.get(id), indexById.get(dependencyId)));
1157
- }
1158
- }
1159
- if (lowLinkById.get(id) !== indexById.get(id)) {
1160
- return;
1161
- }
1162
- const component = [];
1163
- while (stack.length > 0) {
1164
- const member = stack.pop();
1165
- inStack.delete(member);
1166
- component.push(member);
1167
- if (member === id) {
1168
- break;
1169
- }
1170
- }
1171
- component.sort((left, right) => left.localeCompare(right));
1172
- components.push(component);
1173
- };
1174
- const sortedNodeIds = [...graph.keys()].sort((left, right) => left.localeCompare(right));
1175
- for (const id of sortedNodeIds) {
1176
- if (!indexById.has(id)) {
1177
- visit(id);
1178
- }
1179
- }
1180
- const cycleComponents = components.filter((component) => {
1181
- if (component.length > 1) {
1182
- return true;
1183
- }
1184
- const selfId = component[0];
1185
- return (graph.get(selfId) ?? []).includes(selfId);
1186
- });
1187
- return cycleComponents.sort((left, right) => left[0].localeCompare(right[0]) || left.length - right.length || left.join(",").localeCompare(right.join(",")));
1188
- }
1189
- function resolveLifecycleDependencyCycleSamplePath(component, graph) {
1190
- const start = component[0];
1191
- if (component.length === 1) {
1192
- return [start, start];
1193
- }
1194
- const componentSet = new Set(component);
1195
- const path2 = [start];
1196
- const visited = /* @__PURE__ */ new Set([start]);
1197
- const search = (current) => {
1198
- const neighbors = (graph.get(current) ?? []).filter((candidate) => componentSet.has(candidate));
1199
- for (const next of neighbors) {
1200
- if (next === start && path2.length > 1) {
1201
- path2.push(start);
1202
- return true;
1203
- }
1204
- if (visited.has(next)) {
1205
- continue;
1206
- }
1207
- visited.add(next);
1208
- path2.push(next);
1209
- if (search(next)) {
1210
- return true;
1211
- }
1212
- path2.pop();
1213
- visited.delete(next);
1214
- }
1215
- return false;
1216
- };
1217
- if (search(start)) {
1218
- return [...path2];
1219
- }
1220
- return [...component, start];
1221
- }
1222
- function detectLifecycleDependencyCycles(activeItems, idPrefix = "pm") {
1223
- const graph = buildLifecycleDependencyGraph(activeItems, idPrefix);
1224
- const cycleComponents = findLifecycleDependencyCycleComponents(graph);
1225
- const cycleItemIds = [...new Set(cycleComponents.flat())].sort((left, right) => left.localeCompare(right));
1226
- const cycleSamplePaths = cycleComponents.map((component) => resolveLifecycleDependencyCycleSamplePath(component, graph).join("->"));
1227
- return {
1228
- cycle_count: cycleComponents.length,
1229
- cycle_item_ids: cycleItemIds,
1230
- cycle_sample_paths: cycleSamplePaths
1231
- };
1232
- }
1233
- function buildLifecycleParentGraph(items) {
1234
- const canonicalIdByLowercase = new Map(items.map((item) => [item.id.toLowerCase(), item.id]));
1235
- const graph = /* @__PURE__ */ new Map();
1236
- const sortedItems = [...items].sort((left, right) => left.id.localeCompare(right.id));
1237
- for (const item of sortedItems) {
1238
- const edges = [];
1239
- const parentId = toMeaningfulString(item.parent);
1240
- const canonicalParentId = parentId ? canonicalIdByLowercase.get(parentId.toLowerCase()) : void 0;
1241
- if (canonicalParentId) {
1242
- edges.push(canonicalParentId);
1243
- }
1244
- graph.set(item.id, edges);
1245
- }
1246
- return graph;
1247
- }
1248
- function detectLifecycleParentCycles(items) {
1249
- const graph = buildLifecycleParentGraph(items);
1250
- const cycleComponents = findLifecycleDependencyCycleComponents(graph);
1251
- const cycleItemIds = [...new Set(cycleComponents.flat())].sort((left, right) => left.localeCompare(right));
1252
- const cycleSamplePaths = cycleComponents.map((component) => resolveLifecycleDependencyCycleSamplePath(component, graph).join("->"));
1253
- return {
1254
- cycle_count: cycleComponents.length,
1255
- cycle_item_ids: cycleItemIds,
1256
- cycle_sample_paths: cycleSamplePaths
1257
- };
1258
- }
1259
- function classifyOrphanedPath(pathValue) {
1260
- if (pathValue.startsWith("docs/")) {
1261
- return "docs_unowned";
1262
- }
1263
- if (pathValue.startsWith("tests/")) {
1264
- return "tests_unowned";
1265
- }
1266
- if (pathValue.startsWith("src/")) {
1267
- return "source_unowned";
1268
- }
1269
- if (pathValue.endsWith(".md")) {
1270
- return "docs_unowned";
1271
- }
1272
- return "unlinked_existing";
1273
- }
1274
- function directoryOf(relativePath) {
1275
- const slash = relativePath.lastIndexOf("/");
1276
- return slash === -1 ? "" : relativePath.slice(0, slash);
1277
- }
1278
- function sharedDirectoryPrefixLength(left, right) {
1279
- const leftParts = directoryOf(left).split("/").filter(Boolean);
1280
- const rightParts = directoryOf(right).split("/").filter(Boolean);
1281
- let count = 0;
1282
- while (count < leftParts.length && count < rightParts.length && leftParts[count] === rightParts[count]) {
1283
- count += 1;
1284
- }
1285
- return count;
1286
- }
1287
- function scoreOrphanOwnerCandidate(pathValue, linkedPath) {
1288
- const linkedDir = directoryOf(linkedPath);
1289
- const orphanDir = directoryOf(pathValue);
1290
- const directoryPrefix = linkedPath.endsWith("/") ? linkedPath : `${linkedPath}/`;
1291
- const isDirectoryPrefix = pathValue.startsWith(directoryPrefix);
1292
- const sameDirectory = linkedDir.length > 0 && linkedDir === orphanDir;
1293
- const sharedPrefixLength = sharedDirectoryPrefixLength(pathValue, linkedPath);
1294
- if (!isDirectoryPrefix && !sameDirectory && sharedPrefixLength === 0) {
1295
- return null;
1296
- }
1297
- if (isDirectoryPrefix) {
1298
- return { score: linkedPath.length + 1e3, confidence: "path_prefix" };
1299
- }
1300
- return sameDirectory ? { score: sharedPrefixLength + 500, confidence: "same_directory" } : { score: sharedPrefixLength, confidence: "shared_directory" };
1301
- }
1302
- function shouldReplaceOrphanOwnerCandidate(best, item, score) {
1303
- return best === void 0 || score > best.score || score === best.score && item.id.localeCompare(best.item.id) < 0;
1304
- }
1305
- function findOrphanOwnerCandidate(pathValue, classification, items) {
1306
- const linkKind = classification === "docs_unowned" ? "docs" : "files";
1307
- let best;
1308
- for (const item of items) {
1309
- const links = linkKind === "docs" ? item.docs ?? [] : item.files ?? [];
1310
- for (const link of links) {
1311
- if (link.scope !== "project") {
1312
- continue;
1313
- }
1314
- const linkedPath = normalizeRelativePath(link.path);
1315
- if (linkedPath.length === 0 || linkedPath === pathValue) {
1316
- continue;
1317
- }
1318
- const scored = scoreOrphanOwnerCandidate(pathValue, linkedPath);
1319
- if (scored === null) {
1320
- continue;
1321
- }
1322
- if (shouldReplaceOrphanOwnerCandidate(best, item, scored.score)) {
1323
- best = {
1324
- item,
1325
- score: scored.score,
1326
- confidence: scored.confidence
1327
- };
1328
- }
1329
- }
1330
- }
1331
- if (!best) {
1332
- return null;
1333
- }
1334
- return {
1335
- id: best.item.id,
1336
- type: best.item.type,
1337
- title: best.item.title,
1338
- status: best.item.status,
1339
- confidence: best.confidence
1340
- };
1341
- }
1342
- function buildOrphanedPathRows(orphanedFiles, items) {
1343
- return orphanedFiles.map((pathValue) => {
1344
- const classification = classifyOrphanedPath(pathValue);
1345
- const linkCommand = classification === "docs_unowned" ? "docs" : "files";
1346
- const ownerCandidate = findOrphanOwnerCandidate(pathValue, classification, items);
1347
- const target = ownerCandidate?.id ?? "<id>";
1348
- return {
1349
- path: pathValue,
1350
- classification,
1351
- owner_candidate: ownerCandidate,
1352
- remediation_hint: `pm ${linkCommand} ${target} --add path=${pathValue},scope=project,note="<why this artifact belongs to the item>"`
1353
- };
1354
- });
1355
- }
1356
- function summarizeOrphanedPathRows(rows) {
1357
- return rows.map((row) => `${row.path}:${row.classification} owner_candidate=${row.owner_candidate?.id ?? "unowned"} hint=${JSON.stringify(row.remediation_hint)}`);
1358
- }
1359
- function closureLikeFieldsForItem(item, lifecyclePatternPolicy) {
1360
- return Object.entries(lifecyclePatternPolicy.closure_like_metadata_field_patterns).filter(([field, patterns]) => {
1361
- const value = toMeaningfulString(item[field]);
1362
- return value ? patterns.some((pattern) => value.toLowerCase().includes(pattern)) : false;
1363
- }).map(([field]) => field).sort((left, right) => left.localeCompare(right));
1364
- }
1365
- function buildTerminalParentFixRow(item, parent, itemsById, canonicalIdByLowercase, statusRegistry) {
1366
- const grandparentId = toMeaningfulString(parent.parent);
1367
- const grandparent = grandparentId ? itemsById.get(canonicalIdByLowercase.get(grandparentId.toLowerCase()) ?? grandparentId) : void 0;
1368
- return {
1369
- id: item.id,
1370
- parent_id: parent.id,
1371
- grandparent_id: grandparent?.id,
1372
- grandparent_active: grandparent !== void 0 && !isTerminalStatus(grandparent.status, statusRegistry)
1373
- };
1374
- }
1375
- function staleBlockerReasonsForItem(item, blockedStatuses, statusRegistry, lifecyclePatternPolicy) {
1376
- const blockedBy = toMeaningfulString(item.blocked_by);
1377
- const blockedReason = toMeaningfulString(item.blocked_reason);
1378
- const blockedReasonNormalized = blockedReason?.toLowerCase();
1379
- const normalizedStatus = normalizeStatusForRegistry(item.status, statusRegistry);
1380
- const reasons = [];
1381
- if (!blockedStatuses.has(normalizedStatus)) {
1382
- if (blockedBy) {
1383
- reasons.push("non_blocked_status_has_blocked_by");
1384
- }
1385
- if (blockedReason) {
1386
- reasons.push("non_blocked_status_has_blocked_reason");
1387
- }
1388
- return reasons;
1389
- }
1390
- if (!blockedBy && !blockedReason) {
1391
- reasons.push("blocked_status_missing_blocker_context");
1392
- }
1393
- if (blockedReasonNormalized?.includes("no active blocker")) {
1394
- reasons.push("blocked_status_reason_reports_no_active_blocker");
1395
- }
1396
- if (blockedReasonNormalized && lifecyclePatternPolicy.stale_blocker_reason_patterns.some((pattern) => blockedReasonNormalized.includes(pattern))) {
1397
- reasons.push("blocked_status_reason_matches_stale_pattern");
1398
- }
1399
- return reasons;
1400
- }
1401
- function collectLifecycleScanRows(items, includeStaleBlockers, statusRegistry, lifecyclePatternPolicy) {
1402
- const itemsById = new Map(items.map((item) => [item.id, item]));
1403
- const canonicalIdByLowercase = new Map(items.map((item) => [item.id.toLowerCase(), item.id]));
1404
- const blockedStatuses = statusRegistry.blocked_statuses.size > 0 ? statusRegistry.blocked_statuses : /* @__PURE__ */ new Set(["blocked"]);
1405
- const rows = {
1406
- activeItems: items.filter((item) => !isTerminalStatus(item.status, statusRegistry)),
1407
- closureLikeRows: [],
1408
- terminalParentRows: [],
1409
- terminalParentFixRows: [],
1410
- staleBlockerRows: []
1411
- };
1412
- for (const item of rows.activeItems) {
1413
- const closureLikeFields = closureLikeFieldsForItem(item, lifecyclePatternPolicy);
1414
- if (closureLikeFields.length > 0) {
1415
- rows.closureLikeRows.push({ id: item.id, fields: closureLikeFields });
1416
- }
1417
- const parentId = toMeaningfulString(item.parent);
1418
- const parent = parentId ? itemsById.get(canonicalIdByLowercase.get(parentId.toLowerCase()) ?? parentId) : void 0;
1419
- if (parent && isTerminalStatus(parent.status, statusRegistry)) {
1420
- rows.terminalParentRows.push({ id: item.id, parent_id: parent.id, parent_status: parent.status });
1421
- rows.terminalParentFixRows.push(buildTerminalParentFixRow(item, parent, itemsById, canonicalIdByLowercase, statusRegistry));
1422
- }
1423
- if (includeStaleBlockers) {
1424
- const reasons = staleBlockerReasonsForItem(item, blockedStatuses, statusRegistry, lifecyclePatternPolicy);
1425
- if (reasons.length > 0) {
1426
- rows.staleBlockerRows.push({
1427
- id: item.id,
1428
- status: item.status,
1429
- reasons: [...new Set(reasons)].sort((left, right) => left.localeCompare(right))
1430
- });
1431
- }
1432
- }
1433
- }
1434
- return rows;
1435
- }
1436
- function sortLifecycleScanRows(rows) {
1437
- rows.closureLikeRows.sort((left, right) => left.id.localeCompare(right.id));
1438
- rows.terminalParentRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
1439
- rows.terminalParentFixRows.sort((left, right) => left.id.localeCompare(right.id) || left.parent_id.localeCompare(right.parent_id));
1440
- rows.staleBlockerRows.sort((left, right) => left.id.localeCompare(right.id));
1441
- }
1442
- function lifecycleCycleWarningToken(prefix, severity, count) {
1443
- if (count <= 0 || severity === "off") {
1444
- return null;
1445
- }
1446
- return `${severity === "error" ? `${prefix}_error` : prefix}:${count}`;
1447
- }
1448
- function buildLifecycleWarnings(rows, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, dependencyCycleCount, parentCycleCount) {
1449
- const warnings = [];
1450
- if (rows.closureLikeRows.length > 0) {
1451
- warnings.push(`validate_lifecycle_active_closure_like_metadata:${rows.closureLikeRows.length}`);
1452
- }
1453
- if (rows.terminalParentRows.length > 0) {
1454
- warnings.push(`validate_lifecycle_active_terminal_parent:${rows.terminalParentRows.length}`);
1455
- }
1456
- if (includeStaleBlockers && rows.staleBlockerRows.length > 0) {
1457
- warnings.push(`validate_lifecycle_stale_blockers:${rows.staleBlockerRows.length}`);
1458
- }
1459
- const dependencyWarning = lifecycleCycleWarningToken("validate_lifecycle_dependency_cycles", dependencyCycleSeverity, dependencyCycleCount);
1460
- const parentWarning = lifecycleCycleWarningToken("validate_hierarchy_parent_cycle", parentCycleSeverity, parentCycleCount);
1461
- return [...warnings, ...dependencyWarning ? [dependencyWarning] : [], ...parentWarning ? [parentWarning] : []];
1462
- }
1463
- function linkedArtifactPathExceedsFilesystemLimits(artifactPath) {
1464
- const normalized = normalizeRelativePath(artifactPath);
1465
- return normalized.length > LINKED_ARTIFACT_MAX_PATH_LENGTH || normalized.split(/[\\/]/).some((segment) => segment.length > LINKED_ARTIFACT_MAX_SEGMENT_LENGTH);
1466
- }
1467
- async function linkedArtifactIsMissing(workspaceRoot, artifactPath) {
1468
- const absolutePath = path.isAbsolute(artifactPath) ? artifactPath : path.resolve(workspaceRoot, artifactPath);
1469
- if (linkedArtifactPathExceedsFilesystemLimits(absolutePath)) {
1470
- return false;
1471
- }
1472
- try {
1473
- const stats = await fs.stat(absolutePath);
1474
- return !stats.isFile() && !stats.isDirectory();
1475
- } catch (error) {
1476
- const code = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
1477
- return code === "ENOENT" || code === "ENOTDIR";
1478
- }
1479
- }
1480
- async function collectLinkedPathScanState(items, workspaceRoot) {
1481
- const state = {
1482
- linkedProjectPaths: /* @__PURE__ */ new Set(),
1483
- remoteLinkedPaths: /* @__PURE__ */ new Set(),
1484
- missingLinkedPaths: [],
1485
- staleLinkRows: []
1486
- };
1487
- for (const item of items) {
1488
- const linkedArtifactGroups = [
1489
- { link_kind: "files", artifacts: item.files ?? [] },
1490
- { link_kind: "docs", artifacts: item.docs ?? [] }
1491
- ];
1492
- for (const group of linkedArtifactGroups) {
1493
- for (const artifact of group.artifacts) {
1494
- if (artifact.scope !== "project") {
1495
- continue;
1496
- }
1497
- if (isRemoteLinkedArtifactReference(artifact.path)) {
1498
- state.remoteLinkedPaths.add(artifact.path.trim());
1499
- continue;
1500
- }
1501
- const normalizedPath = normalizeRelativePath(artifact.path);
1502
- if (normalizedPath.length === 0) {
1503
- continue;
1504
- }
1505
- state.linkedProjectPaths.add(normalizedPath);
1506
- if (await linkedArtifactIsMissing(workspaceRoot, artifact.path)) {
1507
- state.missingLinkedPaths.push(normalizedPath);
1508
- state.staleLinkRows.push({ item_id: item.id, path: normalizedPath, link_kind: group.link_kind });
1509
- }
1510
- }
1511
- }
1512
- }
1513
- return state;
1514
- }
1515
- function partitionFileCandidates(fileCandidates, pmRoot, workspaceRoot, fileScanMode, includePmInternals, verboseFileLists) {
1516
- const strictTrackedAllMode = fileScanMode === "tracked-all-strict";
1517
- const strictModeForcesPmInternals = strictTrackedAllMode && !includePmInternals;
1518
- const includePmInternalsEffective = includePmInternals || strictTrackedAllMode;
1519
- const pmInternalCandidatePrefixes = includePmInternalsEffective ? [] : resolvePmInternalCandidatePrefixes(pmRoot, workspaceRoot);
1520
- const excludedPmInternalPaths = pmInternalCandidatePrefixes.length === 0 ? [] : fileCandidates.candidateFiles.filter((candidate) => hasPathPrefix(candidate, pmInternalCandidatePrefixes));
1521
- const candidateFiles = pmInternalCandidatePrefixes.length === 0 ? fileCandidates.candidateFiles : fileCandidates.candidateFiles.filter((candidate) => !hasPathPrefix(candidate, pmInternalCandidatePrefixes));
1522
- const excludedByReason = {};
1523
- if (excludedPmInternalPaths.length > 0) {
1524
- const summarizedPmInternalPaths = summarizeFileList(excludedPmInternalPaths, verboseFileLists);
1525
- excludedByReason.pm_internals = {
1526
- count: excludedPmInternalPaths.length,
1527
- paths: summarizedPmInternalPaths.values,
1528
- paths_truncated: summarizedPmInternalPaths.truncated,
1529
- paths_total: summarizedPmInternalPaths.total
1530
- };
1531
- }
1532
- return {
1533
- strictTrackedAllMode,
1534
- strictModeForcesPmInternals,
1535
- includePmInternalsEffective,
1536
- pmInternalCandidatePrefixes,
1537
- excludedPmInternalPaths,
1538
- candidateFiles,
1539
- excludedByReason
1540
- };
1541
- }
1542
- function buildLifecycleCheck(items, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, statusRegistry, lifecyclePatternPolicy, verboseDiagnostics, idPrefix = "pm") {
1543
- const rows = collectLifecycleScanRows(items, includeStaleBlockers, statusRegistry, lifecyclePatternPolicy);
1544
- sortLifecycleScanRows(rows);
1545
- const dependencyCycleDiagnostics = detectLifecycleDependencyCycles(rows.activeItems, idPrefix);
1546
- const parentCycleDiagnostics = detectLifecycleParentCycles(items);
1547
- const warnings = buildLifecycleWarnings(rows, includeStaleBlockers, dependencyCycleSeverity, parentCycleSeverity, dependencyCycleDiagnostics.cycle_count, parentCycleDiagnostics.cycle_count);
1548
- const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1549
- const summarizedClosureLikeRows = summarizeList(rows.closureLikeRows.map((row) => `${row.id}:${row.fields.join(",")}`), diagnosticLimit);
1550
- const summarizedTerminalParentRows = summarizeList(rows.terminalParentRows.map((row) => `${row.id}:${row.parent_id}:${row.parent_status}`), diagnosticLimit);
1551
- const summarizedStaleBlockerRows = summarizeList(rows.staleBlockerRows.map((row) => `${row.id}:${row.status}:${row.reasons.join(",")}`), diagnosticLimit);
1552
- const summarizedDependencyCycleItemIds = summarizeList(dependencyCycleDiagnostics.cycle_item_ids, diagnosticLimit);
1553
- const summarizedDependencyCycleSamplePaths = summarizeList(dependencyCycleDiagnostics.cycle_sample_paths, diagnosticLimit);
1554
- const summarizedParentCycleItemIds = summarizeList(parentCycleDiagnostics.cycle_item_ids, diagnosticLimit);
1555
- const summarizedParentCycleSamplePaths = summarizeList(parentCycleDiagnostics.cycle_sample_paths, diagnosticLimit);
1556
- const hasErrorSeverityCycle = dependencyCycleDiagnostics.cycle_count > 0 && dependencyCycleSeverity === "error" || parentCycleDiagnostics.cycle_count > 0 && parentCycleSeverity === "error";
1557
- return {
1558
- check: {
1559
- name: "lifecycle",
1560
- status: hasErrorSeverityCycle ? "error" : warnings.length === 0 ? "ok" : "warn",
1561
- details: {
1562
- checked_active_items: rows.activeItems.length,
1563
- active_closure_like_metadata_items: rows.closureLikeRows.length,
1564
- active_closure_like_metadata_rows: summarizedClosureLikeRows.values,
1565
- active_closure_like_metadata_rows_truncated: summarizedClosureLikeRows.truncated,
1566
- active_terminal_parent_items: rows.terminalParentRows.length,
1567
- active_terminal_parent_rows: summarizedTerminalParentRows.values,
1568
- active_terminal_parent_rows_truncated: summarizedTerminalParentRows.truncated,
1569
- stale_blocker_checks_enabled: includeStaleBlockers,
1570
- stale_blocker_items: rows.staleBlockerRows.length,
1571
- stale_blocker_rows: summarizedStaleBlockerRows.values,
1572
- stale_blocker_rows_truncated: summarizedStaleBlockerRows.truncated,
1573
- dependency_cycle_severity_policy: dependencyCycleSeverity,
1574
- dependency_cycle_count: dependencyCycleDiagnostics.cycle_count,
1575
- dependency_cycle_item_count: dependencyCycleDiagnostics.cycle_item_ids.length,
1576
- dependency_cycle_item_ids: summarizedDependencyCycleItemIds.values,
1577
- dependency_cycle_item_ids_truncated: summarizedDependencyCycleItemIds.truncated,
1578
- dependency_cycle_sample_paths: summarizedDependencyCycleSamplePaths.values,
1579
- dependency_cycle_sample_paths_truncated: summarizedDependencyCycleSamplePaths.truncated,
1580
- parent_cycle_severity_policy: parentCycleSeverity,
1581
- parent_cycle_count: parentCycleDiagnostics.cycle_count,
1582
- parent_cycle_item_count: parentCycleDiagnostics.cycle_item_ids.length,
1583
- parent_cycle_item_ids: summarizedParentCycleItemIds.values,
1584
- parent_cycle_item_ids_truncated: summarizedParentCycleItemIds.truncated,
1585
- parent_cycle_sample_paths: summarizedParentCycleSamplePaths.values,
1586
- parent_cycle_sample_paths_truncated: summarizedParentCycleSamplePaths.truncated,
1587
- stale_blocker_reason_patterns: [...lifecyclePatternPolicy.stale_blocker_reason_patterns],
1588
- stale_blocker_reason_pattern_source: lifecyclePatternPolicy.stale_blocker_reason_pattern_source,
1589
- closure_like_blocked_reason_patterns: [
1590
- ...lifecyclePatternPolicy.closure_like_metadata_field_patterns.blocked_reason
1591
- ],
1592
- closure_like_blocked_reason_pattern_source: lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.blocked_reason,
1593
- closure_like_resolution_patterns: [...lifecyclePatternPolicy.closure_like_metadata_field_patterns.resolution],
1594
- closure_like_resolution_pattern_source: lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.resolution,
1595
- closure_like_actual_result_patterns: [...lifecyclePatternPolicy.closure_like_metadata_field_patterns.actual_result],
1596
- closure_like_actual_result_pattern_source: lifecyclePatternPolicy.closure_like_metadata_field_pattern_sources.actual_result
1597
- }
1598
- },
1599
- warnings,
1600
- terminalParentFixRows: rows.terminalParentFixRows
1601
- };
1602
- }
1603
- async function buildFilesCheck(items, workspaceRoot, pmRoot, fileScanMode, includePmInternals, verboseFileLists) {
1604
- const linkedPathState = await collectLinkedPathScanState(items, workspaceRoot);
1605
- const itemsById = new Map(items.map((item) => [item.id, item]));
1606
- const uniqueMissingLinkedPaths = [...new Set(linkedPathState.missingLinkedPaths)].sort((left, right) => left.localeCompare(right));
1607
- const fileCandidates = await collectProjectFileCandidates(workspaceRoot, fileScanMode);
1608
- const partition = partitionFileCandidates(fileCandidates, pmRoot, workspaceRoot, fileScanMode, includePmInternals, verboseFileLists);
1609
- const orphanedFiles = partition.candidateFiles.filter((candidate) => !linkedPathState.linkedProjectPaths.has(candidate));
1610
- const orphanedPathRows = buildOrphanedPathRows(orphanedFiles, items);
1611
- const classifiedStalePaths = classifyStaleLinkedPaths(uniqueMissingLinkedPaths, partition.candidateFiles);
1612
- const classificationByPath = new Map(classifiedStalePaths.map((entry) => [entry.path, entry.classification]));
1613
- const movedStalePathCount = classifiedStalePaths.filter((entry) => entry.classification === "moved").length;
1614
- const staleLinkPruneRows = linkedPathState.staleLinkRows.map((row) => ({
1615
- ...row,
1616
- classification: classificationByPath.get(row.path) ?? "deleted"
1617
- })).sort((left, right) => left.item_id.localeCompare(right.item_id) || left.path.localeCompare(right.path) || left.link_kind.localeCompare(right.link_kind));
1618
- const warnings = [];
1619
- if (partition.strictModeForcesPmInternals) {
1620
- warnings.push("validate_files_tracked_all_strict_forces_pm_internals");
1621
- }
1622
- if (uniqueMissingLinkedPaths.length > 0) {
1623
- warnings.push(`validate_files_missing_linked_paths:${uniqueMissingLinkedPaths.length}`);
1624
- }
1625
- if (orphanedFiles.length > 0) {
1626
- warnings.push(`validate_files_orphaned_paths:${orphanedFiles.length}`);
1627
- }
1628
- const uniqueRemoteLinkedPaths = [...linkedPathState.remoteLinkedPaths].sort((left, right) => left.localeCompare(right));
1629
- const summarizedRemote = summarizeFileList(uniqueRemoteLinkedPaths, verboseFileLists);
1630
- const summarizedMissing = summarizeFileList(uniqueMissingLinkedPaths, verboseFileLists);
1631
- const summarizedOrphaned = summarizeFileList(orphanedFiles, verboseFileLists);
1632
- const summarizedOrphanedClassifications = summarizeFileList(orphanedPathRows.map((row) => `${row.path}:${row.classification}:owner_candidate=${row.owner_candidate?.id ?? "unowned"}`), verboseFileLists);
1633
- const orphanedPathRowDetail = verboseFileLists ? orphanedPathRows : summarizeFileList(summarizeOrphanedPathRows(orphanedPathRows), false).values;
1634
- const summarizedClassifications = summarizeFileList(summarizeStaleLinkedPathClassifications(classifiedStalePaths), verboseFileLists);
1635
- const missingLinkedPathRows = staleLinkPruneRows.map((row) => ({
1636
- item_id: row.item_id,
1637
- path: row.path,
1638
- link_kind: row.link_kind,
1639
- classification: row.classification
1640
- }));
1641
- const ownerRows = buildMissingLinkedPathRows(missingLinkedPathRows, (id) => {
1642
- const owner = itemsById.get(id);
1643
- return owner ? { type: owner.type, title: owner.title, status: owner.status } : void 0;
1644
- });
1645
- const ownerRowDetail = verboseFileLists ? ownerRows : summarizeFileList(summarizeMissingLinkedPathRows(ownerRows), false).values;
1646
- return {
1647
- check: {
1648
- name: "files",
1649
- status: warnings.length === 0 ? "ok" : "warn",
1650
- details: {
1651
- workspace_root: workspaceRoot,
1652
- scan_mode_requested: fileCandidates.requestedMode,
1653
- scan_mode_applied: fileCandidates.appliedMode,
1654
- strict_tracked_all_mode: partition.strictTrackedAllMode,
1655
- strict_mode_forces_pm_internals: partition.strictModeForcesPmInternals,
1656
- strict_mode_forces_pm_internals_notice: partition.strictModeForcesPmInternals ? "tracked-all-strict force-enables PM internals; pass --include-pm-internals to make inclusion explicit." : null,
1657
- file_list_detail_mode: verboseFileLists ? "full" : "summary",
1658
- file_list_summary_limit: FILE_LIST_SUMMARY_LIMIT,
1659
- candidate_scan_source: fileCandidates.source,
1660
- include_pm_internals: partition.includePmInternalsEffective,
1661
- include_pm_internals_requested: includePmInternals,
1662
- pm_internal_candidate_prefixes: partition.pmInternalCandidatePrefixes,
1663
- pm_internal_excluded_count: partition.excludedPmInternalPaths.length,
1664
- excluded_total: partition.excludedPmInternalPaths.length,
1665
- excluded_by_reason: partition.excludedByReason,
1666
- linked_project_paths: linkedPathState.linkedProjectPaths.size,
1667
- remote_linked_paths_count: uniqueRemoteLinkedPaths.length,
1668
- remote_linked_paths_total: summarizedRemote.total,
1669
- remote_linked_paths: summarizedRemote.values,
1670
- remote_linked_paths_truncated: summarizedRemote.truncated,
1671
- candidate_total_raw: fileCandidates.candidateTotal,
1672
- candidate_scanned_raw: fileCandidates.candidateScanned,
1673
- candidate_total: partition.candidateFiles.length,
1674
- candidate_scanned: partition.candidateFiles.length,
1675
- scanned_candidate_files: partition.candidateFiles.length,
1676
- missing_linked_paths_count: uniqueMissingLinkedPaths.length,
1677
- missing_linked_paths_total: summarizedMissing.total,
1678
- missing_linked_paths: summarizedMissing.values,
1679
- missing_linked_paths_truncated: summarizedMissing.truncated,
1680
- missing_linked_paths_moved_count: movedStalePathCount,
1681
- missing_linked_paths_deleted_count: uniqueMissingLinkedPaths.length - movedStalePathCount,
1682
- missing_linked_path_classifications: summarizedClassifications.values,
1683
- missing_linked_path_classifications_truncated: summarizedClassifications.truncated,
1684
- missing_linked_path_rows_count: ownerRows.length,
1685
- missing_linked_path_rows: ownerRowDetail,
1686
- orphaned_paths_count: orphanedFiles.length,
1687
- orphaned_paths_total: summarizedOrphaned.total,
1688
- orphaned_paths: summarizedOrphaned.values,
1689
- orphaned_paths_truncated: summarizedOrphaned.truncated,
1690
- orphaned_path_classifications: summarizedOrphanedClassifications.values,
1691
- orphaned_path_classifications_truncated: summarizedOrphanedClassifications.truncated,
1692
- orphaned_path_rows_count: orphanedPathRows.length,
1693
- orphaned_path_rows: orphanedPathRowDetail
1694
- }
1695
- },
1696
- warnings,
1697
- staleLinkPruneRows
1698
- };
1699
- }
1700
- async function buildHistoryDriftCheck(pmRoot, items, verboseDiagnostics) {
1701
- const { missingStreams, unreadableStreams, hashMismatches, chainMismatches, driftedItems } = await scanHistoryDrift(pmRoot, items);
1702
- const warnings = [];
1703
- if (missingStreams.length > 0) {
1704
- warnings.push(`validate_history_drift_missing_streams:${missingStreams.length}`);
1705
- }
1706
- if (unreadableStreams.length > 0) {
1707
- warnings.push(`validate_history_drift_unreadable_streams:${unreadableStreams.length}`);
1708
- }
1709
- if (hashMismatches.length > 0) {
1710
- warnings.push(`validate_history_drift_hash_mismatches:${hashMismatches.length}`);
1711
- }
1712
- if (chainMismatches.length > 0) {
1713
- warnings.push(`validate_history_drift_chain_mismatches:${chainMismatches.length}`);
1714
- }
1715
- const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1716
- const summarizedDrifted = summarizeList(driftedItems, diagnosticLimit);
1717
- return {
1718
- check: {
1719
- name: "history_drift",
1720
- status: warnings.length === 0 ? "ok" : "warn",
1721
- details: {
1722
- checked_items: items.length,
1723
- drifted_items_count: driftedItems.length,
1724
- drifted_items: summarizedDrifted.values,
1725
- drifted_items_truncated: summarizedDrifted.truncated,
1726
- counts: {
1727
- missing_streams: missingStreams.length,
1728
- unreadable_streams: unreadableStreams.length,
1729
- hash_mismatches: hashMismatches.length,
1730
- chain_mismatches: chainMismatches.length
1731
- }
1732
- }
1733
- },
1734
- warnings
1735
- };
1736
- }
1737
- function summarizeCommandReferenceRow(ownerId, referencedId, command) {
1738
- const normalizedCommand = command.trim().replaceAll(/\s+/g, " ");
1739
- const commandPreview = normalizedCommand.length > 120 ? `${normalizedCommand.slice(0, 117)}...` : normalizedCommand;
1740
- return `${ownerId}:${referencedId}:${commandPreview}`;
1741
- }
1742
- function buildCommandReferencesCheck(items, idPrefix, verboseDiagnostics) {
1743
- const knownIds = new Set(items.map((item) => item.id.toLowerCase()));
1744
- let linkedCommandsScanned = 0;
1745
- let referencedPmIdCount = 0;
1746
- const referencedPmIds = /* @__PURE__ */ new Set();
1747
- const staleReferenceRows = [];
1748
- for (const item of items) {
1749
- for (const linkedTest of item.tests ?? []) {
1750
- if (typeof linkedTest.command !== "string" || linkedTest.command.trim().length === 0) {
1751
- continue;
1752
- }
1753
- linkedCommandsScanned += 1;
1754
- const referencedIds = extractReferencedPmItemIdsFromCommand(linkedTest.command, idPrefix);
1755
- if (referencedIds.length === 0) {
1756
- continue;
1757
- }
1758
- referencedPmIdCount += referencedIds.length;
1759
- for (const referencedId of referencedIds) {
1760
- referencedPmIds.add(referencedId);
1761
- if (!knownIds.has(referencedId.toLowerCase())) {
1762
- staleReferenceRows.push(summarizeCommandReferenceRow(item.id, referencedId, linkedTest.command));
1763
- }
1764
- }
1765
- }
1766
- }
1767
- const uniqueStaleReferenceRows = [...new Set(staleReferenceRows)].sort((left, right) => left.localeCompare(right));
1768
- const stalePmIds = [...new Set(uniqueStaleReferenceRows.map((row) => row.split(":")[1] ?? ""))].filter((value) => value.length > 0).sort((left, right) => left.localeCompare(right));
1769
- const warnings = uniqueStaleReferenceRows.length > 0 ? [`validate_command_references_stale_pm_ids:${uniqueStaleReferenceRows.length}`] : [];
1770
- const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1771
- const summarizedRows = summarizeList(uniqueStaleReferenceRows, diagnosticLimit);
1772
- const summarizedStalePmIds = summarizeList(stalePmIds, diagnosticLimit);
1773
- const summarizedReferencedPmIds = summarizeList([...referencedPmIds].sort((left, right) => left.localeCompare(right)), diagnosticLimit);
1774
- return {
1775
- check: {
1776
- name: "command_references",
1777
- status: warnings.length === 0 ? "ok" : "warn",
1778
- details: {
1779
- checked_items: items.length,
1780
- linked_commands_scanned: linkedCommandsScanned,
1781
- referenced_pm_ids_count: referencedPmIdCount,
1782
- unique_referenced_pm_ids_count: referencedPmIds.size,
1783
- unique_referenced_pm_ids: summarizedReferencedPmIds.values,
1784
- unique_referenced_pm_ids_truncated: summarizedReferencedPmIds.truncated,
1785
- stale_pm_id_references_count: uniqueStaleReferenceRows.length,
1786
- stale_pm_ids_count: stalePmIds.length,
1787
- stale_pm_ids: summarizedStalePmIds.values,
1788
- stale_pm_ids_truncated: summarizedStalePmIds.truncated,
1789
- stale_pm_id_reference_rows: summarizedRows.values,
1790
- stale_pm_id_reference_rows_truncated: summarizedRows.truncated
1791
- }
1792
- },
1793
- warnings
1794
- };
1795
- }
1796
- function buildFormatVersionCheck(items, verboseDiagnostics) {
1797
- const scan = scanItemFormatVersions(items.map((item) => ({ ref: item.id, version: effectiveItemFormatVersion(item) })));
1798
- const warnings = [];
1799
- if (scan.outdated.length > 0) {
1800
- warnings.push(`validate_format_version_outdated_items:${scan.outdated.length}`);
1801
- }
1802
- if (scan.ahead.length > 0) {
1803
- warnings.push(`validate_format_version_ahead_items:${scan.ahead.length}`);
1804
- }
1805
- const diagnosticLimit = verboseDiagnostics ? Number.POSITIVE_INFINITY : DIAGNOSTIC_LIST_SUMMARY_LIMIT;
1806
- const summarizedOutdated = summarizeList(scan.outdated, diagnosticLimit);
1807
- const summarizedAhead = summarizeList(scan.ahead, diagnosticLimit);
1808
- const status = scan.ahead.length > 0 ? "error" : scan.outdated.length > 0 ? "warn" : "ok";
1809
- return {
1810
- check: {
1811
- name: "format_version",
1812
- status,
1813
- details: {
1814
- checked_items: items.length,
1815
- current_format_version: CURRENT_ITEM_FORMAT_VERSION,
1816
- outdated_items_count: scan.outdated.length,
1817
- outdated_items: summarizedOutdated.values,
1818
- outdated_items_truncated: summarizedOutdated.truncated,
1819
- ahead_items_count: scan.ahead.length,
1820
- ahead_items: summarizedAhead.values,
1821
- ahead_items_truncated: summarizedAhead.truncated
1822
- }
1823
- },
1824
- warnings
1825
- };
1826
- }
1827
- var VALIDATE_AUTO_FIX_MESSAGE = "pm validate auto-fix";
1828
- async function applyValidateFix(fix, global) {
1829
- switch (fix.kind) {
1830
- case "set_resolution":
1831
- case "set_close_reason":
1832
- case "set_estimate":
1833
- case "reparent":
1834
- case "unset_parent": {
1835
- const { runUpdate } = await import("./update-SFLZPJXX.js");
1836
- const updateOptions = { message: VALIDATE_AUTO_FIX_MESSAGE };
1837
- if (fix.kind === "set_resolution") {
1838
- updateOptions.resolution = fix.value;
1839
- } else if (fix.kind === "set_close_reason") {
1840
- updateOptions.closeReason = fix.value;
1841
- } else if (fix.kind === "set_estimate") {
1842
- updateOptions.estimatedMinutes = fix.value;
1843
- } else if (fix.kind === "reparent") {
1844
- updateOptions.parent = fix.parent_id;
1845
- } else {
1846
- updateOptions.unset = ["parent"];
1847
- }
1848
- await runUpdate(fix.item_id, updateOptions, global);
1849
- return;
1850
- }
1851
- case "prune_file_link": {
1852
- throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`);
1853
- }
1854
- case "prune_doc_link": {
1855
- throw new Error(`Unsupported non-batched fix kind: ${fix.kind}`);
1856
- }
1857
- }
1858
- }
1859
- function pruneBatchKey(fix) {
1860
- if (fix.kind !== "prune_file_link" && fix.kind !== "prune_doc_link") {
1861
- return null;
1862
- }
1863
- return `${fix.kind}:${fix.item_id}`;
1864
- }
1865
- async function applyValidateFixes(applicable, global) {
1866
- const applied = [];
1867
- const failed = [];
1868
- const pruneBatches = /* @__PURE__ */ new Map();
1869
- for (const fix of applicable) {
1870
- const batchKey = pruneBatchKey(fix);
1871
- if (batchKey === null) {
1872
- try {
1873
- await applyValidateFix(fix, global);
1874
- applied.push(fix);
1875
- } catch (error) {
1876
- failed.push({ fix, error });
1877
- }
1878
- continue;
1879
- }
1880
- const existing = pruneBatches.get(batchKey);
1881
- if (existing) {
1882
- existing.push(fix);
1883
- } else {
1884
- pruneBatches.set(batchKey, [fix]);
1885
- }
1886
- }
1887
- for (const batch of pruneBatches.values()) {
1888
- const first = batch[0];
1889
- if (!first) {
1890
- continue;
1891
- }
1892
- const remove = batch.map((fix) => fix.path).filter((value) => typeof value === "string" && value.length > 0);
1893
- try {
1894
- if (first.kind === "prune_file_link") {
1895
- const { runFiles } = await import("./files-JPU3FNJ7.js");
1896
- await runFiles(first.item_id, { remove, message: VALIDATE_AUTO_FIX_MESSAGE }, global);
1897
- } else {
1898
- const { runDocs } = await import("./docs-6CRCSVKK.js");
1899
- await runDocs(first.item_id, { remove, message: VALIDATE_AUTO_FIX_MESSAGE }, global);
1900
- }
1901
- applied.push(...batch);
1902
- } catch (error) {
1903
- failed.push(...batch.map((fix) => ({ fix, error })));
1904
- }
1905
- }
1906
- return { applied, failed };
1907
- }
1908
- var _testOnlyValidateCommand = {
1909
- applyValidateFix,
1910
- applyValidateFixes,
1911
- attachValidateFixHints,
1912
- buildCommandReferencesCheck,
1913
- buildCloseReasonBackfillRows,
1914
- buildFilesCheck,
1915
- buildLifecycleCheck,
1916
- buildLifecycleDependencyGraph,
1917
- buildLifecycleParentGraph,
1918
- buildEstimateBackfillRows,
1919
- buildMetadataCounts,
1920
- buildMissingFieldOccurrences,
1921
- buildOrphanedPathRows,
1922
- classifyOrphanedPath,
1923
- collectDefaultProjectFileCandidates,
1924
- collectTrackedGitFileCandidates,
1925
- detectLifecycleDependencyCycles,
1926
- detectLifecycleParentCycles,
1927
- escapeRegExp,
1928
- extractItemIds,
1929
- findLifecycleDependencyCycleComponents,
1930
- isMetadataFieldMissing,
1931
- linkedArtifactPathExceedsFilesystemLimits,
1932
- listFilesRecursive,
1933
- resolveDependencyCycleSeverity,
1934
- resolveParentCycleSeverity,
1935
- resolveFileScanMode,
1936
- resolveLifecycleDependencyCycleSamplePath,
1937
- resolveRequestedChecks,
1938
- resolveValidateMetadataProfile,
1939
- resolveWorkspaceRoot,
1940
- sharedDirectoryPrefixLength,
1941
- summarizeOrphanedPathRows,
1942
- summarizeDuplicateIssueCodes,
1943
- toMeaningfulString
1944
- };
1945
- function recordValidateCheck(state, built, fixHintsEnabled) {
1946
- if (fixHintsEnabled) {
1947
- attachValidateFixHints(built.check, built.warnings);
1948
- }
1949
- state.checks.push(built.check);
1950
- state.warnings.push(...built.warnings);
1951
- }
1952
- async function executeRequestedValidateChecks(params) {
1953
- const state = {
1954
- checks: [],
1955
- warnings: [...params.initialWarnings],
1956
- closeReasonBackfillRows: [],
1957
- estimateBackfillRows: [],
1958
- resolutionBackfillRows: [],
1959
- terminalParentFixRows: [],
1960
- staleLinkPruneRows: []
1961
- };
1962
- const fixHintsEnabled = params.options.fixHints === true;
1963
- const fullDiagnostics = params.options.verboseDiagnostics === true || params.options.allAffectedIds === true || params.global.json === true;
1964
- if (params.requestedChecks.has("metadata")) {
1965
- const built = buildMetadataCheck(params.items, params.metadataPolicy, params.statusRegistry, fullDiagnostics);
1966
- state.closeReasonBackfillRows = built.closeReasonBackfillRows;
1967
- state.estimateBackfillRows = built.estimateBackfillRows;
1968
- recordValidateCheck(state, built, fixHintsEnabled);
1969
- }
1970
- if (params.requestedChecks.has("resolution")) {
1971
- const built = buildResolutionCheck(params.items, params.statusRegistry, fullDiagnostics);
1972
- state.resolutionBackfillRows = built.resolutionBackfillRows;
1973
- recordValidateCheck(state, built, fixHintsEnabled);
1974
- }
1975
- if (params.requestedChecks.has("lifecycle")) {
1976
- const built = buildLifecycleCheck(params.items, Boolean(params.options.checkStaleBlockers), params.dependencyCycleSeverity, params.parentCycleSeverity, params.statusRegistry, params.lifecyclePatternPolicy, fullDiagnostics, params.settings.id_prefix);
1977
- state.terminalParentFixRows = built.terminalParentFixRows;
1978
- recordValidateCheck(state, built, fixHintsEnabled);
1979
- }
1980
- if (params.requestedChecks.has("files")) {
1981
- const built = await buildFilesCheck(params.items, params.workspaceRoot, params.pmRoot, params.fileScanMode, Boolean(params.options.includePmInternals), Boolean(params.options.verboseFileLists));
1982
- state.staleLinkPruneRows = built.staleLinkPruneRows;
1983
- recordValidateCheck(state, built, fixHintsEnabled);
1984
- }
1985
- if (params.requestedChecks.has("command_references")) {
1986
- recordValidateCheck(state, buildCommandReferencesCheck(params.items, params.settings.id_prefix, fullDiagnostics), fixHintsEnabled);
1987
- }
1988
- if (params.requestedChecks.has("history_drift")) {
1989
- recordValidateCheck(state, await buildHistoryDriftCheck(params.pmRoot, params.items, fullDiagnostics), fixHintsEnabled);
1990
- }
1991
- if (params.requestedChecks.has("format_version")) {
1992
- recordValidateCheck(state, buildFormatVersionCheck(params.items, fullDiagnostics), fixHintsEnabled);
1993
- }
1994
- return state;
1995
- }
1996
- function planValidateFixes(options, state, settings) {
1997
- const planned = [];
1998
- if (options.autoFix === true) {
1999
- planned.push(...planCloseReasonBackfillFixes(state.closeReasonBackfillRows));
2000
- planned.push(...planResolutionBackfillFixes(state.resolutionBackfillRows));
2001
- planned.push(...planEstimateBackfillFixes(state.estimateBackfillRows, settings.validation.estimate_defaults_by_type));
2002
- planned.push(...planTerminalParentFixes(state.terminalParentFixRows));
2003
- }
2004
- if (options.pruneMissing === true) {
2005
- planned.push(...planStaleLinkPruneFixes(state.staleLinkPruneRows));
2006
- }
2007
- return planned;
2008
- }
2009
- async function buildValidateFixesSummary(options, state, settings, grantedFixScopes, global) {
2010
- if (options.autoFix !== true && options.pruneMissing !== true) {
2011
- return void 0;
2012
- }
2013
- const planned = planValidateFixes(options, state, settings);
2014
- const { applicable, gated } = partitionFixesByGrant(planned, grantedFixScopes);
2015
- const dryRun = options.dryRun === true;
2016
- const appliedFixRows = [];
2017
- const failedFixRows = [];
2018
- if (!dryRun) {
2019
- const applied = await applyValidateFixes(applicable, global);
2020
- appliedFixRows.push(...applied.applied.map(toFixOutputRow));
2021
- failedFixRows.push(...applied.failed.map(({ fix, error }) => ({
2022
- ...toFixOutputRow(fix),
2023
- error: error instanceof Error ? error.message : String(error)
2024
- })));
2025
- }
2026
- return {
2027
- mode: dryRun ? "dry_run" : "apply",
2028
- auto_fix: options.autoFix === true,
2029
- prune_missing: options.pruneMissing === true,
2030
- granted_fix_scopes: [...grantedFixScopes].sort((left, right) => left.localeCompare(right)),
2031
- planned_count: planned.length,
2032
- applied_count: appliedFixRows.length,
2033
- gated_count: gated.length,
2034
- failed_count: failedFixRows.length,
2035
- planned_fixes: planned.map(toFixOutputRow),
2036
- applied_fixes: appliedFixRows,
2037
- gated_fixes: gated.map((fix) => ({
2038
- ...toFixOutputRow(fix),
2039
- gate_hint: `Withheld: re-run with --fix-scope ${fix.gate} to apply.`
2040
- })),
2041
- failed_fixes: failedFixRows
2042
- };
2043
- }
2044
- async function runValidate(options, global) {
2045
- const fixesRequested = options.autoFix === true || options.pruneMissing === true;
2046
- if (options.dryRun === true && !fixesRequested) {
2047
- throw new PmCliError("--dry-run requires --auto-fix or --prune-missing (there is nothing to preview otherwise).", EXIT_CODE.USAGE);
2048
- }
2049
- if (options.fixScope !== void 0 && options.fixScope.length > 0 && options.autoFix !== true) {
2050
- throw new PmCliError("--fix-scope requires --auto-fix.", EXIT_CODE.USAGE);
2051
- }
2052
- const grantedFixScopes = resolveGrantedFixScopes(options.fixScope);
2053
- const pmRoot = resolvePmRoot(process.cwd(), global.path);
2054
- if (!await pathExists(getSettingsPath(pmRoot))) {
2055
- throw new PmCliError(`Tracker is not initialized at ${pmRoot}. Run pm init first.`, EXIT_CODE.NOT_FOUND);
2056
- }
2057
- const settings = await readSettings(pmRoot);
2058
- const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
2059
- const typeRegistry = resolveItemTypeRegistry(settings, getActiveExtensionRegistrations());
2060
- const itemReadWarnings = [];
2061
- const items = await listAllFrontMatterWithBody(pmRoot, settings.item_format, typeRegistry.type_to_folder, itemReadWarnings, settings.schema);
2062
- const requestedChecks = resolveRequestedChecks(options);
2063
- const metadataProfileSource = typeof options.metadataProfile === "string" ? "option" : "settings";
2064
- const metadataProfile = resolveValidateMetadataProfile(typeof options.metadataProfile === "string" ? options.metadataProfile : settings.validation.metadata_profile);
2065
- const metadataPolicy = resolveValidateMetadataPolicy(metadataProfile, metadataProfileSource, settings.validation.metadata_required_fields);
2066
- const lifecyclePatternPolicy = resolveLifecyclePatternPolicy(settings);
2067
- const dependencyCycleSeverity = resolveDependencyCycleSeverity(options.dependencyCycleSeverity);
2068
- const parentCycleSeverity = resolveParentCycleSeverity(options.parentCycleSeverity);
2069
- const fileScanMode = resolveFileScanMode(options.scanMode);
2070
- const workspaceRoot = resolveWorkspaceRoot(pmRoot);
2071
- const state = await executeRequestedValidateChecks({
2072
- requestedChecks,
2073
- options,
2074
- global,
2075
- pmRoot,
2076
- workspaceRoot,
2077
- settings,
2078
- items,
2079
- statusRegistry,
2080
- metadataPolicy,
2081
- lifecyclePatternPolicy,
2082
- dependencyCycleSeverity,
2083
- parentCycleSeverity,
2084
- fileScanMode,
2085
- initialWarnings: [...new Set(itemReadWarnings)]
2086
- });
2087
- const fixes = fixesRequested ? await buildValidateFixesSummary(options, state, settings, grantedFixScopes, global) : void 0;
2088
- const normalizedWarnings = [...new Set(state.warnings)].sort((left, right) => left.localeCompare(right));
2089
- const hasErrors = state.checks.some((check) => check.status === "error");
2090
- return {
2091
- ok: !hasErrors,
2092
- has_warnings: normalizedWarnings.length > 0,
2093
- checks: state.checks,
2094
- warnings: normalizedWarnings,
2095
- ...fixes !== void 0 ? { fixes } : {},
2096
- generated_at: nowIso()
2097
- };
2098
- }
2099
- export {
2100
- _testOnlyValidateCommand,
2101
- runValidate
2102
- };
2103
- //# sourceMappingURL=validate-Z7L75YEJ.js.map
2104
-
2105
- //# debugId=7b42ea6d-c9b5-5d22-b82e-64af26f3173c