@unbrained/pm-cli 2026.7.21 → 2026.7.22

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 (506) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +25 -0
  3. package/dist/cli/bundle-integrity.js +3 -3
  4. package/dist/cli/bundle-integrity.js.map +1 -1
  5. package/dist/cli/commands/contracts.d.ts +5 -0
  6. package/dist/cli/commands/contracts.js +8 -6
  7. package/dist/cli/commands/contracts.js.map +1 -1
  8. package/dist/cli/commands/copy.js +36 -20
  9. package/dist/cli/commands/copy.js.map +1 -1
  10. package/dist/cli/commands/create.js +48 -24
  11. package/dist/cli/commands/create.js.map +1 -1
  12. package/dist/cli/commands/merge.d.ts +1 -1
  13. package/dist/cli/commands/merge.js +3 -3
  14. package/dist/cli/commands/merge.js.map +1 -1
  15. package/dist/cli/commands/restore.js +40 -22
  16. package/dist/cli/commands/restore.js.map +1 -1
  17. package/dist/cli/commands/update.js +12 -9
  18. package/dist/cli/commands/update.js.map +1 -1
  19. package/dist/cli/extension-command-help.js +3 -4
  20. package/dist/cli/extension-command-help.js.map +1 -1
  21. package/dist/cli/main.d.ts +3 -2
  22. package/dist/cli/main.js +6 -6
  23. package/dist/cli/main.js.map +1 -1
  24. package/dist/cli/register-list-query.js +33 -21
  25. package/dist/cli/register-list-query.js.map +1 -1
  26. package/dist/cli/register-mutation.js +63 -37
  27. package/dist/cli/register-mutation.js.map +1 -1
  28. package/dist/cli/registration-helpers.d.ts +2 -0
  29. package/dist/cli/registration-helpers.js +3 -2
  30. package/dist/cli/registration-helpers.js.map +1 -1
  31. package/dist/cli-bundle/bundle-manifest.json +349 -341
  32. package/dist/cli-bundle/chunks/{append-7OVFYR3C.js → append-CYMA7RJT.js} +5 -5
  33. package/dist/cli-bundle/chunks/append-H53CAPMP.js +11 -0
  34. package/dist/cli-bundle/chunks/{chunk-PFNHX655.js → chunk-2P7OK4WG.js} +3 -3
  35. package/dist/cli-bundle/chunks/{chunk-EJDGV4GR.js → chunk-3EBGHNNQ.js} +3 -3
  36. package/dist/cli-bundle/chunks/{chunk-DZRV2OPA.js → chunk-3EDFN3VV.js} +2 -2
  37. package/dist/cli-bundle/chunks/{chunk-ZOY5K4D3.js → chunk-3PWJWLLQ.js} +2 -2
  38. package/dist/cli-bundle/chunks/{chunk-VXOOB6YX.js → chunk-3SJAR3CY.js} +4 -4
  39. package/dist/cli-bundle/chunks/{chunk-GTLCVJOE.js → chunk-3WVKMF2A.js} +3 -3
  40. package/dist/cli-bundle/chunks/{chunk-LAV26CQG.js → chunk-42SYYKA4.js} +4 -4
  41. package/dist/cli-bundle/chunks/{chunk-NLR32VFS.js → chunk-4IXLNV7W.js} +2 -2
  42. package/dist/cli-bundle/chunks/{chunk-BKIAH72N.js → chunk-4LTPHDKA.js} +39 -23
  43. package/dist/cli-bundle/chunks/chunk-4LTPHDKA.js.map +1 -0
  44. package/dist/cli-bundle/chunks/{chunk-ABWCF646.js → chunk-4YTQVO3V.js} +5 -5
  45. package/dist/cli-bundle/chunks/{chunk-E5XMKOSB.js → chunk-5EBRMHI6.js} +4 -4
  46. package/dist/cli-bundle/chunks/{chunk-IY6VZ3IW.js → chunk-5FAG2JUC.js} +320 -62
  47. package/dist/cli-bundle/chunks/chunk-5FAG2JUC.js.map +7 -0
  48. package/dist/cli-bundle/chunks/{chunk-GKX4NJ7U.js → chunk-5K5LHZZX.js} +6 -6
  49. package/dist/cli-bundle/chunks/{chunk-T6PPNM7V.js → chunk-5K7BOAB6.js} +4 -4
  50. package/dist/cli-bundle/chunks/{chunk-4QOB7L7I.js → chunk-5MUZ54G2.js} +5 -5
  51. package/dist/cli-bundle/chunks/{chunk-SF3DT5HJ.js → chunk-5QME4KX2.js} +3 -3
  52. package/dist/cli-bundle/chunks/{chunk-RMF7LMBS.js → chunk-6PDGFY3P.js} +27 -17
  53. package/dist/cli-bundle/chunks/{chunk-RMF7LMBS.js.map → chunk-6PDGFY3P.js.map} +2 -2
  54. package/dist/cli-bundle/chunks/{chunk-TRSHFPRZ.js → chunk-6PM6CPPP.js} +5 -5
  55. package/dist/cli-bundle/chunks/{chunk-O4BCOJTZ.js → chunk-7AHRY3ZB.js} +21 -16
  56. package/dist/cli-bundle/chunks/chunk-7AHRY3ZB.js.map +7 -0
  57. package/dist/cli-bundle/chunks/{chunk-OR42SO64.js → chunk-7B36A3VT.js} +4 -4
  58. package/dist/cli-bundle/chunks/{chunk-QWRVBJ4D.js → chunk-7OR2YKKD.js} +2 -2
  59. package/dist/cli-bundle/chunks/{chunk-FPBMLYPI.js → chunk-7QUV54XX.js} +4 -4
  60. package/dist/cli-bundle/chunks/{chunk-WWNL6WMH.js → chunk-7WXW6JHG.js} +2 -2
  61. package/dist/cli-bundle/chunks/{chunk-BXNDKOR2.js → chunk-A2VL5SVG.js} +4 -4
  62. package/dist/cli-bundle/chunks/chunk-AXGDUXJW.js +5 -0
  63. package/dist/cli-bundle/chunks/{chunk-IAQE32BI.js → chunk-B2AVNGG3.js} +4 -4
  64. package/dist/cli-bundle/chunks/{chunk-K36WV5J6.js → chunk-B7O44UBR.js} +71 -8
  65. package/dist/cli-bundle/chunks/chunk-B7O44UBR.js.map +1 -0
  66. package/dist/cli-bundle/chunks/{chunk-HCEBZNC3.js → chunk-BRMPF2RM.js} +4 -4
  67. package/dist/cli-bundle/chunks/{chunk-Z7VWXXJM.js → chunk-BTNKMF2A.js} +4 -4
  68. package/dist/cli-bundle/chunks/{chunk-KH44WBAT.js → chunk-CD4643VW.js} +4 -4
  69. package/dist/cli-bundle/chunks/{chunk-OWXOPDHD.js → chunk-CJEEC5O4.js} +4 -4
  70. package/dist/cli-bundle/chunks/{chunk-PZC2FUOQ.js → chunk-CTPKCZCF.js} +2 -2
  71. package/dist/cli-bundle/chunks/{chunk-7W2UAXXT.js → chunk-D4OBQVL3.js} +10 -10
  72. package/dist/cli-bundle/chunks/{chunk-EWJWSNRU.js → chunk-DM4TYC2A.js} +4 -4
  73. package/dist/cli-bundle/chunks/{chunk-VJQG4BIM.js → chunk-DSFTAQ7T.js} +3 -3
  74. package/dist/cli-bundle/chunks/{chunk-AELMUANP.js → chunk-DVB6SQU7.js} +2 -2
  75. package/dist/cli-bundle/chunks/{chunk-KBLZ3AA5.js → chunk-E3ZWOFSO.js} +4 -4
  76. package/dist/cli-bundle/chunks/chunk-EP25DV6P.js +9 -0
  77. package/dist/cli-bundle/chunks/{chunk-GTK4DTEW.js → chunk-F4VCB4WY.js} +10 -10
  78. package/dist/cli-bundle/chunks/{chunk-V22ZPOKN.js → chunk-F4XAQUQA.js} +6 -6
  79. package/dist/cli-bundle/chunks/{chunk-QOOTOD3W.js → chunk-FGR6IBAF.js} +6 -6
  80. package/dist/cli-bundle/chunks/{chunk-JSLT7WVE.js → chunk-FKBMT2Q6.js} +2 -2
  81. package/dist/cli-bundle/chunks/{chunk-QIH77CAG.js → chunk-G5RLSSIX.js} +2 -2
  82. package/dist/cli-bundle/chunks/{chunk-P7MTHPJQ.js → chunk-GEKRVH3G.js} +2 -2
  83. package/dist/cli-bundle/chunks/{chunk-2L6ZP22J.js → chunk-GSP6IZFU.js} +3 -3
  84. package/dist/cli-bundle/chunks/{chunk-ATBCUC7Y.js → chunk-H3MDK2VU.js} +48 -30
  85. package/dist/cli-bundle/chunks/chunk-H3MDK2VU.js.map +1 -0
  86. package/dist/cli-bundle/chunks/{chunk-ZVZGXPQ5.js → chunk-HYZZM3Q2.js} +2 -2
  87. package/dist/cli-bundle/chunks/{chunk-XJTABV3X.js → chunk-IBWG3OSH.js} +22 -17
  88. package/dist/cli-bundle/chunks/chunk-IBWG3OSH.js.map +1 -0
  89. package/dist/cli-bundle/chunks/{chunk-4XGJLADW.js → chunk-IHY5SX7O.js} +3 -3
  90. package/dist/cli-bundle/chunks/{chunk-UCBDQI5E.js → chunk-IMU7JLUI.js} +7 -7
  91. package/dist/cli-bundle/chunks/{chunk-Z75ONV25.js → chunk-IPAQAJWB.js} +77 -7
  92. package/dist/cli-bundle/chunks/chunk-IPAQAJWB.js.map +7 -0
  93. package/dist/cli-bundle/chunks/{chunk-7RW4JCU2.js → chunk-IQCD6OO3.js} +25 -13
  94. package/dist/cli-bundle/chunks/chunk-IQCD6OO3.js.map +7 -0
  95. package/dist/cli-bundle/chunks/{chunk-YQWCZ5AC.js → chunk-J3ZKFEDM.js} +38 -22
  96. package/dist/cli-bundle/chunks/chunk-J3ZKFEDM.js.map +7 -0
  97. package/dist/cli-bundle/chunks/{chunk-PEQGTJ5Q.js → chunk-JCLXCGIL.js} +3 -3
  98. package/dist/cli-bundle/chunks/{chunk-GROYI4RB.js → chunk-JLTHOYR7.js} +3 -3
  99. package/dist/cli-bundle/chunks/{chunk-JHJSFOAM.js → chunk-JMPVHM44.js} +4 -4
  100. package/dist/cli-bundle/chunks/{chunk-MATHDCGG.js → chunk-JWYG36RV.js} +8 -8
  101. package/dist/cli-bundle/chunks/{chunk-ZTVA4KLN.js → chunk-KEGVMZNA.js} +28 -16
  102. package/dist/cli-bundle/chunks/chunk-KEGVMZNA.js.map +7 -0
  103. package/dist/cli-bundle/chunks/{chunk-VLRGDBLY.js → chunk-KEHOPUHH.js} +4 -4
  104. package/dist/cli-bundle/chunks/{chunk-K55VMLSS.js → chunk-KJ4ZF35M.js} +63 -13
  105. package/dist/cli-bundle/chunks/chunk-KJ4ZF35M.js.map +7 -0
  106. package/dist/cli-bundle/chunks/{chunk-CPX275C6.js → chunk-KPCZL2YK.js} +6 -6
  107. package/dist/cli-bundle/chunks/{chunk-POG76WWZ.js → chunk-L7DZV6EZ.js} +319 -61
  108. package/dist/cli-bundle/chunks/chunk-L7DZV6EZ.js.map +1 -0
  109. package/dist/cli-bundle/chunks/{chunk-FO6OSVEN.js → chunk-LANV45W2.js} +8 -8
  110. package/dist/cli-bundle/chunks/{chunk-LVC72YRD.js → chunk-LC5ZUXWE.js} +7 -7
  111. package/dist/cli-bundle/chunks/{chunk-SY4SFZSD.js → chunk-LE522OXA.js} +55 -30
  112. package/dist/cli-bundle/chunks/chunk-LE522OXA.js.map +7 -0
  113. package/dist/cli-bundle/chunks/{chunk-TVYYO5A7.js → chunk-MBHYQYCS.js} +2 -2
  114. package/dist/cli-bundle/chunks/{chunk-FJIFFBJX.js → chunk-MROP2RNT.js} +66 -74
  115. package/dist/cli-bundle/chunks/chunk-MROP2RNT.js.map +1 -0
  116. package/dist/cli-bundle/chunks/{chunk-7656MAUL.js → chunk-MUAJHL2R.js} +2 -2
  117. package/dist/cli-bundle/chunks/{chunk-R3P6FZJW.js → chunk-N6QCY2AX.js} +43 -25
  118. package/dist/cli-bundle/chunks/chunk-N6QCY2AX.js.map +1 -0
  119. package/dist/cli-bundle/chunks/{chunk-7WCE6Y64.js → chunk-NUQCSV4P.js} +2 -2
  120. package/dist/cli-bundle/chunks/{chunk-SZVB53Y3.js → chunk-O3GFE2PX.js} +3 -3
  121. package/dist/cli-bundle/chunks/{chunk-OY7DMU5P.js → chunk-O43LEUSD.js} +2 -2
  122. package/dist/cli-bundle/chunks/{chunk-AMJPSANK.js → chunk-O7RH6BWP.js} +103 -44
  123. package/dist/cli-bundle/chunks/chunk-O7RH6BWP.js.map +7 -0
  124. package/dist/cli-bundle/chunks/{chunk-NUF7ROFH.js → chunk-OODR5KYF.js} +26 -27
  125. package/dist/cli-bundle/chunks/chunk-OODR5KYF.js.map +1 -0
  126. package/dist/cli-bundle/chunks/{chunk-LZYP423P.js → chunk-OZ25YD4Q.js} +3 -3
  127. package/dist/cli-bundle/chunks/{chunk-VZIZB6QH.js → chunk-PKYKQCTJ.js} +4 -4
  128. package/dist/cli-bundle/chunks/{chunk-UZLJOEAC.js → chunk-PMRED6QZ.js} +3 -3
  129. package/dist/cli-bundle/chunks/{chunk-ADBTSVGK.js → chunk-PPATPPI6.js} +65 -73
  130. package/dist/cli-bundle/chunks/chunk-PPATPPI6.js.map +7 -0
  131. package/dist/cli-bundle/chunks/{chunk-K4CI6Y45.js → chunk-PWGJCP2V.js} +2 -2
  132. package/dist/cli-bundle/chunks/{chunk-UVN66B3M.js → chunk-Q3Z2Y5WJ.js} +2 -2
  133. package/dist/cli-bundle/chunks/{chunk-RNPZYNHS.js → chunk-Q6YZ3VCI.js} +104 -45
  134. package/dist/cli-bundle/chunks/chunk-Q6YZ3VCI.js.map +1 -0
  135. package/dist/cli-bundle/chunks/{chunk-7DOJC3HS.js → chunk-QE5EUHKN.js} +28 -18
  136. package/dist/cli-bundle/chunks/chunk-QE5EUHKN.js.map +1 -0
  137. package/dist/cli-bundle/chunks/{chunk-AS4SAZ5R.js → chunk-QKMMWESK.js} +25 -26
  138. package/dist/cli-bundle/chunks/chunk-QKMMWESK.js.map +7 -0
  139. package/dist/cli-bundle/chunks/{chunk-R7QV7ICM.js → chunk-QSXN2FAN.js} +4 -4
  140. package/dist/cli-bundle/chunks/{chunk-5NTE36LD.js → chunk-RBECHH5K.js} +4 -4
  141. package/dist/cli-bundle/chunks/{chunk-JXCW2TI2.js → chunk-RPNC7M63.js} +8 -8
  142. package/dist/cli-bundle/chunks/{chunk-ICDAQ4TD.js → chunk-S2QQNTA6.js} +26 -14
  143. package/dist/cli-bundle/chunks/chunk-S2QQNTA6.js.map +1 -0
  144. package/dist/cli-bundle/chunks/{chunk-JFD5LPMI.js → chunk-SP3BAXFF.js} +29 -17
  145. package/dist/cli-bundle/chunks/chunk-SP3BAXFF.js.map +1 -0
  146. package/dist/cli-bundle/chunks/{chunk-F2LBF7XJ.js → chunk-SUSFH6F7.js} +5 -5
  147. package/dist/cli-bundle/chunks/{chunk-VHXHVTUU.js → chunk-TDOPC7UY.js} +2 -2
  148. package/dist/cli-bundle/chunks/{chunk-HYW67VJ5.js → chunk-TLF52ZDP.js} +30 -25
  149. package/dist/cli-bundle/chunks/chunk-TLF52ZDP.js.map +1 -0
  150. package/dist/cli-bundle/chunks/{chunk-FSE2IKJQ.js → chunk-TWHG646K.js} +2 -2
  151. package/dist/cli-bundle/chunks/{chunk-OCUBRA6D.js → chunk-U7U7WGEC.js} +4 -4
  152. package/dist/cli-bundle/chunks/{chunk-PONKZPCJ.js → chunk-UFRVIIJ2.js} +4 -4
  153. package/dist/cli-bundle/chunks/{chunk-VNTCM3VW.js → chunk-VKX2VZZH.js} +8 -8
  154. package/dist/cli-bundle/chunks/{chunk-7AVEY74G.js → chunk-VTOCZ343.js} +29 -24
  155. package/dist/cli-bundle/chunks/chunk-VTOCZ343.js.map +7 -0
  156. package/dist/cli-bundle/chunks/{chunk-6JUTHVQS.js → chunk-W2JDNTN3.js} +2 -2
  157. package/dist/cli-bundle/chunks/{chunk-PQSEQD6E.js → chunk-W35PHE44.js} +62 -12
  158. package/dist/cli-bundle/chunks/chunk-W35PHE44.js.map +1 -0
  159. package/dist/cli-bundle/chunks/{chunk-4QSQ6XDK.js → chunk-WT4KXBUD.js} +68 -31
  160. package/dist/cli-bundle/chunks/chunk-WT4KXBUD.js.map +1 -0
  161. package/dist/cli-bundle/chunks/{chunk-RPESLSO5.js → chunk-XC5RVKHH.js} +69 -32
  162. package/dist/cli-bundle/chunks/chunk-XC5RVKHH.js.map +7 -0
  163. package/dist/cli-bundle/chunks/{chunk-QG4GFLQ6.js → chunk-XD6UF2NB.js} +42 -24
  164. package/dist/cli-bundle/chunks/chunk-XD6UF2NB.js.map +7 -0
  165. package/dist/cli-bundle/chunks/{chunk-AF2CCM5U.js → chunk-XKRVX4B3.js} +4 -4
  166. package/dist/cli-bundle/chunks/{chunk-JGUKMMRS.js → chunk-XN4NQZJK.js} +3 -3
  167. package/dist/cli-bundle/chunks/{chunk-3P7UJQOX.js → chunk-YKFMLQNK.js} +2 -2
  168. package/dist/cli-bundle/chunks/{chunk-YCIUJJOD.js → chunk-YKWKMGL7.js} +2 -2
  169. package/dist/cli-bundle/chunks/{chunk-TOBGV45Y.js → chunk-YUKIFPWK.js} +2 -2
  170. package/dist/cli-bundle/chunks/{chunk-72LQ4TKV.js → chunk-YYEZEP3E.js} +3 -3
  171. package/dist/cli-bundle/chunks/{chunk-X3W65QK3.js → chunk-ZEY3XSZQ.js} +5 -5
  172. package/dist/cli-bundle/chunks/{chunk-MWQ2HC2A.js → chunk-ZKOQHLJP.js} +59 -34
  173. package/dist/cli-bundle/chunks/chunk-ZKOQHLJP.js.map +1 -0
  174. package/dist/cli-bundle/chunks/{chunk-QJIKE24M.js → chunk-ZQ3UMKWE.js} +2 -2
  175. package/dist/cli-bundle/chunks/{chunk-4PUUNQDV.js → chunk-ZVVEWHWK.js} +58 -33
  176. package/dist/cli-bundle/chunks/chunk-ZVVEWHWK.js.map +7 -0
  177. package/dist/cli-bundle/chunks/{chunk-OG5DVFMA.js → chunk-ZXE6SNKO.js} +5 -5
  178. package/dist/cli-bundle/chunks/close-GAUIGOQC.js +12 -0
  179. package/dist/cli-bundle/chunks/{close-QEMOYZN3.js → close-SJIEKNY4.js} +5 -5
  180. package/dist/cli-bundle/chunks/{close-many-RZVTUGBG.js → close-many-B6AIC5OQ.js} +15 -14
  181. package/dist/cli-bundle/chunks/close-many-QCINT6I2.js +24 -0
  182. package/dist/cli-bundle/chunks/comments-4SK5EUEJ.js +13 -0
  183. package/dist/cli-bundle/chunks/{comments-TPU7QRBL.js → comments-DM5KV2RS.js} +7 -7
  184. package/dist/cli-bundle/chunks/copy-4KCCLTYQ.js +10 -0
  185. package/dist/cli-bundle/chunks/{copy-DKTSSCK7.js → copy-HEP5SZHB.js} +5 -4
  186. package/dist/cli-bundle/chunks/create-BDKQFPRE.js +30 -0
  187. package/dist/cli-bundle/chunks/{create-EIFBIVNQ.js → create-VCGBCYL2.js} +11 -10
  188. package/dist/cli-bundle/chunks/delete-JWDXPR3H.js +10 -0
  189. package/dist/cli-bundle/chunks/{delete-LCS3VPDH.js → delete-ZSPBTVJD.js} +4 -4
  190. package/dist/cli-bundle/chunks/{deps-YG7UF3VR.js → deps-BZTWWOIE.js} +6 -6
  191. package/dist/cli-bundle/chunks/{deps-UH5EQQUY.js → deps-OVAJOQIE.js} +6 -6
  192. package/dist/cli-bundle/chunks/{docs-G32TK6XS.js → docs-3GFMSWLL.js} +6 -6
  193. package/dist/cli-bundle/chunks/docs-SY2NPT6Y.js +14 -0
  194. package/dist/cli-bundle/chunks/{files-4ALMCSKB.js → files-2SEL4QIU.js} +6 -6
  195. package/dist/cli-bundle/chunks/{files-3H32UQ4K.js → files-FYMMJGNN.js} +6 -6
  196. package/dist/cli-bundle/chunks/focus-4A27YJ2Z.js +10 -0
  197. package/dist/cli-bundle/chunks/{focus-7SOUT5PZ.js → focus-TEUJKTAT.js} +5 -5
  198. package/dist/cli-bundle/chunks/history-compact-7QOKL2NB.js +16 -0
  199. package/dist/cli-bundle/chunks/{history-compact-77BT2LUB.js → history-compact-U7A37VR6.js} +6 -6
  200. package/dist/cli-bundle/chunks/{history-redact-LJPZPNFA.js → history-redact-TNKUO4ZE.js} +4 -4
  201. package/dist/cli-bundle/chunks/{history-redact-PWTTJ3XS.js → history-redact-ZWRUWQY3.js} +4 -4
  202. package/dist/cli-bundle/chunks/{history-repair-I7CBNCV3.js → history-repair-6IU5VWHN.js} +7 -7
  203. package/dist/cli-bundle/chunks/history-repair-GWCGJUM2.js +17 -0
  204. package/dist/cli-bundle/chunks/learnings-DDFAUUX3.js +13 -0
  205. package/dist/cli-bundle/chunks/{learnings-KTYW3AL7.js → learnings-GOEZXMKL.js} +7 -7
  206. package/dist/cli-bundle/chunks/{notes-ZERD3KB2.js → notes-BZWODAEK.js} +7 -7
  207. package/dist/cli-bundle/chunks/notes-OBJ6FL36.js +13 -0
  208. package/dist/cli-bundle/chunks/{plan-OFJUBIM5.js → plan-V57VQTAG.js} +12 -11
  209. package/dist/cli-bundle/chunks/plan-ZMOBD6FX.js +27 -0
  210. package/dist/cli-bundle/chunks/{profile-3THJPIQY.js → profile-BG3N4ETA.js} +9 -9
  211. package/dist/cli-bundle/chunks/{profile-XEZAMMBW.js → profile-XLM45FKV.js} +9 -9
  212. package/dist/cli-bundle/chunks/{register-list-query-BR435Q2H.js → register-list-query-EYYNTGMF.js} +48 -38
  213. package/dist/cli-bundle/chunks/register-list-query-EYYNTGMF.js.map +1 -0
  214. package/dist/cli-bundle/chunks/{register-list-query-RWTWLOBE.js → register-list-query-WGXJPXXY.js} +47 -37
  215. package/dist/cli-bundle/chunks/register-list-query-WGXJPXXY.js.map +7 -0
  216. package/dist/cli-bundle/chunks/{register-mutation-HLWC2WNP.js → register-mutation-3YSDDVOL.js} +131 -105
  217. package/dist/cli-bundle/chunks/register-mutation-3YSDDVOL.js.map +1 -0
  218. package/dist/cli-bundle/chunks/{register-mutation-ZJX5AZM5.js → register-mutation-VDGUMMUY.js} +131 -105
  219. package/dist/cli-bundle/chunks/register-mutation-VDGUMMUY.js.map +7 -0
  220. package/dist/cli-bundle/chunks/{register-operations-744YBJMV.js → register-operations-H4URGAHX.js} +36 -35
  221. package/dist/cli-bundle/chunks/{register-operations-744YBJMV.js.map → register-operations-H4URGAHX.js.map} +1 -1
  222. package/dist/cli-bundle/chunks/{register-operations-UEBJH6AN.js → register-operations-HSO7X77D.js} +34 -33
  223. package/dist/cli-bundle/chunks/{register-operations-UEBJH6AN.js.map → register-operations-HSO7X77D.js.map} +1 -1
  224. package/dist/cli-bundle/chunks/{register-setup-5DA4UZXI.js → register-setup-HZ2KKXK4.js} +13 -13
  225. package/dist/cli-bundle/chunks/{register-setup-6H25M3BH.js → register-setup-WCBKJ3H3.js} +13 -13
  226. package/dist/cli-bundle/chunks/{restore-6TDVSATY.js → restore-3NGRFDPX.js} +7 -6
  227. package/dist/cli-bundle/chunks/restore-LNVNUWHE.js +15 -0
  228. package/dist/cli-bundle/chunks/{schema-TPVTIJPO.js → schema-LMFZ742C.js} +6 -6
  229. package/dist/cli-bundle/chunks/{schema-HFXFSGPG.js → schema-O34O33UW.js} +6 -6
  230. package/dist/cli-bundle/chunks/update-BN6VZSYX.js +24 -0
  231. package/dist/cli-bundle/chunks/{update-LJZCL5SI.js → update-FDLPLKOB.js} +14 -13
  232. package/dist/cli-bundle/chunks/update-many-WCKOPN3K.js +35 -0
  233. package/dist/cli-bundle/chunks/update-many-WCKOPN3K.js.map +7 -0
  234. package/dist/cli-bundle/chunks/update-many-X6DVGOMM.js +39 -0
  235. package/dist/cli-bundle/chunks/update-many-X6DVGOMM.js.map +1 -0
  236. package/dist/cli-bundle/main.js +65 -64
  237. package/dist/cli-bundle/main.js.map +2 -2
  238. package/dist/cli-bundle/sdk-runtime.js +53 -52
  239. package/dist/cli-bundle/sdk-testing.js +6 -6
  240. package/dist/cli-bundle/sdk.js +362 -56
  241. package/dist/cli-bundle/sdk.js.map +4 -4
  242. package/dist/cli.js +10 -4
  243. package/dist/cli.js.map +1 -1
  244. package/dist/core/diagnostics/remediation.js +7 -2
  245. package/dist/core/diagnostics/remediation.js.map +1 -1
  246. package/dist/core/search/background-refresh.d.ts +3 -1
  247. package/dist/core/search/background-refresh.js +34 -6
  248. package/dist/core/search/background-refresh.js.map +1 -1
  249. package/dist/core/search/cache.js +28 -5
  250. package/dist/core/search/cache.js.map +1 -1
  251. package/dist/core/shared/constants.d.ts +2 -0
  252. package/dist/core/shared/constants.js +29 -24
  253. package/dist/core/shared/constants.js.map +1 -1
  254. package/dist/core/store/item-metadata-cache.d.ts +32 -1
  255. package/dist/core/store/item-metadata-cache.js +289 -21
  256. package/dist/core/store/item-metadata-cache.js.map +1 -1
  257. package/dist/core/store/item-store.js +71 -34
  258. package/dist/core/store/item-store.js.map +1 -1
  259. package/dist/core/store/settings.js +9 -3
  260. package/dist/core/store/settings.js.map +1 -1
  261. package/dist/sdk/cli-bootstrap.js +68 -76
  262. package/dist/sdk/cli-bootstrap.js.map +1 -1
  263. package/dist/sdk/compile-cache.d.ts +16 -0
  264. package/dist/sdk/compile-cache.js +73 -0
  265. package/dist/sdk/compile-cache.js.map +1 -0
  266. package/dist/sdk/context-relevance.d.ts +16 -1
  267. package/dist/sdk/context-relevance.js +20 -8
  268. package/dist/sdk/context-relevance.js.map +1 -1
  269. package/dist/sdk/context-signal-store.d.ts +77 -0
  270. package/dist/sdk/context-signal-store.js +201 -0
  271. package/dist/sdk/context-signal-store.js.map +1 -0
  272. package/dist/sdk/dependency-provenance.d.ts +12 -0
  273. package/dist/sdk/dependency-provenance.js +38 -0
  274. package/dist/sdk/dependency-provenance.js.map +1 -0
  275. package/dist/sdk/governance/storage-integrity.d.ts +1 -1
  276. package/dist/sdk/governance/storage-integrity.js +47 -6
  277. package/dist/sdk/governance/storage-integrity.js.map +1 -1
  278. package/dist/sdk/graph/assembly.d.ts +2 -0
  279. package/dist/sdk/graph/assembly.js +51 -4
  280. package/dist/sdk/graph/assembly.js.map +1 -1
  281. package/dist/sdk/graph/run.js +12 -13
  282. package/dist/sdk/graph/run.js.map +1 -1
  283. package/dist/sdk/index.d.ts +5 -0
  284. package/dist/sdk/index.js +7 -2
  285. package/dist/sdk/index.js.map +1 -1
  286. package/dist/sdk/item-metadata-index.d.ts +11 -0
  287. package/dist/sdk/item-metadata-index.js +15 -0
  288. package/dist/sdk/item-metadata-index.js.map +1 -0
  289. package/dist/sdk/merge/index.d.ts +1 -0
  290. package/dist/sdk/merge/index.js +3 -2
  291. package/dist/sdk/merge/index.js.map +1 -1
  292. package/dist/sdk/merge/install.js +25 -9
  293. package/dist/sdk/merge/install.js.map +1 -1
  294. package/dist/sdk/merge/reconcile.d.ts +46 -0
  295. package/dist/sdk/merge/reconcile.js +46 -0
  296. package/dist/sdk/merge/reconcile.js.map +1 -0
  297. package/dist/sdk/query/list.d.ts +5 -4
  298. package/dist/sdk/query/list.js +22 -14
  299. package/dist/sdk/query/list.js.map +1 -1
  300. package/dist/sdk/relationship-history.d.ts +30 -0
  301. package/dist/sdk/relationship-history.js +75 -7
  302. package/dist/sdk/relationship-history.js.map +1 -1
  303. package/dist/sdk/relationship-migration.d.ts +42 -0
  304. package/dist/sdk/relationship-migration.js +78 -0
  305. package/dist/sdk/relationship-migration.js.map +1 -0
  306. package/dist/sdk/structured-mutations.js +4 -25
  307. package/dist/sdk/structured-mutations.js.map +1 -1
  308. package/docs/COMMANDS.md +26 -3
  309. package/docs/CONFIGURATION.md +1 -1
  310. package/docs/MERGE_SAFETY.md +14 -5
  311. package/docs/PERFORMANCE.md +28 -0
  312. package/docs/RELATIONSHIP_GRAPH.md +47 -1
  313. package/docs/SDK.md +78 -5
  314. package/marketplace.json +2 -2
  315. package/package.json +2 -2
  316. package/packages/pm-beads/package.json +1 -1
  317. package/packages/pm-calendar/package.json +1 -1
  318. package/packages/pm-command-kit/package.json +1 -1
  319. package/packages/pm-governance-audit/package.json +1 -1
  320. package/packages/pm-guide-shell/package.json +1 -1
  321. package/packages/pm-kanban/package.json +1 -1
  322. package/packages/pm-lifecycle-hooks/package.json +1 -1
  323. package/packages/pm-linked-test-adapters/package.json +1 -1
  324. package/packages/pm-search-advanced/package.json +1 -1
  325. package/packages/pm-templates/package.json +1 -1
  326. package/packages/pm-todos/package.json +1 -1
  327. package/packages/pm-vcs/package.json +1 -1
  328. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  329. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  330. package/dist/cli-bundle/chunks/append-DFETHAZL.js +0 -11
  331. package/dist/cli-bundle/chunks/chunk-4PUUNQDV.js.map +0 -7
  332. package/dist/cli-bundle/chunks/chunk-4QSQ6XDK.js.map +0 -1
  333. package/dist/cli-bundle/chunks/chunk-7AVEY74G.js.map +0 -7
  334. package/dist/cli-bundle/chunks/chunk-7DOJC3HS.js.map +0 -1
  335. package/dist/cli-bundle/chunks/chunk-7RW4JCU2.js.map +0 -7
  336. package/dist/cli-bundle/chunks/chunk-ADBTSVGK.js.map +0 -7
  337. package/dist/cli-bundle/chunks/chunk-AMJPSANK.js.map +0 -7
  338. package/dist/cli-bundle/chunks/chunk-AS4SAZ5R.js.map +0 -7
  339. package/dist/cli-bundle/chunks/chunk-ATBCUC7Y.js.map +0 -1
  340. package/dist/cli-bundle/chunks/chunk-BKIAH72N.js.map +0 -1
  341. package/dist/cli-bundle/chunks/chunk-FJIFFBJX.js.map +0 -1
  342. package/dist/cli-bundle/chunks/chunk-HYW67VJ5.js.map +0 -1
  343. package/dist/cli-bundle/chunks/chunk-ICDAQ4TD.js.map +0 -1
  344. package/dist/cli-bundle/chunks/chunk-IY6VZ3IW.js.map +0 -7
  345. package/dist/cli-bundle/chunks/chunk-JFD5LPMI.js.map +0 -1
  346. package/dist/cli-bundle/chunks/chunk-K36WV5J6.js.map +0 -1
  347. package/dist/cli-bundle/chunks/chunk-K55VMLSS.js.map +0 -7
  348. package/dist/cli-bundle/chunks/chunk-MWQ2HC2A.js.map +0 -1
  349. package/dist/cli-bundle/chunks/chunk-NUF7ROFH.js.map +0 -1
  350. package/dist/cli-bundle/chunks/chunk-O4BCOJTZ.js.map +0 -7
  351. package/dist/cli-bundle/chunks/chunk-POG76WWZ.js.map +0 -1
  352. package/dist/cli-bundle/chunks/chunk-PQSEQD6E.js.map +0 -1
  353. package/dist/cli-bundle/chunks/chunk-QG4GFLQ6.js.map +0 -7
  354. package/dist/cli-bundle/chunks/chunk-R3P6FZJW.js.map +0 -1
  355. package/dist/cli-bundle/chunks/chunk-RNPZYNHS.js.map +0 -1
  356. package/dist/cli-bundle/chunks/chunk-RPESLSO5.js.map +0 -7
  357. package/dist/cli-bundle/chunks/chunk-SY4SFZSD.js.map +0 -7
  358. package/dist/cli-bundle/chunks/chunk-XJTABV3X.js.map +0 -1
  359. package/dist/cli-bundle/chunks/chunk-YQWCZ5AC.js.map +0 -7
  360. package/dist/cli-bundle/chunks/chunk-Z75ONV25.js.map +0 -7
  361. package/dist/cli-bundle/chunks/chunk-ZTVA4KLN.js.map +0 -7
  362. package/dist/cli-bundle/chunks/close-O5QVZ6ET.js +0 -12
  363. package/dist/cli-bundle/chunks/close-many-5RZXVN4J.js +0 -23
  364. package/dist/cli-bundle/chunks/comments-Z4KV6FU3.js +0 -13
  365. package/dist/cli-bundle/chunks/copy-M7DDI6LS.js +0 -9
  366. package/dist/cli-bundle/chunks/create-RGSPN5GD.js +0 -29
  367. package/dist/cli-bundle/chunks/delete-MD7YXQLH.js +0 -10
  368. package/dist/cli-bundle/chunks/docs-JWWNRC27.js +0 -14
  369. package/dist/cli-bundle/chunks/focus-DRQ6FQH6.js +0 -10
  370. package/dist/cli-bundle/chunks/history-compact-VCKGTX64.js +0 -16
  371. package/dist/cli-bundle/chunks/history-repair-YTDZRK5E.js +0 -17
  372. package/dist/cli-bundle/chunks/learnings-CYNOICKR.js +0 -13
  373. package/dist/cli-bundle/chunks/notes-FGO63FXL.js +0 -13
  374. package/dist/cli-bundle/chunks/plan-SGCDDTYR.js +0 -26
  375. package/dist/cli-bundle/chunks/register-list-query-BR435Q2H.js.map +0 -1
  376. package/dist/cli-bundle/chunks/register-list-query-RWTWLOBE.js.map +0 -7
  377. package/dist/cli-bundle/chunks/register-mutation-HLWC2WNP.js.map +0 -1
  378. package/dist/cli-bundle/chunks/register-mutation-ZJX5AZM5.js.map +0 -7
  379. package/dist/cli-bundle/chunks/restore-RSL7C7LO.js +0 -14
  380. package/dist/cli-bundle/chunks/update-SIA7LH5Y.js +0 -23
  381. package/dist/cli-bundle/chunks/update-many-BDBZVGQL.js +0 -38
  382. package/dist/cli-bundle/chunks/update-many-MOY3A5B3.js +0 -34
  383. /package/dist/cli-bundle/chunks/{append-7OVFYR3C.js.map → append-CYMA7RJT.js.map} +0 -0
  384. /package/dist/cli-bundle/chunks/{append-DFETHAZL.js.map → append-H53CAPMP.js.map} +0 -0
  385. /package/dist/cli-bundle/chunks/{chunk-PFNHX655.js.map → chunk-2P7OK4WG.js.map} +0 -0
  386. /package/dist/cli-bundle/chunks/{chunk-EJDGV4GR.js.map → chunk-3EBGHNNQ.js.map} +0 -0
  387. /package/dist/cli-bundle/chunks/{chunk-DZRV2OPA.js.map → chunk-3EDFN3VV.js.map} +0 -0
  388. /package/dist/cli-bundle/chunks/{chunk-ZOY5K4D3.js.map → chunk-3PWJWLLQ.js.map} +0 -0
  389. /package/dist/cli-bundle/chunks/{chunk-VXOOB6YX.js.map → chunk-3SJAR3CY.js.map} +0 -0
  390. /package/dist/cli-bundle/chunks/{chunk-GTLCVJOE.js.map → chunk-3WVKMF2A.js.map} +0 -0
  391. /package/dist/cli-bundle/chunks/{chunk-LAV26CQG.js.map → chunk-42SYYKA4.js.map} +0 -0
  392. /package/dist/cli-bundle/chunks/{chunk-NLR32VFS.js.map → chunk-4IXLNV7W.js.map} +0 -0
  393. /package/dist/cli-bundle/chunks/{chunk-ABWCF646.js.map → chunk-4YTQVO3V.js.map} +0 -0
  394. /package/dist/cli-bundle/chunks/{chunk-E5XMKOSB.js.map → chunk-5EBRMHI6.js.map} +0 -0
  395. /package/dist/cli-bundle/chunks/{chunk-GKX4NJ7U.js.map → chunk-5K5LHZZX.js.map} +0 -0
  396. /package/dist/cli-bundle/chunks/{chunk-T6PPNM7V.js.map → chunk-5K7BOAB6.js.map} +0 -0
  397. /package/dist/cli-bundle/chunks/{chunk-4QOB7L7I.js.map → chunk-5MUZ54G2.js.map} +0 -0
  398. /package/dist/cli-bundle/chunks/{chunk-SF3DT5HJ.js.map → chunk-5QME4KX2.js.map} +0 -0
  399. /package/dist/cli-bundle/chunks/{chunk-TRSHFPRZ.js.map → chunk-6PM6CPPP.js.map} +0 -0
  400. /package/dist/cli-bundle/chunks/{chunk-OR42SO64.js.map → chunk-7B36A3VT.js.map} +0 -0
  401. /package/dist/cli-bundle/chunks/{chunk-QWRVBJ4D.js.map → chunk-7OR2YKKD.js.map} +0 -0
  402. /package/dist/cli-bundle/chunks/{chunk-FPBMLYPI.js.map → chunk-7QUV54XX.js.map} +0 -0
  403. /package/dist/cli-bundle/chunks/{chunk-WWNL6WMH.js.map → chunk-7WXW6JHG.js.map} +0 -0
  404. /package/dist/cli-bundle/chunks/{chunk-BXNDKOR2.js.map → chunk-A2VL5SVG.js.map} +0 -0
  405. /package/dist/cli-bundle/chunks/{close-QEMOYZN3.js.map → chunk-AXGDUXJW.js.map} +0 -0
  406. /package/dist/cli-bundle/chunks/{chunk-IAQE32BI.js.map → chunk-B2AVNGG3.js.map} +0 -0
  407. /package/dist/cli-bundle/chunks/{chunk-HCEBZNC3.js.map → chunk-BRMPF2RM.js.map} +0 -0
  408. /package/dist/cli-bundle/chunks/{chunk-Z7VWXXJM.js.map → chunk-BTNKMF2A.js.map} +0 -0
  409. /package/dist/cli-bundle/chunks/{chunk-KH44WBAT.js.map → chunk-CD4643VW.js.map} +0 -0
  410. /package/dist/cli-bundle/chunks/{chunk-OWXOPDHD.js.map → chunk-CJEEC5O4.js.map} +0 -0
  411. /package/dist/cli-bundle/chunks/{chunk-PZC2FUOQ.js.map → chunk-CTPKCZCF.js.map} +0 -0
  412. /package/dist/cli-bundle/chunks/{chunk-7W2UAXXT.js.map → chunk-D4OBQVL3.js.map} +0 -0
  413. /package/dist/cli-bundle/chunks/{chunk-EWJWSNRU.js.map → chunk-DM4TYC2A.js.map} +0 -0
  414. /package/dist/cli-bundle/chunks/{chunk-VJQG4BIM.js.map → chunk-DSFTAQ7T.js.map} +0 -0
  415. /package/dist/cli-bundle/chunks/{chunk-AELMUANP.js.map → chunk-DVB6SQU7.js.map} +0 -0
  416. /package/dist/cli-bundle/chunks/{chunk-KBLZ3AA5.js.map → chunk-E3ZWOFSO.js.map} +0 -0
  417. /package/dist/cli-bundle/chunks/{close-O5QVZ6ET.js.map → chunk-EP25DV6P.js.map} +0 -0
  418. /package/dist/cli-bundle/chunks/{chunk-GTK4DTEW.js.map → chunk-F4VCB4WY.js.map} +0 -0
  419. /package/dist/cli-bundle/chunks/{chunk-V22ZPOKN.js.map → chunk-F4XAQUQA.js.map} +0 -0
  420. /package/dist/cli-bundle/chunks/{chunk-QOOTOD3W.js.map → chunk-FGR6IBAF.js.map} +0 -0
  421. /package/dist/cli-bundle/chunks/{chunk-JSLT7WVE.js.map → chunk-FKBMT2Q6.js.map} +0 -0
  422. /package/dist/cli-bundle/chunks/{chunk-QIH77CAG.js.map → chunk-G5RLSSIX.js.map} +0 -0
  423. /package/dist/cli-bundle/chunks/{chunk-P7MTHPJQ.js.map → chunk-GEKRVH3G.js.map} +0 -0
  424. /package/dist/cli-bundle/chunks/{chunk-2L6ZP22J.js.map → chunk-GSP6IZFU.js.map} +0 -0
  425. /package/dist/cli-bundle/chunks/{chunk-ZVZGXPQ5.js.map → chunk-HYZZM3Q2.js.map} +0 -0
  426. /package/dist/cli-bundle/chunks/{chunk-4XGJLADW.js.map → chunk-IHY5SX7O.js.map} +0 -0
  427. /package/dist/cli-bundle/chunks/{chunk-UCBDQI5E.js.map → chunk-IMU7JLUI.js.map} +0 -0
  428. /package/dist/cli-bundle/chunks/{chunk-PEQGTJ5Q.js.map → chunk-JCLXCGIL.js.map} +0 -0
  429. /package/dist/cli-bundle/chunks/{chunk-GROYI4RB.js.map → chunk-JLTHOYR7.js.map} +0 -0
  430. /package/dist/cli-bundle/chunks/{chunk-JHJSFOAM.js.map → chunk-JMPVHM44.js.map} +0 -0
  431. /package/dist/cli-bundle/chunks/{chunk-MATHDCGG.js.map → chunk-JWYG36RV.js.map} +0 -0
  432. /package/dist/cli-bundle/chunks/{chunk-VLRGDBLY.js.map → chunk-KEHOPUHH.js.map} +0 -0
  433. /package/dist/cli-bundle/chunks/{chunk-CPX275C6.js.map → chunk-KPCZL2YK.js.map} +0 -0
  434. /package/dist/cli-bundle/chunks/{chunk-FO6OSVEN.js.map → chunk-LANV45W2.js.map} +0 -0
  435. /package/dist/cli-bundle/chunks/{chunk-LVC72YRD.js.map → chunk-LC5ZUXWE.js.map} +0 -0
  436. /package/dist/cli-bundle/chunks/{chunk-TVYYO5A7.js.map → chunk-MBHYQYCS.js.map} +0 -0
  437. /package/dist/cli-bundle/chunks/{chunk-7656MAUL.js.map → chunk-MUAJHL2R.js.map} +0 -0
  438. /package/dist/cli-bundle/chunks/{chunk-7WCE6Y64.js.map → chunk-NUQCSV4P.js.map} +0 -0
  439. /package/dist/cli-bundle/chunks/{chunk-SZVB53Y3.js.map → chunk-O3GFE2PX.js.map} +0 -0
  440. /package/dist/cli-bundle/chunks/{chunk-OY7DMU5P.js.map → chunk-O43LEUSD.js.map} +0 -0
  441. /package/dist/cli-bundle/chunks/{chunk-LZYP423P.js.map → chunk-OZ25YD4Q.js.map} +0 -0
  442. /package/dist/cli-bundle/chunks/{chunk-VZIZB6QH.js.map → chunk-PKYKQCTJ.js.map} +0 -0
  443. /package/dist/cli-bundle/chunks/{chunk-UZLJOEAC.js.map → chunk-PMRED6QZ.js.map} +0 -0
  444. /package/dist/cli-bundle/chunks/{chunk-K4CI6Y45.js.map → chunk-PWGJCP2V.js.map} +0 -0
  445. /package/dist/cli-bundle/chunks/{chunk-UVN66B3M.js.map → chunk-Q3Z2Y5WJ.js.map} +0 -0
  446. /package/dist/cli-bundle/chunks/{chunk-R7QV7ICM.js.map → chunk-QSXN2FAN.js.map} +0 -0
  447. /package/dist/cli-bundle/chunks/{chunk-5NTE36LD.js.map → chunk-RBECHH5K.js.map} +0 -0
  448. /package/dist/cli-bundle/chunks/{chunk-JXCW2TI2.js.map → chunk-RPNC7M63.js.map} +0 -0
  449. /package/dist/cli-bundle/chunks/{chunk-F2LBF7XJ.js.map → chunk-SUSFH6F7.js.map} +0 -0
  450. /package/dist/cli-bundle/chunks/{chunk-VHXHVTUU.js.map → chunk-TDOPC7UY.js.map} +0 -0
  451. /package/dist/cli-bundle/chunks/{chunk-FSE2IKJQ.js.map → chunk-TWHG646K.js.map} +0 -0
  452. /package/dist/cli-bundle/chunks/{chunk-OCUBRA6D.js.map → chunk-U7U7WGEC.js.map} +0 -0
  453. /package/dist/cli-bundle/chunks/{chunk-PONKZPCJ.js.map → chunk-UFRVIIJ2.js.map} +0 -0
  454. /package/dist/cli-bundle/chunks/{chunk-VNTCM3VW.js.map → chunk-VKX2VZZH.js.map} +0 -0
  455. /package/dist/cli-bundle/chunks/{chunk-6JUTHVQS.js.map → chunk-W2JDNTN3.js.map} +0 -0
  456. /package/dist/cli-bundle/chunks/{chunk-AF2CCM5U.js.map → chunk-XKRVX4B3.js.map} +0 -0
  457. /package/dist/cli-bundle/chunks/{chunk-JGUKMMRS.js.map → chunk-XN4NQZJK.js.map} +0 -0
  458. /package/dist/cli-bundle/chunks/{chunk-3P7UJQOX.js.map → chunk-YKFMLQNK.js.map} +0 -0
  459. /package/dist/cli-bundle/chunks/{chunk-YCIUJJOD.js.map → chunk-YKWKMGL7.js.map} +0 -0
  460. /package/dist/cli-bundle/chunks/{chunk-TOBGV45Y.js.map → chunk-YUKIFPWK.js.map} +0 -0
  461. /package/dist/cli-bundle/chunks/{chunk-72LQ4TKV.js.map → chunk-YYEZEP3E.js.map} +0 -0
  462. /package/dist/cli-bundle/chunks/{chunk-X3W65QK3.js.map → chunk-ZEY3XSZQ.js.map} +0 -0
  463. /package/dist/cli-bundle/chunks/{chunk-QJIKE24M.js.map → chunk-ZQ3UMKWE.js.map} +0 -0
  464. /package/dist/cli-bundle/chunks/{chunk-OG5DVFMA.js.map → chunk-ZXE6SNKO.js.map} +0 -0
  465. /package/dist/cli-bundle/chunks/{close-many-5RZXVN4J.js.map → close-GAUIGOQC.js.map} +0 -0
  466. /package/dist/cli-bundle/chunks/{close-many-RZVTUGBG.js.map → close-SJIEKNY4.js.map} +0 -0
  467. /package/dist/cli-bundle/chunks/{comments-TPU7QRBL.js.map → close-many-B6AIC5OQ.js.map} +0 -0
  468. /package/dist/cli-bundle/chunks/{comments-Z4KV6FU3.js.map → close-many-QCINT6I2.js.map} +0 -0
  469. /package/dist/cli-bundle/chunks/{copy-M7DDI6LS.js.map → comments-4SK5EUEJ.js.map} +0 -0
  470. /package/dist/cli-bundle/chunks/{copy-DKTSSCK7.js.map → comments-DM5KV2RS.js.map} +0 -0
  471. /package/dist/cli-bundle/chunks/{create-RGSPN5GD.js.map → copy-4KCCLTYQ.js.map} +0 -0
  472. /package/dist/cli-bundle/chunks/{create-EIFBIVNQ.js.map → copy-HEP5SZHB.js.map} +0 -0
  473. /package/dist/cli-bundle/chunks/{delete-MD7YXQLH.js.map → create-BDKQFPRE.js.map} +0 -0
  474. /package/dist/cli-bundle/chunks/{delete-LCS3VPDH.js.map → create-VCGBCYL2.js.map} +0 -0
  475. /package/dist/cli-bundle/chunks/{deps-YG7UF3VR.js.map → delete-JWDXPR3H.js.map} +0 -0
  476. /package/dist/cli-bundle/chunks/{deps-UH5EQQUY.js.map → delete-ZSPBTVJD.js.map} +0 -0
  477. /package/dist/cli-bundle/chunks/{docs-JWWNRC27.js.map → deps-BZTWWOIE.js.map} +0 -0
  478. /package/dist/cli-bundle/chunks/{docs-G32TK6XS.js.map → deps-OVAJOQIE.js.map} +0 -0
  479. /package/dist/cli-bundle/chunks/{files-3H32UQ4K.js.map → docs-3GFMSWLL.js.map} +0 -0
  480. /package/dist/cli-bundle/chunks/{files-4ALMCSKB.js.map → docs-SY2NPT6Y.js.map} +0 -0
  481. /package/dist/cli-bundle/chunks/{focus-DRQ6FQH6.js.map → files-2SEL4QIU.js.map} +0 -0
  482. /package/dist/cli-bundle/chunks/{focus-7SOUT5PZ.js.map → files-FYMMJGNN.js.map} +0 -0
  483. /package/dist/cli-bundle/chunks/{history-compact-VCKGTX64.js.map → focus-4A27YJ2Z.js.map} +0 -0
  484. /package/dist/cli-bundle/chunks/{history-compact-77BT2LUB.js.map → focus-TEUJKTAT.js.map} +0 -0
  485. /package/dist/cli-bundle/chunks/{history-redact-PWTTJ3XS.js.map → history-compact-7QOKL2NB.js.map} +0 -0
  486. /package/dist/cli-bundle/chunks/{history-redact-LJPZPNFA.js.map → history-compact-U7A37VR6.js.map} +0 -0
  487. /package/dist/cli-bundle/chunks/{history-repair-I7CBNCV3.js.map → history-redact-TNKUO4ZE.js.map} +0 -0
  488. /package/dist/cli-bundle/chunks/{history-repair-YTDZRK5E.js.map → history-redact-ZWRUWQY3.js.map} +0 -0
  489. /package/dist/cli-bundle/chunks/{learnings-KTYW3AL7.js.map → history-repair-6IU5VWHN.js.map} +0 -0
  490. /package/dist/cli-bundle/chunks/{learnings-CYNOICKR.js.map → history-repair-GWCGJUM2.js.map} +0 -0
  491. /package/dist/cli-bundle/chunks/{notes-FGO63FXL.js.map → learnings-DDFAUUX3.js.map} +0 -0
  492. /package/dist/cli-bundle/chunks/{notes-ZERD3KB2.js.map → learnings-GOEZXMKL.js.map} +0 -0
  493. /package/dist/cli-bundle/chunks/{plan-OFJUBIM5.js.map → notes-BZWODAEK.js.map} +0 -0
  494. /package/dist/cli-bundle/chunks/{plan-SGCDDTYR.js.map → notes-OBJ6FL36.js.map} +0 -0
  495. /package/dist/cli-bundle/chunks/{profile-3THJPIQY.js.map → plan-V57VQTAG.js.map} +0 -0
  496. /package/dist/cli-bundle/chunks/{profile-XEZAMMBW.js.map → plan-ZMOBD6FX.js.map} +0 -0
  497. /package/dist/cli-bundle/chunks/{restore-6TDVSATY.js.map → profile-BG3N4ETA.js.map} +0 -0
  498. /package/dist/cli-bundle/chunks/{restore-RSL7C7LO.js.map → profile-XLM45FKV.js.map} +0 -0
  499. /package/dist/cli-bundle/chunks/{register-setup-5DA4UZXI.js.map → register-setup-HZ2KKXK4.js.map} +0 -0
  500. /package/dist/cli-bundle/chunks/{register-setup-6H25M3BH.js.map → register-setup-WCBKJ3H3.js.map} +0 -0
  501. /package/dist/cli-bundle/chunks/{schema-TPVTIJPO.js.map → restore-3NGRFDPX.js.map} +0 -0
  502. /package/dist/cli-bundle/chunks/{schema-HFXFSGPG.js.map → restore-LNVNUWHE.js.map} +0 -0
  503. /package/dist/cli-bundle/chunks/{update-LJZCL5SI.js.map → schema-LMFZ742C.js.map} +0 -0
  504. /package/dist/cli-bundle/chunks/{update-SIA7LH5Y.js.map → schema-O34O33UW.js.map} +0 -0
  505. /package/dist/cli-bundle/chunks/{update-many-MOY3A5B3.js.map → update-BN6VZSYX.js.map} +0 -0
  506. /package/dist/cli-bundle/chunks/{update-many-BDBZVGQL.js.map → update-FDLPLKOB.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-signal-store.js","sources":["sdk/context-signal-store.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/context-signal-store\n *\n * Rebuildable, cursor-stamped feature-store primitives for context relevance.\n * Snapshots are derived read artifacts: callers retain authoritative items and\n * history, while stale, absent, or corrupt snapshots rebuild transparently.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n buildItemContextRelevanceCandidates,\n CONTEXT_RELEVANCE_SIGNAL_NAMES,\n type BuildItemContextRelevanceCandidatesOptions,\n type ContextRelevanceCandidate,\n type ContextRelevanceSignalName,\n type ContextRelevanceSignals,\n} from \"./context-relevance.js\";\nimport type { ItemMetadata } from \"../types/index.js\";\n\n/** Current serialized feature-store envelope version. */\nexport const CONTEXT_SIGNAL_STORE_FORMAT_VERSION = 1;\n\n/** Current canonical signal-vector version. */\nexport const CONTEXT_SIGNAL_SET_VERSION = 1;\n\nconst STORED_CONTEXT_SIGNAL_NAMES = CONTEXT_RELEVANCE_SIGNAL_NAMES.slice(1) as readonly Exclude<\n ContextRelevanceSignalName,\n \"structural\"\n>[];\n\n/** Authoritative substrate used to derive one snapshot. */\nexport type ContextSignalSnapshotSource = \"derived_index\" | \"scan_fallback\";\n\n/** One immutable item signal row. */\nexport interface ContextSignalSnapshotItem {\n /** Stable item identifier. */\n id: string;\n /** Canonical normalized signal vector. */\n signals: ContextRelevanceSignals;\n}\n\n/** Rebuildable, deterministic context-signal snapshot. */\nexport interface ContextSignalSnapshot {\n /** Serialized envelope version. */\n format_version: number;\n /** Signal algorithm version. */\n signal_set_version: number;\n /** Authoritative history or derived-index cursor folded into this snapshot. */\n source_cursor: string;\n /** Stable clock supplied by the caller. */\n generated_at: string;\n /** Read substrate used for the fold. */\n source: ContextSignalSnapshotSource;\n /** Item rows sorted by canonical id. */\n items: readonly ContextSignalSnapshotItem[];\n}\n\n/** Pluggable persistence boundary for context-signal snapshots. */\nexport interface ContextSignalStoreAdapter {\n /** Read the serialized snapshot, or null when none exists. */\n read(): Promise<unknown | null>;\n /** Atomically replace the serialized snapshot. */\n write(snapshot: ContextSignalSnapshot): Promise<void>;\n}\n\n/** Options required to fold authoritative items into a snapshot. */\nexport interface BuildContextSignalSnapshotOptions\n extends BuildItemContextRelevanceCandidatesOptions {\n /** Authoritative history or derived-index cursor. */\n sourceCursor: string;\n /** Substrate used to load the authoritative items. */\n source: ContextSignalSnapshotSource;\n}\n\n/** Result of a feature-store read with explicit degradation metadata. */\nexport interface ContextSignalStoreReadResult {\n /** Valid snapshot used for candidate assembly. */\n snapshot: ContextSignalSnapshot;\n /** Candidates joined to the caller's authoritative item objects. */\n candidates: ContextRelevanceCandidate<ItemMetadata>[];\n /** Whether the persisted snapshot was reused or rebuilt. */\n cache_status: \"fresh\" | \"rebuilt\";\n /** Non-fatal recovery diagnostics. */\n warnings: readonly string[];\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNormalizedSignal(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value >= 0 && value <= 1;\n}\n\nfunction compactSignals(signals: ContextRelevanceSignals): ContextRelevanceSignals {\n const compact: ContextRelevanceSignals = {};\n for (const name of STORED_CONTEXT_SIGNAL_NAMES) {\n const value = signals[name];\n if (value === undefined) continue;\n if (!isNormalizedSignal(value)) {\n throw new TypeError(`Context relevance signal ${name} must be a finite number from 0 to 1`);\n }\n compact[name] = value;\n }\n return compact;\n}\n\nfunction parseSnapshotItem(value: unknown): ContextSignalSnapshotItem | null {\n if (!isRecord(value) || typeof value.id !== \"string\" || !isRecord(value.signals)) {\n return null;\n }\n const signals: Record<string, number> = {};\n const supportedSignals = new Set<string>(STORED_CONTEXT_SIGNAL_NAMES);\n for (const [name, signal] of Object.entries(value.signals)) {\n if (!supportedSignals.has(name) || !isNormalizedSignal(signal)) {\n return null;\n }\n signals[name] = signal;\n }\n return { id: value.id, signals: signals as ContextRelevanceSignals };\n}\n\n/** Validate an untrusted serialized snapshot without accepting partial envelopes. */\nexport function parseContextSignalSnapshot(value: unknown): ContextSignalSnapshot | null {\n if (\n !isRecord(value) ||\n value.format_version !== CONTEXT_SIGNAL_STORE_FORMAT_VERSION ||\n value.signal_set_version !== CONTEXT_SIGNAL_SET_VERSION ||\n typeof value.source_cursor !== \"string\" ||\n value.source_cursor.trim().length === 0 ||\n typeof value.generated_at !== \"string\" ||\n !Number.isFinite(Date.parse(value.generated_at)) ||\n (value.source !== \"derived_index\" && value.source !== \"scan_fallback\") ||\n !Array.isArray(value.items)\n ) {\n return null;\n }\n const items = value.items.map(parseSnapshotItem);\n if (items.some((item) => item === null)) {\n return null;\n }\n const validItems = items as ContextSignalSnapshotItem[];\n if (\n new Set(validItems.map((item) => item.id)).size !== validItems.length ||\n validItems.some((item) => item.id.trim().length === 0)\n ) {\n return null;\n }\n return {\n format_version: CONTEXT_SIGNAL_STORE_FORMAT_VERSION,\n signal_set_version: CONTEXT_SIGNAL_SET_VERSION,\n source_cursor: value.source_cursor,\n generated_at: value.generated_at,\n source: value.source,\n items: validItems.sort((left, right) => left.id.localeCompare(right.id)),\n };\n}\n\n/** Fold authoritative items into a deterministic, immutable signal snapshot. */\nexport function buildContextSignalSnapshot(\n items: readonly ItemMetadata[],\n options: BuildContextSignalSnapshotOptions,\n): ContextSignalSnapshot {\n if (typeof options.sourceCursor !== \"string\" || options.sourceCursor.trim().length === 0) {\n throw new TypeError(\"Context signal source cursor must be non-empty\");\n }\n if (!Number.isFinite(Date.parse(options.now))) {\n throw new TypeError(\"Context signal snapshot clock must be a valid timestamp\");\n }\n const rows = buildItemContextRelevanceCandidates(items, options)\n .map(({ id, signals }) => ({\n id,\n signals: compactSignals(signals),\n }))\n .sort((left, right) => left.id.localeCompare(right.id));\n return Object.freeze({\n format_version: CONTEXT_SIGNAL_STORE_FORMAT_VERSION,\n signal_set_version: CONTEXT_SIGNAL_SET_VERSION,\n source_cursor: options.sourceCursor,\n generated_at: options.now,\n source: options.source,\n items: Object.freeze(rows.map((row) => Object.freeze(row))),\n });\n}\n\n/** Filesystem adapter using same-directory atomic replacement. */\nexport class JsonFileContextSignalStoreAdapter implements ContextSignalStoreAdapter {\n private readonly filePath: string;\n\n /** Create an adapter for an explicit derived-state file path. */\n constructor(filePath: string) {\n if (typeof filePath !== \"string\" || filePath.trim().length === 0) {\n throw new TypeError(\"Context signal store path must be non-empty\");\n }\n this.filePath = path.resolve(filePath);\n }\n\n /** Read and decode the JSON snapshot, returning null when it does not exist. */\n async read(): Promise<unknown | null> {\n try {\n return JSON.parse(await fs.readFile(this.filePath, \"utf8\")) as unknown;\n } catch (error: unknown) {\n if (isRecord(error) && error.code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n }\n\n /** Write a complete snapshot through a unique same-directory temporary file. */\n async write(snapshot: ContextSignalSnapshot): Promise<void> {\n const directory = path.dirname(this.filePath);\n await fs.mkdir(directory, { recursive: true });\n const temporaryPath = path.join(directory, `.${path.basename(this.filePath)}.${randomUUID()}.tmp`);\n try {\n await fs.writeFile(temporaryPath, `${JSON.stringify(snapshot)}\\n`, { encoding: \"utf8\", flag: \"wx\" });\n await fs.rename(temporaryPath, this.filePath);\n } finally {\n try {\n await fs.rm(temporaryPath, { force: true });\n } catch {\n // The complete snapshot is already committed; temporary-file cleanup is best effort.\n }\n }\n }\n}\n\n/** Cursor-aware feature store that self-heals from absent, stale, or corrupt state. */\nexport class ContextSignalStore {\n private readonly adapter: ContextSignalStoreAdapter;\n\n /** Bind the store to a caller-selected persistence adapter. */\n constructor(adapter: ContextSignalStoreAdapter) {\n this.adapter = adapter;\n }\n\n /** Read matching signals or rebuild them from authoritative items. */\n async readOrRebuild(\n items: readonly ItemMetadata[],\n options: BuildContextSignalSnapshotOptions,\n ): Promise<ContextSignalStoreReadResult> {\n const warnings: string[] = [];\n let snapshot: ContextSignalSnapshot | null = null;\n try {\n const serialized = await this.adapter.read();\n snapshot = parseContextSignalSnapshot(serialized);\n if (serialized !== null && snapshot === null) {\n warnings.push(\"context_signal_store_invalid\");\n }\n } catch {\n warnings.push(\"context_signal_store_invalid\");\n }\n const authoritativeIds = items.map((item) => item.id).sort((left, right) => left.localeCompare(right));\n const snapshotIds = snapshot?.items.map((item) => item.id) ?? [];\n const fresh =\n snapshot !== null &&\n snapshot.source_cursor === options.sourceCursor &&\n snapshot.source === options.source &&\n snapshotIds.length === authoritativeIds.length &&\n snapshotIds.every((id, index) => id === authoritativeIds[index]);\n let resolvedSnapshot: ContextSignalSnapshot;\n if (fresh && snapshot !== null) {\n resolvedSnapshot = snapshot;\n } else {\n if (snapshot !== null) {\n warnings.push(\"context_signal_store_stale\");\n }\n resolvedSnapshot = buildContextSignalSnapshot(items, options);\n try {\n await this.adapter.write(resolvedSnapshot);\n } catch {\n warnings.push(\"context_signal_store_write_failed\");\n }\n }\n const signalsById = new Map(resolvedSnapshot.items.map((item) => [item.id, item.signals]));\n return {\n snapshot: resolvedSnapshot,\n candidates: items.map((item) => ({ id: item.id, item, signals: signalsById.get(item.id) })),\n cache_status: fresh ? \"fresh\" : \"rebuilt\",\n warnings,\n };\n }\n}\n"],"names":[],"mappings":"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","debugId":"26f26fe2-7795-5447-8a43-6d86f5da0e73"}
