@unbrained/pm-cli 2026.7.20 → 2026.7.21

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 (421) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +11 -0
  3. package/dist/cli/commander-usage.d.ts +1 -1
  4. package/dist/cli/commander-usage.js +5 -5
  5. package/dist/cli/commander-usage.js.map +1 -1
  6. package/dist/cli/commands/completion.js +13 -5
  7. package/dist/cli/commands/completion.js.map +1 -1
  8. package/dist/cli/commands/contracts.js +4 -3
  9. package/dist/cli/commands/contracts.js.map +1 -1
  10. package/dist/cli/error-guidance.d.ts +2 -0
  11. package/dist/cli/error-guidance.js +7 -2
  12. package/dist/cli/error-guidance.js.map +1 -1
  13. package/dist/cli/main.d.ts +1 -5
  14. package/dist/cli/main.js +12 -50
  15. package/dist/cli/main.js.map +1 -1
  16. package/dist/cli/register-list-query.js +13 -3
  17. package/dist/cli/register-list-query.js.map +1 -1
  18. package/dist/cli/register-mutation.js +45 -3
  19. package/dist/cli/register-mutation.js.map +1 -1
  20. package/dist/cli/register-structured-mutation.d.ts +14 -0
  21. package/dist/cli/register-structured-mutation.js +62 -0
  22. package/dist/cli/register-structured-mutation.js.map +1 -0
  23. package/dist/cli/registration-helpers.js +5 -3
  24. package/dist/cli/registration-helpers.js.map +1 -1
  25. package/dist/cli-bundle/bundle-manifest.json +280 -296
  26. package/dist/cli-bundle/chunks/{append-E6V54WOQ.js → append-7OVFYR3C.js} +3 -3
  27. package/dist/cli-bundle/chunks/{append-NNJ3EFIT.js → append-DFETHAZL.js} +3 -3
  28. package/dist/cli-bundle/chunks/{chunk-C3KD7U3T.js → chunk-2L6ZP22J.js} +241 -10
  29. package/dist/cli-bundle/chunks/chunk-2L6ZP22J.js.map +7 -0
  30. package/dist/cli-bundle/chunks/{chunk-KZEANWJS.js → chunk-4PUUNQDV.js} +98 -30
  31. package/dist/cli-bundle/chunks/chunk-4PUUNQDV.js.map +7 -0
  32. package/dist/cli-bundle/chunks/{chunk-RDV4ZFYS.js → chunk-4QOB7L7I.js} +7 -9
  33. package/dist/cli-bundle/chunks/{chunk-RDV4ZFYS.js.map → chunk-4QOB7L7I.js.map} +1 -1
  34. package/dist/cli-bundle/chunks/{chunk-3LPFHE3P.js → chunk-4QSQ6XDK.js} +62 -20
  35. package/dist/cli-bundle/chunks/chunk-4QSQ6XDK.js.map +1 -0
  36. package/dist/cli-bundle/chunks/{chunk-QJKL5PHS.js → chunk-7656MAUL.js} +2 -2
  37. package/dist/cli-bundle/chunks/{chunk-3AO5VSDR.js → chunk-7RW4JCU2.js} +328 -6
  38. package/dist/cli-bundle/chunks/chunk-7RW4JCU2.js.map +7 -0
  39. package/dist/cli-bundle/chunks/{chunk-X6K5XTTN.js → chunk-7W2UAXXT.js} +5 -5
  40. package/dist/cli-bundle/chunks/{chunk-SSKOQNMS.js → chunk-ABWCF646.js} +9 -11
  41. package/dist/cli-bundle/chunks/{chunk-SSKOQNMS.js.map → chunk-ABWCF646.js.map} +1 -1
  42. package/dist/cli-bundle/chunks/{chunk-WVA4DVNV.js → chunk-ADBTSVGK.js} +71 -33
  43. package/dist/cli-bundle/chunks/chunk-ADBTSVGK.js.map +7 -0
  44. package/dist/cli-bundle/chunks/{chunk-J4FBIFU6.js → chunk-AELMUANP.js} +12 -6
  45. package/dist/cli-bundle/chunks/chunk-AELMUANP.js.map +1 -0
  46. package/dist/cli-bundle/chunks/{chunk-4F6BWJ4J.js → chunk-AMJPSANK.js} +57 -36
  47. package/dist/cli-bundle/chunks/chunk-AMJPSANK.js.map +7 -0
  48. package/dist/cli-bundle/chunks/{chunk-6VIJ7UA5.js → chunk-AS4SAZ5R.js} +850 -819
  49. package/dist/cli-bundle/chunks/chunk-AS4SAZ5R.js.map +7 -0
  50. package/dist/cli-bundle/chunks/{chunk-SG74J6MV.js → chunk-ATBCUC7Y.js} +574 -5
  51. package/dist/cli-bundle/chunks/chunk-ATBCUC7Y.js.map +1 -0
  52. package/dist/cli-bundle/chunks/{chunk-5OK4UGFV.js → chunk-BXNDKOR2.js} +3 -3
  53. package/dist/cli-bundle/chunks/{chunk-KSPWRNVP.js → chunk-CPX275C6.js} +2 -2
  54. package/dist/cli-bundle/chunks/{chunk-JH2ZSLO3.js → chunk-DZRV2OPA.js} +2 -2
  55. package/dist/cli-bundle/chunks/{chunk-L7BH7IWU.js → chunk-E5XMKOSB.js} +2 -2
  56. package/dist/cli-bundle/chunks/{chunk-CQTQKUUV.js → chunk-EWJWSNRU.js} +3 -3
  57. package/dist/cli-bundle/chunks/{chunk-DAQ45GCS.js → chunk-F2LBF7XJ.js} +22 -15
  58. package/dist/cli-bundle/chunks/chunk-F2LBF7XJ.js.map +7 -0
  59. package/dist/cli-bundle/chunks/{chunk-6XMUURSS.js → chunk-FJIFFBJX.js} +64 -33
  60. package/dist/cli-bundle/chunks/chunk-FJIFFBJX.js.map +1 -0
  61. package/dist/cli-bundle/chunks/{chunk-E7ICD63T.js → chunk-FO6OSVEN.js} +4 -6
  62. package/dist/cli-bundle/chunks/{chunk-E7ICD63T.js.map → chunk-FO6OSVEN.js.map} +1 -1
  63. package/dist/cli-bundle/chunks/{chunk-3MCTMJXI.js → chunk-FPBMLYPI.js} +2 -2
  64. package/dist/cli-bundle/chunks/{chunk-UZDQXNUB.js → chunk-FSE2IKJQ.js} +46 -5
  65. package/dist/cli-bundle/chunks/chunk-FSE2IKJQ.js.map +1 -0
  66. package/dist/cli-bundle/chunks/{chunk-IX677TRO.js → chunk-GKX4NJ7U.js} +8 -10
  67. package/dist/cli-bundle/chunks/{chunk-IX677TRO.js.map → chunk-GKX4NJ7U.js.map} +1 -1
  68. package/dist/cli-bundle/chunks/{chunk-DVDBQA3B.js → chunk-GTK4DTEW.js} +5 -5
  69. package/dist/cli-bundle/chunks/chunk-H7EAER5L.js +974 -0
  70. package/dist/cli-bundle/chunks/chunk-H7EAER5L.js.map +1 -0
  71. package/dist/cli-bundle/chunks/{chunk-5UX66S6U.js → chunk-ICDAQ4TD.js} +316 -8
  72. package/dist/cli-bundle/chunks/chunk-ICDAQ4TD.js.map +1 -0
  73. package/dist/cli-bundle/chunks/{chunk-YQQNAKW3.js → chunk-JFD5LPMI.js} +6 -8
  74. package/dist/cli-bundle/chunks/{chunk-YQQNAKW3.js.map → chunk-JFD5LPMI.js.map} +1 -1
  75. package/dist/cli-bundle/chunks/{chunk-QANSTTC7.js → chunk-JXCW2TI2.js} +6 -8
  76. package/dist/cli-bundle/chunks/{chunk-QANSTTC7.js.map → chunk-JXCW2TI2.js.map} +1 -1
  77. package/dist/cli-bundle/chunks/{chunk-GSJSM5BJ.js → chunk-K36WV5J6.js} +76 -13
  78. package/dist/cli-bundle/chunks/chunk-K36WV5J6.js.map +1 -0
  79. package/dist/cli-bundle/chunks/{chunk-GVI6FAFG.js → chunk-K55VMLSS.js} +7 -5
  80. package/dist/cli-bundle/chunks/chunk-K55VMLSS.js.map +7 -0
  81. package/dist/cli-bundle/chunks/{chunk-GIQSU6S2.js → chunk-KBLZ3AA5.js} +2 -2
  82. package/dist/cli-bundle/chunks/{chunk-XJF7CDNH.js → chunk-KH44WBAT.js} +2 -2
  83. package/dist/cli-bundle/chunks/{chunk-GV2262OF.js → chunk-LAV26CQG.js} +2 -2
  84. package/dist/cli-bundle/chunks/{chunk-VDO2JMD4.js → chunk-LVC72YRD.js} +2 -2
  85. package/dist/cli-bundle/chunks/{chunk-3VY6MIEO.js → chunk-LZYP423P.js} +35 -6
  86. package/dist/cli-bundle/chunks/chunk-LZYP423P.js.map +7 -0
  87. package/dist/cli-bundle/chunks/{chunk-ZYPFOO3L.js → chunk-MATHDCGG.js} +3 -3
  88. package/dist/cli-bundle/chunks/{chunk-OV7MSW3I.js → chunk-MWQ2HC2A.js} +99 -31
  89. package/dist/cli-bundle/chunks/chunk-MWQ2HC2A.js.map +1 -0
  90. package/dist/cli-bundle/chunks/{chunk-NHT3F4WZ.js → chunk-NUF7ROFH.js} +840 -816
  91. package/dist/cli-bundle/chunks/chunk-NUF7ROFH.js.map +1 -0
  92. package/dist/cli-bundle/chunks/{chunk-AOEOYL3S.js → chunk-O4BCOJTZ.js} +3 -3
  93. package/dist/cli-bundle/chunks/{chunk-RJO3YAFM.js → chunk-OCUBRA6D.js} +2 -2
  94. package/dist/cli-bundle/chunks/{chunk-5IZJWSDB.js → chunk-OG5DVFMA.js} +22 -15
  95. package/dist/cli-bundle/chunks/chunk-OG5DVFMA.js.map +1 -0
  96. package/dist/cli-bundle/chunks/{chunk-I577UHC7.js → chunk-OR42SO64.js} +2 -2
  97. package/dist/cli-bundle/chunks/{chunk-ZOJ3LR7O.js → chunk-OY7DMU5P.js} +2 -2
  98. package/dist/cli-bundle/chunks/{chunk-HEWM6CEN.js → chunk-P7MTHPJQ.js} +50 -9
  99. package/dist/cli-bundle/chunks/chunk-P7MTHPJQ.js.map +7 -0
  100. package/dist/cli-bundle/chunks/{chunk-2BO4CA46.js → chunk-PFNHX655.js} +236 -12
  101. package/dist/cli-bundle/chunks/{chunk-2BO4CA46.js.map → chunk-PFNHX655.js.map} +1 -1
  102. package/dist/cli-bundle/chunks/{chunk-ZV2NTVMJ.js → chunk-PONKZPCJ.js} +2 -2
  103. package/dist/cli-bundle/chunks/{chunk-THAOZG4U.js → chunk-PQSEQD6E.js} +8 -6
  104. package/dist/cli-bundle/chunks/chunk-PQSEQD6E.js.map +1 -0
  105. package/dist/cli-bundle/chunks/chunk-PWDEHT3L.js +991 -0
  106. package/dist/cli-bundle/chunks/chunk-PWDEHT3L.js.map +7 -0
  107. package/dist/cli-bundle/chunks/{chunk-UX6SSO2I.js → chunk-PZC2FUOQ.js} +2 -2
  108. package/dist/cli-bundle/chunks/{chunk-WUVEBQW6.js → chunk-QG4GFLQ6.js} +3 -5
  109. package/dist/cli-bundle/chunks/{chunk-WUVEBQW6.js.map → chunk-QG4GFLQ6.js.map} +1 -1
  110. package/dist/cli-bundle/chunks/{chunk-VQIHNHMJ.js → chunk-QIH77CAG.js} +2 -2
  111. package/dist/cli-bundle/chunks/{chunk-R3EWPG4A.js → chunk-QJIKE24M.js} +2 -2
  112. package/dist/cli-bundle/chunks/{chunk-QLZ643FM.js → chunk-QOOTOD3W.js} +10 -12
  113. package/dist/cli-bundle/chunks/{chunk-QLZ643FM.js.map → chunk-QOOTOD3W.js.map} +1 -1
  114. package/dist/cli-bundle/chunks/{chunk-MYSS5H2A.js → chunk-R3P6FZJW.js} +5 -7
  115. package/dist/cli-bundle/chunks/{chunk-MYSS5H2A.js.map → chunk-R3P6FZJW.js.map} +1 -1
  116. package/dist/cli-bundle/chunks/{chunk-G3COA6GS.js → chunk-RNPZYNHS.js} +56 -35
  117. package/dist/cli-bundle/chunks/chunk-RNPZYNHS.js.map +1 -0
  118. package/dist/cli-bundle/chunks/{chunk-T44FMVRL.js → chunk-RPESLSO5.js} +62 -20
  119. package/dist/cli-bundle/chunks/chunk-RPESLSO5.js.map +7 -0
  120. package/dist/cli-bundle/chunks/{chunk-INSTSQNZ.js → chunk-SY4SFZSD.js} +595 -3
  121. package/dist/cli-bundle/chunks/chunk-SY4SFZSD.js.map +7 -0
  122. package/dist/cli-bundle/chunks/{chunk-HB3P4M52.js → chunk-TRSHFPRZ.js} +2 -2
  123. package/dist/cli-bundle/chunks/{chunk-HRW7GF6T.js → chunk-UCBDQI5E.js} +2 -2
  124. package/dist/cli-bundle/chunks/{chunk-4U4Z6AHI.js → chunk-V22ZPOKN.js} +2 -2
  125. package/dist/cli-bundle/chunks/{chunk-JM6YAXTR.js → chunk-VHXHVTUU.js} +2 -2
  126. package/dist/cli-bundle/chunks/{chunk-LPEYZRUR.js → chunk-VJQG4BIM.js} +35 -6
  127. package/dist/cli-bundle/chunks/chunk-VJQG4BIM.js.map +1 -0
  128. package/dist/cli-bundle/chunks/{chunk-D6NXDNP3.js → chunk-VLRGDBLY.js} +2 -2
  129. package/dist/cli-bundle/chunks/{chunk-JAPE62Y5.js → chunk-VNTCM3VW.js} +3 -3
  130. package/dist/cli-bundle/chunks/{chunk-FDHPAVVB.js → chunk-VXOOB6YX.js} +2 -2
  131. package/dist/cli-bundle/chunks/{chunk-GFQP7HAZ.js → chunk-VZIZB6QH.js} +3 -5
  132. package/dist/cli-bundle/chunks/{chunk-GFQP7HAZ.js.map → chunk-VZIZB6QH.js.map} +1 -1
  133. package/dist/cli-bundle/chunks/{chunk-HQ3SB4CN.js → chunk-X3W65QK3.js} +2 -2
  134. package/dist/cli-bundle/chunks/{chunk-RZJLNXFG.js → chunk-XJTABV3X.js} +3 -3
  135. package/dist/cli-bundle/chunks/{chunk-GVT754PX.js → chunk-YCIUJJOD.js} +11 -5
  136. package/dist/cli-bundle/chunks/chunk-YCIUJJOD.js.map +7 -0
  137. package/dist/cli-bundle/chunks/{chunk-IJNK6WW2.js → chunk-Z75ONV25.js} +75 -12
  138. package/dist/cli-bundle/chunks/chunk-Z75ONV25.js.map +7 -0
  139. package/dist/cli-bundle/chunks/{chunk-4L23AGQ7.js → chunk-Z7VWXXJM.js} +5 -7
  140. package/dist/cli-bundle/chunks/{chunk-4L23AGQ7.js.map → chunk-Z7VWXXJM.js.map} +1 -1
  141. package/dist/cli-bundle/chunks/{chunk-YBT7O4KT.js → chunk-ZTVA4KLN.js} +4 -6
  142. package/dist/cli-bundle/chunks/{chunk-YBT7O4KT.js.map → chunk-ZTVA4KLN.js.map} +1 -1
  143. package/dist/cli-bundle/chunks/{chunk-TYHJDFYW.js → chunk-ZVZGXPQ5.js} +2 -2
  144. package/dist/cli-bundle/chunks/{close-many-SDA426VT.js → close-many-5RZXVN4J.js} +5 -6
  145. package/dist/cli-bundle/chunks/{close-many-UTZANOCQ.js → close-many-RZVTUGBG.js} +5 -6
  146. package/dist/cli-bundle/chunks/{comments-LZN6FXXC.js → comments-TPU7QRBL.js} +4 -4
  147. package/dist/cli-bundle/chunks/{comments-VBQ345ND.js → comments-Z4KV6FU3.js} +4 -4
  148. package/dist/cli-bundle/chunks/{create-GG4RBCGC.js → create-EIFBIVNQ.js} +6 -6
  149. package/dist/cli-bundle/chunks/{create-JBC5KUW6.js → create-RGSPN5GD.js} +6 -6
  150. package/dist/cli-bundle/chunks/{deps-FI4O6NQS.js → deps-UH5EQQUY.js} +3 -3
  151. package/dist/cli-bundle/chunks/{deps-DELOO4TL.js → deps-YG7UF3VR.js} +3 -3
  152. package/dist/cli-bundle/chunks/{docs-6Z2MP526.js → docs-G32TK6XS.js} +4 -4
  153. package/dist/cli-bundle/chunks/{docs-2UYBP5D6.js → docs-JWWNRC27.js} +4 -4
  154. package/dist/cli-bundle/chunks/{files-HKEAN5MA.js → files-3H32UQ4K.js} +4 -4
  155. package/dist/cli-bundle/chunks/{files-HEUGSJZL.js → files-4ALMCSKB.js} +4 -4
  156. package/dist/cli-bundle/chunks/{history-compact-7NDVP3PT.js → history-compact-77BT2LUB.js} +3 -4
  157. package/dist/cli-bundle/chunks/{history-compact-65YVN5DB.js → history-compact-VCKGTX64.js} +3 -4
  158. package/dist/cli-bundle/chunks/{history-redact-7YBL4XSG.js → history-redact-LJPZPNFA.js} +2 -3
  159. package/dist/cli-bundle/chunks/{history-redact-IZGNJBU4.js → history-redact-PWTTJ3XS.js} +2 -3
  160. package/dist/cli-bundle/chunks/{history-repair-7M4PYQUH.js → history-repair-I7CBNCV3.js} +5 -6
  161. package/dist/cli-bundle/chunks/{history-repair-GNGETJLI.js → history-repair-YTDZRK5E.js} +5 -6
  162. package/dist/cli-bundle/chunks/{learnings-3YXDRWFT.js → learnings-CYNOICKR.js} +4 -4
  163. package/dist/cli-bundle/chunks/{learnings-ALC6IMNL.js → learnings-KTYW3AL7.js} +4 -4
  164. package/dist/cli-bundle/chunks/{notes-7JMLQ447.js → notes-FGO63FXL.js} +4 -4
  165. package/dist/cli-bundle/chunks/{notes-JFCLTC5C.js → notes-ZERD3KB2.js} +4 -4
  166. package/dist/cli-bundle/chunks/{plan-T3XB3WTK.js → plan-OFJUBIM5.js} +7 -7
  167. package/dist/cli-bundle/chunks/{plan-KOIPWVOZ.js → plan-SGCDDTYR.js} +7 -7
  168. package/dist/cli-bundle/chunks/{profile-OILJHKUW.js → profile-3THJPIQY.js} +4 -5
  169. package/dist/cli-bundle/chunks/{profile-RJXA7PGS.js → profile-XEZAMMBW.js} +4 -5
  170. package/dist/cli-bundle/chunks/{register-list-query-CFVG75P3.js → register-list-query-BR435Q2H.js} +19 -16
  171. package/dist/cli-bundle/chunks/register-list-query-BR435Q2H.js.map +1 -0
  172. package/dist/cli-bundle/chunks/{register-list-query-E7UVY4TN.js → register-list-query-RWTWLOBE.js} +18 -15
  173. package/dist/cli-bundle/chunks/register-list-query-RWTWLOBE.js.map +7 -0
  174. package/dist/cli-bundle/chunks/{register-mutation-IQ55E25C.js → register-mutation-HLWC2WNP.js} +167 -31
  175. package/dist/cli-bundle/chunks/register-mutation-HLWC2WNP.js.map +1 -0
  176. package/dist/cli-bundle/chunks/{register-mutation-4VJTXBZW.js → register-mutation-ZJX5AZM5.js} +173 -30
  177. package/dist/cli-bundle/chunks/register-mutation-ZJX5AZM5.js.map +7 -0
  178. package/dist/cli-bundle/chunks/{register-operations-AR7RMX4W.js → register-operations-744YBJMV.js} +23 -25
  179. package/dist/cli-bundle/chunks/{register-operations-AR7RMX4W.js.map → register-operations-744YBJMV.js.map} +1 -1
  180. package/dist/cli-bundle/chunks/{register-operations-NOLZGORC.js → register-operations-UEBJH6AN.js} +21 -23
  181. package/dist/cli-bundle/chunks/{register-operations-NOLZGORC.js.map → register-operations-UEBJH6AN.js.map} +1 -1
  182. package/dist/cli-bundle/chunks/{register-setup-EYZ7VTPZ.js → register-setup-5DA4UZXI.js} +7 -8
  183. package/dist/cli-bundle/chunks/{register-setup-EYZ7VTPZ.js.map → register-setup-5DA4UZXI.js.map} +1 -1
  184. package/dist/cli-bundle/chunks/{register-setup-BB77VUEE.js → register-setup-6H25M3BH.js} +9 -10
  185. package/dist/cli-bundle/chunks/{register-setup-BB77VUEE.js.map → register-setup-6H25M3BH.js.map} +1 -1
  186. package/dist/cli-bundle/chunks/{restore-ZH65GZFB.js → restore-6TDVSATY.js} +4 -5
  187. package/dist/cli-bundle/chunks/{restore-L6IAGOD7.js → restore-RSL7C7LO.js} +4 -5
  188. package/dist/cli-bundle/chunks/{schema-4ERWM5QJ.js → schema-HFXFSGPG.js} +2 -3
  189. package/dist/cli-bundle/chunks/{schema-55DL3Q52.js → schema-TPVTIJPO.js} +2 -3
  190. package/dist/cli-bundle/chunks/{update-FW6FKDOP.js → update-LJZCL5SI.js} +7 -7
  191. package/dist/cli-bundle/chunks/{update-TJHSPRPT.js → update-SIA7LH5Y.js} +7 -7
  192. package/dist/cli-bundle/chunks/{update-many-PWXX5WHO.js → update-many-BDBZVGQL.js} +11 -12
  193. package/dist/cli-bundle/chunks/{update-many-NNALYQCN.js → update-many-MOY3A5B3.js} +11 -12
  194. package/dist/cli-bundle/main.js +60 -85
  195. package/dist/cli-bundle/main.js.map +2 -2
  196. package/dist/cli-bundle/sdk-runtime.js +37 -37
  197. package/dist/cli-bundle/sdk.js +126 -291
  198. package/dist/cli-bundle/sdk.js.map +4 -4
  199. package/dist/core/item/parse.d.ts +1 -1
  200. package/dist/core/item/parse.js +13 -7
  201. package/dist/core/item/parse.js.map +1 -1
  202. package/dist/core/output/mutation-projection.d.ts +2 -0
  203. package/dist/core/output/mutation-projection.js +33 -2
  204. package/dist/core/output/mutation-projection.js.map +1 -1
  205. package/dist/core/output/output.d.ts +4 -0
  206. package/dist/core/output/output.js +18 -13
  207. package/dist/core/output/output.js.map +1 -1
  208. package/dist/core/shared/command-types.d.ts +4 -0
  209. package/dist/core/shared/command-types.js +2 -2
  210. package/dist/core/shared/command-types.js.map +1 -1
  211. package/dist/mcp/server.js +39 -4
  212. package/dist/mcp/server.js.map +1 -1
  213. package/dist/mcp/tool-definitions.js +45 -4
  214. package/dist/mcp/tool-definitions.js.map +1 -1
  215. package/dist/sdk/cli-bootstrap.d.ts +2 -0
  216. package/dist/sdk/cli-bootstrap.js +20 -27
  217. package/dist/sdk/cli-bootstrap.js.map +1 -1
  218. package/dist/sdk/cli-contracts/enum-contracts.d.ts +2 -2
  219. package/dist/sdk/cli-contracts/enum-contracts.js +7 -2
  220. package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
  221. package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
  222. package/dist/sdk/cli-contracts/flag-contracts.js +21 -2
  223. package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
  224. package/dist/sdk/cli-contracts/tool-option-contracts.js +10 -2
  225. package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
  226. package/dist/sdk/cli-contracts/tool-parameter-tables.js +16 -3
  227. package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
  228. package/dist/sdk/cli-contracts/tool-schema.js +6 -2
  229. package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
  230. package/dist/sdk/cli-contracts.d.ts +1 -1
  231. package/dist/sdk/cli-contracts.js +3 -3
  232. package/dist/sdk/cli-contracts.js.map +1 -1
  233. package/dist/sdk/cli-program.js +4 -2
  234. package/dist/sdk/cli-program.js.map +1 -1
  235. package/dist/sdk/dependencies.d.ts +3 -2
  236. package/dist/sdk/dependencies.js +13 -12
  237. package/dist/sdk/dependencies.js.map +1 -1
  238. package/dist/sdk/error-runtime.d.ts +10 -0
  239. package/dist/sdk/error-runtime.js +59 -0
  240. package/dist/sdk/error-runtime.js.map +1 -0
  241. package/dist/sdk/graph/analytics.d.ts +9 -0
  242. package/dist/sdk/graph/analytics.js +24 -13
  243. package/dist/sdk/graph/analytics.js.map +1 -1
  244. package/dist/sdk/graph/assembly.d.ts +39 -0
  245. package/dist/sdk/graph/assembly.js +92 -12
  246. package/dist/sdk/graph/assembly.js.map +1 -1
  247. package/dist/sdk/graph/cache.d.ts +4 -1
  248. package/dist/sdk/graph/cache.js +17 -4
  249. package/dist/sdk/graph/cache.js.map +1 -1
  250. package/dist/sdk/graph/centrality.d.ts +82 -0
  251. package/dist/sdk/graph/centrality.js +259 -0
  252. package/dist/sdk/graph/centrality.js.map +1 -0
  253. package/dist/sdk/graph/durable-cache.d.ts +71 -0
  254. package/dist/sdk/graph/durable-cache.js +205 -0
  255. package/dist/sdk/graph/durable-cache.js.map +1 -0
  256. package/dist/sdk/graph/governance.d.ts +69 -1
  257. package/dist/sdk/graph/governance.js +143 -35
  258. package/dist/sdk/graph/governance.js.map +1 -1
  259. package/dist/sdk/graph/index.d.ts +7 -4
  260. package/dist/sdk/graph/index.js +8 -5
  261. package/dist/sdk/graph/index.js.map +1 -1
  262. package/dist/sdk/graph/mutation-advisory.d.ts +35 -4
  263. package/dist/sdk/graph/mutation-advisory.js +124 -35
  264. package/dist/sdk/graph/mutation-advisory.js.map +1 -1
  265. package/dist/sdk/graph/remediation.js +12 -2
  266. package/dist/sdk/graph/remediation.js.map +1 -1
  267. package/dist/sdk/graph/run.d.ts +133 -2
  268. package/dist/sdk/graph/run.js +217 -8
  269. package/dist/sdk/graph/run.js.map +1 -1
  270. package/dist/sdk/graph/scheduling.d.ts +59 -0
  271. package/dist/sdk/graph/scheduling.js +125 -0
  272. package/dist/sdk/graph/scheduling.js.map +1 -0
  273. package/dist/sdk/graph/traversal.d.ts +11 -0
  274. package/dist/sdk/graph/traversal.js +16 -2
  275. package/dist/sdk/graph/traversal.js.map +1 -1
  276. package/dist/sdk/index.d.ts +4 -0
  277. package/dist/sdk/index.js +6 -2
  278. package/dist/sdk/index.js.map +1 -1
  279. package/dist/sdk/runtime-input.js +7 -2
  280. package/dist/sdk/runtime-input.js.map +1 -1
  281. package/dist/sdk/runtime-primitives.d.ts +10 -0
  282. package/dist/sdk/runtime-primitives.js +14 -0
  283. package/dist/sdk/runtime-primitives.js.map +1 -0
  284. package/dist/sdk/runtime.d.ts +15 -0
  285. package/dist/sdk/runtime.js +16 -3
  286. package/dist/sdk/runtime.js.map +1 -1
  287. package/dist/sdk/structured-mutations.d.ts +21 -0
  288. package/dist/sdk/structured-mutations.js +375 -0
  289. package/dist/sdk/structured-mutations.js.map +1 -0
  290. package/docs/COMMANDS.md +85 -5
  291. package/docs/RELATIONSHIP_GRAPH.md +48 -7
  292. package/docs/SDK.md +78 -3
  293. package/marketplace.json +2 -2
  294. package/package.json +1 -1
  295. package/packages/pm-beads/package.json +1 -1
  296. package/packages/pm-calendar/package.json +1 -1
  297. package/packages/pm-command-kit/package.json +1 -1
  298. package/packages/pm-governance-audit/package.json +1 -1
  299. package/packages/pm-guide-shell/package.json +1 -1
  300. package/packages/pm-kanban/package.json +1 -1
  301. package/packages/pm-lifecycle-hooks/package.json +1 -1
  302. package/packages/pm-linked-test-adapters/package.json +1 -1
  303. package/packages/pm-search-advanced/package.json +1 -1
  304. package/packages/pm-templates/package.json +1 -1
  305. package/packages/pm-todos/package.json +1 -1
  306. package/packages/pm-vcs/package.json +1 -1
  307. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  308. package/plugins/pm-claude/README.md +5 -3
  309. package/plugins/pm-claude/commands/pm-init.md +1 -1
  310. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  311. package/dist/cli-bundle/chunks/chunk-3AO5VSDR.js.map +0 -7
  312. package/dist/cli-bundle/chunks/chunk-3LPFHE3P.js.map +0 -1
  313. package/dist/cli-bundle/chunks/chunk-3VY6MIEO.js.map +0 -7
  314. package/dist/cli-bundle/chunks/chunk-4F6BWJ4J.js.map +0 -7
  315. package/dist/cli-bundle/chunks/chunk-5IZJWSDB.js.map +0 -1
  316. package/dist/cli-bundle/chunks/chunk-5UX66S6U.js.map +0 -1
  317. package/dist/cli-bundle/chunks/chunk-6C2ZZX5Z.js +0 -286
  318. package/dist/cli-bundle/chunks/chunk-6C2ZZX5Z.js.map +0 -1
  319. package/dist/cli-bundle/chunks/chunk-6VIJ7UA5.js.map +0 -7
  320. package/dist/cli-bundle/chunks/chunk-6XMUURSS.js.map +0 -1
  321. package/dist/cli-bundle/chunks/chunk-C3KD7U3T.js.map +0 -7
  322. package/dist/cli-bundle/chunks/chunk-CFHAODHQ.js +0 -334
  323. package/dist/cli-bundle/chunks/chunk-CFHAODHQ.js.map +0 -1
  324. package/dist/cli-bundle/chunks/chunk-DAQ45GCS.js.map +0 -7
  325. package/dist/cli-bundle/chunks/chunk-E6LEMURX.js +0 -249
  326. package/dist/cli-bundle/chunks/chunk-E6LEMURX.js.map +0 -7
  327. package/dist/cli-bundle/chunks/chunk-G3COA6GS.js.map +0 -1
  328. package/dist/cli-bundle/chunks/chunk-GSJSM5BJ.js.map +0 -1
  329. package/dist/cli-bundle/chunks/chunk-GVI6FAFG.js.map +0 -7
  330. package/dist/cli-bundle/chunks/chunk-GVT754PX.js.map +0 -7
  331. package/dist/cli-bundle/chunks/chunk-HEWM6CEN.js.map +0 -7
  332. package/dist/cli-bundle/chunks/chunk-IJNK6WW2.js.map +0 -7
  333. package/dist/cli-bundle/chunks/chunk-INSTSQNZ.js.map +0 -7
  334. package/dist/cli-bundle/chunks/chunk-J4FBIFU6.js.map +0 -1
  335. package/dist/cli-bundle/chunks/chunk-KZEANWJS.js.map +0 -7
  336. package/dist/cli-bundle/chunks/chunk-LPEYZRUR.js.map +0 -1
  337. package/dist/cli-bundle/chunks/chunk-NHT3F4WZ.js.map +0 -1
  338. package/dist/cli-bundle/chunks/chunk-OV7MSW3I.js.map +0 -1
  339. package/dist/cli-bundle/chunks/chunk-P7JTWYLH.js +0 -246
  340. package/dist/cli-bundle/chunks/chunk-P7JTWYLH.js.map +0 -1
  341. package/dist/cli-bundle/chunks/chunk-R5U2VZ3K.js +0 -344
  342. package/dist/cli-bundle/chunks/chunk-R5U2VZ3K.js.map +0 -7
  343. package/dist/cli-bundle/chunks/chunk-SG74J6MV.js.map +0 -1
  344. package/dist/cli-bundle/chunks/chunk-T44FMVRL.js.map +0 -7
  345. package/dist/cli-bundle/chunks/chunk-THAOZG4U.js.map +0 -1
  346. package/dist/cli-bundle/chunks/chunk-UQLXSG72.js +0 -289
  347. package/dist/cli-bundle/chunks/chunk-UQLXSG72.js.map +0 -7
  348. package/dist/cli-bundle/chunks/chunk-UZDQXNUB.js.map +0 -1
  349. package/dist/cli-bundle/chunks/chunk-WVA4DVNV.js.map +0 -7
  350. package/dist/cli-bundle/chunks/register-list-query-CFVG75P3.js.map +0 -1
  351. package/dist/cli-bundle/chunks/register-list-query-E7UVY4TN.js.map +0 -7
  352. package/dist/cli-bundle/chunks/register-mutation-4VJTXBZW.js.map +0 -7
  353. package/dist/cli-bundle/chunks/register-mutation-IQ55E25C.js.map +0 -1
  354. /package/dist/cli-bundle/chunks/{append-E6V54WOQ.js.map → append-7OVFYR3C.js.map} +0 -0
  355. /package/dist/cli-bundle/chunks/{append-NNJ3EFIT.js.map → append-DFETHAZL.js.map} +0 -0
  356. /package/dist/cli-bundle/chunks/{chunk-QJKL5PHS.js.map → chunk-7656MAUL.js.map} +0 -0
  357. /package/dist/cli-bundle/chunks/{chunk-X6K5XTTN.js.map → chunk-7W2UAXXT.js.map} +0 -0
  358. /package/dist/cli-bundle/chunks/{chunk-5OK4UGFV.js.map → chunk-BXNDKOR2.js.map} +0 -0
  359. /package/dist/cli-bundle/chunks/{chunk-KSPWRNVP.js.map → chunk-CPX275C6.js.map} +0 -0
  360. /package/dist/cli-bundle/chunks/{chunk-JH2ZSLO3.js.map → chunk-DZRV2OPA.js.map} +0 -0
  361. /package/dist/cli-bundle/chunks/{chunk-L7BH7IWU.js.map → chunk-E5XMKOSB.js.map} +0 -0
  362. /package/dist/cli-bundle/chunks/{chunk-CQTQKUUV.js.map → chunk-EWJWSNRU.js.map} +0 -0
  363. /package/dist/cli-bundle/chunks/{chunk-3MCTMJXI.js.map → chunk-FPBMLYPI.js.map} +0 -0
  364. /package/dist/cli-bundle/chunks/{chunk-DVDBQA3B.js.map → chunk-GTK4DTEW.js.map} +0 -0
  365. /package/dist/cli-bundle/chunks/{chunk-GIQSU6S2.js.map → chunk-KBLZ3AA5.js.map} +0 -0
  366. /package/dist/cli-bundle/chunks/{chunk-XJF7CDNH.js.map → chunk-KH44WBAT.js.map} +0 -0
  367. /package/dist/cli-bundle/chunks/{chunk-GV2262OF.js.map → chunk-LAV26CQG.js.map} +0 -0
  368. /package/dist/cli-bundle/chunks/{chunk-VDO2JMD4.js.map → chunk-LVC72YRD.js.map} +0 -0
  369. /package/dist/cli-bundle/chunks/{chunk-ZYPFOO3L.js.map → chunk-MATHDCGG.js.map} +0 -0
  370. /package/dist/cli-bundle/chunks/{chunk-AOEOYL3S.js.map → chunk-O4BCOJTZ.js.map} +0 -0
  371. /package/dist/cli-bundle/chunks/{chunk-RJO3YAFM.js.map → chunk-OCUBRA6D.js.map} +0 -0
  372. /package/dist/cli-bundle/chunks/{chunk-I577UHC7.js.map → chunk-OR42SO64.js.map} +0 -0
  373. /package/dist/cli-bundle/chunks/{chunk-ZOJ3LR7O.js.map → chunk-OY7DMU5P.js.map} +0 -0
  374. /package/dist/cli-bundle/chunks/{chunk-ZV2NTVMJ.js.map → chunk-PONKZPCJ.js.map} +0 -0
  375. /package/dist/cli-bundle/chunks/{chunk-UX6SSO2I.js.map → chunk-PZC2FUOQ.js.map} +0 -0
  376. /package/dist/cli-bundle/chunks/{chunk-VQIHNHMJ.js.map → chunk-QIH77CAG.js.map} +0 -0
  377. /package/dist/cli-bundle/chunks/{chunk-R3EWPG4A.js.map → chunk-QJIKE24M.js.map} +0 -0
  378. /package/dist/cli-bundle/chunks/{chunk-HB3P4M52.js.map → chunk-TRSHFPRZ.js.map} +0 -0
  379. /package/dist/cli-bundle/chunks/{chunk-HRW7GF6T.js.map → chunk-UCBDQI5E.js.map} +0 -0
  380. /package/dist/cli-bundle/chunks/{chunk-4U4Z6AHI.js.map → chunk-V22ZPOKN.js.map} +0 -0
  381. /package/dist/cli-bundle/chunks/{chunk-JM6YAXTR.js.map → chunk-VHXHVTUU.js.map} +0 -0
  382. /package/dist/cli-bundle/chunks/{chunk-D6NXDNP3.js.map → chunk-VLRGDBLY.js.map} +0 -0
  383. /package/dist/cli-bundle/chunks/{chunk-JAPE62Y5.js.map → chunk-VNTCM3VW.js.map} +0 -0
  384. /package/dist/cli-bundle/chunks/{chunk-FDHPAVVB.js.map → chunk-VXOOB6YX.js.map} +0 -0
  385. /package/dist/cli-bundle/chunks/{chunk-HQ3SB4CN.js.map → chunk-X3W65QK3.js.map} +0 -0
  386. /package/dist/cli-bundle/chunks/{chunk-RZJLNXFG.js.map → chunk-XJTABV3X.js.map} +0 -0
  387. /package/dist/cli-bundle/chunks/{chunk-TYHJDFYW.js.map → chunk-ZVZGXPQ5.js.map} +0 -0
  388. /package/dist/cli-bundle/chunks/{close-many-SDA426VT.js.map → close-many-5RZXVN4J.js.map} +0 -0
  389. /package/dist/cli-bundle/chunks/{close-many-UTZANOCQ.js.map → close-many-RZVTUGBG.js.map} +0 -0
  390. /package/dist/cli-bundle/chunks/{comments-LZN6FXXC.js.map → comments-TPU7QRBL.js.map} +0 -0
  391. /package/dist/cli-bundle/chunks/{comments-VBQ345ND.js.map → comments-Z4KV6FU3.js.map} +0 -0
  392. /package/dist/cli-bundle/chunks/{create-GG4RBCGC.js.map → create-EIFBIVNQ.js.map} +0 -0
  393. /package/dist/cli-bundle/chunks/{create-JBC5KUW6.js.map → create-RGSPN5GD.js.map} +0 -0
  394. /package/dist/cli-bundle/chunks/{deps-FI4O6NQS.js.map → deps-UH5EQQUY.js.map} +0 -0
  395. /package/dist/cli-bundle/chunks/{deps-DELOO4TL.js.map → deps-YG7UF3VR.js.map} +0 -0
  396. /package/dist/cli-bundle/chunks/{docs-6Z2MP526.js.map → docs-G32TK6XS.js.map} +0 -0
  397. /package/dist/cli-bundle/chunks/{docs-2UYBP5D6.js.map → docs-JWWNRC27.js.map} +0 -0
  398. /package/dist/cli-bundle/chunks/{files-HKEAN5MA.js.map → files-3H32UQ4K.js.map} +0 -0
  399. /package/dist/cli-bundle/chunks/{files-HEUGSJZL.js.map → files-4ALMCSKB.js.map} +0 -0
  400. /package/dist/cli-bundle/chunks/{history-compact-7NDVP3PT.js.map → history-compact-77BT2LUB.js.map} +0 -0
  401. /package/dist/cli-bundle/chunks/{history-compact-65YVN5DB.js.map → history-compact-VCKGTX64.js.map} +0 -0
  402. /package/dist/cli-bundle/chunks/{history-redact-7YBL4XSG.js.map → history-redact-LJPZPNFA.js.map} +0 -0
  403. /package/dist/cli-bundle/chunks/{history-redact-IZGNJBU4.js.map → history-redact-PWTTJ3XS.js.map} +0 -0
  404. /package/dist/cli-bundle/chunks/{history-repair-7M4PYQUH.js.map → history-repair-I7CBNCV3.js.map} +0 -0
  405. /package/dist/cli-bundle/chunks/{history-repair-GNGETJLI.js.map → history-repair-YTDZRK5E.js.map} +0 -0
  406. /package/dist/cli-bundle/chunks/{learnings-3YXDRWFT.js.map → learnings-CYNOICKR.js.map} +0 -0
  407. /package/dist/cli-bundle/chunks/{learnings-ALC6IMNL.js.map → learnings-KTYW3AL7.js.map} +0 -0
  408. /package/dist/cli-bundle/chunks/{notes-7JMLQ447.js.map → notes-FGO63FXL.js.map} +0 -0
  409. /package/dist/cli-bundle/chunks/{notes-JFCLTC5C.js.map → notes-ZERD3KB2.js.map} +0 -0
  410. /package/dist/cli-bundle/chunks/{plan-T3XB3WTK.js.map → plan-OFJUBIM5.js.map} +0 -0
  411. /package/dist/cli-bundle/chunks/{plan-KOIPWVOZ.js.map → plan-SGCDDTYR.js.map} +0 -0
  412. /package/dist/cli-bundle/chunks/{profile-OILJHKUW.js.map → profile-3THJPIQY.js.map} +0 -0
  413. /package/dist/cli-bundle/chunks/{profile-RJXA7PGS.js.map → profile-XEZAMMBW.js.map} +0 -0
  414. /package/dist/cli-bundle/chunks/{restore-ZH65GZFB.js.map → restore-6TDVSATY.js.map} +0 -0
  415. /package/dist/cli-bundle/chunks/{restore-L6IAGOD7.js.map → restore-RSL7C7LO.js.map} +0 -0
  416. /package/dist/cli-bundle/chunks/{schema-4ERWM5QJ.js.map → schema-HFXFSGPG.js.map} +0 -0
  417. /package/dist/cli-bundle/chunks/{schema-55DL3Q52.js.map → schema-TPVTIJPO.js.map} +0 -0
  418. /package/dist/cli-bundle/chunks/{update-FW6FKDOP.js.map → update-LJZCL5SI.js.map} +0 -0
  419. /package/dist/cli-bundle/chunks/{update-TJHSPRPT.js.map → update-SIA7LH5Y.js.map} +0 -0
  420. /package/dist/cli-bundle/chunks/{update-many-PWXX5WHO.js.map → update-many-BDBZVGQL.js.map} +0 -0
  421. /package/dist/cli-bundle/chunks/{update-many-NNALYQCN.js.map → update-many-MOY3A5B3.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  collectStaleVectorizationIds,
3
3
  recordContextUsageTouches
4
- } from "./chunk-YBT7O4KT.js";
4
+ } from "./chunk-ZTVA4KLN.js";
5
5
  import {
6
6
  buildEventCorpus,
7
7
  buildPlanFlatCorpus,
@@ -14,15 +14,26 @@ import {
14
14
  resolveSearchCorpusFields,
15
15
  resolveSettingsWithSemanticRuntimeDefaults,
16
16
  resolveVectorStores
17
- } from "./chunk-GVI6FAFG.js";
17
+ } from "./chunk-K55VMLSS.js";
18
18
  import {
19
19
  GRAPH_SUBCOMMAND_VALUES
20
- } from "./chunk-HEWM6CEN.js";
20
+ } from "./chunk-P7MTHPJQ.js";
21
21
  import {
22
- analyzeGraphImpact,
23
- analyzeKnowledgeGraph,
24
- analyzeRelationshipExecution
25
- } from "./chunk-UQLXSG72.js";
22
+ auditWorkspaceRelationshipGraph,
23
+ collectDuplicateRelationshipEdgeGroups,
24
+ computeRelationshipDominators,
25
+ detectRelationshipCommunities,
26
+ diffRelationshipAuditSnapshots,
27
+ enumerateRelationshipPaths,
28
+ findRedundantRelationshipEdges,
29
+ forEachMatchedRelationshipEdge,
30
+ formatDuplicateEdgeGroup,
31
+ hierarchyAncestors,
32
+ hierarchyDescendants,
33
+ orderingPredecessors,
34
+ orderingSuccessors,
35
+ orientOrderingEdge
36
+ } from "./chunk-PWDEHT3L.js";
26
37
  import {
27
38
  computeWorkspaceGraphFingerprint,
28
39
  parseDirection,
@@ -30,10 +41,11 @@ import {
30
41
  parseMaxDepth,
31
42
  parsePositiveInteger,
32
43
  workspaceGraphCache
33
- } from "./chunk-DAQ45GCS.js";
44
+ } from "./chunk-F2LBF7XJ.js";
34
45
  import {
35
- assembleWorkspaceRelationshipGraph
36
- } from "./chunk-IJNK6WW2.js";
46
+ assembleWorkspaceRelationshipGraph,
47
+ resolveWorkspaceRelationshipKindRegistry
48
+ } from "./chunk-Z75ONV25.js";
37
49
  import {
38
50
  splitCommaList
39
51
  } from "./chunk-D6HZN36B.js";
