@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +11 -0
- package/dist/cli/commander-usage.d.ts +1 -1
- package/dist/cli/commander-usage.js +5 -5
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/completion.js +13 -5
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/contracts.js +4 -3
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +2 -0
- package/dist/cli/error-guidance.js +7 -2
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/main.d.ts +1 -5
- package/dist/cli/main.js +12 -50
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +13 -3
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +45 -3
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-structured-mutation.d.ts +14 -0
- package/dist/cli/register-structured-mutation.js +62 -0
- package/dist/cli/register-structured-mutation.js.map +1 -0
- package/dist/cli/registration-helpers.js +5 -3
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli-bundle/bundle-manifest.json +280 -296
- package/dist/cli-bundle/chunks/{append-E6V54WOQ.js → append-7OVFYR3C.js} +3 -3
- package/dist/cli-bundle/chunks/{append-NNJ3EFIT.js → append-DFETHAZL.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-C3KD7U3T.js → chunk-2L6ZP22J.js} +241 -10
- package/dist/cli-bundle/chunks/chunk-2L6ZP22J.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-KZEANWJS.js → chunk-4PUUNQDV.js} +98 -30
- package/dist/cli-bundle/chunks/chunk-4PUUNQDV.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-RDV4ZFYS.js → chunk-4QOB7L7I.js} +7 -9
- package/dist/cli-bundle/chunks/{chunk-RDV4ZFYS.js.map → chunk-4QOB7L7I.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-3LPFHE3P.js → chunk-4QSQ6XDK.js} +62 -20
- package/dist/cli-bundle/chunks/chunk-4QSQ6XDK.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-QJKL5PHS.js → chunk-7656MAUL.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3AO5VSDR.js → chunk-7RW4JCU2.js} +328 -6
- package/dist/cli-bundle/chunks/chunk-7RW4JCU2.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-X6K5XTTN.js → chunk-7W2UAXXT.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-SSKOQNMS.js → chunk-ABWCF646.js} +9 -11
- package/dist/cli-bundle/chunks/{chunk-SSKOQNMS.js.map → chunk-ABWCF646.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-WVA4DVNV.js → chunk-ADBTSVGK.js} +71 -33
- package/dist/cli-bundle/chunks/chunk-ADBTSVGK.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-J4FBIFU6.js → chunk-AELMUANP.js} +12 -6
- package/dist/cli-bundle/chunks/chunk-AELMUANP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-4F6BWJ4J.js → chunk-AMJPSANK.js} +57 -36
- package/dist/cli-bundle/chunks/chunk-AMJPSANK.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-6VIJ7UA5.js → chunk-AS4SAZ5R.js} +850 -819
- package/dist/cli-bundle/chunks/chunk-AS4SAZ5R.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-SG74J6MV.js → chunk-ATBCUC7Y.js} +574 -5
- package/dist/cli-bundle/chunks/chunk-ATBCUC7Y.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-5OK4UGFV.js → chunk-BXNDKOR2.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-KSPWRNVP.js → chunk-CPX275C6.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JH2ZSLO3.js → chunk-DZRV2OPA.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-L7BH7IWU.js → chunk-E5XMKOSB.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-CQTQKUUV.js → chunk-EWJWSNRU.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-DAQ45GCS.js → chunk-F2LBF7XJ.js} +22 -15
- package/dist/cli-bundle/chunks/chunk-F2LBF7XJ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-6XMUURSS.js → chunk-FJIFFBJX.js} +64 -33
- package/dist/cli-bundle/chunks/chunk-FJIFFBJX.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-E7ICD63T.js → chunk-FO6OSVEN.js} +4 -6
- package/dist/cli-bundle/chunks/{chunk-E7ICD63T.js.map → chunk-FO6OSVEN.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-3MCTMJXI.js → chunk-FPBMLYPI.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UZDQXNUB.js → chunk-FSE2IKJQ.js} +46 -5
- package/dist/cli-bundle/chunks/chunk-FSE2IKJQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-IX677TRO.js → chunk-GKX4NJ7U.js} +8 -10
- package/dist/cli-bundle/chunks/{chunk-IX677TRO.js.map → chunk-GKX4NJ7U.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-DVDBQA3B.js → chunk-GTK4DTEW.js} +5 -5
- package/dist/cli-bundle/chunks/chunk-H7EAER5L.js +974 -0
- package/dist/cli-bundle/chunks/chunk-H7EAER5L.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-5UX66S6U.js → chunk-ICDAQ4TD.js} +316 -8
- package/dist/cli-bundle/chunks/chunk-ICDAQ4TD.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-YQQNAKW3.js → chunk-JFD5LPMI.js} +6 -8
- package/dist/cli-bundle/chunks/{chunk-YQQNAKW3.js.map → chunk-JFD5LPMI.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-QANSTTC7.js → chunk-JXCW2TI2.js} +6 -8
- package/dist/cli-bundle/chunks/{chunk-QANSTTC7.js.map → chunk-JXCW2TI2.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-GSJSM5BJ.js → chunk-K36WV5J6.js} +76 -13
- package/dist/cli-bundle/chunks/chunk-K36WV5J6.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-GVI6FAFG.js → chunk-K55VMLSS.js} +7 -5
- package/dist/cli-bundle/chunks/chunk-K55VMLSS.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GIQSU6S2.js → chunk-KBLZ3AA5.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XJF7CDNH.js → chunk-KH44WBAT.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GV2262OF.js → chunk-LAV26CQG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VDO2JMD4.js → chunk-LVC72YRD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3VY6MIEO.js → chunk-LZYP423P.js} +35 -6
- package/dist/cli-bundle/chunks/chunk-LZYP423P.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-ZYPFOO3L.js → chunk-MATHDCGG.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-OV7MSW3I.js → chunk-MWQ2HC2A.js} +99 -31
- package/dist/cli-bundle/chunks/chunk-MWQ2HC2A.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-NHT3F4WZ.js → chunk-NUF7ROFH.js} +840 -816
- package/dist/cli-bundle/chunks/chunk-NUF7ROFH.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-AOEOYL3S.js → chunk-O4BCOJTZ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-RJO3YAFM.js → chunk-OCUBRA6D.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-5IZJWSDB.js → chunk-OG5DVFMA.js} +22 -15
- package/dist/cli-bundle/chunks/chunk-OG5DVFMA.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-I577UHC7.js → chunk-OR42SO64.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZOJ3LR7O.js → chunk-OY7DMU5P.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HEWM6CEN.js → chunk-P7MTHPJQ.js} +50 -9
- package/dist/cli-bundle/chunks/chunk-P7MTHPJQ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-2BO4CA46.js → chunk-PFNHX655.js} +236 -12
- package/dist/cli-bundle/chunks/{chunk-2BO4CA46.js.map → chunk-PFNHX655.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-ZV2NTVMJ.js → chunk-PONKZPCJ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-THAOZG4U.js → chunk-PQSEQD6E.js} +8 -6
- package/dist/cli-bundle/chunks/chunk-PQSEQD6E.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-PWDEHT3L.js +991 -0
- package/dist/cli-bundle/chunks/chunk-PWDEHT3L.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-UX6SSO2I.js → chunk-PZC2FUOQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-WUVEBQW6.js → chunk-QG4GFLQ6.js} +3 -5
- package/dist/cli-bundle/chunks/{chunk-WUVEBQW6.js.map → chunk-QG4GFLQ6.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-VQIHNHMJ.js → chunk-QIH77CAG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-R3EWPG4A.js → chunk-QJIKE24M.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QLZ643FM.js → chunk-QOOTOD3W.js} +10 -12
- package/dist/cli-bundle/chunks/{chunk-QLZ643FM.js.map → chunk-QOOTOD3W.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-MYSS5H2A.js → chunk-R3P6FZJW.js} +5 -7
- package/dist/cli-bundle/chunks/{chunk-MYSS5H2A.js.map → chunk-R3P6FZJW.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-G3COA6GS.js → chunk-RNPZYNHS.js} +56 -35
- package/dist/cli-bundle/chunks/chunk-RNPZYNHS.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-T44FMVRL.js → chunk-RPESLSO5.js} +62 -20
- package/dist/cli-bundle/chunks/chunk-RPESLSO5.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-INSTSQNZ.js → chunk-SY4SFZSD.js} +595 -3
- package/dist/cli-bundle/chunks/chunk-SY4SFZSD.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-HB3P4M52.js → chunk-TRSHFPRZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HRW7GF6T.js → chunk-UCBDQI5E.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4U4Z6AHI.js → chunk-V22ZPOKN.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JM6YAXTR.js → chunk-VHXHVTUU.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LPEYZRUR.js → chunk-VJQG4BIM.js} +35 -6
- package/dist/cli-bundle/chunks/chunk-VJQG4BIM.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-D6NXDNP3.js → chunk-VLRGDBLY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JAPE62Y5.js → chunk-VNTCM3VW.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-FDHPAVVB.js → chunk-VXOOB6YX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GFQP7HAZ.js → chunk-VZIZB6QH.js} +3 -5
- package/dist/cli-bundle/chunks/{chunk-GFQP7HAZ.js.map → chunk-VZIZB6QH.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-HQ3SB4CN.js → chunk-X3W65QK3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RZJLNXFG.js → chunk-XJTABV3X.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-GVT754PX.js → chunk-YCIUJJOD.js} +11 -5
- package/dist/cli-bundle/chunks/chunk-YCIUJJOD.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-IJNK6WW2.js → chunk-Z75ONV25.js} +75 -12
- package/dist/cli-bundle/chunks/chunk-Z75ONV25.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-4L23AGQ7.js → chunk-Z7VWXXJM.js} +5 -7
- package/dist/cli-bundle/chunks/{chunk-4L23AGQ7.js.map → chunk-Z7VWXXJM.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-YBT7O4KT.js → chunk-ZTVA4KLN.js} +4 -6
- package/dist/cli-bundle/chunks/{chunk-YBT7O4KT.js.map → chunk-ZTVA4KLN.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-TYHJDFYW.js → chunk-ZVZGXPQ5.js} +2 -2
- package/dist/cli-bundle/chunks/{close-many-SDA426VT.js → close-many-5RZXVN4J.js} +5 -6
- package/dist/cli-bundle/chunks/{close-many-UTZANOCQ.js → close-many-RZVTUGBG.js} +5 -6
- package/dist/cli-bundle/chunks/{comments-LZN6FXXC.js → comments-TPU7QRBL.js} +4 -4
- package/dist/cli-bundle/chunks/{comments-VBQ345ND.js → comments-Z4KV6FU3.js} +4 -4
- package/dist/cli-bundle/chunks/{create-GG4RBCGC.js → create-EIFBIVNQ.js} +6 -6
- package/dist/cli-bundle/chunks/{create-JBC5KUW6.js → create-RGSPN5GD.js} +6 -6
- package/dist/cli-bundle/chunks/{deps-FI4O6NQS.js → deps-UH5EQQUY.js} +3 -3
- package/dist/cli-bundle/chunks/{deps-DELOO4TL.js → deps-YG7UF3VR.js} +3 -3
- package/dist/cli-bundle/chunks/{docs-6Z2MP526.js → docs-G32TK6XS.js} +4 -4
- package/dist/cli-bundle/chunks/{docs-2UYBP5D6.js → docs-JWWNRC27.js} +4 -4
- package/dist/cli-bundle/chunks/{files-HKEAN5MA.js → files-3H32UQ4K.js} +4 -4
- package/dist/cli-bundle/chunks/{files-HEUGSJZL.js → files-4ALMCSKB.js} +4 -4
- package/dist/cli-bundle/chunks/{history-compact-7NDVP3PT.js → history-compact-77BT2LUB.js} +3 -4
- package/dist/cli-bundle/chunks/{history-compact-65YVN5DB.js → history-compact-VCKGTX64.js} +3 -4
- package/dist/cli-bundle/chunks/{history-redact-7YBL4XSG.js → history-redact-LJPZPNFA.js} +2 -3
- package/dist/cli-bundle/chunks/{history-redact-IZGNJBU4.js → history-redact-PWTTJ3XS.js} +2 -3
- package/dist/cli-bundle/chunks/{history-repair-7M4PYQUH.js → history-repair-I7CBNCV3.js} +5 -6
- package/dist/cli-bundle/chunks/{history-repair-GNGETJLI.js → history-repair-YTDZRK5E.js} +5 -6
- package/dist/cli-bundle/chunks/{learnings-3YXDRWFT.js → learnings-CYNOICKR.js} +4 -4
- package/dist/cli-bundle/chunks/{learnings-ALC6IMNL.js → learnings-KTYW3AL7.js} +4 -4
- package/dist/cli-bundle/chunks/{notes-7JMLQ447.js → notes-FGO63FXL.js} +4 -4
- package/dist/cli-bundle/chunks/{notes-JFCLTC5C.js → notes-ZERD3KB2.js} +4 -4
- package/dist/cli-bundle/chunks/{plan-T3XB3WTK.js → plan-OFJUBIM5.js} +7 -7
- package/dist/cli-bundle/chunks/{plan-KOIPWVOZ.js → plan-SGCDDTYR.js} +7 -7
- package/dist/cli-bundle/chunks/{profile-OILJHKUW.js → profile-3THJPIQY.js} +4 -5
- package/dist/cli-bundle/chunks/{profile-RJXA7PGS.js → profile-XEZAMMBW.js} +4 -5
- package/dist/cli-bundle/chunks/{register-list-query-CFVG75P3.js → register-list-query-BR435Q2H.js} +19 -16
- package/dist/cli-bundle/chunks/register-list-query-BR435Q2H.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-list-query-E7UVY4TN.js → register-list-query-RWTWLOBE.js} +18 -15
- package/dist/cli-bundle/chunks/register-list-query-RWTWLOBE.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-IQ55E25C.js → register-mutation-HLWC2WNP.js} +167 -31
- package/dist/cli-bundle/chunks/register-mutation-HLWC2WNP.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-mutation-4VJTXBZW.js → register-mutation-ZJX5AZM5.js} +173 -30
- package/dist/cli-bundle/chunks/register-mutation-ZJX5AZM5.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-operations-AR7RMX4W.js → register-operations-744YBJMV.js} +23 -25
- package/dist/cli-bundle/chunks/{register-operations-AR7RMX4W.js.map → register-operations-744YBJMV.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-operations-NOLZGORC.js → register-operations-UEBJH6AN.js} +21 -23
- package/dist/cli-bundle/chunks/{register-operations-NOLZGORC.js.map → register-operations-UEBJH6AN.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-setup-EYZ7VTPZ.js → register-setup-5DA4UZXI.js} +7 -8
- package/dist/cli-bundle/chunks/{register-setup-EYZ7VTPZ.js.map → register-setup-5DA4UZXI.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-setup-BB77VUEE.js → register-setup-6H25M3BH.js} +9 -10
- package/dist/cli-bundle/chunks/{register-setup-BB77VUEE.js.map → register-setup-6H25M3BH.js.map} +1 -1
- package/dist/cli-bundle/chunks/{restore-ZH65GZFB.js → restore-6TDVSATY.js} +4 -5
- package/dist/cli-bundle/chunks/{restore-L6IAGOD7.js → restore-RSL7C7LO.js} +4 -5
- package/dist/cli-bundle/chunks/{schema-4ERWM5QJ.js → schema-HFXFSGPG.js} +2 -3
- package/dist/cli-bundle/chunks/{schema-55DL3Q52.js → schema-TPVTIJPO.js} +2 -3
- package/dist/cli-bundle/chunks/{update-FW6FKDOP.js → update-LJZCL5SI.js} +7 -7
- package/dist/cli-bundle/chunks/{update-TJHSPRPT.js → update-SIA7LH5Y.js} +7 -7
- package/dist/cli-bundle/chunks/{update-many-PWXX5WHO.js → update-many-BDBZVGQL.js} +11 -12
- package/dist/cli-bundle/chunks/{update-many-NNALYQCN.js → update-many-MOY3A5B3.js} +11 -12
- package/dist/cli-bundle/main.js +60 -85
- package/dist/cli-bundle/main.js.map +2 -2
- package/dist/cli-bundle/sdk-runtime.js +37 -37
- package/dist/cli-bundle/sdk.js +126 -291
- package/dist/cli-bundle/sdk.js.map +4 -4
- package/dist/core/item/parse.d.ts +1 -1
- package/dist/core/item/parse.js +13 -7
- package/dist/core/item/parse.js.map +1 -1
- package/dist/core/output/mutation-projection.d.ts +2 -0
- package/dist/core/output/mutation-projection.js +33 -2
- package/dist/core/output/mutation-projection.js.map +1 -1
- package/dist/core/output/output.d.ts +4 -0
- package/dist/core/output/output.js +18 -13
- package/dist/core/output/output.js.map +1 -1
- package/dist/core/shared/command-types.d.ts +4 -0
- package/dist/core/shared/command-types.js +2 -2
- package/dist/core/shared/command-types.js.map +1 -1
- package/dist/mcp/server.js +39 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-definitions.js +45 -4
- package/dist/mcp/tool-definitions.js.map +1 -1
- package/dist/sdk/cli-bootstrap.d.ts +2 -0
- package/dist/sdk/cli-bootstrap.js +20 -27
- package/dist/sdk/cli-bootstrap.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +2 -2
- package/dist/sdk/cli-contracts/enum-contracts.js +7 -2
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +21 -2
- package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.js +10 -2
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +16 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-schema.js +6 -2
- package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts.js +3 -3
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/cli-program.js +4 -2
- package/dist/sdk/cli-program.js.map +1 -1
- package/dist/sdk/dependencies.d.ts +3 -2
- package/dist/sdk/dependencies.js +13 -12
- package/dist/sdk/dependencies.js.map +1 -1
- package/dist/sdk/error-runtime.d.ts +10 -0
- package/dist/sdk/error-runtime.js +59 -0
- package/dist/sdk/error-runtime.js.map +1 -0
- package/dist/sdk/graph/analytics.d.ts +9 -0
- package/dist/sdk/graph/analytics.js +24 -13
- package/dist/sdk/graph/analytics.js.map +1 -1
- package/dist/sdk/graph/assembly.d.ts +39 -0
- package/dist/sdk/graph/assembly.js +92 -12
- package/dist/sdk/graph/assembly.js.map +1 -1
- package/dist/sdk/graph/cache.d.ts +4 -1
- package/dist/sdk/graph/cache.js +17 -4
- package/dist/sdk/graph/cache.js.map +1 -1
- package/dist/sdk/graph/centrality.d.ts +82 -0
- package/dist/sdk/graph/centrality.js +259 -0
- package/dist/sdk/graph/centrality.js.map +1 -0
- package/dist/sdk/graph/durable-cache.d.ts +71 -0
- package/dist/sdk/graph/durable-cache.js +205 -0
- package/dist/sdk/graph/durable-cache.js.map +1 -0
- package/dist/sdk/graph/governance.d.ts +69 -1
- package/dist/sdk/graph/governance.js +143 -35
- package/dist/sdk/graph/governance.js.map +1 -1
- package/dist/sdk/graph/index.d.ts +7 -4
- package/dist/sdk/graph/index.js +8 -5
- package/dist/sdk/graph/index.js.map +1 -1
- package/dist/sdk/graph/mutation-advisory.d.ts +35 -4
- package/dist/sdk/graph/mutation-advisory.js +124 -35
- package/dist/sdk/graph/mutation-advisory.js.map +1 -1
- package/dist/sdk/graph/remediation.js +12 -2
- package/dist/sdk/graph/remediation.js.map +1 -1
- package/dist/sdk/graph/run.d.ts +133 -2
- package/dist/sdk/graph/run.js +217 -8
- package/dist/sdk/graph/run.js.map +1 -1
- package/dist/sdk/graph/scheduling.d.ts +59 -0
- package/dist/sdk/graph/scheduling.js +125 -0
- package/dist/sdk/graph/scheduling.js.map +1 -0
- package/dist/sdk/graph/traversal.d.ts +11 -0
- package/dist/sdk/graph/traversal.js +16 -2
- package/dist/sdk/graph/traversal.js.map +1 -1
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +6 -2
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runtime-input.js +7 -2
- package/dist/sdk/runtime-input.js.map +1 -1
- package/dist/sdk/runtime-primitives.d.ts +10 -0
- package/dist/sdk/runtime-primitives.js +14 -0
- package/dist/sdk/runtime-primitives.js.map +1 -0
- package/dist/sdk/runtime.d.ts +15 -0
- package/dist/sdk/runtime.js +16 -3
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/sdk/structured-mutations.d.ts +21 -0
- package/dist/sdk/structured-mutations.js +375 -0
- package/dist/sdk/structured-mutations.js.map +1 -0
- package/docs/COMMANDS.md +85 -5
- package/docs/RELATIONSHIP_GRAPH.md +48 -7
- package/docs/SDK.md +78 -3
- package/marketplace.json +2 -2
- package/package.json +1 -1
- package/packages/pm-beads/package.json +1 -1
- package/packages/pm-calendar/package.json +1 -1
- package/packages/pm-command-kit/package.json +1 -1
- package/packages/pm-governance-audit/package.json +1 -1
- package/packages/pm-guide-shell/package.json +1 -1
- package/packages/pm-kanban/package.json +1 -1
- package/packages/pm-lifecycle-hooks/package.json +1 -1
- package/packages/pm-linked-test-adapters/package.json +1 -1
- package/packages/pm-search-advanced/package.json +1 -1
- package/packages/pm-templates/package.json +1 -1
- package/packages/pm-todos/package.json +1 -1
- package/packages/pm-vcs/package.json +1 -1
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/README.md +5 -3
- package/plugins/pm-claude/commands/pm-init.md +1 -1
- package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli-bundle/chunks/chunk-3AO5VSDR.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-3LPFHE3P.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-3VY6MIEO.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-4F6BWJ4J.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-5IZJWSDB.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-5UX66S6U.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-6C2ZZX5Z.js +0 -286
- package/dist/cli-bundle/chunks/chunk-6C2ZZX5Z.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-6VIJ7UA5.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-6XMUURSS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-C3KD7U3T.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-CFHAODHQ.js +0 -334
- package/dist/cli-bundle/chunks/chunk-CFHAODHQ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-DAQ45GCS.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-E6LEMURX.js +0 -249
- package/dist/cli-bundle/chunks/chunk-E6LEMURX.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-G3COA6GS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-GSJSM5BJ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-GVI6FAFG.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-GVT754PX.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-HEWM6CEN.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-IJNK6WW2.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-INSTSQNZ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-J4FBIFU6.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-KZEANWJS.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-LPEYZRUR.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-NHT3F4WZ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-OV7MSW3I.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-P7JTWYLH.js +0 -246
- package/dist/cli-bundle/chunks/chunk-P7JTWYLH.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-R5U2VZ3K.js +0 -344
- package/dist/cli-bundle/chunks/chunk-R5U2VZ3K.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SG74J6MV.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-T44FMVRL.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-THAOZG4U.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-UQLXSG72.js +0 -289
- package/dist/cli-bundle/chunks/chunk-UQLXSG72.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-UZDQXNUB.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-WVA4DVNV.js.map +0 -7
- package/dist/cli-bundle/chunks/register-list-query-CFVG75P3.js.map +0 -1
- package/dist/cli-bundle/chunks/register-list-query-E7UVY4TN.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-4VJTXBZW.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-IQ55E25C.js.map +0 -1
- /package/dist/cli-bundle/chunks/{append-E6V54WOQ.js.map → append-7OVFYR3C.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-NNJ3EFIT.js.map → append-DFETHAZL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QJKL5PHS.js.map → chunk-7656MAUL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-X6K5XTTN.js.map → chunk-7W2UAXXT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-5OK4UGFV.js.map → chunk-BXNDKOR2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KSPWRNVP.js.map → chunk-CPX275C6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JH2ZSLO3.js.map → chunk-DZRV2OPA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-L7BH7IWU.js.map → chunk-E5XMKOSB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CQTQKUUV.js.map → chunk-EWJWSNRU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3MCTMJXI.js.map → chunk-FPBMLYPI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DVDBQA3B.js.map → chunk-GTK4DTEW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GIQSU6S2.js.map → chunk-KBLZ3AA5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XJF7CDNH.js.map → chunk-KH44WBAT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GV2262OF.js.map → chunk-LAV26CQG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VDO2JMD4.js.map → chunk-LVC72YRD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZYPFOO3L.js.map → chunk-MATHDCGG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AOEOYL3S.js.map → chunk-O4BCOJTZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RJO3YAFM.js.map → chunk-OCUBRA6D.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-I577UHC7.js.map → chunk-OR42SO64.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZOJ3LR7O.js.map → chunk-OY7DMU5P.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZV2NTVMJ.js.map → chunk-PONKZPCJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UX6SSO2I.js.map → chunk-PZC2FUOQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VQIHNHMJ.js.map → chunk-QIH77CAG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-R3EWPG4A.js.map → chunk-QJIKE24M.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HB3P4M52.js.map → chunk-TRSHFPRZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HRW7GF6T.js.map → chunk-UCBDQI5E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4U4Z6AHI.js.map → chunk-V22ZPOKN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JM6YAXTR.js.map → chunk-VHXHVTUU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-D6NXDNP3.js.map → chunk-VLRGDBLY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JAPE62Y5.js.map → chunk-VNTCM3VW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FDHPAVVB.js.map → chunk-VXOOB6YX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HQ3SB4CN.js.map → chunk-X3W65QK3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RZJLNXFG.js.map → chunk-XJTABV3X.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TYHJDFYW.js.map → chunk-ZVZGXPQ5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-SDA426VT.js.map → close-many-5RZXVN4J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-UTZANOCQ.js.map → close-many-RZVTUGBG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-LZN6FXXC.js.map → comments-TPU7QRBL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-VBQ345ND.js.map → comments-Z4KV6FU3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-GG4RBCGC.js.map → create-EIFBIVNQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-JBC5KUW6.js.map → create-RGSPN5GD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-FI4O6NQS.js.map → deps-UH5EQQUY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-DELOO4TL.js.map → deps-YG7UF3VR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-6Z2MP526.js.map → docs-G32TK6XS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-2UYBP5D6.js.map → docs-JWWNRC27.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-HKEAN5MA.js.map → files-3H32UQ4K.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-HEUGSJZL.js.map → files-4ALMCSKB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-7NDVP3PT.js.map → history-compact-77BT2LUB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-65YVN5DB.js.map → history-compact-VCKGTX64.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-7YBL4XSG.js.map → history-redact-LJPZPNFA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-IZGNJBU4.js.map → history-redact-PWTTJ3XS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-7M4PYQUH.js.map → history-repair-I7CBNCV3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-GNGETJLI.js.map → history-repair-YTDZRK5E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-3YXDRWFT.js.map → learnings-CYNOICKR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-ALC6IMNL.js.map → learnings-KTYW3AL7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-7JMLQ447.js.map → notes-FGO63FXL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-JFCLTC5C.js.map → notes-ZERD3KB2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-T3XB3WTK.js.map → plan-OFJUBIM5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-KOIPWVOZ.js.map → plan-SGCDDTYR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-OILJHKUW.js.map → profile-3THJPIQY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-RJXA7PGS.js.map → profile-XEZAMMBW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-ZH65GZFB.js.map → restore-6TDVSATY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-L6IAGOD7.js.map → restore-RSL7C7LO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-4ERWM5QJ.js.map → schema-HFXFSGPG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-55DL3Q52.js.map → schema-TPVTIJPO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-FW6FKDOP.js.map → update-LJZCL5SI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-TJHSPRPT.js.map → update-SIA7LH5Y.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-PWXX5WHO.js.map → update-many-BDBZVGQL.js.map} +0 -0
- /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-
|
|
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-
|
|
17
|
+
} from "./chunk-K55VMLSS.js";
|
|
18
18
|
import {
|
|
19
19
|
GRAPH_SUBCOMMAND_VALUES
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-P7MTHPJQ.js";
|
|
21
21
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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-
|
|
44
|
+
} from "./chunk-F2LBF7XJ.js";
|
|
34
45
|
import {
|
|
35
|
-
assembleWorkspaceRelationshipGraph
|
|
36
|
-
|
|
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-
|
|
89
|
+
} from "./chunk-VZIZB6QH.js";
|
|
78
90
|
import {
|
|
79
91
|
readHistoryEntries
|
|
80
|
-
} from "./chunk-
|
|
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/
|
|
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] = "
|
|
492
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "0a54b889-6d5c-565c-85ff-47e5cce68a32");
|
|
476
493
|
} catch (e2) {
|
|
477
494
|
}
|
|
478
495
|
})();
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
function
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
if (
|
|
494
|
-
return
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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
|
-
|
|
527
|
+
}
|
|
528
|
+
if (visited.has(current.id))
|
|
520
529
|
continue;
|
|
521
|
-
|
|
522
|
-
|
|
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
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
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
|
-
|
|
543
|
-
state.truncated = true;
|
|
544
|
-
return true;
|
|
545
|
-
}
|
|
546
|
-
state.value.push(neighbor);
|
|
565
|
+
components.push(component);
|
|
547
566
|
}
|
|
548
|
-
return
|
|
567
|
+
return sortComponents(components);
|
|
549
568
|
}
|
|
550
|
-
function
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
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
|
|
588
|
-
|
|
589
|
-
|
|
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
|
|
592
|
-
const
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
const
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
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
|
|
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
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
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
|
-
|
|
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
|
-
|
|
638
|
-
truncated = true;
|
|
639
|
-
break;
|
|
640
|
-
}
|
|
641
|
-
const partial = state.queue[index];
|
|
674
|
+
const current = queue[index];
|
|
642
675
|
visitedNodes += 1;
|
|
643
|
-
|
|
644
|
-
|
|
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
|
-
|
|
649
|
-
|
|
650
|
-
|
|
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
|
-
|
|
655
|
-
|
|
706
|
+
root,
|
|
707
|
+
affected,
|
|
708
|
+
exact: true,
|
|
709
|
+
truncated,
|
|
710
|
+
cost: { visitedNodes, inspectedEdges }
|
|
656
711
|
};
|
|
657
712
|
}
|
|
658
|
-
function
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
const
|
|
662
|
-
const
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
for (const
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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
|
-
|
|
679
|
-
value: [{ nodes: [source], edges: [], length: 0 }],
|
|
680
|
-
meta: { visitedNodes: 1, inspectedEdges: 0, truncated: false }
|
|
681
|
-
};
|
|
740
|
+
components.push(component);
|
|
682
741
|
}
|
|
683
|
-
|
|
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/
|
|
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] = "
|
|
770
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "0b226d67-72f3-57f4-8428-d3af70ecf306");
|
|
691
771
|
} catch (e2) {
|
|
692
772
|
}
|
|
693
773
|
})();
|
|
694
|
-
|
|
695
|
-
|
|
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
|
|
722
|
-
const
|
|
723
|
-
if (
|
|
724
|
-
|
|
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
|
-
|
|
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
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
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
|
|
767
|
-
const
|
|
768
|
-
const
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
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
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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
|
-
|
|
846
|
-
|
|
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
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
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
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
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
|
-
|
|
906
|
-
|
|
907
|
-
const
|
|
908
|
-
|
|
909
|
-
|
|
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
|
|
931
|
-
|
|
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
|
|
956
|
-
const
|
|
957
|
-
const
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
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
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
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
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
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
|
-
|
|
946
|
+
retreatCutFrame(frame, root, state);
|
|
1002
947
|
stack.pop();
|
|
1003
948
|
}
|
|
1004
949
|
}
|
|
1005
|
-
return postorder.reverse();
|
|
1006
950
|
}
|
|
1007
|
-
function
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
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
|
-
|
|
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: {
|
|
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:
|
|
1071
|
-
inspectedEdges:
|
|
1072
|
-
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/
|
|
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] = "
|
|
983
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "b92fecb2-bbc5-5837-906c-bf5d32b2a4d6");
|
|
1082
984
|
} catch (e2) {
|
|
1083
985
|
}
|
|
1084
986
|
})();
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
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
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
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
|
-
|
|
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
|
|
1006
|
+
return { forward, participants };
|
|
1142
1007
|
}
|
|
1143
|
-
function
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
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
|
-
|
|
1159
|
-
state.components.push(component.sort((left, right) => left.localeCompare(right)));
|
|
1017
|
+
return bound;
|
|
1160
1018
|
}
|
|
1161
|
-
function
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
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
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
const
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
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
|
-
|
|
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
|
|
1186
|
-
return
|
|
1084
|
+
function durableGraphCachePath(pmRoot) {
|
|
1085
|
+
return path.join(pmRoot, "runtime", "graph-cache.json");
|
|
1187
1086
|
}
|
|
1188
|
-
function
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
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
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
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
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
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
|
|
1319
|
-
const
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
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
|
-
|
|
1349
|
-
|
|
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] = "
|
|
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] = "
|
|
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((
|
|
1587
|
-
nodes:
|
|
1588
|
-
kinds:
|
|
1589
|
-
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
|
-
|
|
1835
|
-
const
|
|
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
|
|
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
|
-
...
|
|
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
|
|
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 =
|
|
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 =
|
|
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:${
|
|
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
|
|
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 =
|
|
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 ?
|
|
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
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
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-
|
|
4945
|
+
//# sourceMappingURL=chunk-AS4SAZ5R.js.map
|