@@ -0,0 +1,12 @@
1
+ /** Provenance value declaring that a dependency id belongs to another workspace. */
2
+ export declare const EXTERNAL_DEPENDENCY_SOURCE_KIND = "global";
3
+ /** Return whether a dependency provenance value identifies an external workspace target. */
4
+ export declare function isExternalDependencySourceKind(sourceKind: string | undefined): boolean;
5
+ /** Canonicalize external provenance while preserving other named source kinds. */
6
+ export declare function normalizeDependencySourceKind(sourceKind: string | undefined): string | undefined;
7
+ /**
8
+ * Normalize a dependency seed id without corrupting cross-workspace identity.
9
+ * Local and legacy seeds retain normal workspace-prefix behavior; explicitly
10
+ * global seeds preserve the caller-provided id verbatim (apart from trimming).
11
+ */
12
+ export declare function normalizeDependencySeedId(id: string, prefix: string, sourceKind: string | undefined): string;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @module sdk/dependency-provenance
3
+ *
4
+ * Defines the public provenance contract for dependency seeds that reference
5
+ * items outside the current workspace.
6
+ */
7
+
8
+ !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]="c0beae8d-f654-5edb-bc3a-8d285f7653e2")}catch(e){}}();
9
+ import { normalizeItemId } from "../core/item/id.js";
10
+ /** Provenance value declaring that a dependency id belongs to another workspace. */
11
+ export const EXTERNAL_DEPENDENCY_SOURCE_KIND = "global";
12
+ /** Return whether a dependency provenance value identifies an external workspace target. */
13
+ export function isExternalDependencySourceKind(sourceKind) {
14
+ return sourceKind?.trim().toLowerCase() === EXTERNAL_DEPENDENCY_SOURCE_KIND;
15
+ }
16
+ /** Canonicalize external provenance while preserving other named source kinds. */
17
+ export function normalizeDependencySourceKind(sourceKind) {
18
+ const trimmed = sourceKind?.trim();
19
+ if (!trimmed) {
20
+ return undefined;
21
+ }
22
+ return isExternalDependencySourceKind(trimmed)
23
+ ? EXTERNAL_DEPENDENCY_SOURCE_KIND
24
+ : trimmed;
25
+ }
26
+ /**
27
+ * Normalize a dependency seed id without corrupting cross-workspace identity.
28
+ * Local and legacy seeds retain normal workspace-prefix behavior; explicitly
29
+ * global seeds preserve the caller-provided id verbatim (apart from trimming).
30
+ */
31
+ export function normalizeDependencySeedId(id, prefix, sourceKind) {
32
+ const trimmed = id.trim();
33
+ return isExternalDependencySourceKind(sourceKind)
34
+ ? trimmed
35
+ : normalizeItemId(trimmed, prefix);
36
+ }
37
+ //# sourceMappingURL=dependency-provenance.js.map
38
+ //# debugId=c0beae8d-f654-5edb-bc3a-8d285f7653e2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-provenance.js","sources":["sdk/dependency-provenance.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/dependency-provenance\n *\n * Defines the public provenance contract for dependency seeds that reference\n * items outside the current workspace.\n */\nimport { normalizeItemId } from \"../core/item/id.js\";\n\n/** Provenance value declaring that a dependency id belongs to another workspace. */\nexport const EXTERNAL_DEPENDENCY_SOURCE_KIND = \"global\";\n\n/** Return whether a dependency provenance value identifies an external workspace target. */\nexport function isExternalDependencySourceKind(\n sourceKind: string | undefined,\n): boolean {\n return sourceKind?.trim().toLowerCase() === EXTERNAL_DEPENDENCY_SOURCE_KIND;\n}\n\n/** Canonicalize external provenance while preserving other named source kinds. */\nexport function normalizeDependencySourceKind(\n sourceKind: string | undefined,\n): string | undefined {\n const trimmed = sourceKind?.trim();\n if (!trimmed) {\n return undefined;\n }\n return isExternalDependencySourceKind(trimmed)\n ? EXTERNAL_DEPENDENCY_SOURCE_KIND\n : trimmed;\n}\n\n/**\n * Normalize a dependency seed id without corrupting cross-workspace identity.\n * Local and legacy seeds retain normal workspace-prefix behavior; explicitly\n * global seeds preserve the caller-provided id verbatim (apart from trimming).\n */\nexport function normalizeDependencySeedId(\n id: string,\n prefix: string,\n sourceKind: string | undefined,\n): string {\n const trimmed = id.trim();\n return isExternalDependencySourceKind(sourceKind)\n ? trimmed\n : normalizeItemId(trimmed, prefix);\n}\n"],"names":[],"mappings":"AAAA;;;;;GAKG;;;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,oFAAoF;AACpF,MAAM,CAAC,MAAM,+BAA+B,GAAG,QAAQ,CAAC;AAExD,4FAA4F;AAC5F,MAAM,UAAU,8BAA8B,CAC5C,UAA8B;IAE9B,OAAO,UAAU,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,+BAA+B,CAAC;AAC9E,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,6BAA6B,CAC3C,UAA8B;IAE9B,MAAM,OAAO,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,8BAA8B,CAAC,OAAO,CAAC;QAC5C,CAAC,CAAC,+BAA+B;QACjC,CAAC,CAAC,OAAO,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,EAAU,EACV,MAAc,EACd,UAA8B;IAE9B,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;IAC1B,OAAO,8BAA8B,CAAC,UAAU,CAAC;QAC/C,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC","debugId":"c0beae8d-f654-5edb-bc3a-8d285f7653e2"}
@@ -56,7 +56,7 @@ export interface StorageIntegrityScanResult {
56
56
  history_streams_scanned: number;
57
57
  /** History streams containing unresolved merge-conflict markers. */
58
58
  history_conflict_marker_streams: HistoryStreamIntegrityRow[];
59
- /** History streams containing an entry that is not a JSON object. */
59
+ /** History streams that cannot be read or contain an entry that is not a JSON object. */
60
60
  history_unparseable_streams: HistoryStreamIntegrityRow[];
61
61
  /** Live items whose newest history operation is a delete (delete/modify merge resurrection candidates). */
62
62
  resurrected_items: ResurrectedItemRow[];
@@ -11,7 +11,7 @@
11
11
  * contract; the merge drivers in `sdk/merge` are the prevention half.
12
12
  */
13
13
 
14
- !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]="99fdc5e7-d08b-54a7-8169-1385c91f8ed6")}catch(e){}}();
14
+ !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]="3afbf4fd-fb88-5b2f-9dd1-86d9b132c2e9")}catch(e){}}();
15
15
  import fs from "node:fs/promises";