@@ -74,11 +86,12 @@ import {
74
86
  } from "./chunk-GTLCVJOE.js";
75
87
  import {
76
88
  getItemAt
77
- } from "./chunk-GFQP7HAZ.js";
89
+ } from "./chunk-VZIZB6QH.js";
78
90
  import {
79
91
  readHistoryEntries
80
- } from "./chunk-C3KD7U3T.js";
92
+ } from "./chunk-2L6ZP22J.js";
81
93
  import {
94
+ acquireLock,
82
95
  buildItemNotFoundError,
83
96
  compareTimestampStrings,
84
97
  getActiveExtensionRegistrations,
@@ -105,18 +118,22 @@ import {
105
118
  coerceNumberInRange,
106
119
  coercePositiveInteger,
107
120
  collectRegisteredItemFieldNames,
121
+ createRelationshipKindRegistry,
108
122
  getHistoryPath,
109
123
  getItemPath,
110
124
  getSettingsPath,
111
125
  isPathWithinDirectory,
112
126
  pathExists,
127
+ readFileIfExists,
128
+ removeFileIfExists,
113
129
  resolveGlobalPmRoot,
114
130
  resolveItemTypeRegistry,
115
131
  resolvePmRoot,
116
132
  resolveRuntimeFieldRegistry,
117
133
  resolveRuntimeStatusRegistry,
118
134
  toNonEmptyString,
119
- toNonEmptyStringOrUndefined
135
+ toNonEmptyStringOrUndefined,
136
+ writeFileAtomic
120
137
  } from "./chunk-7AVEY74G.js";
121
138
 
122
139
  // dist/cli/commands/aggregate.js
@@ -468,893 +485,726 @@ async function runAggregate(options, global2) {
468
485
  };
469
486
  }
470
487
 
471
- // dist/sdk/graph/traversal.js
488
+ // dist/sdk/relationship-analytics.js
472
489
  !(function() {
473
490
  try {
474
491
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
475
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "ed9f0831-6011-5ee2-abd6-72375eac0a3a");
492
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "0a54b889-6d5c-565c-85ff-47e5cce68a32");
476
493
  } catch (e2) {
477
494
  }
478
495
  })();
479
- var DEFAULT_MAX_PATHS = 5;
480
- var DEFAULT_MAX_VISITED_PATHS = 1e4;
481
- var DEFAULT_PATH_MAX_DEPTH = 8;
482
- function assertPathBound(name, value) {
483
- if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0)
484
- throw new TypeError(`Invalid path ${name} bound: ${String(value)}`);
485
- }
486
- function hierarchyParentEndpoint(edge, definition) {
487
- return definition.hierarchyDirection === "target_parent" ? edge.target : edge.source;
488
- }
489
- function orderingPredecessorEndpoint(edge, definition) {
490
- return (definition.precedence ?? "source_before_target") === "target_before_source" ? edge.target : edge.source;
491
- }
492
- function resolveFamilyKinds(graph, kinds, family) {
493
- if (kinds === void 0)
494
- return void 0;
495
- const registry = graph.registry();
496
- const resolved = /* @__PURE__ */ new Set();
497
- for (const kind of kinds) {
498
- const definition = registry.require(kind);
499
- if (!definition[family])
500
- throw new TypeError(`Relationship kind ${definition.kind} is not a ${family} kind`);
501
- resolved.add(definition.kind);
502
- }
503
- return resolved;
504
- }
505
- function expandSemanticNeighbors(graph, nodeId, familyKinds, family, matches) {
506
- const registry = graph.registry();
507
- const rows = graph.neighborEdges(nodeId, {
508
- direction: "both",
509
- ...familyKinds === void 0 ? {} : { kinds: [...familyKinds] }
510
- });
511
- const neighbors = [];
512
- const seen = /* @__PURE__ */ new Set();
513
- for (const row of rows.value) {
514
- const definition = registry.require(row.edge.kind);
515
- if (!definition[family])
516
- continue;
517
- if (!matches(row, definition, nodeId))
496
+ function appendNeighbor(adjacency, source, target) {
497
+ adjacency.get(source).add(target);
498
+ }
499
+ function createAdjacency(nodes) {
500
+ return new Map(nodes.map((node) => [node, /* @__PURE__ */ new Set()]));
501
+ }
502
+ function sortComponents(components) {
503
+ for (const component of components)
504
+ component.sort();
505
+ return components.sort((left, right) => right.length - left.length || left[0].localeCompare(right[0]));
506
+ }
507
+ function stableJsonValue(value) {
508
+ if (Array.isArray(value))
509
+ return value.map((entry) => stableJsonValue(entry));
510
+ if (value === null || typeof value !== "object")
511
+ return value;
512
+ const toJSON = value.toJSON;
513
+ if (typeof toJSON === "function")
514
+ return stableJsonValue(toJSON.call(value));
515
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, stableJsonValue(entry)]));
516
+ }
517
+ function relationshipEdgeKey(edge) {
518
+ return JSON.stringify(stableJsonValue(edge));
519
+ }
520
+ function appendFinishingOrder(start, adjacency, visited, order) {
521
+ const stack = [{ id: start, expanded: false }];
522
+ while (stack.length > 0) {
523
+ const current = stack.pop();
524
+ if (current.expanded) {
525
+ order.push(current.id);
518
526
  continue;
519
- if (seen.has(row.id))
527
+ }
528
+ if (visited.has(current.id))
520
529
  continue;
521
- seen.add(row.id);
522
- neighbors.push(row.id);
530
+ visited.add(current.id);
531
+ stack.push({ id: current.id, expanded: true });
532
+ const neighbors = [...adjacency.get(current.id)].sort().reverse();
533
+ for (const neighbor of neighbors)
534
+ if (!visited.has(neighbor))
535
+ stack.push({ id: neighbor, expanded: false });
523
536
  }
524
- return { neighbors, inspectedEdges: rows.meta.inspectedEdges };
525
537
  }