16
16
  import path from "node:path";
17
17
  import { readFileIfExists } from "../../core/fs/fs-utils.js";
@@ -45,7 +45,6 @@ async function listItemFilesOnDisk(pmRoot, typeToFolder) {
45
45
  }
46
46
  function scanHistoryStreamContent(accumulator, raw) {
47
47
  const { id, relativePath, liveItemIds, out } = accumulator;
48
- out.scanned += 1;
49
48
  const conflictMarker = findFirstMergeConflictMarker(raw);
50
49
  if (conflictMarker) {
51
50
  out.conflictMarkers.push({
@@ -97,6 +96,16 @@ function scanHistoryStreamContent(accumulator, raw) {
97
96
  out.repairReconciliations += 1;
98
97
  }
99
98
  }
99
+ /** Describe a filesystem read failure without exposing the absolute workspace path. */
100
+ function describeFileReadFailure(subject, error) {
101
+ const code = typeof error === "object" &&
102
+ error !== null &&
103
+ "code" in error &&
104
+ typeof error.code === "string"
105
+ ? error.code
106
+ : "UNKNOWN";
107
+ return `${subject} could not be read (error code: ${code})`;
108
+ }
100
109
  async function scanHistoryStreams(pmRoot, liveItemIds) {
101
110
  const out = {
102
111
  conflictMarkers: [],
@@ -116,7 +125,19 @@ async function scanHistoryStreams(pmRoot, liveItemIds) {
116
125
  if (!entry.endsWith(".jsonl")) {
117
126
  continue;
118
127
  }
119
- const raw = await fs.readFile(path.join(pmRoot, "history", entry), "utf8");
128
+ out.scanned += 1;
129
+ let raw;
130
+ try {
131
+ raw = await fs.readFile(path.join(pmRoot, "history", entry), "utf8");
132
+ }
133
+ catch (error) {
134
+ out.unparseable.push({
135
+ id: entry.slice(0, -".jsonl".length),
136
+ path: `history/${entry}`,
137
+ detail: describeFileReadFailure("history stream", error),
138
+ });
139
+ continue;
140
+ }
120
141
  scanHistoryStreamContent({
121
142
  id: entry.slice(0, -".jsonl".length),
122
143
  relativePath: `history/${entry}`,
@@ -142,7 +163,17 @@ function describeUnparseableJson(raw) {
142
163
  async function scanConfigFiles(pmRoot) {
143
164
  const unparseable = [];
144
165
  let scanned = 0;
145
- const settingsRaw = await readFileIfExists(getSettingsPath(pmRoot));
166
+ let settingsRaw = null;
167
+ try {
168
+ settingsRaw = await readFileIfExists(getSettingsPath(pmRoot));
169
+ }
170
+ catch (error) {
171
+ scanned += 1;
172
+ unparseable.push({
173
+ path: "settings.json",
174
+ detail: describeFileReadFailure("configuration file", error),
175
+ });
176
+ }
146
177
  if (settingsRaw !== null) {
147
178
  scanned += 1;
148
179
  const detail = describeUnparseableJson(settingsRaw);
@@ -161,8 +192,18 @@ async function scanConfigFiles(pmRoot) {
161
192
  if (!entry.endsWith(".json")) {
162
193
  continue;
163
194
  }
164
- const raw = await fs.readFile(path.join(pmRoot, "schema", entry), "utf8");
165
195
  scanned += 1;
196
+ let raw;
197
+ try {
198
+ raw = await fs.readFile(path.join(pmRoot, "schema", entry), "utf8");
199
+ }
200
+ catch (error) {
201
+ unparseable.push({
202
+ path: `schema/${entry}`,
203
+ detail: describeFileReadFailure("configuration file", error),
204
+ });
205
+ continue;
206
+ }
166
207
  const detail = describeUnparseableJson(raw);
167
208
  if (detail !== null) {
168
209
  unparseable.push({ path: `schema/${entry}`, detail });
@@ -237,4 +278,4 @@ export async function scanStorageIntegrity(pmRoot, parsedItemIds, typeToFolder,
237
278
  };
238
279
  }
239
280
  //# sourceMappingURL=storage-integrity.js.map
240
- //# debugId=99fdc5e7-d08b-54a7-8169-1385c91f8ed6
281
+ //# debugId=3afbf4fd-fb88-5b2f-9dd1-86d9b132c2e9
@@ -1 +1 @@
1
- {"version":3,"file":"storage-integrity.js","sources":["sdk/governance/storage-integrity.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/governance/storage-integrity\n *\n * Post-merge storage-integrity check for `pm validate`: fails the workspace\n * when tracker storage is provably corrupted in ways the ordinary read path\n * silently tolerates — unparseable item documents (skipped by the list scan),\n * history streams containing unresolved merge-conflict markers, deleted items\n * silently resurrected by a delete/modify merge, and configuration or schema\n * files whose parse failure would otherwise fall back to defaults behind a\n * green gate. This is the detection half of the tracker merge-semantics\n * contract; the merge drivers in `sdk/merge` are the prevention half.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { readFileIfExists } from \"../../core/fs/fs-utils.js\";\nimport {\n parseItemDocument,\n type ItemDocumentFormatOptions,\n} from \"../../core/item/item-format.js\";\nimport { findFirstMergeConflictMarker } from \"../../core/shared/conflict-markers.js\";\nimport {\n getSettingsPath,\n ITEM_FILE_EXTENSIONS,\n} from \"../../core/store/paths.js\";\nimport type { HistoryEntry } from \"../../types/index.js\";\n\n/** Documents one unreadable item-file finding surfaced by the storage-integrity check. */\nexport interface UnreadableItemFileRow {\n /** Tracker-relative path of the item file that failed to parse. */\n path: string;\n /** Item id derived from the file name. */\n id: string;\n}\n\n/** Documents one history-stream finding surfaced by the storage-integrity check. */\nexport interface HistoryStreamIntegrityRow {\n /** Item id whose history stream is affected. */\n id: string;\n /** Tracker-relative path of the history stream. */\n path: string;\n /** Line number of the first offending content, when line-addressable. */\n line?: number;\n /** Failure detail (conflict marker text or parse failure reason). */\n detail: string;\n}\n\n/** Documents one resurrection-candidate finding: a live item whose history says it was deleted. */\nexport interface ResurrectedItemRow {\n /** Live item id whose newest history operation is a delete. */\n id: string;\n /** Timestamp of the recorded delete operation. */\n deleted_at: string;\n /** Author of the recorded delete operation. */\n deleted_by: string;\n}\n\n/** Documents one duplicate-item-id finding: one id claimed by multiple item documents (cross-branch add/add collision or duplicated format variant). */\nexport interface DuplicateItemIdRow {\n /** Item id claimed by more than one on-disk document. */\n id: string;\n /** Tracker-relative paths of every document claiming the id, sorted for determinism. */\n paths: string[];\n}\n\n/** Documents one unparseable configuration/schema file finding. */\nexport interface UnparseableConfigRow {\n /** Tracker-relative path of the configuration file. */\n path: string;\n /** Failure detail (conflict marker location or JSON parse failure). */\n detail: string;\n}\n\n/** Documents the storage-integrity scan result consumed by the validate check builder. */\nexport interface StorageIntegrityScanResult {\n /** Number of item files present on disk across all type folders. */\n item_files_on_disk: number;\n /** Number of distinct item ids present on disk. */\n item_ids_on_disk: number;\n /** Number of items the standard read path successfully parsed. */\n parsed_items: number;\n /** Item files whose ids the standard read path could not parse (silently skipped elsewhere). */\n unreadable_item_files: UnreadableItemFileRow[];\n /** Ids claimed by more than one item document (post-merge add/add id collisions across type folders or format variants; GH-600). */\n duplicate_item_ids: DuplicateItemIdRow[];\n /** Number of history streams scanned. */\n history_streams_scanned: number;\n /** History streams containing unresolved merge-conflict markers. */\n history_conflict_marker_streams: HistoryStreamIntegrityRow[];\n /** History streams containing an entry that is not a JSON object. */\n history_unparseable_streams: HistoryStreamIntegrityRow[];\n /** Live items whose newest history operation is a delete (delete/modify merge resurrection candidates). */\n resurrected_items: ResurrectedItemRow[];\n /** Streams whose final entry is a non-empty history_repair reconciliation patch — the post-repair divergence signal (informational, not a failure). */\n history_repair_reconciliations: number;\n /** Number of configuration/schema files scanned. */\n config_files_scanned: number;\n /** Configuration/schema files that cannot be parsed (silent-defaults fallback risk). */\n unparseable_config_files: UnparseableConfigRow[];\n}\n\n/** Runtime schema context used to parse every physical item file exactly as the ordinary read path does. */\nexport interface StorageIntegrityItemParseOptions {\n /** Active runtime schema, including unknown-field policy and custom field definitions. */\n schema?: ItemDocumentFormatOptions[\"schema\"];\n /** Item fields contributed by active extensions and therefore valid under a rejecting schema. */\n extensionFieldNames?: readonly string[];\n}\n\nasync function listItemFilesOnDisk(\n pmRoot: string,\n typeToFolder: Record<string, string>,\n): Promise<Array<{ relativePath: string; id: string }>> {\n const folders = [...new Set(Object.values(typeToFolder))];\n const found: Array<{ relativePath: string; id: string }> = [];\n await Promise.all(\n folders.map(async (folder) => {\n let entries: string[];\n try {\n entries = await fs.readdir(path.join(pmRoot, folder));\n } catch {\n return;\n }\n for (const entry of entries) {\n for (const extension of ITEM_FILE_EXTENSIONS) {\n if (entry.toLowerCase().endsWith(extension)) {\n found.push({\n relativePath: `${folder}/${entry}`,\n id: entry.slice(0, -extension.length),\n });\n break;\n }\n }\n }\n }),\n );\n return found.sort((left, right) =>\n left.relativePath.localeCompare(right.relativePath),\n );\n}\n\ninterface HistoryStreamScanAccumulator {\n conflictMarkers: HistoryStreamIntegrityRow[];\n unparseable: HistoryStreamIntegrityRow[];\n resurrected: ResurrectedItemRow[];\n repairReconciliations: number;\n scanned: number;\n}\n\nfunction scanHistoryStreamContent(\n accumulator: HistoryStreamAccumulatorInput,\n raw: string,\n): void {\n const { id, relativePath, liveItemIds, out } = accumulator;\n out.scanned += 1;\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n out.conflictMarkers.push({\n id,\n path: relativePath,\n line: conflictMarker.line,\n detail: `unresolved merge conflict marker ${conflictMarker.marker}`,\n });\n return;\n }\n let latestEntry: HistoryEntry | null = null;\n const lines = raw\n .split(/\\r?\\n/)\n .map((line, index) => ({ content: line.trim(), number: index + 1 }))\n .filter((line) => line.content.length > 0);\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line.content) as unknown;\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n Array.isArray(parsed)\n ) {\n throw new TypeError(\"history entry must be an object\");\n }\n latestEntry = parsed as HistoryEntry;\n } catch {\n out.unparseable.push({\n id,\n path: relativePath,\n line: line.number,\n detail: \"history line is not a valid JSON object\",\n });\n return;\n }\n }\n if (latestEntry === null) {\n return;\n }\n if (latestEntry.op === \"delete\" && liveItemIds.has(id)) {\n out.resurrected.push({\n id,\n deleted_at: typeof latestEntry.ts === \"string\" ? latestEntry.ts : \"\",\n deleted_by:\n typeof latestEntry.author === \"string\" ? latestEntry.author : \"\",\n });\n }\n if (\n latestEntry.op === \"history_repair\" &&\n Array.isArray(latestEntry.patch) &&\n latestEntry.patch.length > 0\n ) {\n out.repairReconciliations += 1;\n }\n}\n\ninterface HistoryStreamAccumulatorInput {\n id: string;\n relativePath: string;\n liveItemIds: Set<string>;\n out: HistoryStreamScanAccumulator;\n}\n\nasync function scanHistoryStreams(\n pmRoot: string,\n liveItemIds: Set<string>,\n): Promise<HistoryStreamScanAccumulator> {\n const out: HistoryStreamScanAccumulator = {\n conflictMarkers: [],\n unparseable: [],\n resurrected: [],\n repairReconciliations: 0,\n scanned: 0,\n };\n let entries: string[];\n try {\n entries = await fs.readdir(path.join(pmRoot, \"history\"));\n } catch {\n return out;\n }\n for (const entry of entries.sort((left, right) =>\n left.localeCompare(right),\n )) {\n if (!entry.endsWith(\".jsonl\")) {\n continue;\n }\n const raw = await fs.readFile(path.join(pmRoot, \"history\", entry), \"utf8\");\n scanHistoryStreamContent(\n {\n id: entry.slice(0, -\".jsonl\".length),\n relativePath: `history/${entry}`,\n liveItemIds,\n out,\n },\n raw,\n );\n }\n return out;\n}\n\nfunction describeUnparseableJson(raw: string): string | null {\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n return `unresolved merge conflict marker ${conflictMarker.marker} at line ${conflictMarker.line}`;\n }\n try {\n JSON.parse(raw);\n return null;\n } catch (error) {\n return `invalid JSON (${String(error)})`;\n }\n}\n\nasync function scanConfigFiles(pmRoot: string): Promise<{\n scanned: number;\n unparseable: UnparseableConfigRow[];\n}> {\n const unparseable: UnparseableConfigRow[] = [];\n let scanned = 0;\n const settingsRaw = await readFileIfExists(getSettingsPath(pmRoot));\n if (settingsRaw !== null) {\n scanned += 1;\n const detail = describeUnparseableJson(settingsRaw);\n if (detail !== null) {\n unparseable.push({ path: \"settings.json\", detail });\n }\n }\n let schemaEntries: string[];\n try {\n schemaEntries = await fs.readdir(path.join(pmRoot, \"schema\"));\n } catch {\n return { scanned, unparseable };\n }\n for (const entry of schemaEntries.sort((left, right) =>\n left.localeCompare(right),\n )) {\n if (!entry.endsWith(\".json\")) {\n continue;\n }\n const raw = await fs.readFile(path.join(pmRoot, \"schema\", entry), \"utf8\");\n scanned += 1;\n const detail = describeUnparseableJson(raw);\n if (detail !== null) {\n unparseable.push({ path: `schema/${entry}`, detail });\n }\n }\n return { scanned, unparseable };\n}\n\n/**\n * Scan tracker storage for integrity failures the ordinary read path masks.\n * `parsedItemIds` are the ids the standard cached list scan successfully\n * parsed; any on-disk item file whose id is missing from that set is an\n * unreadable document that `pm get` would hard-error on while list-based\n * commands silently skip it.\n */\nexport async function scanStorageIntegrity(\n pmRoot: string,\n parsedItemIds: ReadonlySet<string>,\n typeToFolder: Record<string, string>,\n itemParseOptions: StorageIntegrityItemParseOptions = {},\n): Promise<StorageIntegrityScanResult> {\n const itemFiles = await listItemFilesOnDisk(pmRoot, typeToFolder);\n const idsOnDisk = new Set(itemFiles.map((file) => file.id));\n const pathsById = new Map<string, string[]>();\n for (const file of itemFiles) {\n const paths = pathsById.get(file.id);\n if (paths === undefined) {\n pathsById.set(file.id, [file.relativePath]);\n } else {\n paths.push(file.relativePath);\n }\n }\n const duplicateItemIds: DuplicateItemIdRow[] = [...pathsById.entries()]\n .filter(([, paths]) => paths.length > 1)\n .map(([id, paths]) => ({\n id,\n paths: [...paths].sort((left, right) => left.localeCompare(right)),\n }))\n .sort((left, right) => left.id.localeCompare(right.id));\n const unreadableItemFiles = (\n await Promise.all(\n itemFiles.map(async (file): Promise<UnreadableItemFileRow | null> => {\n if (!parsedItemIds.has(file.id)) {\n return { path: file.relativePath, id: file.id };\n }\n try {\n const absolutePath = path.join(pmRoot, file.relativePath);\n parseItemDocument(await fs.readFile(absolutePath, \"utf8\"), {\n format: absolutePath.toLowerCase().endsWith(\".md\")\n ? \"json_markdown\"\n : \"toon\",\n schema: itemParseOptions.schema,\n extensionFieldNames: itemParseOptions.extensionFieldNames,\n });\n return null;\n } catch {\n return { path: file.relativePath, id: file.id };\n }\n }),\n )\n ).filter((row): row is UnreadableItemFileRow => row !== null);\n // \"Live\" for resurrection detection means an item file exists on disk —\n // deleted items keep their history stream but lose the document, so a\n // delete-terminated stream is only suspicious when the document is back.\n const historyScan = await scanHistoryStreams(pmRoot, idsOnDisk);\n const configScan = await scanConfigFiles(pmRoot);\n return {\n item_files_on_disk: itemFiles.length,\n item_ids_on_disk: idsOnDisk.size,\n parsed_items: parsedItemIds.size,\n unreadable_item_files: unreadableItemFiles,\n duplicate_item_ids: duplicateItemIds,\n history_streams_scanned: historyScan.scanned,\n history_conflict_marker_streams: historyScan.conflictMarkers,\n history_unparseable_streams: historyScan.unparseable,\n resurrected_items: historyScan.resurrected,\n history_repair_reconciliations: historyScan.repairReconciliations,\n config_files_scanned: configScan.scanned,\n unparseable_config_files: configScan.unparseable,\n };\n}\n"],"names":[],"mappings":"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","debugId":"99fdc5e7-d08b-54a7-8169-1385c91f8ed6"}
1
+ {"version":3,"file":"storage-integrity.js","sources":["sdk/governance/storage-integrity.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/governance/storage-integrity\n *\n * Post-merge storage-integrity check for `pm validate`: fails the workspace\n * when tracker storage is provably corrupted in ways the ordinary read path\n * silently tolerates — unparseable item documents (skipped by the list scan),\n * history streams containing unresolved merge-conflict markers, deleted items\n * silently resurrected by a delete/modify merge, and configuration or schema\n * files whose parse failure would otherwise fall back to defaults behind a\n * green gate. This is the detection half of the tracker merge-semantics\n * contract; the merge drivers in `sdk/merge` are the prevention half.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { readFileIfExists } from \"../../core/fs/fs-utils.js\";\nimport {\n parseItemDocument,\n type ItemDocumentFormatOptions,\n} from \"../../core/item/item-format.js\";\nimport { findFirstMergeConflictMarker } from \"../../core/shared/conflict-markers.js\";\nimport {\n getSettingsPath,\n ITEM_FILE_EXTENSIONS,\n} from \"../../core/store/paths.js\";\nimport type { HistoryEntry } from \"../../types/index.js\";\n\n/** Documents one unreadable item-file finding surfaced by the storage-integrity check. */\nexport interface UnreadableItemFileRow {\n /** Tracker-relative path of the item file that failed to parse. */\n path: string;\n /** Item id derived from the file name. */\n id: string;\n}\n\n/** Documents one history-stream finding surfaced by the storage-integrity check. */\nexport interface HistoryStreamIntegrityRow {\n /** Item id whose history stream is affected. */\n id: string;\n /** Tracker-relative path of the history stream. */\n path: string;\n /** Line number of the first offending content, when line-addressable. */\n line?: number;\n /** Failure detail (conflict marker text or parse failure reason). */\n detail: string;\n}\n\n/** Documents one resurrection-candidate finding: a live item whose history says it was deleted. */\nexport interface ResurrectedItemRow {\n /** Live item id whose newest history operation is a delete. */\n id: string;\n /** Timestamp of the recorded delete operation. */\n deleted_at: string;\n /** Author of the recorded delete operation. */\n deleted_by: string;\n}\n\n/** Documents one duplicate-item-id finding: one id claimed by multiple item documents (cross-branch add/add collision or duplicated format variant). */\nexport interface DuplicateItemIdRow {\n /** Item id claimed by more than one on-disk document. */\n id: string;\n /** Tracker-relative paths of every document claiming the id, sorted for determinism. */\n paths: string[];\n}\n\n/** Documents one unparseable configuration/schema file finding. */\nexport interface UnparseableConfigRow {\n /** Tracker-relative path of the configuration file. */\n path: string;\n /** Failure detail (conflict marker location or JSON parse failure). */\n detail: string;\n}\n\n/** Documents the storage-integrity scan result consumed by the validate check builder. */\nexport interface StorageIntegrityScanResult {\n /** Number of item files present on disk across all type folders. */\n item_files_on_disk: number;\n /** Number of distinct item ids present on disk. */\n item_ids_on_disk: number;\n /** Number of items the standard read path successfully parsed. */\n parsed_items: number;\n /** Item files whose ids the standard read path could not parse (silently skipped elsewhere). */\n unreadable_item_files: UnreadableItemFileRow[];\n /** Ids claimed by more than one item document (post-merge add/add id collisions across type folders or format variants; GH-600). */\n duplicate_item_ids: DuplicateItemIdRow[];\n /** Number of history streams scanned. */\n history_streams_scanned: number;\n /** History streams containing unresolved merge-conflict markers. */\n history_conflict_marker_streams: HistoryStreamIntegrityRow[];\n /** History streams that cannot be read or contain an entry that is not a JSON object. */\n history_unparseable_streams: HistoryStreamIntegrityRow[];\n /** Live items whose newest history operation is a delete (delete/modify merge resurrection candidates). */\n resurrected_items: ResurrectedItemRow[];\n /** Streams whose final entry is a non-empty history_repair reconciliation patch — the post-repair divergence signal (informational, not a failure). */\n history_repair_reconciliations: number;\n /** Number of configuration/schema files scanned. */\n config_files_scanned: number;\n /** Configuration/schema files that cannot be parsed (silent-defaults fallback risk). */\n unparseable_config_files: UnparseableConfigRow[];\n}\n\n/** Runtime schema context used to parse every physical item file exactly as the ordinary read path does. */\nexport interface StorageIntegrityItemParseOptions {\n /** Active runtime schema, including unknown-field policy and custom field definitions. */\n schema?: ItemDocumentFormatOptions[\"schema\"];\n /** Item fields contributed by active extensions and therefore valid under a rejecting schema. */\n extensionFieldNames?: readonly string[];\n}\n\nasync function listItemFilesOnDisk(\n pmRoot: string,\n typeToFolder: Record<string, string>,\n): Promise<Array<{ relativePath: string; id: string }>> {\n const folders = [...new Set(Object.values(typeToFolder))];\n const found: Array<{ relativePath: string; id: string }> = [];\n await Promise.all(\n folders.map(async (folder) => {\n let entries: string[];\n try {\n entries = await fs.readdir(path.join(pmRoot, folder));\n } catch {\n return;\n }\n for (const entry of entries) {\n for (const extension of ITEM_FILE_EXTENSIONS) {\n if (entry.toLowerCase().endsWith(extension)) {\n found.push({\n relativePath: `${folder}/${entry}`,\n id: entry.slice(0, -extension.length),\n });\n break;\n }\n }\n }\n }),\n );\n return found.sort((left, right) =>\n left.relativePath.localeCompare(right.relativePath),\n );\n}\n\ninterface HistoryStreamScanAccumulator {\n conflictMarkers: HistoryStreamIntegrityRow[];\n unparseable: HistoryStreamIntegrityRow[];\n resurrected: ResurrectedItemRow[];\n repairReconciliations: number;\n scanned: number;\n}\n\nfunction scanHistoryStreamContent(\n accumulator: HistoryStreamAccumulatorInput,\n raw: string,\n): void {\n const { id, relativePath, liveItemIds, out } = accumulator;\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n out.conflictMarkers.push({\n id,\n path: relativePath,\n line: conflictMarker.line,\n detail: `unresolved merge conflict marker ${conflictMarker.marker}`,\n });\n return;\n }\n let latestEntry: HistoryEntry | null = null;\n const lines = raw\n .split(/\\r?\\n/)\n .map((line, index) => ({ content: line.trim(), number: index + 1 }))\n .filter((line) => line.content.length > 0);\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line.content) as unknown;\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n Array.isArray(parsed)\n ) {\n throw new TypeError(\"history entry must be an object\");\n }\n latestEntry = parsed as HistoryEntry;\n } catch {\n out.unparseable.push({\n id,\n path: relativePath,\n line: line.number,\n detail: \"history line is not a valid JSON object\",\n });\n return;\n }\n }\n if (latestEntry === null) {\n return;\n }\n if (latestEntry.op === \"delete\" && liveItemIds.has(id)) {\n out.resurrected.push({\n id,\n deleted_at: typeof latestEntry.ts === \"string\" ? latestEntry.ts : \"\",\n deleted_by:\n typeof latestEntry.author === \"string\" ? latestEntry.author : \"\",\n });\n }\n if (\n latestEntry.op === \"history_repair\" &&\n Array.isArray(latestEntry.patch) &&\n latestEntry.patch.length > 0\n ) {\n out.repairReconciliations += 1;\n }\n}\n\ninterface HistoryStreamAccumulatorInput {\n id: string;\n relativePath: string;\n liveItemIds: Set<string>;\n out: HistoryStreamScanAccumulator;\n}\n\n/** Describe a filesystem read failure without exposing the absolute workspace path. */\nfunction describeFileReadFailure(subject: string, error: unknown): string {\n const code =\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n typeof error.code === \"string\"\n ? error.code\n : \"UNKNOWN\";\n return `${subject} could not be read (error code: ${code})`;\n}\n\nasync function scanHistoryStreams(\n pmRoot: string,\n liveItemIds: Set<string>,\n): Promise<HistoryStreamScanAccumulator> {\n const out: HistoryStreamScanAccumulator = {\n conflictMarkers: [],\n unparseable: [],\n resurrected: [],\n repairReconciliations: 0,\n scanned: 0,\n };\n let entries: string[];\n try {\n entries = await fs.readdir(path.join(pmRoot, \"history\"));\n } catch {\n return out;\n }\n for (const entry of entries.sort((left, right) =>\n left.localeCompare(right),\n )) {\n if (!entry.endsWith(\".jsonl\")) {\n continue;\n }\n out.scanned += 1;\n let raw: string;\n try {\n raw = await fs.readFile(path.join(pmRoot, \"history\", entry), \"utf8\");\n } catch (error) {\n out.unparseable.push({\n id: entry.slice(0, -\".jsonl\".length),\n path: `history/${entry}`,\n detail: describeFileReadFailure(\"history stream\", error),\n });\n continue;\n }\n scanHistoryStreamContent(\n {\n id: entry.slice(0, -\".jsonl\".length),\n relativePath: `history/${entry}`,\n liveItemIds,\n out,\n },\n raw,\n );\n }\n return out;\n}\n\nfunction describeUnparseableJson(raw: string): string | null {\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n return `unresolved merge conflict marker ${conflictMarker.marker} at line ${conflictMarker.line}`;\n }\n try {\n JSON.parse(raw);\n return null;\n } catch (error) {\n return `invalid JSON (${String(error)})`;\n }\n}\n\nasync function scanConfigFiles(pmRoot: string): Promise<{\n scanned: number;\n unparseable: UnparseableConfigRow[];\n}> {\n const unparseable: UnparseableConfigRow[] = [];\n let scanned = 0;\n let settingsRaw: string | null = null;\n try {\n settingsRaw = await readFileIfExists(getSettingsPath(pmRoot));\n } catch (error) {\n scanned += 1;\n unparseable.push({\n path: \"settings.json\",\n detail: describeFileReadFailure(\"configuration file\", error),\n });\n }\n if (settingsRaw !== null) {\n scanned += 1;\n const detail = describeUnparseableJson(settingsRaw);\n if (detail !== null) {\n unparseable.push({ path: \"settings.json\", detail });\n }\n }\n let schemaEntries: string[];\n try {\n schemaEntries = await fs.readdir(path.join(pmRoot, \"schema\"));\n } catch {\n return { scanned, unparseable };\n }\n for (const entry of schemaEntries.sort((left, right) =>\n left.localeCompare(right),\n )) {\n if (!entry.endsWith(\".json\")) {\n continue;\n }\n scanned += 1;\n let raw: string;\n try {\n raw = await fs.readFile(path.join(pmRoot, \"schema\", entry), \"utf8\");\n } catch (error) {\n unparseable.push({\n path: `schema/${entry}`,\n detail: describeFileReadFailure(\"configuration file\", error),\n });\n continue;\n }\n const detail = describeUnparseableJson(raw);\n if (detail !== null) {\n unparseable.push({ path: `schema/${entry}`, detail });\n }\n }\n return { scanned, unparseable };\n}\n\n/**\n * Scan tracker storage for integrity failures the ordinary read path masks.\n * `parsedItemIds` are the ids the standard cached list scan successfully\n * parsed; any on-disk item file whose id is missing from that set is an\n * unreadable document that `pm get` would hard-error on while list-based\n * commands silently skip it.\n */\nexport async function scanStorageIntegrity(\n pmRoot: string,\n parsedItemIds: ReadonlySet<string>,\n typeToFolder: Record<string, string>,\n itemParseOptions: StorageIntegrityItemParseOptions = {},\n): Promise<StorageIntegrityScanResult> {\n const itemFiles = await listItemFilesOnDisk(pmRoot, typeToFolder);\n const idsOnDisk = new Set(itemFiles.map((file) => file.id));\n const pathsById = new Map<string, string[]>();\n for (const file of itemFiles) {\n const paths = pathsById.get(file.id);\n if (paths === undefined) {\n pathsById.set(file.id, [file.relativePath]);\n } else {\n paths.push(file.relativePath);\n }\n }\n const duplicateItemIds: DuplicateItemIdRow[] = [...pathsById.entries()]\n .filter(([, paths]) => paths.length > 1)\n .map(([id, paths]) => ({\n id,\n paths: [...paths].sort((left, right) => left.localeCompare(right)),\n }))\n .sort((left, right) => left.id.localeCompare(right.id));\n const unreadableItemFiles = (\n await Promise.all(\n itemFiles.map(async (file): Promise<UnreadableItemFileRow | null> => {\n if (!parsedItemIds.has(file.id)) {\n return { path: file.relativePath, id: file.id };\n }\n try {\n const absolutePath = path.join(pmRoot, file.relativePath);\n parseItemDocument(await fs.readFile(absolutePath, \"utf8\"), {\n format: absolutePath.toLowerCase().endsWith(\".md\")\n ? \"json_markdown\"\n : \"toon\",\n schema: itemParseOptions.schema,\n extensionFieldNames: itemParseOptions.extensionFieldNames,\n });\n return null;\n } catch {\n return { path: file.relativePath, id: file.id };\n }\n }),\n )\n ).filter((row): row is UnreadableItemFileRow => row !== null);\n // \"Live\" for resurrection detection means an item file exists on disk —\n // deleted items keep their history stream but lose the document, so a\n // delete-terminated stream is only suspicious when the document is back.\n const historyScan = await scanHistoryStreams(pmRoot, idsOnDisk);\n const configScan = await scanConfigFiles(pmRoot);\n return {\n item_files_on_disk: itemFiles.length,\n item_ids_on_disk: idsOnDisk.size,\n parsed_items: parsedItemIds.size,\n unreadable_item_files: unreadableItemFiles,\n duplicate_item_ids: duplicateItemIds,\n history_streams_scanned: historyScan.scanned,\n history_conflict_marker_streams: historyScan.conflictMarkers,\n history_unparseable_streams: historyScan.unparseable,\n resurrected_items: historyScan.resurrected,\n history_repair_reconciliations: historyScan.repairReconciliations,\n config_files_scanned: configScan.scanned,\n unparseable_config_files: configScan.unparseable,\n };\n}\n"],"names":[],"mappings":"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","debugId":"3afbf4fd-fb88-5b2f-9dd1-86d9b132c2e9"}
@@ -95,6 +95,8 @@ export declare function collectDuplicateDependencyRows(items: readonly Dependenc
95
95
  export declare function collectDanglingDependencyReferences(items: readonly DependencyReferenceHolder[], isTerminal?: (status: ItemStatus) => boolean): DanglingDependencyReferenceSummary;
96
96
  /** Return unique real missing targets while excluding the legacy no-blocker sentinel. */
97
97
  export declare function collectMissingDependencyTargetIds(dangling: DanglingDependencyReferenceSummary): string[];
98
+ /** Return unique explicitly external dependency targets in deterministic order. */
99
+ export declare function collectExternalDependencyTargetIds(items: readonly DependencyReferenceHolder[]): string[];
98
100
  /** Item shape accepted by workspace relationship-graph assembly. */
99
101
  export interface WorkspaceRelationshipItem extends DependencyReferenceHolder {
100
102
  /** Human-readable title projected into per-node details. */
@@ -1,7 +1,8 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="208d0dcd-c6b6-5959-acdb-6969b1005edd")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="10d72477-685d-5ee6-8b1c-2b7565f09d81")}catch(e){}}();
3
3
  import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
4
4
  import { RelationshipGraph, createRelationshipKindRegistry, } from "../relationships.js";
5
+ import { isExternalDependencySourceKind } from "../dependency-provenance.js";
5
6
  /** Normalize a decoded reference target and reject empty legacy placeholders. */
6
7
  function normalizeDependencyReferenceTarget(target) {
7
8
  if (typeof target !== "string")
@@ -140,6 +141,9 @@ export function collectDanglingDependencyReferences(items, isTerminal = (status)
140
141
  continue;
141
142
  }
142
143
  const legacyDependency = dependency;
144
+ if (isExternalDependencySourceKind(legacyDependency.source_kind)) {
145
+ continue;
146
+ }
143
147
  addReference(item, legacyDependency.id, typeof legacyDependency.kind === "string"
144
148
  ? legacyDependency.kind
145
149
  : "related", "dependency");
@@ -169,6 +173,24 @@ export function collectMissingDependencyTargetIds(dangling) {
169
173
  }
170
174
  return [...targets.values()].sort((left, right) => left.localeCompare(right));
171
175
  }
176
+ /** Return unique explicitly external dependency targets in deterministic order. */
177
+ export function collectExternalDependencyTargetIds(items) {
178
+ const targets = new Map();
179
+ for (const item of items) {
180
+ for (const dependency of item.dependencies ?? []) {
181
+ if (typeof dependency !== "object" ||
182
+ dependency === null ||
183
+ !isExternalDependencySourceKind(dependency.source_kind)) {
184
+ continue;
185
+ }
186
+ const id = normalizeDependencyReferenceTarget(dependency.id);
187
+ if (id && !targets.has(id.toLowerCase())) {
188
+ targets.set(id.toLowerCase(), id);
189
+ }
190
+ }
191
+ }
192
+ return [...targets.values()].sort((left, right) => left.localeCompare(right));
193
+ }
172
194
  /**
173
195
  * Build the shared workspace relationship graph including missing placeholder
174
196
  * nodes. One assembly serves every bounded query in an invocation — dependency
@@ -184,6 +206,17 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
184
206
  const missingIds = collectMissingDependencyTargetIds(dangling);
185
207
  for (const id of missingIds)
186
208
  canonicalIds.set(id.toLowerCase(), id);
209
+ const externalIds = collectExternalDependencyTargetIds(safeItems);
210
+ const usedGraphIds = new Set(canonicalIds.keys());
211
+ const externalGraphIds = new Map();
212
+ for (const id of externalIds) {
213
+ let graphId = id;
214
+ while (usedGraphIds.has(graphId.toLowerCase())) {
215
+ graphId = `external:${graphId}`;
216
+ }
217
+ externalGraphIds.set(id.toLowerCase(), graphId);
218
+ usedGraphIds.add(graphId.toLowerCase());
219
+ }
187
220
  const graphItems = safeItems.map((item) => {
188
221
  const parent = normalizeDependencyGraphTarget(item.parent);
189
222
  const blocker = normalizeDependencyGraphTarget(item.blocked_by);
@@ -194,9 +227,12 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
194
227
  const target = normalizeDependencyGraphTarget(dependency.id);
195
228
  if (!target)
196
229
  return [];
230
+ const targetId = isExternalDependencySourceKind(dependency.source_kind)
231
+ ? externalGraphIds.get(target.toLowerCase())
232
+ : canonicalIds.get(target.toLowerCase());
197
233
  return [
198
234
  {
199
- id: canonicalIds.get(target.toLowerCase()),
235
+ id: targetId,
200
236
  kind: typeof dependency.kind === "string" ? dependency.kind : "related",
201
237
  },
202
238
  ];
@@ -211,7 +247,13 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
211
247
  };
212
248
  });
213
249
  return {
214
- graph: RelationshipGraph.fromItems([...graphItems, ...missingIds.map((id) => ({ id }))], relationshipRegistry),
250
+ graph: RelationshipGraph.fromItems([
251
+ ...graphItems,
252
+ ...missingIds.map((id) => ({ id })),
253
+ ...externalIds.map((id) => ({
254
+ id: externalGraphIds.get(id.toLowerCase()),
255
+ })),
256
+ ], relationshipRegistry),
215
257
  details: [
216
258
  ...safeItems.map((item) => ({
217
259
  id: item.id.trim(),
@@ -226,6 +268,11 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
226
268
  title: `[missing] ${id}`,
227
269
  status: "missing",
228
270
  })),
271
+ ...externalIds.map((id) => ({
272
+ id: externalGraphIds.get(id.toLowerCase()),
273
+ title: `[external] ${id}`,
274
+ status: "external",
275
+ })),
229
276
  ],
230
277
  missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),
231
278
  dangling,
@@ -233,4 +280,4 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
233
280
  };
234
281
  }
235
282
  //# sourceMappingURL=assembly.js.map
236
- //# debugId=208d0dcd-c6b6-5959-acdb-6969b1005edd
283
+ //# debugId=10d72477-685d-5ee6-8b1c-2b7565f09d81
@@ -1 +1 @@
1
- {"version":3,"file":"assembly.js","sources":["sdk/graph/assembly.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/graph/assembly\n *\n * Builds the shared workspace relationship graph consumed by dependency\n * queries, bounded context packets, impact analysis, and governance audits.\n * Assembly normalizes hierarchy, legacy scalar blockers, and structured\n * dependency edges into one deterministic {@link RelationshipGraph}, classifies\n * dangling references without mutating their holders, and materializes missing\n * endpoints as placeholder nodes so bounded traversals can explain absent work\n * instead of silently dropping it.\n */\nimport type { Dependency, ItemStatus } from \"../../types/index.js\";\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport {\n RelationshipGraph,\n createRelationshipKindRegistry,\n type RelationshipKindRegistry,\n} from \"../relationships.js\";\n\n/** Minimal item shape inspected by dependency-reference governance. */\nexport interface DependencyReferenceHolder {\n /** Stable item identifier. */\n id: string;\n /** Lifecycle status used to separate actionable work from historical debt. */\n status: ItemStatus;\n /** Optional hierarchy parent reference. */\n parent?: string;\n /** Optional legacy scalar blocker reference. */\n blocked_by?: string;\n /** Structured dependency edges. */\n dependencies?: Dependency[];\n}\n\n/** Storage surface that contributed a normalized dependency reference. */\nexport type DependencyReferenceSource = \"parent\" | \"blocked_by\" | \"dependency\";\n\n/** One normalized dependency reference whose target is absent from the tracker. */\nexport interface DanglingDependencyReference {\n /** Item that owns the reference. */\n holder_id: string;\n /** Missing referenced item id or legacy sentinel. */\n target_id: string;\n /** Relationship field or dependency kind. */\n kind: string;\n /** Storage surface that owns the reference and determines its remediation. */\n source: DependencyReferenceSource;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and therefore historical, non-actionable debt. */\n legacy_terminal: boolean;\n /** Whether the target is the pre-structured-dependency `no-active-blocker` sentinel. */\n no_active_blocker_sentinel: boolean;\n}\n\n/** Actionable and historical partitions returned by dependency-reference governance. */\nexport interface DanglingDependencyReferenceSummary {\n /** Missing references held by active items; these may affect scheduling and should gate validation. */\n active: DanglingDependencyReference[];\n /** Missing references held only by terminal items; retained as informational history debt. */\n legacy_terminal: DanglingDependencyReference[];\n /** Legacy sentinel rows across active and terminal holders, called out separately from typo-like ids. */\n no_active_blocker_sentinels: DanglingDependencyReference[];\n}\n\n/** Normalize a decoded reference target and reject empty legacy placeholders. */\nfunction normalizeDependencyReferenceTarget(\n target: unknown,\n): string | undefined {\n if (typeof target !== \"string\") return undefined;\n const normalized = target.trim();\n if (\n !normalized ||\n [\"none\", \"null\", \"n/a\", \"na\"].includes(normalized.toLowerCase())\n )\n return undefined;\n return normalized;\n}\n\n/** Normalize a graph target while removing the historical no-blocker marker. */\nexport function normalizeDependencyGraphTarget(\n target: unknown,\n): string | undefined {\n const normalized = normalizeDependencyReferenceTarget(target);\n return normalized?.toLowerCase() === \"no-active-blocker\"\n ? undefined\n : normalized;\n}\n\n/**\n * Resolve the default workspace relationship-kind registry: the built-in kinds\n * merged with every active extension-contributed relationship-kind\n * registration. Assembly, mutation advisories, and standalone graph consumers\n * share this resolution so custom ordering semantics apply identically on\n * every surface.\n */\nexport function resolveWorkspaceRelationshipKindRegistry(): RelationshipKindRegistry {\n const registry = createRelationshipKindRegistry();\n for (const registration of getActiveExtensionRegistrations()\n ?.relationship_kinds ?? []) {\n for (const definition of registration.definitions) {\n registry.register(definition);\n }\n }\n return registry;\n}\n\n/** One raw stored dependency row duplicated verbatim on a single holder. */\nexport interface DuplicateDependencyRow {\n /** Item that stores the duplicated row. */\n holder_id: string;\n /** Referenced target id in its first stored spelling. */\n target_id: string;\n /** Stored relationship kind shared by every duplicate occurrence. */\n kind: string;\n /** Total stored occurrences of the identical row (always >= 2). */\n occurrences: number;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and the duplication is historical debt. */\n legacy_terminal: boolean;\n}\n\n/** Compare text case-insensitively with an exact-spelling deterministic tie-breaker. */\nfunction compareCaseFoldedText(left: string, right: string): number {\n const normalizedLeft = left.toLowerCase();\n const normalizedRight = right.toLowerCase();\n if (normalizedLeft !== normalizedRight)\n return normalizedLeft < normalizedRight ? -1 : 1;\n if (left !== right) return left < right ? -1 : 1;\n return 0;\n}\n\n/** Count one holder's dependency rows by their case-insensitive kind-plus-target identity. */\nfunction countDependencyRowIdentities(\n item: DependencyReferenceHolder,\n): Map<string, { target_id: string; kind: string; count: number }> {\n const occurrences = new Map<\n string,\n { target_id: string; kind: string; count: number }\n >();\n for (const dependency of item.dependencies ?? []) {\n if (typeof dependency !== \"object\" || dependency === null) continue;\n const legacyDependency = dependency as Partial<Dependency>;\n const target = normalizeDependencyReferenceTarget(legacyDependency.id);\n if (!target) continue;\n const kind =\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\";\n const key = `${kind}\\u0000${target.toLowerCase()}`;\n const existing = occurrences.get(key);\n if (existing) existing.count += 1;\n else occurrences.set(key, { target_id: target, kind, count: 1 });\n }\n return occurrences;\n}\n\n/**\n * Collect raw stored dependency rows whose exact identity — holder, kind, and\n * case-insensitive target — appears more than once on one item. Graph\n * construction deduplicates these by edge identity, so the assembled graph and\n * every projection built on it cannot see them; this pre-assembly scan is the\n * only surface that reports the storage-layer defect.\n */\nexport function collectDuplicateDependencyRows(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DuplicateDependencyRow[] {\n const rows: DuplicateDependencyRow[] = [];\n for (const item of items) {\n if (typeof item?.id !== \"string\" || item.id.trim().length === 0) continue;\n for (const entry of countDependencyRowIdentities(item).values()) {\n if (entry.count < 2) continue;\n rows.push({\n holder_id: item.id.trim(),\n target_id: entry.target_id,\n kind: entry.kind,\n occurrences: entry.count,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n });\n }\n }\n return rows.sort((left, right) => {\n const holderCompare = compareCaseFoldedText(\n left.holder_id,\n right.holder_id,\n );\n if (holderCompare !== 0) return holderCompare;\n const targetCompare = compareCaseFoldedText(\n left.target_id,\n right.target_id,\n );\n if (targetCompare !== 0) return targetCompare;\n return compareCaseFoldedText(left.kind, right.kind);\n });\n}\n\n/**\n * Classify missing hierarchy and dependency targets without mutating their holders.\n *\n * Consumers provide the workspace's terminal-status predicate so custom lifecycle\n * schemas receive the same active-versus-historical behavior as the built-in\n * closed/canceled statuses.\n */\nexport function collectDanglingDependencyReferences(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DanglingDependencyReferenceSummary {\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const knownIds = new Set(\n safeItems.map((item) => item.id.trim().toLowerCase()),\n );\n const rows = new Map<string, DanglingDependencyReference>();\n const addReference = (\n item: DependencyReferenceHolder,\n target: unknown,\n kind: string,\n source: DependencyReferenceSource,\n ): void => {\n const normalized = normalizeDependencyReferenceTarget(target);\n if (!normalized || knownIds.has(normalized.toLowerCase())) {\n return;\n }\n const row: DanglingDependencyReference = {\n holder_id: item.id.trim(),\n target_id: normalized,\n kind,\n source,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n no_active_blocker_sentinel:\n normalized.toLowerCase() === \"no-active-blocker\",\n };\n rows.set(\n `${row.holder_id}::${row.target_id}::${row.kind}::${row.source}`,\n row,\n );\n };\n for (const item of safeItems) {\n addReference(item, item.parent, \"parent\", \"parent\");\n addReference(item, item.blocked_by, \"blocked_by\", \"blocked_by\");\n for (const dependency of item.dependencies ?? []) {\n // Public SDK callers may supply legacy or JSON-decoded payloads that do\n // not yet satisfy the current structured dependency contract.\n if (typeof dependency !== \"object\" || dependency === null) {\n continue;\n }\n const legacyDependency = dependency as Partial<Dependency>;\n addReference(\n item,\n legacyDependency.id,\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\",\n \"dependency\",\n );\n }\n }\n const sorted = [...rows.values()].sort(\n (left, right) =>\n left.holder_id.localeCompare(right.holder_id) ||\n left.target_id.localeCompare(right.target_id) ||\n left.kind.localeCompare(right.kind) ||\n left.source.localeCompare(right.source),\n );\n const legacyTerminal = sorted.filter((row) => row.legacy_terminal);\n return {\n active: sorted.filter((row) => !row.legacy_terminal),\n legacy_terminal: legacyTerminal,\n no_active_blocker_sentinels: sorted.filter(\n (row) => row.no_active_blocker_sentinel,\n ),\n };\n}\n\n/** Return unique real missing targets while excluding the legacy no-blocker sentinel. */\nexport function collectMissingDependencyTargetIds(\n dangling: DanglingDependencyReferenceSummary,\n): string[] {\n const targets = new Map<string, string>();\n for (const reference of [...dangling.active, ...dangling.legacy_terminal]) {\n if (reference.no_active_blocker_sentinel) continue;\n const target = reference.target_id.trim();\n const key = target.toLowerCase();\n if (!targets.has(key)) targets.set(key, target);\n }\n return [...targets.values()].sort((left, right) => left.localeCompare(right));\n}\n\n/** Item shape accepted by workspace relationship-graph assembly. */\nexport interface WorkspaceRelationshipItem extends DependencyReferenceHolder {\n /** Human-readable title projected into per-node details. */\n title: string;\n /** Optional item type powering per-type coverage profiles and policies. */\n type?: string;\n}\n\n/** Compact node projection paired with the assembled graph. */\nexport interface WorkspaceRelationshipNodeDetails {\n /** Stable node identifier. */\n id: string;\n /** Human-readable node title, or a `[missing]` marker for absent endpoints. */\n title: string;\n /** Lifecycle status, or the `missing` marker status for absent endpoints. */\n status: string;\n /** Item type when the source item declared one; absent on missing placeholders. */\n type?: string;\n}\n\n/** Assembled workspace relationship graph with governance side-products. */\nexport interface WorkspaceRelationshipAssembly {\n /** Deterministic relationship graph including missing placeholder nodes. */\n graph: RelationshipGraph;\n /** Per-node compact details covering real and missing nodes. */\n details: WorkspaceRelationshipNodeDetails[];\n /** Lowercased identifiers of materialized missing endpoints. */\n missingIdSet: Set<string>;\n /** Dangling-reference classification computed during assembly. */\n dangling: DanglingDependencyReferenceSummary;\n /** Raw same-identity duplicated dependency rows found before graph dedup. */\n duplicateRows: DuplicateDependencyRow[];\n}\n\n/**\n * Build the shared workspace relationship graph including missing placeholder\n * nodes. One assembly serves every bounded query in an invocation — dependency\n * trees, context packets, impact analysis, path enumeration, and governance\n * audits — so the full-workspace normalization cost is paid once instead of\n * once per query surface.\n */\nexport function assembleWorkspaceRelationshipGraph(\n items: readonly WorkspaceRelationshipItem[],\n isTerminal?: (status: ItemStatus) => boolean,\n registry?: RelationshipKindRegistry,\n): WorkspaceRelationshipAssembly {\n const relationshipRegistry =\n registry ?? resolveWorkspaceRelationshipKindRegistry();\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const canonicalIds = new Map(\n safeItems.map((item) => [item.id.trim().toLowerCase(), item.id.trim()]),\n );\n const dangling = collectDanglingDependencyReferences(safeItems, isTerminal);\n const missingIds = collectMissingDependencyTargetIds(dangling);\n for (const id of missingIds) canonicalIds.set(id.toLowerCase(), id);\n const graphItems = safeItems.map((item) => {\n const parent = normalizeDependencyGraphTarget(item.parent);\n const blocker = normalizeDependencyGraphTarget(item.blocked_by);\n const dependencies = (item.dependencies ?? []).flatMap((rawDependency) => {\n if (typeof rawDependency !== \"object\" || rawDependency === null)\n return [];\n const dependency = rawDependency as Partial<Dependency>;\n const target = normalizeDependencyGraphTarget(dependency.id);\n if (!target) return [];\n return [\n {\n id: canonicalIds.get(target.toLowerCase())!,\n kind:\n typeof dependency.kind === \"string\" ? dependency.kind : \"related\",\n },\n ];\n });\n return {\n id: item.id.trim(),\n ...(parent ? { parent: canonicalIds.get(parent.toLowerCase())! } : {}),\n ...(blocker\n ? { blocked_by: canonicalIds.get(blocker.toLowerCase())! }\n : {}),\n dependencies,\n };\n });\n return {\n graph: RelationshipGraph.fromItems(\n [...graphItems, ...missingIds.map((id) => ({ id }))],\n relationshipRegistry,\n ),\n details: [\n ...safeItems.map((item) => ({\n id: item.id.trim(),\n title: item.title,\n status: item.status,\n ...(typeof item.type === \"string\" && item.type.trim().length > 0\n ? { type: item.type.trim() }\n : {}),\n })),\n ...missingIds.map((id) => ({\n id,\n title: `[missing] ${id}`,\n status: \"missing\",\n })),\n ],\n missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),\n dangling,\n duplicateRows: collectDuplicateDependencyRows(safeItems, isTerminal),\n };\n}\n"],"names":[],"mappings":"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","debugId":"208d0dcd-c6b6-5959-acdb-6969b1005edd"}
1
+ {"version":3,"file":"assembly.js","sources":["sdk/graph/assembly.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/graph/assembly\n *\n * Builds the shared workspace relationship graph consumed by dependency\n * queries, bounded context packets, impact analysis, and governance audits.\n * Assembly normalizes hierarchy, legacy scalar blockers, and structured\n * dependency edges into one deterministic {@link RelationshipGraph}, classifies\n * dangling references without mutating their holders, and materializes missing\n * endpoints as placeholder nodes so bounded traversals can explain absent work\n * instead of silently dropping it.\n */\nimport type { Dependency, ItemStatus } from \"../../types/index.js\";\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport {\n RelationshipGraph,\n createRelationshipKindRegistry,\n type RelationshipKindRegistry,\n} from \"../relationships.js\";\nimport { isExternalDependencySourceKind } from \"../dependency-provenance.js\";\n\n/** Minimal item shape inspected by dependency-reference governance. */\nexport interface DependencyReferenceHolder {\n /** Stable item identifier. */\n id: string;\n /** Lifecycle status used to separate actionable work from historical debt. */\n status: ItemStatus;\n /** Optional hierarchy parent reference. */\n parent?: string;\n /** Optional legacy scalar blocker reference. */\n blocked_by?: string;\n /** Structured dependency edges. */\n dependencies?: Dependency[];\n}\n\n/** Storage surface that contributed a normalized dependency reference. */\nexport type DependencyReferenceSource = \"parent\" | \"blocked_by\" | \"dependency\";\n\n/** One normalized dependency reference whose target is absent from the tracker. */\nexport interface DanglingDependencyReference {\n /** Item that owns the reference. */\n holder_id: string;\n /** Missing referenced item id or legacy sentinel. */\n target_id: string;\n /** Relationship field or dependency kind. */\n kind: string;\n /** Storage surface that owns the reference and determines its remediation. */\n source: DependencyReferenceSource;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and therefore historical, non-actionable debt. */\n legacy_terminal: boolean;\n /** Whether the target is the pre-structured-dependency `no-active-blocker` sentinel. */\n no_active_blocker_sentinel: boolean;\n}\n\n/** Actionable and historical partitions returned by dependency-reference governance. */\nexport interface DanglingDependencyReferenceSummary {\n /** Missing references held by active items; these may affect scheduling and should gate validation. */\n active: DanglingDependencyReference[];\n /** Missing references held only by terminal items; retained as informational history debt. */\n legacy_terminal: DanglingDependencyReference[];\n /** Legacy sentinel rows across active and terminal holders, called out separately from typo-like ids. */\n no_active_blocker_sentinels: DanglingDependencyReference[];\n}\n\n/** Normalize a decoded reference target and reject empty legacy placeholders. */\nfunction normalizeDependencyReferenceTarget(\n target: unknown,\n): string | undefined {\n if (typeof target !== \"string\") return undefined;\n const normalized = target.trim();\n if (\n !normalized ||\n [\"none\", \"null\", \"n/a\", \"na\"].includes(normalized.toLowerCase())\n )\n return undefined;\n return normalized;\n}\n\n/** Normalize a graph target while removing the historical no-blocker marker. */\nexport function normalizeDependencyGraphTarget(\n target: unknown,\n): string | undefined {\n const normalized = normalizeDependencyReferenceTarget(target);\n return normalized?.toLowerCase() === \"no-active-blocker\"\n ? undefined\n : normalized;\n}\n\n/**\n * Resolve the default workspace relationship-kind registry: the built-in kinds\n * merged with every active extension-contributed relationship-kind\n * registration. Assembly, mutation advisories, and standalone graph consumers\n * share this resolution so custom ordering semantics apply identically on\n * every surface.\n */\nexport function resolveWorkspaceRelationshipKindRegistry(): RelationshipKindRegistry {\n const registry = createRelationshipKindRegistry();\n for (const registration of getActiveExtensionRegistrations()\n ?.relationship_kinds ?? []) {\n for (const definition of registration.definitions) {\n registry.register(definition);\n }\n }\n return registry;\n}\n\n/** One raw stored dependency row duplicated verbatim on a single holder. */\nexport interface DuplicateDependencyRow {\n /** Item that stores the duplicated row. */\n holder_id: string;\n /** Referenced target id in its first stored spelling. */\n target_id: string;\n /** Stored relationship kind shared by every duplicate occurrence. */\n kind: string;\n /** Total stored occurrences of the identical row (always >= 2). */\n occurrences: number;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and the duplication is historical debt. */\n legacy_terminal: boolean;\n}\n\n/** Compare text case-insensitively with an exact-spelling deterministic tie-breaker. */\nfunction compareCaseFoldedText(left: string, right: string): number {\n const normalizedLeft = left.toLowerCase();\n const normalizedRight = right.toLowerCase();\n if (normalizedLeft !== normalizedRight)\n return normalizedLeft < normalizedRight ? -1 : 1;\n if (left !== right) return left < right ? -1 : 1;\n return 0;\n}\n\n/** Count one holder's dependency rows by their case-insensitive kind-plus-target identity. */\nfunction countDependencyRowIdentities(\n item: DependencyReferenceHolder,\n): Map<string, { target_id: string; kind: string; count: number }> {\n const occurrences = new Map<\n string,\n { target_id: string; kind: string; count: number }\n >();\n for (const dependency of item.dependencies ?? []) {\n if (typeof dependency !== \"object\" || dependency === null) continue;\n const legacyDependency = dependency as Partial<Dependency>;\n const target = normalizeDependencyReferenceTarget(legacyDependency.id);\n if (!target) continue;\n const kind =\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\";\n const key = `${kind}\\u0000${target.toLowerCase()}`;\n const existing = occurrences.get(key);\n if (existing) existing.count += 1;\n else occurrences.set(key, { target_id: target, kind, count: 1 });\n }\n return occurrences;\n}\n\n/**\n * Collect raw stored dependency rows whose exact identity — holder, kind, and\n * case-insensitive target — appears more than once on one item. Graph\n * construction deduplicates these by edge identity, so the assembled graph and\n * every projection built on it cannot see them; this pre-assembly scan is the\n * only surface that reports the storage-layer defect.\n */\nexport function collectDuplicateDependencyRows(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DuplicateDependencyRow[] {\n const rows: DuplicateDependencyRow[] = [];\n for (const item of items) {\n if (typeof item?.id !== \"string\" || item.id.trim().length === 0) continue;\n for (const entry of countDependencyRowIdentities(item).values()) {\n if (entry.count < 2) continue;\n rows.push({\n holder_id: item.id.trim(),\n target_id: entry.target_id,\n kind: entry.kind,\n occurrences: entry.count,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n });\n }\n }\n return rows.sort((left, right) => {\n const holderCompare = compareCaseFoldedText(\n left.holder_id,\n right.holder_id,\n );\n if (holderCompare !== 0) return holderCompare;\n const targetCompare = compareCaseFoldedText(\n left.target_id,\n right.target_id,\n );\n if (targetCompare !== 0) return targetCompare;\n return compareCaseFoldedText(left.kind, right.kind);\n });\n}\n\n/**\n * Classify missing hierarchy and dependency targets without mutating their holders.\n *\n * Consumers provide the workspace's terminal-status predicate so custom lifecycle\n * schemas receive the same active-versus-historical behavior as the built-in\n * closed/canceled statuses.\n */\nexport function collectDanglingDependencyReferences(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DanglingDependencyReferenceSummary {\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const knownIds = new Set(\n safeItems.map((item) => item.id.trim().toLowerCase()),\n );\n const rows = new Map<string, DanglingDependencyReference>();\n const addReference = (\n item: DependencyReferenceHolder,\n target: unknown,\n kind: string,\n source: DependencyReferenceSource,\n ): void => {\n const normalized = normalizeDependencyReferenceTarget(target);\n if (!normalized || knownIds.has(normalized.toLowerCase())) {\n return;\n }\n const row: DanglingDependencyReference = {\n holder_id: item.id.trim(),\n target_id: normalized,\n kind,\n source,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n no_active_blocker_sentinel:\n normalized.toLowerCase() === \"no-active-blocker\",\n };\n rows.set(\n `${row.holder_id}::${row.target_id}::${row.kind}::${row.source}`,\n row,\n );\n };\n for (const item of safeItems) {\n addReference(item, item.parent, \"parent\", \"parent\");\n addReference(item, item.blocked_by, \"blocked_by\", \"blocked_by\");\n for (const dependency of item.dependencies ?? []) {\n // Public SDK callers may supply legacy or JSON-decoded payloads that do\n // not yet satisfy the current structured dependency contract.\n if (typeof dependency !== \"object\" || dependency === null) {\n continue;\n }\n const legacyDependency = dependency as Partial<Dependency>;\n if (isExternalDependencySourceKind(legacyDependency.source_kind)) {\n continue;\n }\n addReference(\n item,\n legacyDependency.id,\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\",\n \"dependency\",\n );\n }\n }\n const sorted = [...rows.values()].sort(\n (left, right) =>\n left.holder_id.localeCompare(right.holder_id) ||\n left.target_id.localeCompare(right.target_id) ||\n left.kind.localeCompare(right.kind) ||\n left.source.localeCompare(right.source),\n );\n const legacyTerminal = sorted.filter((row) => row.legacy_terminal);\n return {\n active: sorted.filter((row) => !row.legacy_terminal),\n legacy_terminal: legacyTerminal,\n no_active_blocker_sentinels: sorted.filter(\n (row) => row.no_active_blocker_sentinel,\n ),\n };\n}\n\n/** Return unique real missing targets while excluding the legacy no-blocker sentinel. */\nexport function collectMissingDependencyTargetIds(\n dangling: DanglingDependencyReferenceSummary,\n): string[] {\n const targets = new Map<string, string>();\n for (const reference of [...dangling.active, ...dangling.legacy_terminal]) {\n if (reference.no_active_blocker_sentinel) continue;\n const target = reference.target_id.trim();\n const key = target.toLowerCase();\n if (!targets.has(key)) targets.set(key, target);\n }\n return [...targets.values()].sort((left, right) => left.localeCompare(right));\n}\n\n/** Return unique explicitly external dependency targets in deterministic order. */\nexport function collectExternalDependencyTargetIds(\n items: readonly DependencyReferenceHolder[],\n): string[] {\n const targets = new Map<string, string>();\n for (const item of items) {\n for (const dependency of item.dependencies ?? []) {\n if (\n typeof dependency !== \"object\" ||\n dependency === null ||\n !isExternalDependencySourceKind(dependency.source_kind)\n ) {\n continue;\n }\n const id = normalizeDependencyReferenceTarget(dependency.id);\n if (id && !targets.has(id.toLowerCase())) {\n targets.set(id.toLowerCase(), id);\n }\n }\n }\n return [...targets.values()].sort((left, right) => left.localeCompare(right));\n}\n\n/** Item shape accepted by workspace relationship-graph assembly. */\nexport interface WorkspaceRelationshipItem extends DependencyReferenceHolder {\n /** Human-readable title projected into per-node details. */\n title: string;\n /** Optional item type powering per-type coverage profiles and policies. */\n type?: string;\n}\n\n/** Compact node projection paired with the assembled graph. */\nexport interface WorkspaceRelationshipNodeDetails {\n /** Stable node identifier. */\n id: string;\n /** Human-readable node title, or a `[missing]` marker for absent endpoints. */\n title: string;\n /** Lifecycle status, or the `missing` marker status for absent endpoints. */\n status: string;\n /** Item type when the source item declared one; absent on missing placeholders. */\n type?: string;\n}\n\n/** Assembled workspace relationship graph with governance side-products. */\nexport interface WorkspaceRelationshipAssembly {\n /** Deterministic relationship graph including missing placeholder nodes. */\n graph: RelationshipGraph;\n /** Per-node compact details covering real and missing nodes. */\n details: WorkspaceRelationshipNodeDetails[];\n /** Lowercased identifiers of materialized missing endpoints. */\n missingIdSet: Set<string>;\n /** Dangling-reference classification computed during assembly. */\n dangling: DanglingDependencyReferenceSummary;\n /** Raw same-identity duplicated dependency rows found before graph dedup. */\n duplicateRows: DuplicateDependencyRow[];\n}\n\n/**\n * Build the shared workspace relationship graph including missing placeholder\n * nodes. One assembly serves every bounded query in an invocation — dependency\n * trees, context packets, impact analysis, path enumeration, and governance\n * audits — so the full-workspace normalization cost is paid once instead of\n * once per query surface.\n */\nexport function assembleWorkspaceRelationshipGraph(\n items: readonly WorkspaceRelationshipItem[],\n isTerminal?: (status: ItemStatus) => boolean,\n registry?: RelationshipKindRegistry,\n): WorkspaceRelationshipAssembly {\n const relationshipRegistry =\n registry ?? resolveWorkspaceRelationshipKindRegistry();\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const canonicalIds = new Map(\n safeItems.map((item) => [item.id.trim().toLowerCase(), item.id.trim()]),\n );\n const dangling = collectDanglingDependencyReferences(safeItems, isTerminal);\n const missingIds = collectMissingDependencyTargetIds(dangling);\n for (const id of missingIds) canonicalIds.set(id.toLowerCase(), id);\n const externalIds = collectExternalDependencyTargetIds(safeItems);\n const usedGraphIds = new Set(canonicalIds.keys());\n const externalGraphIds = new Map<string, string>();\n for (const id of externalIds) {\n let graphId = id;\n while (usedGraphIds.has(graphId.toLowerCase())) {\n graphId = `external:${graphId}`;\n }\n externalGraphIds.set(id.toLowerCase(), graphId);\n usedGraphIds.add(graphId.toLowerCase());\n }\n const graphItems = safeItems.map((item) => {\n const parent = normalizeDependencyGraphTarget(item.parent);\n const blocker = normalizeDependencyGraphTarget(item.blocked_by);\n const dependencies = (item.dependencies ?? []).flatMap((rawDependency) => {\n if (typeof rawDependency !== \"object\" || rawDependency === null)\n return [];\n const dependency = rawDependency as Partial<Dependency>;\n const target = normalizeDependencyGraphTarget(dependency.id);\n if (!target) return [];\n const targetId = isExternalDependencySourceKind(dependency.source_kind)\n ? externalGraphIds.get(target.toLowerCase())!\n : canonicalIds.get(target.toLowerCase())!;\n return [\n {\n id: targetId,\n kind:\n typeof dependency.kind === \"string\" ? dependency.kind : \"related\",\n },\n ];\n });\n return {\n id: item.id.trim(),\n ...(parent ? { parent: canonicalIds.get(parent.toLowerCase())! } : {}),\n ...(blocker\n ? { blocked_by: canonicalIds.get(blocker.toLowerCase())! }\n : {}),\n dependencies,\n };\n });\n return {\n graph: RelationshipGraph.fromItems(\n [\n ...graphItems,\n ...missingIds.map((id) => ({ id })),\n ...externalIds.map((id) => ({\n id: externalGraphIds.get(id.toLowerCase())!,\n })),\n ],\n relationshipRegistry,\n ),\n details: [\n ...safeItems.map((item) => ({\n id: item.id.trim(),\n title: item.title,\n status: item.status,\n ...(typeof item.type === \"string\" && item.type.trim().length > 0\n ? { type: item.type.trim() }\n : {}),\n })),\n ...missingIds.map((id) => ({\n id,\n title: `[missing] ${id}`,\n status: \"missing\",\n })),\n ...externalIds.map((id) => ({\n id: externalGraphIds.get(id.toLowerCase())!,\n title: `[external] ${id}`,\n status: \"external\",\n })),\n ],\n missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),\n dangling,\n duplicateRows: collectDuplicateDependencyRows(safeItems, isTerminal),\n };\n}\n"],"names":[],"mappings":"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","debugId":"10d72477-685d-5ee6-8b1c-2b7565f09d81"}