526
- function appendSemanticExpansion(expansion, currentDepth, maxDepth, limit, after, state) {
527
- if (currentDepth >= maxDepth) {
528
- if (expansion.neighbors.some((neighbor) => !state.seen.has(neighbor)))
529
- state.truncated = true;
530
- return false;
531
- }
532
- for (const neighbor of expansion.neighbors) {
533
- if (state.seen.has(neighbor))
534
- continue;
535
- state.seen.add(neighbor);
536
- state.queue.push({ id: neighbor, depth: currentDepth + 1 });
537
- if (!state.resumed) {
538
- if (neighbor === after)
539
- state.resumed = true;
538
+ function computeFinishingOrder(nodes, adjacency) {
539
+ const visited = /* @__PURE__ */ new Set();
540
+ const order = [];
541
+ for (const start of nodes)
542
+ if (!visited.has(start))
543
+ appendFinishingOrder(start, adjacency, visited, order);
544
+ return order;
545
+ }
546
+ function collectReverseComponents(order, reverse) {
547
+ const visited = /* @__PURE__ */ new Set();
548
+ const components = [];
549
+ for (const start of [...order].reverse()) {
550
+ if (visited.has(start))
540
551
  continue;
552
+ const component = [];
553
+ const stack = [start];
554
+ visited.add(start);
555
+ while (stack.length > 0) {
556
+ const current = stack.pop();
557
+ component.push(current);
558
+ for (const neighbor of reverse.get(current)) {
559
+ if (visited.has(neighbor))
560
+ continue;
561
+ visited.add(neighbor);
562
+ stack.push(neighbor);
563
+ }
541
564
  }
542
- if (state.value.length >= limit) {
543
- state.truncated = true;
544
- return true;
545
- }
546
- state.value.push(neighbor);
565
+ components.push(component);
547
566
  }
548
- return false;
567
+ return sortComponents(components);
549
568
  }
550
- function boundedSemanticWalk(graph, start, options, family, matches) {
551
- if (!graph.hasNode(start))
552
- throw new TypeError(`Relationship node not found: ${start}`);
553
- const familyKinds = resolveFamilyKinds(graph, options.kinds, family);
554
- const limit = options.limit ?? Number.POSITIVE_INFINITY;
555
- const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
556
- const after = options.after;
557
- const state = {
558
- seen: /* @__PURE__ */ new Set([start]),
559
- value: [],
560
- queue: [{ id: start, depth: 0 }],
561
- resumed: after === void 0,
562
- truncated: false
563
- };
564
- let visitedNodes = 0;
565
- let inspectedEdges = 0;
566
- for (let index = 0; index < state.queue.length; index += 1) {
567
- options.signal?.throwIfAborted();
568
- const current = state.queue[index];
569
- visitedNodes += 1;
570
- const expansion = expandSemanticNeighbors(graph, current.id, familyKinds, family, matches);
571
- inspectedEdges += expansion.inspectedEdges;
572
- if (appendSemanticExpansion(expansion, current.depth, maxDepth, limit, after, state))
573
- break;
574
- }
575
- if (!state.resumed)
576
- throw new TypeError(`Traversal cursor not found in sequence: ${after}`);
577
- return {
578
- value: state.value,
579
- meta: {
580
- visitedNodes,
581
- inspectedEdges,
582
- truncated: state.truncated,
583
- nextCursor: state.value.at(-1)
584
- }
585
- };
569
+ function stronglyConnectedComponents(nodes, adjacency) {
570
+ const reverse = createAdjacency(nodes);
571
+ for (const [source, targets] of adjacency)
572
+ for (const target of targets)
573
+ appendNeighbor(reverse, target, source);
574
+ return collectReverseComponents(computeFinishingOrder(nodes, adjacency), reverse);
586
575
  }
587
- function assertPathEndpoint(graph, id) {
588
- if (!graph.hasNode(id))
589
- throw new TypeError(`Relationship node not found: ${id}`);
576
+ function buildExecutionAdjacency(graph, registry) {
577
+ const adjacency = createAdjacency(graph.nodes());
578
+ for (const edge of graph.edges()) {
579
+ const definition = registry.require(edge.kind);
580
+ if (!definition.ordering)
581
+ continue;
582
+ const sourceFirst = (definition.precedence ?? "source_before_target") === "source_before_target";
583
+ appendNeighbor(adjacency, sourceFirst ? edge.source : edge.target, sourceFirst ? edge.target : edge.source);
584
+ }
585
+ return adjacency;
590
586
  }
591
- function readPathContinuations(graph, partial, options, direction, state) {
592
- const rows = graph.neighborEdges(partial.nodes.at(-1), {
593
- direction,
594
- ...options.kinds === void 0 ? {} : { kinds: options.kinds }
595
- });
596
- state.inspectedEdges += rows.meta.inspectedEdges;
597
- return rows.value.filter((row) => !partial.nodeSet.has(row.id));
598
- }
599
- function expandPartialPath(graph, partial, target, options, direction, probeLimit, state) {
600
- for (const row of readPathContinuations(graph, partial, options, direction, state)) {
601
- const nodes = [...partial.nodes, row.id];
602
- const nodeSet = new Set(partial.nodeSet).add(row.id);
603
- const edges = [...partial.edges, row.edge];
604
- if (row.id === target) {
605
- state.value.push({ nodes, edges, length: edges.length });
606
- if (state.value.length >= probeLimit)
607
- return true;
608
- } else {
609
- state.queue.push({ nodes, nodeSet, edges });
587
+ function topologicalLayers(nodes, adjacency) {
588
+ const indegree = new Map(nodes.map((node) => [node, 0]));
589
+ for (const targets of adjacency.values())
590
+ for (const target of targets)
591
+ indegree.set(target, indegree.get(target) + 1);
592
+ let frontier = nodes.filter((node) => indegree.get(node) === 0).sort();
593
+ const layers = [];
594
+ while (frontier.length > 0) {
595
+ layers.push(frontier);
596
+ const next = [];
597
+ for (const source of frontier) {
598
+ for (const target of adjacency.get(source)) {
599
+ const remaining = indegree.get(target) - 1;
600
+ indegree.set(target, remaining);
601
+ if (remaining === 0)
602
+ next.push(target);
603
+ }
610
604
  }
605
+ frontier = next.sort();
611
606
  }
612
- return false;
613
- }
614
- function hierarchyAncestors(graph, id, options = {}) {
615
- return boundedSemanticWalk(graph, id, options, "hierarchy", (row, definition) => hierarchyParentEndpoint(row.edge, definition) === row.id);
616
- }
617
- function hierarchyDescendants(graph, id, options = {}) {
618
- return boundedSemanticWalk(graph, id, options, "hierarchy", (row, definition, nodeId) => hierarchyParentEndpoint(row.edge, definition) === nodeId);
619
- }
620
- function orderingPredecessors(graph, id, options = {}) {
621
- return boundedSemanticWalk(graph, id, options, "ordering", (row, definition) => orderingPredecessorEndpoint(row.edge, definition) === row.id);
607
+ return layers;
622
608
  }
623
- function orderingSuccessors(graph, id, options = {}) {
624
- return boundedSemanticWalk(graph, id, options, "ordering", (row, definition, nodeId) => orderingPredecessorEndpoint(row.edge, definition) === nodeId);
625
- }
626
- function enumerateNonZeroRelationshipPaths(graph, source, target, options, maxPaths, maxVisitedPaths, maxDepth, direction) {
627
- const state = {
628
- value: [],
629
- queue: [{ nodes: [source], nodeSet: /* @__PURE__ */ new Set([source]), edges: [] }],
630
- inspectedEdges: 0
609
+ function longestPath(order, adjacency) {
610
+ const depth = new Map(order.map((node) => [node, 0]));
611
+ const parent = /* @__PURE__ */ new Map();
612
+ for (const source of order) {
613
+ for (const target of adjacency.get(source)) {
614
+ if (!depth.has(target))
615
+ continue;
616
+ const candidate = depth.get(source) + 1;
617
+ const currentParent = parent.get(target);
618
+ if (candidate > depth.get(target) || candidate === depth.get(target) && (currentParent === void 0 || source.localeCompare(currentParent) < 0)) {
619
+ depth.set(target, candidate);
620
+ parent.set(target, source);
621
+ }
622
+ }
623
+ }
624
+ const end = [...order].sort((left, right) => depth.get(right) - depth.get(left) || left.localeCompare(right))[0];
625
+ const path4 = end === void 0 ? [] : [end];
626
+ while (path4[0] !== void 0 && parent.has(path4[0]))
627
+ path4.unshift(parent.get(path4[0]));
628
+ return { depth: Object.fromEntries(depth), path: path4 };
629
+ }
630
+ function reconstructImpactPath(root, target, parents) {
631
+ const path4 = [target];
632
+ let cursor = target;
633
+ while (cursor !== root) {
634
+ cursor = parents.get(cursor);
635
+ path4.push(cursor);
636
+ }
637
+ return path4.reverse();
638
+ }
639
+ function analyzeRelationshipExecution(graph, options = {}) {
640
+ const registry = options.registry ?? createRelationshipKindRegistry();
641
+ const nodes = [...graph.nodes()];
642
+ const adjacency = buildExecutionAdjacency(graph, registry);
643
+ const layers = topologicalLayers(nodes, adjacency);
644
+ const order = layers.flat();
645
+ const acyclic = order.length === nodes.length;
646
+ const cycles = acyclic ? [] : stronglyConnectedComponents(nodes, adjacency).filter((component) => component.length > 1 || adjacency.get(component[0]).has(component[0]));
647
+ const longest = longestPath(order, adjacency);
648
+ return {
649
+ exact: true,
650
+ acyclic,
651
+ order,
652
+ layers,
653
+ frontier: layers[0] ?? [],
654
+ depth: longest.depth,
655
+ criticalPath: longest.path,
656
+ criticalPathLength: Math.max(0, longest.path.length - 1),
657
+ cycles,
658
+ provenance: { algorithm: "kahn-longest-path", edgeFamily: "ordering" }
631
659
  };
660
+ }
661
+ function analyzeGraphImpact(graph, root, options = {}) {
662
+ const direction = options.direction ?? "outgoing";
663
+ const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
664
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
665
+ const queue = [{ id: root, depth: 0 }];
666
+ const seen = /* @__PURE__ */ new Set([root]);
667
+ const parents = /* @__PURE__ */ new Map();
668
+ const affected = [];
632
669
  let visitedNodes = 0;
670
+ let inspectedEdges = 0;
633
671
  let truncated = false;
634
- const probeLimit = maxPaths + 1;
635
- for (let index = 0; index < state.queue.length; index += 1) {
672
+ traversal: for (let index = 0; index < queue.length; index += 1) {
636
673
  options.signal?.throwIfAborted();
637
- if (state.value.length >= probeLimit || visitedNodes >= maxVisitedPaths) {
638
- truncated = true;
639
- break;
640
- }
641
- const partial = state.queue[index];
674
+ const current = queue[index];
642
675
  visitedNodes += 1;
643
- if (partial.edges.length >= maxDepth) {
644
- if (readPathContinuations(graph, partial, options, direction, state).length > 0)
676
+ const adjacent = graph.adjacency(current.id, {
677
+ direction,
678
+ kinds: options.kinds,
679
+ signal: options.signal
680
+ });
681
+ inspectedEdges += adjacent.meta.inspectedEdges;
682
+ if (current.depth >= maxDepth) {
683
+ if (adjacent.value.some((id) => !seen.has(id)))
645
684
  truncated = true;
646
685
  continue;
647
686
  }
648
- if (expandPartialPath(graph, partial, target, options, direction, probeLimit, state)) {
649
- truncated = true;
650
- break;
687
+ for (const id of adjacent.value) {
688
+ if (seen.has(id))
689
+ continue;
690
+ if (affected.length >= limit) {
691
+ truncated = true;
692
+ break traversal;
693
+ }
694
+ seen.add(id);
695
+ parents.set(id, current.id);
696
+ const depth = current.depth + 1;
697
+ affected.push({
698
+ id,
699
+ distance: depth,
700
+ path: reconstructImpactPath(root, id, parents)
701
+ });
702
+ queue.push({ id, depth });
651
703
  }
652
704
  }
653
705
  return {
654
- value: state.value.slice(0, maxPaths),
655
- meta: { visitedNodes, inspectedEdges: state.inspectedEdges, truncated }
706
+ root,
707
+ affected,
708
+ exact: true,
709
+ truncated,
710
+ cost: { visitedNodes, inspectedEdges }
656
711
  };
657
712
  }
658
- function enumerateRelationshipPaths(graph, source, target, options = {}) {
659
- assertPathEndpoint(graph, source);
660
- assertPathEndpoint(graph, target);
661
- const maxPaths = options.maxPaths ?? DEFAULT_MAX_PATHS;
662
- const maxVisitedPaths = options.maxVisitedPaths ?? DEFAULT_MAX_VISITED_PATHS;
663
- const maxDepth = options.maxDepth ?? DEFAULT_PATH_MAX_DEPTH;
664
- assertPathBound("maxPaths", maxPaths);
665
- assertPathBound("maxVisitedPaths", maxVisitedPaths);
666
- assertPathBound("maxDepth", maxDepth);
667
- const direction = options.direction ?? "outgoing";
668
- options.signal?.throwIfAborted();
669
- for (const kind of options.kinds ?? [])
670
- graph.registry().require(kind);
671
- if (source === target) {
672
- if (maxPaths === 0) {
673
- return {
674
- value: [],
675
- meta: { visitedNodes: 1, inspectedEdges: 0, truncated: true }
676
- };
713
+ function analyzeKnowledgeGraph(graph) {
714
+ const nodes = [...graph.nodes()];
715
+ const weak = createAdjacency(nodes);
716
+ const directed = createAdjacency(nodes);
717
+ for (const edge of graph.edges()) {
718
+ appendNeighbor(weak, edge.source, edge.target);
719
+ appendNeighbor(weak, edge.target, edge.source);
720
+ appendNeighbor(directed, edge.source, edge.target);
721
+ }
722
+ const components = [];
723
+ const visited = /* @__PURE__ */ new Set();
724
+ for (const start of nodes) {
725
+ if (visited.has(start))
726
+ continue;
727
+ const component = [];
728
+ const stack = [start];
729
+ visited.add(start);
730
+ while (stack.length > 0) {
731
+ const current = stack.pop();
732
+ component.push(current);
733
+ for (const neighbor of weak.get(current)) {
734
+ if (visited.has(neighbor))
735
+ continue;
736
+ visited.add(neighbor);
737
+ stack.push(neighbor);
738
+ }
677
739
  }
678
- return {
679
- value: [{ nodes: [source], edges: [], length: 0 }],
680
- meta: { visitedNodes: 1, inspectedEdges: 0, truncated: false }
681
- };
740
+ components.push(component);
682
741
  }
683
- return enumerateNonZeroRelationshipPaths(graph, source, target, options, maxPaths, maxVisitedPaths, maxDepth, direction);
742
+ const degrees = nodes.map((id) => ({ id, degree: weak.get(id).size }));
743
+ const maximum = Math.max(0, ...degrees.map(({ degree }) => degree));
744
+ return {
745
+ components: sortComponents(components),
746
+ stronglyConnected: stronglyConnectedComponents(nodes, directed),
747
+ orphans: degrees.filter(({ degree }) => degree === 0).map(({ id }) => id),
748
+ hubs: degrees.filter(({ degree }) => degree > 0 && degree === maximum),
749
+ exact: true,
750
+ provenance: { algorithm: "component-degree", edgeFamily: "all" }
751
+ };
752
+ }
753
+ function compareRelationshipSnapshots(before, after) {
754
+ const earlier = new Map(before.edges.map((edge) => [relationshipEdgeKey(edge), edge]));
755
+ const later = new Map(after.edges.map((edge) => [relationshipEdgeKey(edge), edge]));
756
+ return {
757
+ fromVersion: before.version,
758
+ toVersion: after.version,
759
+ added: [...later].filter(([key]) => !earlier.has(key)).map(([, edge]) => edge),
760
+ removed: [...earlier].filter(([key]) => !later.has(key)).map(([, edge]) => edge),
761
+ unchangedCount: [...earlier.keys()].filter((key) => later.has(key)).length,
762
+ exact: true
763
+ };
684
764
  }
685
765
 
686
- // dist/sdk/graph/analytics.js
766
+ // dist/sdk/graph/centrality.js
687
767
  !(function() {
688
768
  try {
689
769
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
690
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "19fa7ddd-c396-5fd4-a720-522218a7b11a");
770
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "0b226d67-72f3-57f4-8428-d3af70ecf306");
691
771
  } catch (e2) {
692
772
  }
693
773
  })();
694
- var DEFAULT_MAX_ITERATIONS = 16;
695
- var DEFAULT_MIN_COMMUNITY_SIZE = 2;
696
- var DEFAULT_REDUNDANCY_MAX_DEPTH = 8;
697
- function assertPositiveBound(name, value) {
698
- if (!Number.isInteger(value) || value < 1)
699
- throw new TypeError(`Invalid ${name} bound: ${String(value)}`);
700
- }
701
- function buildUndirectedAdjacency(graph, kinds) {
702
- const registry = graph.registry();
703
- const wanted = kinds === void 0 ? void 0 : new Set(kinds.map((kind) => registry.require(kind).kind));
704
- const adjacency = /* @__PURE__ */ new Map();
705
- for (const edge of graph.edges()) {
706
- if (edge.source === edge.target)
707
- continue;
708
- if (wanted !== void 0) {
709
- const definition = registry.require(edge.kind);
710
- const matches = wanted.has(definition.kind) || definition.inverse !== void 0 && wanted.has(definition.inverse);
711
- if (!matches)
712
- continue;
713
- }
714
- appendAdjacency(adjacency, edge.source, edge.target);
715
- appendAdjacency(adjacency, edge.target, edge.source);
716
- }
717
- for (const neighbors of adjacency.values())
718
- neighbors.sort();
719
- return adjacency;
774
+ function roundScore(value) {
775
+ return Math.round(value * 1e6) / 1e6;
720
776
  }
721
- function appendAdjacency(adjacency, from, to) {
722
- const neighbors = adjacency.get(from);
723
- if (neighbors === void 0)
724
- adjacency.set(from, [to]);
777
+ function addToSetMap(map, key, value) {
778
+ const set = map.get(key);
779
+ if (set === void 0)
780
+ map.set(key, /* @__PURE__ */ new Set([value]));
725
781
  else
726
- neighbors.push(to);
727
- }
728
- function dominantNeighborLabel(neighbors, labels) {
729
- const counts = /* @__PURE__ */ new Map();
730
- for (const neighbor of neighbors) {
731
- const label = labels.get(neighbor);
732
- counts.set(label, (counts.get(label) ?? 0) + 1);
733
- }
734
- let best;
735
- let bestCount = 0;
736
- for (const [label, count] of counts) {
737
- if (count > bestCount || count === bestCount && label < best) {
738
- best = label;
739
- bestCount = count;
740
- }
741
- }
742
- return best;
782
+ set.add(value);
743
783
  }
744
- function collectCommunities(labels, minSize) {
745
- const groups = /* @__PURE__ */ new Map();
746
- for (const [id, label] of labels) {
747
- const members = groups.get(label);
748
- if (members === void 0)
749
- groups.set(label, [id]);
750
- else
751
- members.push(id);
752
- }
753
- const communities = [];
754
- for (const members of groups.values()) {
755
- if (members.length < minSize)
756
- continue;
757
- members.sort();
758
- communities.push({
759
- representative: members[0],
760
- size: members.length,
761
- members
762
- });
763
- }
764
- return communities.sort((left, right) => right.size - left.size || left.representative.localeCompare(right.representative));
784
+ function buildSimpleUndirectedAdjacency(graph, kinds) {
785
+ const sets = new Map(graph.nodes().map((id) => [id, /* @__PURE__ */ new Set()]));
786
+ forEachMatchedRelationshipEdge(graph, kinds, (edge) => {
787
+ sets.get(edge.source).add(edge.target);
788
+ sets.get(edge.target).add(edge.source);
789
+ });
790
+ const adjacency = /* @__PURE__ */ new Map();
791
+ for (const [id, neighbors] of sets)
792
+ adjacency.set(id, [...neighbors].sort());
793
+ return adjacency;
765
794
  }
766
- function detectRelationshipCommunities(graph, options = {}) {
767
- const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS;
768
- const minSize = options.minSize ?? DEFAULT_MIN_COMMUNITY_SIZE;
769
- assertPositiveBound("maxIterations", maxIterations);
770
- assertPositiveBound("minSize", minSize);
771
- const adjacency = buildUndirectedAdjacency(graph, options.kinds);
772
- const nodes = graph.nodes();
773
- const labels = new Map(nodes.map((id) => [id, id]));
774
- let iterations = 0;
775
- let converged = false;
776
- let visitedNodes = 0;
777
- let inspectedEdges = 0;
778
- while (iterations < maxIterations && !converged) {
779
- options.signal?.throwIfAborted();
780
- iterations += 1;
781
- converged = true;
782
- for (const id of nodes) {
783
- visitedNodes += 1;
784
- const neighbors = adjacency.get(id);
785
- if (neighbors === void 0)
786
- continue;
787
- inspectedEdges += neighbors.length;
788
- const dominant = dominantNeighborLabel(neighbors, labels);
789
- if (dominant !== labels.get(id)) {
790
- labels.set(id, dominant);
791
- converged = false;
795
+ function collectOrderingDegrees(graph, kinds) {
796
+ const incoming = /* @__PURE__ */ new Map();
797
+ const outgoing = /* @__PURE__ */ new Map();
798
+ forEachMatchedRelationshipEdge(graph, kinds, (edge, definition) => {
799
+ if (!definition.ordering)
800
+ return;
801
+ const { predecessor, successor } = orientOrderingEdge(edge, definition);
802
+ addToSetMap(outgoing, predecessor, successor);
803
+ addToSetMap(incoming, successor, predecessor);
804
+ });
805
+ return { incoming, outgoing };
806
+ }
807
+ function brandesShortestPaths(source, adjacency, cost) {
808
+ const distance = /* @__PURE__ */ new Map([[source, 0]]);
809
+ const sigma = /* @__PURE__ */ new Map([[source, 1]]);
810
+ const predecessors = /* @__PURE__ */ new Map();
811
+ const stack = [];
812
+ const queue = [source];
813
+ let reachableCount = 0;
814
+ let distanceSum = 0;
815
+ for (let index = 0; index < queue.length; index += 1) {
816
+ const node = queue[index];
817
+ cost.visitedNodes += 1;
818
+ stack.push(node);
819
+ const nodeDistance = distance.get(node);
820
+ if (node !== source) {
821
+ reachableCount += 1;
822
+ distanceSum += nodeDistance;
823
+ }
824
+ for (const neighbor of adjacency.get(node)) {
825
+ cost.inspectedEdges += 1;
826
+ if (!distance.has(neighbor)) {
827
+ distance.set(neighbor, nodeDistance + 1);
828
+ queue.push(neighbor);
829
+ }
830
+ if (distance.get(neighbor) === nodeDistance + 1) {
831
+ sigma.set(neighbor, (sigma.get(neighbor) ?? 0) + sigma.get(node));
832
+ const predecessorList = predecessors.get(neighbor);
833
+ if (predecessorList === void 0)
834
+ predecessors.set(neighbor, [node]);
835
+ else
836
+ predecessorList.push(node);
792
837
  }
793
838
  }
794
839
  }
795
- return {
796
- value: {
797
- communities: collectCommunities(labels, minSize),
798
- iterations,
799
- converged
800
- },
801
- meta: { visitedNodes, inspectedEdges, truncated: !converged }
802
- };
803
- }
804
- function isTransitiveKind(definition) {
805
- return definition.direction === "directed" && (definition.ordering || definition.hierarchy);
840
+ return { stack, sigma, predecessors, reachableCount, distanceSum };
806
841
  }
807
- function transitiveFamilyKey(definition) {
808
- return definition.inverse !== void 0 && definition.inverse < definition.kind ? definition.inverse : definition.kind;
809
- }
810
- function orientTransitiveEdge(edge, definition) {
811
- const head = definition.hierarchy ? hierarchyParentEndpoint(edge, definition) : edge.source === orderingPredecessorEndpoint(edge, definition) ? edge.target : edge.source;
812
- return head === edge.target ? { from: edge.source, to: edge.target } : { from: edge.target, to: edge.source };
813
- }
814
- function resolveRedundancyFamilies(graph, kinds) {
815
- if (kinds === void 0)
816
- return void 0;
817
- const registry = graph.registry();
818
- const families = /* @__PURE__ */ new Set();
819
- for (const kind of kinds) {
820
- const definition = registry.require(kind);
821
- if (!isTransitiveKind(definition))
822
- throw new TypeError(`Relationship kind ${definition.kind} is not a directed ordering or hierarchy kind`);
823
- families.add(transitiveFamilyKey(definition));
824
- }
825
- return families;
826
- }
827
- function collectTransitiveFamilies(graph, wanted) {
828
- const registry = graph.registry();
829
- const families = /* @__PURE__ */ new Map();
830
- for (const edge of graph.edges()) {
831
- const definition = registry.require(edge.kind);
832
- if (!isTransitiveKind(definition))
833
- continue;
834
- const key = transitiveFamilyKey(definition);
835
- if (wanted !== void 0 && !wanted.has(key))
836
- continue;
837
- const oriented = orientTransitiveEdge(edge, definition);
838
- if (oriented.from === oriented.to)
839
- continue;
840
- let family = families.get(key);
841
- if (family === void 0) {
842
- family = { adjacency: /* @__PURE__ */ new Map(), records: [] };
843
- families.set(key, family);
842
+ function accumulateBetweenness(sweep, source, betweenness) {
843
+ const dependency = /* @__PURE__ */ new Map();
844
+ for (let index = sweep.stack.length - 1; index >= 0; index -= 1) {
845
+ const node = sweep.stack[index];
846
+ const share = (1 + (dependency.get(node) ?? 0)) / sweep.sigma.get(node);
847
+ for (const predecessor of sweep.predecessors.get(node) ?? []) {
848
+ dependency.set(predecessor, (dependency.get(predecessor) ?? 0) + sweep.sigma.get(predecessor) * share);
844
849
  }
845
- const targets = family.adjacency.get(oriented.from);
846
- if (targets === void 0)
847
- family.adjacency.set(oriented.from, /* @__PURE__ */ new Set([oriented.to]));
848
- else
849
- targets.add(oriented.to);
850
- family.records.push({ ...oriented, edge });
851
- }
852
- return families;
853
- }
854
- function sortedFamilyAdjacency(family) {
855
- const sorted = /* @__PURE__ */ new Map();
856
- for (const [from, targets] of family.adjacency)
857
- sorted.set(from, [...targets].sort());
858
- return sorted;
859
- }
860
- function reconstructWitness(parents, from, tail, head) {
861
- const witness = [head];
862
- for (let node = tail; node !== from; node = parents.get(node))
863
- witness.push(node);
864
- witness.push(from);
865
- return witness.reverse();
866
- }
867
- function expandWitnessFrontier(adjacency, record, current, parents, queue, cost) {
868
- for (const next of adjacency.get(current.id) ?? []) {
869
- cost.inspectedEdges += 1;
870
- if (current.depth === 0 && next === record.to)
871
- continue;
872
- if (parents.has(next))
873
- continue;
874
- parents.set(next, current.id);
875
- if (next === record.to)
876
- return reconstructWitness(parents, record.from, current.id, next);
877
- queue.push({ id: next, depth: current.depth + 1 });
850
+ if (node !== source)
851
+ betweenness.set(node, (betweenness.get(node) ?? 0) + (dependency.get(node) ?? 0));
878
852
  }
879
- return void 0;
880
853
  }
881
- function findWitnessPath(adjacency, record, maxDepth, cost) {
882
- const parents = /* @__PURE__ */ new Map([[record.from, record.from]]);
883
- const queue = [{ id: record.from, depth: 0 }];
884
- for (let index = 0; index < queue.length; index += 1) {
885
- const current = queue[index];
886
- cost.visitedNodes += 1;
887
- if (current.depth >= maxDepth)
888
- continue;
889
- const witness = expandWitnessFrontier(adjacency, record, current, parents, queue, cost);
890
- if (witness !== void 0)
891
- return witness;
892
- }
893
- return void 0;
854
+ function wassermanFaustCloseness(sweep, nodeCount) {
855
+ if (nodeCount <= 1 || sweep.reachableCount === 0)
856
+ return 0;
857
+ return sweep.reachableCount / (nodeCount - 1) * (sweep.reachableCount / sweep.distanceSum);
894
858
  }
895
- function findRedundantRelationshipEdges(graph, options = {}) {
896
- const maxDepth = options.maxDepth ?? DEFAULT_REDUNDANCY_MAX_DEPTH;
897
- assertPositiveBound("maxDepth", maxDepth);
898
- if (options.limit !== void 0)
899
- assertPositiveBound("limit", options.limit);
900
- const limit = options.limit ?? Number.POSITIVE_INFINITY;
901
- const wanted = resolveRedundancyFamilies(graph, options.kinds);
902
- const families = collectTransitiveFamilies(graph, wanted);
903
- const value = [];
859
+ function centralityRow(id, adjacency, directed, betweenness, closeness) {
860
+ return {
861
+ id,
862
+ degree: adjacency.get(id).length,
863
+ inDegree: directed.incoming.get(id)?.size ?? 0,
864
+ outDegree: directed.outgoing.get(id)?.size ?? 0,
865
+ // Undirected betweenness double-counts each ordered pair; halve it.
866
+ betweenness: roundScore((betweenness.get(id) ?? 0) / 2),
867
+ // Every node is a sweep source, so closeness is always populated.
868
+ closeness: roundScore(closeness.get(id))
869
+ };
870
+ }
871
+ function computeRelationshipCentrality(graph, options = {}) {
872
+ const adjacency = buildSimpleUndirectedAdjacency(graph, options.kinds);
873
+ const directed = collectOrderingDegrees(graph, options.kinds);
874
+ const nodes = graph.nodes();
875
+ const betweenness = /* @__PURE__ */ new Map();
876
+ const closeness = /* @__PURE__ */ new Map();
904
877
  const cost = { visitedNodes: 0, inspectedEdges: 0 };
905
- let truncated = false;
906
- scan: for (const key of [...families.keys()].sort()) {
907
- const family = families.get(key);
908
- const adjacency = sortedFamilyAdjacency(family);
909
- for (const record of family.records) {
910
- options.signal?.throwIfAborted();
911
- const witness = findWitnessPath(adjacency, record, maxDepth, cost);
912
- if (witness === void 0)
913
- continue;
914
- if (value.length >= limit) {
915
- truncated = true;
916
- break scan;
917
- }
918
- value.push({ edge: record.edge, witness });
919
- }
878
+ for (const source of nodes) {
879
+ options.signal?.throwIfAborted();
880
+ const sweep = brandesShortestPaths(source, adjacency, cost);
881
+ closeness.set(source, wassermanFaustCloseness(sweep, nodes.length));
882
+ accumulateBetweenness(sweep, source, betweenness);
920
883
  }
884
+ let degreeSum = 0;
885
+ for (const neighbors of adjacency.values())
886
+ degreeSum += neighbors.length;
887
+ const rows = nodes.map((id) => centralityRow(id, adjacency, directed, betweenness, closeness)).sort((left, right) => right.betweenness - left.betweenness || right.degree - left.degree || left.id.localeCompare(right.id));
921
888
  return {
922
- value,
889
+ value: { nodeCount: nodes.length, edgeCount: degreeSum / 2, rows },
923
890
  meta: {
924
891
  visitedNodes: cost.visitedNodes,
925
892
  inspectedEdges: cost.inspectedEdges,
926
- truncated
893
+ truncated: false
927
894
  }
928
895
  };
929
896
  }
930
- function expandReachableNode(id, depth, rows, maxDepth, state) {
931
- const nextSet = /* @__PURE__ */ new Set();
932
- const nexts = [];
933
- for (const row of rows) {
934
- if (row.id === id || nextSet.has(row.id))
935
- continue;
936
- if (!state.seen.has(row.id)) {
937
- if (depth >= maxDepth) {
938
- state.truncated = true;
939
- continue;
940
- }
941
- state.seen.add(row.id);
942
- state.queue.push({ id: row.id, depth: depth + 1 });
943
- }
944
- nextSet.add(row.id);
945
- nexts.push(row.id);
946
- let incoming = state.predecessors.get(row.id);
947
- if (incoming === void 0) {
948
- incoming = /* @__PURE__ */ new Set();
949
- state.predecessors.set(row.id, incoming);
950
- }
951
- incoming.add(id);
952
- }
953
- return nexts;
897
+ function orderedBridge(left, right) {
898
+ return left <= right ? { source: left, target: right } : { source: right, target: left };
954
899
  }
955
- function indexReachableSubgraph(graph, root, options) {
956
- const direction = options.direction ?? "outgoing";
957
- const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
958
- const order = [];
959
- const successors = /* @__PURE__ */ new Map();
960
- const state = {
961
- seen: /* @__PURE__ */ new Set([root]),
962
- queue: [{ id: root, depth: 0 }],
963
- predecessors: /* @__PURE__ */ new Map(),
964
- truncated: false
965
- };
966
- let inspectedEdges = 0;
967
- for (let index = 0; index < state.queue.length; index += 1) {
968
- options.signal?.throwIfAborted();
969
- const { id, depth } = state.queue[index];
970
- order.push(id);
971
- const rows = graph.neighborEdges(id, {
972
- direction,
973
- ...options.kinds === void 0 ? {} : { kinds: options.kinds }
974
- });
975
- inspectedEdges += rows.meta.inspectedEdges;
976
- successors.set(id, expandReachableNode(id, depth, rows.value, maxDepth, state));
900
+ function advanceCutFrame(frame, adjacency, state) {
901
+ const neighbors = adjacency.get(frame.node);
902
+ const neighbor = neighbors[frame.neighborIndex];
903
+ frame.neighborIndex += 1;
904
+ state.inspectedEdges += 1;
905
+ if (neighbor === frame.parent)
906
+ return void 0;
907
+ if (state.discovery.has(neighbor)) {
908
+ state.low.set(frame.node, Math.min(state.low.get(frame.node), state.discovery.get(neighbor)));
909
+ return void 0;
977
910
  }
978
- return {
979
- order,
980
- successors,
981
- predecessors: state.predecessors,
982
- inspectedEdges,
983
- truncated: state.truncated
984
- };
911
+ frame.children += 1;
912
+ state.discovery.set(neighbor, state.timer);
913
+ state.low.set(neighbor, state.timer);
914
+ state.timer += 1;
915
+ return { node: neighbor, parent: frame.node, neighborIndex: 0, children: 0 };
985
916
  }
986
- function reversePostorder(subgraph, root) {
987
- const postorder = [];
988
- const visited = /* @__PURE__ */ new Set([root]);
989
- const stack = [{ id: root, index: 0 }];
917
+ function retreatCutFrame(frame, root, state) {
918
+ if (frame.parent === null) {
919
+ if (frame.children > 1)
920
+ state.articulation.add(frame.node);
921
+ return;
922
+ }
923
+ const parent = frame.parent;
924
+ const childLow = state.low.get(frame.node);
925
+ state.low.set(parent, Math.min(state.low.get(parent), childLow));
926
+ if (parent !== root && childLow >= state.discovery.get(parent))
927
+ state.articulation.add(parent);
928
+ if (childLow > state.discovery.get(parent))
929
+ state.bridges.push(orderedBridge(parent, frame.node));
930
+ }
931
+ function searchComponentCuts(root, adjacency, state, signal) {
932
+ state.discovery.set(root, state.timer);
933
+ state.low.set(root, state.timer);
934
+ state.timer += 1;
935
+ const stack = [
936
+ { node: root, parent: null, neighborIndex: 0, children: 0 }
937
+ ];
990
938
  while (stack.length > 0) {
939
+ signal?.throwIfAborted();
991
940
  const frame = stack.at(-1);
992
- const nexts = subgraph.successors.get(frame.id);
993
- if (frame.index < nexts.length) {
994
- const next = nexts[frame.index];
995
- frame.index += 1;
996
- if (!visited.has(next)) {
997
- visited.add(next);
998
- stack.push({ id: next, index: 0 });
999
- }
941
+ if (frame.neighborIndex < adjacency.get(frame.node).length) {
942
+ const child = advanceCutFrame(frame, adjacency, state);
943
+ if (child !== void 0)
944
+ stack.push(child);
1000
945
  } else {
1001
- postorder.push(frame.id);
946
+ retreatCutFrame(frame, root, state);
1002
947
  stack.pop();
1003
948
  }
1004
949
  }
1005
- return postorder.reverse();
1006
950
  }
1007
- function intersectDominators(left, right, idom, ordinal) {
1008
- let first = left;
1009
- let second = right;
1010
- while (first !== second) {
1011
- while (ordinal.get(first) > ordinal.get(second))
1012
- first = idom.get(first);
1013
- while (ordinal.get(second) > ordinal.get(first))
1014
- second = idom.get(second);
1015
- }
1016
- return first;
1017
- }
1018
- function dominatorCandidate(predecessors, idom, ordinal) {
1019
- let candidate;
1020
- for (const pred of [...predecessors].sort()) {
1021
- if (!idom.has(pred))
1022
- continue;
1023
- candidate = candidate === void 0 ? pred : intersectDominators(candidate, pred, idom, ordinal);
1024
- }
1025
- return candidate;
1026
- }
1027
- function solveImmediateDominators(subgraph, root, order, ordinal, signal) {
1028
- const idom = /* @__PURE__ */ new Map([[root, root]]);
1029
- let changed = true;
1030
- while (changed) {
1031
- changed = false;
1032
- for (const id of order) {
1033
- signal?.throwIfAborted();
1034
- if (id === root)
1035
- continue;
1036
- const candidate = dominatorCandidate(subgraph.predecessors.get(id), idom, ordinal);
1037
- if (candidate !== void 0 && idom.get(id) !== candidate) {
1038
- idom.set(id, candidate);
1039
- changed = true;
1040
- }
1041
- }
1042
- }
1043
- return idom;
1044
- }
1045
- function computeRelationshipDominators(graph, root, options = {}) {
1046
- if (!graph.hasNode(root))
1047
- throw new TypeError(`Relationship node not found: ${root}`);
1048
- if (options.maxDepth !== void 0 && (!Number.isInteger(options.maxDepth) || options.maxDepth < 0))
1049
- throw new TypeError(`Invalid maxDepth bound: ${String(options.maxDepth)}`);
1050
- const subgraph = indexReachableSubgraph(graph, root, options);
1051
- const order = reversePostorder(subgraph, root);
1052
- const ordinal = new Map(order.map((id, index) => [id, index]));
1053
- const idom = solveImmediateDominators(subgraph, root, order, ordinal, options.signal);
1054
- const subtreeSizes = new Map(order.map((id) => [id, 1]));
1055
- for (let index = order.length - 1; index >= 0; index -= 1) {
1056
- const id = order[index];
1057
- if (id === root)
951
+ function findRelationshipCutStructure(graph, options = {}) {
952
+ const adjacency = buildSimpleUndirectedAdjacency(graph, options.kinds);
953
+ const state = {
954
+ discovery: /* @__PURE__ */ new Map(),
955
+ low: /* @__PURE__ */ new Map(),
956
+ timer: 0,
957
+ articulation: /* @__PURE__ */ new Set(),
958
+ bridges: [],
959
+ inspectedEdges: 0
960
+ };
961
+ for (const root of graph.nodes()) {
962
+ if (state.discovery.has(root))
1058
963
  continue;
1059
- const parent = idom.get(id);
1060
- subtreeSizes.set(parent, subtreeSizes.get(parent) + subtreeSizes.get(id));
964
+ searchComponentCuts(root, adjacency, state, options.signal);
1061
965
  }
1062
- const rows = order.filter((id) => id !== root).map((id) => ({
1063
- id,
1064
- idom: idom.get(id),
1065
- dominatedCount: subtreeSizes.get(id) - 1
1066
- })).sort((left, right) => right.dominatedCount - left.dominatedCount || left.id.localeCompare(right.id));
1067
966
  return {
1068
- value: { root, reachableCount: subgraph.order.length, rows },
967
+ value: {
968
+ articulationPoints: [...state.articulation].sort(),
969
+ bridges: state.bridges.sort((left, right) => left.source.localeCompare(right.source) || left.target.localeCompare(right.target))
970
+ },
1069
971
  meta: {
1070
- visitedNodes: subgraph.order.length,
1071
- inspectedEdges: subgraph.inspectedEdges,
1072
- truncated: subgraph.truncated
972
+ visitedNodes: state.discovery.size,
973
+ inspectedEdges: state.inspectedEdges,
974
+ truncated: false
1073
975
  }
1074
976
  };
1075
977
  }
1076
978
 
1077
- // dist/sdk/graph/governance.js
979
+ // dist/sdk/graph/scheduling.js
1078
980
  !(function() {
1079
981
  try {
1080
982
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
1081
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "a78eee2f-0423-565f-91b6-88d0ab46d529");
983
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "b92fecb2-bbc5-5837-906c-bf5d32b2a4d6");
1082
984
  } catch (e2) {
1083
985
  }
1084
986
  })();
1085
- var DEFAULT_MAX_SAMPLE_SIZE = 25;
1086
- var SEVERITY_RANK = {
1087
- error: 0,
1088
- warning: 1,
1089
- info: 2
1090
- };
1091
- function buildFinding(code, severity, policy, describe, subjects, maxSampleSize, remediation) {
1092
- const sorted = [...subjects].sort((left, right) => left.localeCompare(right));
1093
- return {
1094
- code,
1095
- severity,
1096
- policy,
1097
- message: describe(sorted.length),
1098
- count: sorted.length,
1099
- sample: sorted.slice(0, maxSampleSize),
1100
- sample_truncated: sorted.length > maxSampleSize,
1101
- remediation
1102
- };
1103
- }
1104
- function buildOrderingAdjacency(assembly) {
1105
- const registry = assembly.graph.registry();
1106
- const successors = /* @__PURE__ */ new Map();
1107
- for (const edge of assembly.graph.edges()) {
987
+ function collectOrderingParticipation(graph) {
988
+ const registry = graph.registry();
989
+ const forward = /* @__PURE__ */ new Map();
990
+ const participants = /* @__PURE__ */ new Set();
991
+ for (const edge of graph.edges()) {
1108
992
  const definition = registry.require(edge.kind);
1109
993
  if (!definition.ordering)
1110
994
  continue;
1111
- const [predecessor, successor] = (definition.precedence ?? "source_before_target") === "target_before_source" ? [edge.target, edge.source] : [edge.source, edge.target];
1112
- const adjacent = successors.get(predecessor);
1113
- if (adjacent)
1114
- adjacent.push(successor);
995
+ const { predecessor, successor } = orientOrderingEdge(edge, definition);
996
+ participants.add(predecessor);
997
+ participants.add(successor);
998
+ if (predecessor === successor)
999
+ continue;
1000
+ const targets = forward.get(predecessor);
1001
+ if (targets === void 0)
1002
+ forward.set(predecessor, /* @__PURE__ */ new Set([successor]));
1115
1003
  else
1116
- successors.set(predecessor, [successor]);
1117
- }
1118
- for (const adjacent of successors.values())
1119
- adjacent.sort((left, right) => left.localeCompare(right));
1120
- return successors;
1121
- }
1122
- function registerTarjanNode(node, state) {
1123
- state.indexes.set(node, state.nextIndex);
1124
- state.lowLinks.set(node, state.nextIndex);
1125
- state.nextIndex += 1;
1126
- state.stack.push(node);
1127
- state.onStack.add(node);
1128
- }
1129
- function visitNextTarjanNeighbor(frame, frames, successors, state) {
1130
- const neighbors = successors.get(frame.node) ?? [];
1131
- if (frame.neighborIndex >= neighbors.length)
1132
- return false;
1133
- const neighbor = neighbors[frame.neighborIndex];
1134
- frame.neighborIndex += 1;
1135
- if (!state.indexes.has(neighbor)) {
1136
- registerTarjanNode(neighbor, state);
1137
- frames.push({ node: neighbor, neighborIndex: 0 });
1138
- } else if (state.onStack.has(neighbor)) {
1139
- state.lowLinks.set(frame.node, Math.min(state.lowLinks.get(frame.node), state.indexes.get(neighbor)));
1004
+ targets.add(successor);
1140
1005
  }
1141
- return true;
1006
+ return { forward, participants };
1142
1007
  }
1143
- function completeTarjanFrame(frame, frames, successors, state) {
1144
- frames.pop();
1145
- const parent = frames.at(-1);
1146
- if (parent)
1147
- state.lowLinks.set(parent.node, Math.min(state.lowLinks.get(parent.node), state.lowLinks.get(frame.node)));
1148
- if (state.lowLinks.get(frame.node) !== state.indexes.get(frame.node))
1149
- return;
1150
- const component = [];
1151
- while (true) {
1152
- const member = state.stack.pop();
1153
- state.onStack.delete(member);
1154
- component.push(member);
1155
- if (member === frame.node)
1156
- break;
1008
+ function latestFinishFor(successors, acyclic, latestStart, makespan) {
1009
+ if (successors === void 0)
1010
+ return makespan;
1011
+ let bound = makespan;
1012
+ for (const successor of successors) {
1013
+ if (!acyclic.has(successor))
1014
+ continue;
1015
+ bound = Math.min(bound, latestStart.get(successor));
1157
1016
  }
1158
- if (component.length > 1 || component.length === 1 && successors.get(component[0])?.includes(component[0]))
1159
- state.components.push(component.sort((left, right) => left.localeCompare(right)));
1017
+ return bound;
1160
1018
  }
1161
- function collectOrderingCycles(successors) {
1162
- const state = {
1163
- indexes: /* @__PURE__ */ new Map(),
1164
- lowLinks: /* @__PURE__ */ new Map(),
1165
- onStack: /* @__PURE__ */ new Set(),
1166
- stack: [],
1167
- components: [],
1168
- nextIndex: 0
1019
+ function scheduleRow(id, earliestStart, latestStart) {
1020
+ const slack = latestStart - earliestStart;
1021
+ return {
1022
+ id,
1023
+ earliestStart,
1024
+ earliestFinish: earliestStart + 1,
1025
+ latestStart,
1026
+ latestFinish: latestStart + 1,
1027
+ slack,
1028
+ critical: slack === 0
1169
1029
  };
1170
- const roots = [...successors.keys()].sort((left, right) => left.localeCompare(right));
1171
- for (const root of roots) {
1172
- if (state.indexes.has(root))
1173
- continue;
1174
- const frames = [{ node: root, neighborIndex: 0 }];
1175
- registerTarjanNode(root, state);
1176
- while (frames.length > 0) {
1177
- const frame = frames.at(-1);
1178
- if (visitNextTarjanNeighbor(frame, frames, successors, state))
1179
- continue;
1180
- completeTarjanFrame(frame, frames, successors, state);
1030
+ }
1031
+ function computeScheduleRows(topoParticipants, participation, depth, acyclic, makespan) {
1032
+ const latestStart = /* @__PURE__ */ new Map();
1033
+ for (let index = topoParticipants.length - 1; index >= 0; index -= 1) {
1034
+ const id = topoParticipants[index];
1035
+ const finish = latestFinishFor(participation.forward.get(id), acyclic, latestStart, makespan);
1036
+ latestStart.set(id, finish - 1);
1037
+ }
1038
+ return topoParticipants.map((id) => scheduleRow(id, depth[id], latestStart.get(id))).sort((left, right) => left.slack - right.slack || left.earliestStart - right.earliestStart || left.id.localeCompare(right.id));
1039
+ }
1040
+ function analyzeRelationshipSchedule(graph, options = {}) {
1041
+ options.signal?.throwIfAborted();
1042
+ const execution = analyzeRelationshipExecution(graph, { registry: graph.registry() });
1043
+ const participation = collectOrderingParticipation(graph);
1044
+ const acyclic = new Set(execution.order);
1045
+ const topoParticipants = execution.order.filter((id) => participation.participants.has(id));
1046
+ const makespan = topoParticipants.reduce((peak, id) => Math.max(peak, execution.depth[id] + 1), 0);
1047
+ const rows = computeScheduleRows(topoParticipants, participation, execution.depth, acyclic, makespan);
1048
+ const scheduled = rows.length > 0;
1049
+ return {
1050
+ exact: true,
1051
+ acyclic: execution.acyclic,
1052
+ makespan,
1053
+ scheduledCount: rows.length,
1054
+ // A single-node execution "path" over a workspace with no order-bearing
1055
+ // edge is not a real critical path, so report it only when work is scheduled.
1056
+ criticalPath: scheduled ? execution.criticalPath : [],
1057
+ criticalPathLength: scheduled ? execution.criticalPathLength : 0,
1058
+ cycles: execution.cycles,
1059
+ rows,
1060
+ provenance: {
1061
+ algorithm: "critical-path-method",
1062
+ edgeFamily: "ordering",
1063
+ weighting: "unit"
1181
1064
  }
1065
+ };
1066
+ }
1067
+
1068
+ // dist/sdk/graph/durable-cache.js
1069
+ import path from "node:path";
1070
+ !(function() {
1071
+ try {
1072
+ var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
1073
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "3c975105-d3de-51f7-939f-1abafd4c3672");
1074
+ } catch (e2) {
1182
1075
  }
1183
- return state.components.sort((left, right) => left[0].localeCompare(right[0]));
1076
+ })();
1077
+ var GRAPH_DURABLE_CACHE_VERSION = 1;
1078
+ var GRAPH_DURABLE_CACHE_MIN_ITEMS = 500;
1079
+ var MAX_DURABLE_RESULTS = 64;
1080
+ var DURABLE_GRAPH_CACHE_LOCK_ID = "graph-durable-cache";
1081
+ function acquireDurableGraphCacheLock(pmRoot) {
1082
+ return acquireLock(pmRoot, DURABLE_GRAPH_CACHE_LOCK_ID, 30, `graph-cache:${process.pid}`, false, false, 3e3);
1184
1083
  }
1185
- function formatDanglingReference(reference) {
1186
- return `${reference.holder_id} -> ${reference.target_id} (${reference.kind})`;
1084
+ function durableGraphCachePath(pmRoot) {
1085
+ return path.join(pmRoot, "runtime", "graph-cache.json");
1187
1086
  }
1188
- function appendFinding(findings, subjects, maxSampleSize, code, severity, policy, describe, remediation) {
1189
- if (subjects.length === 0)
1190
- return;
1191
- findings.push(buildFinding(code, severity, policy, describe, subjects, maxSampleSize, remediation));
1192
- }
1193
- function collectIntegrityFindings(assembly, isTerminal, maxSampleSize) {
1194
- const findings = [];
1195
- const references = [
1196
- ...assembly.dangling.active,
1197
- ...assembly.dangling.legacy_terminal
1198
- ].filter((reference) => !reference.no_active_blocker_sentinel);
1199
- appendFinding(findings, references.filter((reference) => !isTerminal(reference.holder_status)).map(formatDanglingReference), maxSampleSize, "missing_reference_active", "error", "Active items must not reference absent targets; missing prerequisites distort scheduling.", (count) => `${count} active dangling reference(s) to absent items`, "Restore or re-create the referenced item, or remove/retype the reference on the holder.");
1200
- appendFinding(findings, references.filter((reference) => isTerminal(reference.holder_status)).map(formatDanglingReference), maxSampleSize, "missing_reference_terminal", "info", "Terminal items may retain historical references, but absent targets remain unexplainable context.", (count) => `${count} terminal dangling reference(s) to absent items`, "Leave as history debt or clean up in a dedicated changelog-safe closed-item batch.");
1201
- appendFinding(findings, assembly.dangling.no_active_blocker_sentinels.map(formatDanglingReference), maxSampleSize, "legacy_no_blocker_sentinel", "info", "The pre-structured-dependency no-active-blocker sentinel is retired; real edges carry blocker state.", (count) => `${count} legacy no-active-blocker sentinel reference(s)`, "Delete the sentinel reference; blocker state is derived from blocked_by edges.");
1202
- return findings;
1203
- }
1204
- function isActiveAuditMember(member, nodeStates) {
1205
- const state = nodeStates.get(member);
1206
- if (!state)
1207
- return true;
1208
- return !state.terminal;
1209
- }
1210
- function collectOrderingFindings(assembly, nodeStates, isBlocked, maxSampleSize) {
1211
- const findings = [];
1212
- const orderingAdjacency = buildOrderingAdjacency(assembly);
1213
- for (const cycle of collectOrderingCycles(orderingAdjacency)) {
1214
- const active = cycle.some((member) => isActiveAuditMember(member, nodeStates));
1215
- findings.push(active ? buildFinding("ordering_cycle", "error", "Order-bearing relationship kinds must stay acyclic; a cycle makes every member unschedulable.", (count) => `execution-order cycle across ${count} item(s)`, cycle, maxSampleSize, "Remove or retype one ordering edge inside the cycle, or split the work so precedence is linear.") : buildFinding("legacy_ordering_cycle", "info", "Ordering cycles between exclusively terminal items are historical contradictions with no scheduling effect.", (count) => `terminal-only execution-order cycle across ${count} item(s)`, cycle, maxSampleSize, "Leave as history debt, or clean up in a dedicated changelog-safe closed-item batch; never repair closed items ad hoc."));
1216
- }
1217
- const predecessorsByNode = /* @__PURE__ */ new Map();
1218
- for (const [predecessor, adjacent] of orderingAdjacency)
1219
- for (const successor of adjacent) {
1220
- const predecessors = predecessorsByNode.get(successor);
1221
- if (predecessors)
1222
- predecessors.push(predecessor);
1223
- else
1224
- predecessorsByNode.set(successor, [predecessor]);
1225
- }
1226
- const staleLifecycleBlocks = [...nodeStates.values()].filter((state) => !state.missing && !state.terminal && isBlocked(state.status) && !(predecessorsByNode.get(state.id) ?? []).some((predecessor) => {
1227
- const predecessorState = nodeStates.get(predecessor);
1228
- return predecessorState === void 0 || !predecessorState.terminal;
1229
- })).map((state) => state.id);
1230
- appendFinding(findings, staleLifecycleBlocks, maxSampleSize, "stale_lifecycle_block", "warning", "A blocked lifecycle status must be backed by at least one open ordering predecessor.", (count) => `${count} status-blocked item(s) with no open blocker edge`, "Re-open the missing prerequisite as an edge, or move the item back to an active status.");
1231
- return findings;
1232
- }
1233
- function formatDuplicateEdgeGroup(group) {
1234
- const kinds = group.edges.map((edge) => edge.kind).sort((left, right) => left.localeCompare(right));
1235
- return `${group.from} -> ${group.to} (${kinds.join(" + ")})`;
1236
- }
1237
- function collectDuplicateRelationshipEdgeGroups(assembly) {
1238
- const registry = assembly.graph.registry();
1239
- const groups = /* @__PURE__ */ new Map();
1240
- for (const edge of assembly.graph.edges()) {
1241
- const definition = registry.require(edge.kind);
1242
- if (!isTransitiveKind(definition))
1243
- continue;
1244
- const oriented = orientTransitiveEdge(edge, definition);
1245
- if (oriented.from === oriented.to)
1246
- continue;
1247
- const key = `${transitiveFamilyKey(definition)}::${oriented.from}::${oriented.to}`;
1248
- const group = groups.get(key);
1249
- if (group)
1250
- group.edges.push(edge);
1251
- else
1252
- groups.set(key, { ...oriented, edges: [edge] });
1253
- }
1254
- const duplicated = [...groups.values()].filter((group) => group.edges.length >= 2);
1255
- for (const group of duplicated)
1256
- group.edges.sort((left, right) => left.kind.localeCompare(right.kind));
1257
- return duplicated.sort((left, right) => left.from.localeCompare(right.from) || left.to.localeCompare(right.to));
1258
- }
1259
- function collectDuplicateEdgeFindings(assembly, nodeStates, maxSampleSize) {
1260
- const active = [];
1261
- const legacy = [];
1262
- for (const group of collectDuplicateRelationshipEdgeGroups(assembly)) {
1263
- const subjects = isActiveAuditMember(group.from, nodeStates) || isActiveAuditMember(group.to, nodeStates) ? active : legacy;
1264
- subjects.push(formatDuplicateEdgeGroup(group));
1265
- }
1266
- const findings = [];
1267
- appendFinding(findings, active, maxSampleSize, "duplicate_edge", "info", "One semantic relationship should be stored once; parallel same-family spellings (reciprocal inverse pairs included) add no information and skew degree metrics.", (count) => `${count} duplicated relationship(s) between active endpoints`, "Remove all but one stored spelling of the relationship; keep the canonical direction the holder declared first.");
1268
- appendFinding(findings, legacy, maxSampleSize, "legacy_duplicate_edge", "info", "Duplicated spellings between exclusively terminal items are historical noise with no scheduling effect.", (count) => `${count} duplicated relationship(s) between terminal endpoints`, "Leave as history debt or clean up in a dedicated changelog-safe closed-item batch.");
1269
- return findings;
1270
- }
1271
- function collectCoverageReport(assembly, nodeStates, exemptIsolates, maxSampleSize, edgesByKind) {
1272
- let activeNodes = 0;
1273
- let missingNodes = 0;
1274
- let isolatedActiveNodes = 0;
1275
- let degreeLeqOneActive = 0;
1276
- const isolates = [];
1277
- const sparse = [];
1278
- for (const id of assembly.graph.nodes()) {
1279
- const state = nodeStates.get(id);
1280
- if (!state)
1281
- continue;
1282
- if (state.missing) {
1283
- missingNodes += 1;
1284
- continue;
1285
- }
1286
- if (state.terminal)
1287
- continue;
1288
- activeNodes += 1;
1289
- const degree = assembly.graph.incidentEdges(id).length;
1290
- if (degree > 1)
1291
- continue;
1292
- degreeLeqOneActive += 1;
1293
- if (degree === 0)
1294
- isolatedActiveNodes += 1;
1295
- if (exemptIsolates.has(id.toLowerCase()))
1296
- continue;
1297
- if (degree === 0)
1298
- isolates.push(id);
1299
- else
1300
- sparse.push(id);
1087
+ function graphAuditBaselinePath(pmRoot) {
1088
+ return path.join(pmRoot, "runtime", "graph-audit-baseline.json");
1089
+ }
1090
+ function decodeEnvelope(raw) {
1091
+ if (raw === null)
1092
+ return void 0;
1093
+ try {
1094
+ const parsed = JSON.parse(raw);
1095
+ if (typeof parsed !== "object" || parsed === null || parsed.version !== GRAPH_DURABLE_CACHE_VERSION || typeof parsed.fingerprint !== "string" || typeof parsed.saved_at !== "string" || typeof parsed.results !== "object" || parsed.results === null || Array.isArray(parsed.results))
1096
+ return void 0;
1097
+ return parsed;
1098
+ } catch {
1099
+ return void 0;
1301
1100
  }
1302
- const findings = [];
1303
- appendFinding(findings, isolates, maxSampleSize, "isolated_active_node", "warning", "Active work should be reachable from the graph unless explicitly declared a valid isolate.", (count) => `${count} active item(s) with no relationships`, "Link the item to its parent, prerequisite, or origin \u2014 or register it as an exempt isolate.");
1304
- appendFinding(findings, sparse, maxSampleSize, "sparse_active_node", "info", "Active items with a single edge often miss an honest semantic partner; sparse is not automatically defective.", (count) => `${count} active item(s) with exactly one relationship`, "Investigate for an honest second edge (story->task, defect family, cross-epic complement); do not fabricate one.");
1101
+ }
1102
+ async function openDurableGraphCache(pmRoot, fingerprint) {
1103
+ const raw = await readFileIfExists(durableGraphCachePath(pmRoot));
1104
+ const envelope = decodeEnvelope(raw);
1105
+ const fresh = envelope?.fingerprint === fingerprint;
1305
1106
  return {
1306
- findings,
1307
- profile: {
1308
- nodes: assembly.graph.nodes().length,
1309
- edges: assembly.graph.edges().length,
1310
- edges_by_kind: Object.fromEntries(Object.entries(edgesByKind).sort(([left], [right]) => left.localeCompare(right))),
1311
- active_nodes: activeNodes,
1312
- missing_nodes: missingNodes,
1313
- isolated_active_nodes: isolatedActiveNodes,
1314
- degree_leq_one_active_nodes: degreeLeqOneActive
1315
- }
1107
+ exists: raw !== null,
1108
+ fresh,
1109
+ results: fresh ? envelope.results : {}
1316
1110
  };
1317
1111
  }
1318
- function auditWorkspaceRelationshipGraph(assembly, options = {}) {
1319
- const isTerminal = options.isTerminal ?? ((status) => status === "closed" || status === "canceled");
1320
- const isBlocked = options.isBlocked ?? ((status) => status === "blocked");
1321
- const maxSampleSize = options.maxSampleSize ?? DEFAULT_MAX_SAMPLE_SIZE;
1322
- if (!Number.isInteger(maxSampleSize) || maxSampleSize < 1)
1323
- throw new TypeError(`Invalid audit sample bound: ${String(options.maxSampleSize)}`);
1324
- const exemptIsolates = new Set((options.exemptIsolates ?? []).filter((id) => typeof id === "string").map((id) => id.trim().toLowerCase()));
1325
- const nodeStates = new Map(assembly.details.map((detail) => [
1326
- detail.id,
1327
- {
1328
- id: detail.id,
1329
- status: detail.status,
1330
- missing: assembly.missingIdSet.has(detail.id.toLowerCase()),
1331
- terminal: isTerminal(detail.status)
1332
- }
1333
- ]));
1334
- options.signal?.throwIfAborted();
1335
- const edgesByKind = {};
1336
- for (const edge of assembly.graph.edges())
1337
- edgesByKind[edge.kind] = (edgesByKind[edge.kind] ?? 0) + 1;
1338
- const findings = collectIntegrityFindings(assembly, isTerminal, maxSampleSize);
1339
- options.signal?.throwIfAborted();
1340
- findings.push(...collectOrderingFindings(assembly, nodeStates, isBlocked, maxSampleSize));
1341
- options.signal?.throwIfAborted();
1342
- findings.push(...collectDuplicateEdgeFindings(assembly, nodeStates, maxSampleSize));
1343
- options.signal?.throwIfAborted();
1344
- const coverage = collectCoverageReport(assembly, nodeStates, exemptIsolates, maxSampleSize, edgesByKind);
1345
- findings.push(...coverage.findings);
1346
- findings.sort((left, right) => SEVERITY_RANK[left.severity] - SEVERITY_RANK[right.severity] || left.code.localeCompare(right.code) || left.sample[0].localeCompare(right.sample[0]));
1112
+ async function persistDurableGraphResult(pmRoot, fingerprint, view, queryKey, result) {
1113
+ const release = await acquireDurableGraphCacheLock(pmRoot);
1114
+ try {
1115
+ const envelope = decodeEnvelope(await readFileIfExists(durableGraphCachePath(pmRoot)));
1116
+ const results = envelope?.fingerprint === fingerprint ? envelope.results : {};
1117
+ delete results[queryKey];
1118
+ results[queryKey] = result;
1119
+ const keys = Object.keys(results);
1120
+ for (const stale of keys.slice(0, Math.max(0, keys.length - MAX_DURABLE_RESULTS)))
1121
+ delete results[stale];
1122
+ await writeFileAtomic(durableGraphCachePath(pmRoot), JSON.stringify({
1123
+ version: GRAPH_DURABLE_CACHE_VERSION,
1124
+ fingerprint,
1125
+ saved_at: (/* @__PURE__ */ new Date()).toISOString(),
1126
+ results
1127
+ }));
1128
+ view.results = results;
1129
+ } finally {
1130
+ await release();
1131
+ }
1132
+ }
1133
+ async function clearDurableGraphCache(pmRoot) {
1134
+ const release = await acquireDurableGraphCacheLock(pmRoot);
1135
+ try {
1136
+ await removeFileIfExists(durableGraphCachePath(pmRoot));
1137
+ } finally {
1138
+ await release();
1139
+ }
1140
+ }
1141
+ async function durableGraphCacheStatus(pmRoot, fingerprint) {
1142
+ const cachePath = durableGraphCachePath(pmRoot);
1143
+ const raw = await readFileIfExists(cachePath);
1144
+ const envelope = decodeEnvelope(raw);
1145
+ if (envelope === void 0)
1146
+ return { exists: raw !== null, fresh: false, entry_count: 0 };
1347
1147
  return {
1348
- findings,
1349
- profile: coverage.profile
1148
+ exists: true,
1149
+ fresh: envelope.fingerprint === fingerprint,
1150
+ entry_count: Object.keys(envelope.results).length,
1151
+ fingerprint: envelope.fingerprint.slice(0, 12),
1152
+ saved_at: envelope.saved_at,
1153
+ bytes: Buffer.byteLength(raw, "utf8")
1350
1154
  };
1351
1155
  }
1156
+ function shouldPersistDurableGraphCache(itemCount, envelopeExists) {
1157
+ return envelopeExists || itemCount >= GRAPH_DURABLE_CACHE_MIN_ITEMS;
1158
+ }
1159
+ function isNonnegativeCountRecord(value) {
1160
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((count) => Number.isInteger(count) && count >= 0);
1161
+ }
1162
+ function isNonnegativeCoverageByTypeRecord(value) {
1163
+ if (typeof value !== "object" || value === null || Array.isArray(value))
1164
+ return false;
1165
+ return Object.values(value).every((entry) => typeof entry === "object" && entry !== null && !Array.isArray(entry) && [entry.active, entry.isolated, entry.degree_leq_one].every((count) => Number.isInteger(count) && count >= 0));
1166
+ }
1167
+ function decodeBaseline(raw) {
1168
+ if (raw === null)
1169
+ return void 0;
1170
+ try {
1171
+ const parsed = JSON.parse(raw);
1172
+ if (typeof parsed !== "object" || parsed === null)
1173
+ return void 0;
1174
+ const snapshot = parsed;
1175
+ const profile = snapshot.profile;
1176
+ if (typeof snapshot.saved_at !== "string" || typeof snapshot.fingerprint !== "string" || !isNonnegativeCountRecord(snapshot.affected_subjects_by_code) || typeof profile !== "object" || profile === null || ![
1177
+ profile.nodes,
1178
+ profile.edges,
1179
+ profile.active_nodes,
1180
+ profile.missing_nodes,
1181
+ profile.isolated_active_nodes,
1182
+ profile.degree_leq_one_active_nodes
1183
+ ].every((value) => Number.isInteger(value) && value >= 0) || !isNonnegativeCountRecord(profile.edges_by_kind) || profile.coverage_by_type !== void 0 && !isNonnegativeCoverageByTypeRecord(profile.coverage_by_type))
1184
+ return void 0;
1185
+ return {
1186
+ ...snapshot,
1187
+ profile: {
1188
+ ...profile,
1189
+ coverage_by_type: profile.coverage_by_type ?? {}
1190
+ }
1191
+ };
1192
+ } catch {
1193
+ return void 0;
1194
+ }
1195
+ }
1196
+ async function loadGraphAuditBaseline(pmRoot) {
1197
+ return decodeBaseline(await readFileIfExists(graphAuditBaselinePath(pmRoot)));
1198
+ }
1199
+ async function saveGraphAuditBaseline(pmRoot, snapshot) {
1200
+ await writeFileAtomic(graphAuditBaselinePath(pmRoot), JSON.stringify(snapshot));
1201
+ }
1352
1202
 
1353
1203
  // dist/sdk/graph/remediation.js
1354
1204
  !(function() {
1355
1205
  try {
1356
1206
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
1357
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "662a9796-dbb3-5fd5-bc23-22dba9adde9e");
1207
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "ebb01d6f-d876-5196-9937-24528a66b160");
1358
1208
  } catch (e2) {
1359
1209
  }
1360
1210
  })();
@@ -1397,6 +1247,16 @@ var FINDING_STEP_TEMPLATES = {
1397
1247
  confidence: "high",
1398
1248
  rationale: "Duplicated spellings between terminal items are historical noise; waive or batch changelog-safe cleanup."
1399
1249
  },
1250
+ duplicate_dependency_row: {
1251
+ op: "remove",
1252
+ confidence: "high",
1253
+ rationale: "The identical dependency row is stored more than once on the holder; drop the repeats so the row exists exactly once \u2014 graph semantics are unchanged."
1254
+ },
1255
+ legacy_duplicate_dependency_row: {
1256
+ op: "waive",
1257
+ confidence: "high",
1258
+ rationale: "Repeated identical rows on terminal holders are storage noise; waive or clean up only in a changelog-safe closed-item batch."
1259
+ },
1400
1260
  stale_lifecycle_block: {
1401
1261
  op: "investigate",
1402
1262
  confidence: "medium",
@@ -1484,7 +1344,7 @@ function planRelationshipRemediation(assembly, options = {}) {
1484
1344
  !(function() {
1485
1345
  try {
1486
1346
  var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
1487
- n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "f43d15d0-c4a0-533a-b125-4333554e4ea0");
1347
+ n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "7f767038-30c6-555b-b9ac-adaf98b154e2");
1488
1348
  } catch (e2) {
1489
1349
  }
1490
1350
  })();
@@ -1583,10 +1443,10 @@ function runGraphPaths(root, target, invocation) {
1583
1443
  count: result.value.length,
1584
1444
  ...projectQueryMeta(result.meta),
1585
1445
  ...invocation.summary ? {} : {
1586
- paths: result.value.map((path3) => ({
1587
- nodes: path3.nodes,
1588
- kinds: path3.edges.map((edge) => edge.kind),
1589
- length: path3.length
1446
+ paths: result.value.map((path4) => ({
1447
+ nodes: path4.nodes,
1448
+ kinds: path4.edges.map((edge) => edge.kind),
1449
+ length: path4.length
1590
1450
  }))
1591
1451
  }
1592
1452
  };
@@ -1651,7 +1511,8 @@ function runGraphAudit(invocation, isTerminal) {
1651
1511
  const report = auditWorkspaceRelationshipGraph(invocation.assembly, {
1652
1512
  isTerminal,
1653
1513
  ...invocation.sample === void 0 ? {} : { maxSampleSize: invocation.sample },
1654
- ...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates }
1514
+ ...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates },
1515
+ ...invocation.exemptIsolateTypes.length === 0 ? {} : { isolateExemptTypes: invocation.exemptIsolateTypes }
1655
1516
  });
1656
1517
  const bySeverity = {};
1657
1518
  const byCode = {};
@@ -1753,13 +1614,87 @@ function runGraphDominators(root, invocation) {
1753
1614
  }
1754
1615
  };
1755
1616
  }
1617
+ function runGraphSlack(invocation) {
1618
+ const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
1619
+ const analysis = analyzeRelationshipSchedule(invocation.assembly.graph);
1620
+ const criticalCount = analysis.rows.filter((row) => row.critical).length;
1621
+ return {
1622
+ subcommand: "slack",
1623
+ acyclic: analysis.acyclic,
1624
+ makespan: analysis.makespan,
1625
+ scheduled_count: analysis.scheduledCount,
1626
+ critical_count: criticalCount,
1627
+ critical_path_length: analysis.criticalPathLength,
1628
+ cycle_count: analysis.cycles.length,
1629
+ truncated: analysis.rows.length > limit,
1630
+ ...invocation.summary ? {} : {
1631
+ critical_path: analysis.criticalPath,
1632
+ rows: analysis.rows.slice(0, limit).map((row) => ({
1633
+ id: row.id,
1634
+ earliest_start: row.earliestStart,
1635
+ latest_start: row.latestStart,
1636
+ slack: row.slack,
1637
+ critical: row.critical
1638
+ }))
1639
+ }
1640
+ };
1641
+ }
1642
+ function runGraphCentrality(invocation) {
1643
+ const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
1644
+ const result = computeRelationshipCentrality(invocation.assembly.graph, {
1645
+ ...invocation.kinds === void 0 ? {} : { kinds: invocation.kinds }
1646
+ });
1647
+ const analysis = result.value;
1648
+ return {
1649
+ subcommand: "centrality",
1650
+ node_count: analysis.nodeCount,
1651
+ edge_count: analysis.edgeCount,
1652
+ truncated: analysis.rows.length > limit,
1653
+ cost: {
1654
+ visited_nodes: result.meta.visitedNodes,
1655
+ inspected_edges: result.meta.inspectedEdges
1656
+ },
1657
+ ...invocation.summary ? {} : {
1658
+ rows: analysis.rows.slice(0, limit).map((row) => ({
1659
+ id: row.id,
1660
+ degree: row.degree,
1661
+ in_degree: row.inDegree,
1662
+ out_degree: row.outDegree,
1663
+ betweenness: row.betweenness,
1664
+ closeness: row.closeness
1665
+ }))
1666
+ }
1667
+ };
1668
+ }
1669
+ function runGraphArticulation(invocation) {
1670
+ const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
1671
+ const result = findRelationshipCutStructure(invocation.assembly.graph, {
1672
+ ...invocation.kinds === void 0 ? {} : { kinds: invocation.kinds }
1673
+ });
1674
+ const { articulationPoints, bridges } = result.value;
1675
+ return {
1676
+ subcommand: "articulation",
1677
+ articulation_count: articulationPoints.length,
1678
+ bridge_count: bridges.length,
1679
+ truncated: articulationPoints.length > limit || bridges.length > limit,
1680
+ cost: {
1681
+ visited_nodes: result.meta.visitedNodes,
1682
+ inspected_edges: result.meta.inspectedEdges
1683
+ },
1684
+ ...invocation.summary ? {} : {
1685
+ articulation_points: articulationPoints.slice(0, limit),
1686
+ bridges: bridges.slice(0, limit)
1687
+ }
1688
+ };
1689
+ }
1756
1690
  function runGraphPlan(invocation, isTerminal) {
1757
1691
  const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
1758
1692
  const plan = planRelationshipRemediation(invocation.assembly, {
1759
1693
  isTerminal,
1760
1694
  redundancyLimit: limit,
1761
1695
  ...invocation.sample === void 0 ? {} : { maxSampleSize: invocation.sample },
1762
- ...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates }
1696
+ ...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates },
1697
+ ...invocation.exemptIsolateTypes.length === 0 ? {} : { isolateExemptTypes: invocation.exemptIsolateTypes }
1763
1698
  });
1764
1699
  const byOp = {};
1765
1700
  const byCode = {};
@@ -1798,6 +1733,9 @@ function buildGraphQueryKey(subcommand, root, pathsTarget, invocation) {
1798
1733
  exemptIsolates: [
1799
1734
  ...new Set(invocation.exemptIsolates.map((id) => id.toLowerCase()))
1800
1735
  ].sort(),
1736
+ exemptIsolateTypes: [
1737
+ ...new Set(invocation.exemptIsolateTypes.map((type) => type.toLowerCase()))
1738
+ ].sort(),
1801
1739
  summary: invocation.summary
1802
1740
  });
1803
1741
  }
@@ -1814,12 +1752,82 @@ function executeGraphSubcommand(subcommand, root, pathsTarget, invocation, isTer
1814
1752
  return runGraphRedundancy(invocation);
1815
1753
  if (subcommand === "dominators")
1816
1754
  return runGraphDominators(root, invocation);
1755
+ if (subcommand === "slack")
1756
+ return runGraphSlack(invocation);
1757
+ if (subcommand === "centrality")
1758
+ return runGraphCentrality(invocation);
1759
+ if (subcommand === "articulation")
1760
+ return runGraphArticulation(invocation);
1817
1761
  if (subcommand === "paths")
1818
1762
  return runGraphPaths(root, pathsTarget, invocation);
1819
1763
  if (subcommand === "impact")
1820
1764
  return runGraphImpact(root, invocation);
1821
1765
  return runGraphTraversal(subcommand, root, invocation);
1822
1766
  }
1767
+ function assertGraphFlagScope(subcommand, options) {
1768
+ if (subcommand !== "index" && (options.rebuild === true || options.clear === true))
1769
+ throw new PmCliError("--rebuild and --clear apply only to graph index.", EXIT_CODE.USAGE);
1770
+ if (subcommand !== "audit" && options.saveBaseline === true)
1771
+ throw new PmCliError("--save-baseline applies only to graph audit.", EXIT_CODE.USAGE);
1772
+ if (subcommand === "slack" && options.kind !== void 0)
1773
+ throw new PmCliError("graph slack analyzes every ordering kind; --kind is not supported.", EXIT_CODE.USAGE);
1774
+ if (options.rebuild === true && options.clear === true)
1775
+ throw new PmCliError("graph index accepts either --rebuild or --clear, not both.", EXIT_CODE.USAGE);
1776
+ }
1777
+ async function runGraphIndex(pmRoot, fingerprint, invocation, itemCount, isTerminal, options) {
1778
+ let action = "status";
1779
+ if (options.clear === true) {
1780
+ await clearDurableGraphCache(pmRoot);
1781
+ action = "cleared";
1782
+ }
1783
+ if (options.rebuild === true) {
1784
+ await clearDurableGraphCache(pmRoot);
1785
+ const view = await openDurableGraphCache(pmRoot, fingerprint);
1786
+ const warmInvocation = {
1787
+ assembly: invocation.assembly,
1788
+ direction: "both",
1789
+ exemptIsolates: [],
1790
+ exemptIsolateTypes: [],
1791
+ saveBaseline: false,
1792
+ summary: true
1793
+ };
1794
+ for (const warm of ["analyze", "audit"]) {
1795
+ await persistDurableGraphResult(pmRoot, fingerprint, view, buildGraphQueryKey(warm, void 0, void 0, warmInvocation), executeGraphSubcommand(warm, void 0, void 0, warmInvocation, isTerminal));
1796
+ }
1797
+ action = "rebuilt";
1798
+ }
1799
+ const status = await durableGraphCacheStatus(pmRoot, fingerprint);
1800
+ return {
1801
+ subcommand: "index",
1802
+ action,
1803
+ state: status.exists ? status.fresh ? "fresh" : "stale" : "absent",
1804
+ entry_count: status.entry_count,
1805
+ item_count: itemCount,
1806
+ min_items_threshold: GRAPH_DURABLE_CACHE_MIN_ITEMS,
1807
+ persist_enabled: shouldPersistDurableGraphCache(itemCount, status.exists),
1808
+ current_fingerprint: fingerprint.slice(0, 12),
1809
+ ...status.saved_at === void 0 ? {} : { saved_at: status.saved_at },
1810
+ ...status.bytes === void 0 ? {} : { bytes: status.bytes }
1811
+ };
1812
+ }
1813
+ async function applyAuditBaseline(pmRoot, fingerprint, audit, saveBaseline) {
1814
+ const current = {
1815
+ saved_at: (/* @__PURE__ */ new Date()).toISOString(),
1816
+ fingerprint,
1817
+ affected_subjects_by_code: audit.affected_subjects_by_code,
1818
+ profile: audit.profile
1819
+ };
1820
+ const stored = await loadGraphAuditBaseline(pmRoot);
1821
+ if (saveBaseline)
1822
+ await saveGraphAuditBaseline(pmRoot, current);
1823
+ return stored === void 0 ? audit : { ...audit, baseline: diffRelationshipAuditSnapshots(stored, current) };
1824
+ }
1825
+ async function persistDurableGraphResultBestEffort(pmRoot, fingerprint, view, queryKey, result) {
1826
+ try {
1827
+ await persistDurableGraphResult(pmRoot, fingerprint, view, queryKey, result);
1828
+ } catch {
1829
+ }
1830
+ }
1823
1831
  async function runGraph(subcommandRaw, id, target, options, global2) {
1824
1832
  const subcommand = parseGraphSubcommand(subcommandRaw, id, target);
1825
1833
  const pmRoot = resolvePmRoot(process.cwd(), global2.path);
@@ -1831,8 +1839,10 @@ async function runGraph(subcommandRaw, id, target, options, global2) {
1831
1839
  const items = await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, void 0, settings.schema);
1832
1840
  const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
1833
1841
  const isTerminal = (status) => isTerminalStatus(status, statusRegistry);
1834
- const kinds = parseKinds(options.kind);
1835
- const lookup = workspaceGraphCache().lookup(pmRoot, computeWorkspaceGraphFingerprint(items, isTerminal), () => assembleWorkspaceRelationshipGraph(items, isTerminal));
1842
+ assertGraphFlagScope(subcommand, options);
1843
+ const relationshipRegistry = resolveWorkspaceRelationshipKindRegistry();
1844
+ const kinds = parseKinds(options.kind, relationshipRegistry);
1845
+ const lookup = workspaceGraphCache().lookup(pmRoot, computeWorkspaceGraphFingerprint(items, isTerminal, relationshipRegistry), () => assembleWorkspaceRelationshipGraph(items, isTerminal, relationshipRegistry));
1836
1846
  const invocation = {
1837
1847
  assembly: lookup.assembly,
1838
1848
  ...kinds === void 0 ? {} : { kinds },
@@ -1843,17 +1853,31 @@ async function runGraph(subcommandRaw, id, target, options, global2) {
1843
1853
  maxPaths: parsePositiveInteger(options.maxPaths, "max-paths"),
1844
1854
  sample: parsePositiveInteger(options.sample, "sample"),
1845
1855
  exemptIsolates: normalizeIdList(options.exemptIsolate),
1856
+ exemptIsolateTypes: normalizeIdList(options.exemptIsolateType),
1857
+ saveBaseline: options.saveBaseline === true,
1846
1858
  summary: options.summary === true
1847
1859
  };
1860
+ if (subcommand === "index") {
1861
+ return runGraphIndex(pmRoot, lookup.fingerprint, invocation, items.length, isTerminal, options);
1862
+ }
1848
1863
  const root = ROOTED_SUBCOMMANDS.has(subcommand) ? canonicalizeGraphId(invocation.assembly, id) : void 0;
1849
1864
  const pathsTarget = subcommand === "paths" ? canonicalizeGraphId(invocation.assembly, target) : void 0;
1850
- const memo = lookup.memoize(buildGraphQueryKey(subcommand, root, pathsTarget, invocation), () => executeGraphSubcommand(subcommand, root, pathsTarget, invocation, isTerminal));
1865
+ const queryKey = buildGraphQueryKey(subcommand, root, pathsTarget, invocation);
1866
+ const durableView = await openDurableGraphCache(pmRoot, lookup.fingerprint);
1867
+ const durableValue = durableView.results[queryKey];
1868
+ const memo = lookup.memoize(queryKey, () => durableValue !== void 0 ? structuredClone(durableValue) : executeGraphSubcommand(subcommand, root, pathsTarget, invocation, isTerminal));
1869
+ const persistEnabled = shouldPersistDurableGraphCache(items.length, durableView.exists);
1870
+ if (!memo.reused && durableValue === void 0 && persistEnabled) {
1871
+ await persistDurableGraphResultBestEffort(pmRoot, lookup.fingerprint, durableView, queryKey, memo.value);
1872
+ }
1873
+ const value = memo.value.subcommand === "audit" ? await applyAuditBaseline(pmRoot, lookup.fingerprint, memo.value, invocation.saveBaseline) : memo.value;
1851
1874
  return {
1852
- ...memo.value,
1875
+ ...value,
1853
1876
  cache: {
1854
1877
  fingerprint: lookup.fingerprint.slice(0, 12),
1855
1878
  assembly: lookup.assemblyReused ? "hit" : "miss",
1856
- result: memo.reused ? "hit" : "miss"
1879
+ result: memo.reused ? "hit" : "miss",
1880
+ durable: durableValue !== void 0 ? "hit" : persistEnabled ? "miss" : "off"
1857
1881
  }
1858
1882
  };
1859
1883
  }
@@ -2277,7 +2301,7 @@ async function runGet(id, global2, options = {}) {
2277
2301
 
2278
2302
  // dist/sdk/query/search.js
2279
2303
  import fs from "node:fs/promises";
2280
- import path from "node:path";
2304
+ import path2 from "node:path";
2281
2305
 
2282
2306
  // dist/core/shared/text-normalization.js
2283
2307
  !(function() {
@@ -3221,7 +3245,7 @@ function collectLinkedPaths(item) {
3221
3245
  return [...deduped.values()];
3222
3246
  }
3223
3247
  async function resolveContainmentRoot(root) {
3224
- const resolved = path.resolve(root);
3248
+ const resolved = path2.resolve(root);
3225
3249
  try {
3226
3250
  const realpathRoot = await fs.realpath(resolved);
3227
3251
  return {
@@ -3250,7 +3274,7 @@ async function loadLinkedCorpus(document, roots) {
3250
3274
  if (!containmentRoot) {
3251
3275
  continue;
3252
3276
  }
3253
- const resolved = path.resolve(containmentRoot.resolved, linkedPath.path);
3277
+ const resolved = path2.resolve(containmentRoot.resolved, linkedPath.path);
3254
3278
  if (!isPathWithinDirectory(containmentRoot.resolved, resolved)) {
3255
3279
  continue;
3256
3280
  }
@@ -4072,7 +4096,7 @@ async function loadDocuments(pmRoot, itemFormat, typeToFolder, schema) {
4072
4096
  try {
4073
4097
  return await tryRead(alternatePath, alternateFormat);
4074
4098
  } catch {
4075
- listWarnings.push(`item_list_item_read_failed:${path.relative(pmRoot, alternatePath)}`);
4099
+ listWarnings.push(`item_list_item_read_failed:${path2.relative(pmRoot, alternatePath)}`);
4076
4100
  return "";
4077
4101
  }
4078
4102
  }
@@ -4586,7 +4610,7 @@ async function runSearch(rawQuery, rawOptions, global2) {
4586
4610
 
4587
4611
  // dist/sdk/eval.js
4588
4612
  import fs2 from "node:fs/promises";
4589
- import path2 from "node:path";
4613
+ import path3 from "node:path";
4590
4614
 
4591
4615
  // dist/core/search/eval.js
4592
4616
  !(function() {
@@ -4739,7 +4763,7 @@ function parseEvalQuerySet(raw) {
4739
4763
  } catch (e2) {
4740
4764
  }
4741
4765
  })();
4742
- var DEFAULT_EVAL_QUERIES_RELATIVE_PATH = path2.join("search", "eval-queries.json");
4766
+ var DEFAULT_EVAL_QUERIES_RELATIVE_PATH = path3.join("search", "eval-queries.json");
4743
4767
  var VALID_EVAL_MODES2 = /* @__PURE__ */ new Set([
4744
4768
  "keyword",
4745
4769
  "semantic",
@@ -4820,7 +4844,7 @@ var validateEvalQuerySet = (parsed) => {
4820
4844
  }
4821
4845
  };
4822
4846
  var loadEvalQuerySet = async (queriesPath) => validateEvalQuerySet(parseEvalQuerySetJson(await readEvalQuerySetFile(queriesPath), queriesPath));
4823
- var resolveEvalQueriesPath = (pmRoot, queries) => queries ? path2.resolve(process.cwd(), queries) : path2.join(pmRoot, DEFAULT_EVAL_QUERIES_RELATIVE_PATH);
4847
+ var resolveEvalQueriesPath = (pmRoot, queries) => queries ? path3.resolve(process.cwd(), queries) : path3.join(pmRoot, DEFAULT_EVAL_QUERIES_RELATIVE_PATH);
4824
4848
  var evaluateEvalQuery = async (evalQuery, defaultMode, k, global2) => {
4825
4849
  const mode = evalQuery.mode ?? defaultMode;
4826
4850
  const searchResult = await runSearch(evalQuery.query, { mode, limit: String(k), fields: "id" }, global2);
@@ -4887,17 +4911,24 @@ var runEval = async (options, global2) => {
4887
4911
 
4888
4912
  export {
4889
4913
  runAggregate,
4890
- hierarchyAncestors,
4891
- hierarchyDescendants,
4892
- orderingPredecessors,
4893
- orderingSuccessors,
4894
- enumerateRelationshipPaths,
4895
- detectRelationshipCommunities,
4896
- findRedundantRelationshipEdges,
4897
- computeRelationshipDominators,
4898
- formatDuplicateEdgeGroup,
4899
- collectDuplicateRelationshipEdgeGroups,
4900
- auditWorkspaceRelationshipGraph,
4914
+ analyzeRelationshipExecution,
4915
+ analyzeGraphImpact,
4916
+ analyzeKnowledgeGraph,
4917
+ compareRelationshipSnapshots,
4918
+ computeRelationshipCentrality,
4919
+ findRelationshipCutStructure,
4920
+ analyzeRelationshipSchedule,
4921
+ GRAPH_DURABLE_CACHE_VERSION,
4922
+ GRAPH_DURABLE_CACHE_MIN_ITEMS,
4923
+ durableGraphCachePath,
4924
+ graphAuditBaselinePath,
4925
+ openDurableGraphCache,
4926
+ persistDurableGraphResult,
4927
+ clearDurableGraphCache,
4928
+ durableGraphCacheStatus,
4929
+ shouldPersistDurableGraphCache,
4930
+ loadGraphAuditBaseline,
4931
+ saveGraphAuditBaseline,
4901
4932
  planRelationshipRemediation,
4902
4933
  parseGraphSubcommand,
4903
4934
  runGraph,
@@ -4911,4 +4942,4 @@ export {
4911
4942
  DEFAULT_EVAL_QUERIES_RELATIVE_PATH,
4912
4943
  runEval
4913
4944
  };
4914
- //# sourceMappingURL=chunk-6VIJ7UA5.js.map
4945
+ //# sourceMappingURL=chunk-AS4SAZ5R.js.map