@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,9 +1,9 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="405abecd-c7c4-543d-be2a-eb3e5168def7")}catch(e){}}();
|
|
3
3
|
import {
|
|
4
4
|
collectStaleVectorizationIds,
|
|
5
5
|
recordContextUsageTouches
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JFD5LPMI.js";
|
|
7
7
|
import {
|
|
8
8
|
buildEventCorpus,
|
|
9
9
|
buildPlanFlatCorpus,
|
|
@@ -16,15 +16,26 @@ import {
|
|
|
16
16
|
resolveSearchCorpusFields,
|
|
17
17
|
resolveSettingsWithSemanticRuntimeDefaults,
|
|
18
18
|
resolveVectorStores
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-PQSEQD6E.js";
|
|
20
20
|
import {
|
|
21
21
|
GRAPH_SUBCOMMAND_VALUES
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-FSE2IKJQ.js";
|
|
23
23
|
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
auditWorkspaceRelationshipGraph,
|
|
25
|
+
collectDuplicateRelationshipEdgeGroups,
|
|
26
|
+
computeRelationshipDominators,
|
|
27
|
+
detectRelationshipCommunities,
|
|
28
|
+
diffRelationshipAuditSnapshots,
|
|
29
|
+
enumerateRelationshipPaths,
|
|
30
|
+
findRedundantRelationshipEdges,
|
|
31
|
+
forEachMatchedRelationshipEdge,
|
|
32
|
+
formatDuplicateEdgeGroup,
|
|
33
|
+
hierarchyAncestors,
|
|
34
|
+
hierarchyDescendants,
|
|
35
|
+
orderingPredecessors,
|
|
36
|
+
orderingSuccessors,
|
|
37
|
+
orientOrderingEdge
|
|
38
|
+
} from "./chunk-H7EAER5L.js";
|
|
28
39
|
import {
|
|
29
40
|
computeWorkspaceGraphFingerprint,
|
|
30
41
|
parseDirection,
|
|
@@ -32,10 +43,11 @@ import {
|
|
|
32
43
|
parseMaxDepth,
|
|
33
44
|
parsePositiveInteger,
|
|
34
45
|
workspaceGraphCache
|
|
35
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-OG5DVFMA.js";
|
|
36
47
|
import {
|
|
37
|
-
assembleWorkspaceRelationshipGraph
|
|
38
|
-
|
|
48
|
+
assembleWorkspaceRelationshipGraph,
|
|
49
|
+
resolveWorkspaceRelationshipKindRegistry
|
|
50
|
+
} from "./chunk-K36WV5J6.js";
|
|
39
51
|
import {
|
|
40
52
|
splitCommaList
|
|
41
53
|
} from "./chunk-NETP4DY4.js";
|
|
@@ -76,11 +88,12 @@ import {
|
|
|
76
88
|
} from "./chunk-4XGJLADW.js";
|
|
77
89
|
import {
|
|
78
90
|
getItemAt
|
|
79
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-Z7VWXXJM.js";
|
|
80
92
|
import {
|
|
81
93
|
readHistoryEntries
|
|
82
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-PFNHX655.js";
|
|
83
95
|
import {
|
|
96
|
+
acquireLock,
|
|
84
97
|
buildItemNotFoundError,
|
|
85
98
|
compareTimestampStrings,
|
|
86
99
|
getActiveExtensionRegistrations,
|
|
@@ -107,18 +120,22 @@ import {
|
|
|
107
120
|
coerceNumberInRange,
|
|
108
121
|
coercePositiveInteger,
|
|
109
122
|
collectRegisteredItemFieldNames,
|
|
123
|
+
createRelationshipKindRegistry,
|
|
110
124
|
getHistoryPath,
|
|
111
125
|
getItemPath,
|
|
112
126
|
getSettingsPath,
|
|
113
127
|
isPathWithinDirectory,
|
|
114
128
|
pathExists,
|
|
129
|
+
readFileIfExists,
|
|
130
|
+
removeFileIfExists,
|
|
115
131
|
resolveGlobalPmRoot,
|
|
116
132
|
resolveItemTypeRegistry,
|
|
117
133
|
resolvePmRoot,
|
|
118
134
|
resolveRuntimeFieldRegistry,
|
|
119
135
|
resolveRuntimeStatusRegistry,
|
|
120
136
|
toNonEmptyString,
|
|
121
|
-
toNonEmptyStringOrUndefined
|
|
137
|
+
toNonEmptyStringOrUndefined,
|
|
138
|
+
writeFileAtomic
|
|
122
139
|
} from "./chunk-HYW67VJ5.js";
|
|
123
140
|
|
|
124
141
|
// dist/cli/commands/aggregate.js
|
|
@@ -463,866 +480,692 @@ async function runAggregate(options, global) {
|
|
|
463
480
|
};
|
|
464
481
|
}
|
|
465
482
|
|
|
466
|
-
// dist/sdk/
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
function
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
if (
|
|
482
|
-
return
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
...familyKinds === void 0 ? {} : { kinds: [...familyKinds] }
|
|
498
|
-
});
|
|
499
|
-
const neighbors = [];
|
|
500
|
-
const seen = /* @__PURE__ */ new Set();
|
|
501
|
-
for (const row of rows.value) {
|
|
502
|
-
const definition = registry.require(row.edge.kind);
|
|
503
|
-
if (!definition[family])
|
|
504
|
-
continue;
|
|
505
|
-
if (!matches(row, definition, nodeId))
|
|
483
|
+
// dist/sdk/relationship-analytics.js
|
|
484
|
+
function appendNeighbor(adjacency, source, target) {
|
|
485
|
+
adjacency.get(source).add(target);
|
|
486
|
+
}
|
|
487
|
+
function createAdjacency(nodes) {
|
|
488
|
+
return new Map(nodes.map((node) => [node, /* @__PURE__ */ new Set()]));
|
|
489
|
+
}
|
|
490
|
+
function sortComponents(components) {
|
|
491
|
+
for (const component of components)
|
|
492
|
+
component.sort();
|
|
493
|
+
return components.sort((left, right) => right.length - left.length || left[0].localeCompare(right[0]));
|
|
494
|
+
}
|
|
495
|
+
function stableJsonValue(value) {
|
|
496
|
+
if (Array.isArray(value))
|
|
497
|
+
return value.map((entry) => stableJsonValue(entry));
|
|
498
|
+
if (value === null || typeof value !== "object")
|
|
499
|
+
return value;
|
|
500
|
+
const toJSON = value.toJSON;
|
|
501
|
+
if (typeof toJSON === "function")
|
|
502
|
+
return stableJsonValue(toJSON.call(value));
|
|
503
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, stableJsonValue(entry)]));
|
|
504
|
+
}
|
|
505
|
+
function relationshipEdgeKey(edge) {
|
|
506
|
+
return JSON.stringify(stableJsonValue(edge));
|
|
507
|
+
}
|
|
508
|
+
function appendFinishingOrder(start, adjacency, visited, order) {
|
|
509
|
+
const stack = [{ id: start, expanded: false }];
|
|
510
|
+
while (stack.length > 0) {
|
|
511
|
+
const current = stack.pop();
|
|
512
|
+
if (current.expanded) {
|
|
513
|
+
order.push(current.id);
|
|
506
514
|
continue;
|
|
507
|
-
|
|
515
|
+
}
|
|
516
|
+
if (visited.has(current.id))
|
|
508
517
|
continue;
|
|
509
|
-
|
|
510
|
-
|
|
518
|
+
visited.add(current.id);
|
|
519
|
+
stack.push({ id: current.id, expanded: true });
|
|
520
|
+
const neighbors = [...adjacency.get(current.id)].sort().reverse();
|
|
521
|
+
for (const neighbor of neighbors)
|
|
522
|
+
if (!visited.has(neighbor))
|
|
523
|
+
stack.push({ id: neighbor, expanded: false });
|
|
511
524
|
}
|
|
512
|
-
return { neighbors, inspectedEdges: rows.meta.inspectedEdges };
|
|
513
525
|
}
|
|
514
|
-
function
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
state.resumed = true;
|
|
526
|
+
function computeFinishingOrder(nodes, adjacency) {
|
|
527
|
+
const visited = /* @__PURE__ */ new Set();
|
|
528
|
+
const order = [];
|
|
529
|
+
for (const start of nodes)
|
|
530
|
+
if (!visited.has(start))
|
|
531
|
+
appendFinishingOrder(start, adjacency, visited, order);
|
|
532
|
+
return order;
|
|
533
|
+
}
|
|
534
|
+
function collectReverseComponents(order, reverse) {
|
|
535
|
+
const visited = /* @__PURE__ */ new Set();
|
|
536
|
+
const components = [];
|
|
537
|
+
for (const start of [...order].reverse()) {
|
|
538
|
+
if (visited.has(start))
|
|
528
539
|
continue;
|
|
540
|
+
const component = [];
|
|
541
|
+
const stack = [start];
|
|
542
|
+
visited.add(start);
|
|
543
|
+
while (stack.length > 0) {
|
|
544
|
+
const current = stack.pop();
|
|
545
|
+
component.push(current);
|
|
546
|
+
for (const neighbor of reverse.get(current)) {
|
|
547
|
+
if (visited.has(neighbor))
|
|
548
|
+
continue;
|
|
549
|
+
visited.add(neighbor);
|
|
550
|
+
stack.push(neighbor);
|
|
551
|
+
}
|
|
529
552
|
}
|
|
530
|
-
|
|
531
|
-
state.truncated = true;
|
|
532
|
-
return true;
|
|
533
|
-
}
|
|
534
|
-
state.value.push(neighbor);
|
|
553
|
+
components.push(component);
|
|
535
554
|
}
|
|
536
|
-
return
|
|
555
|
+
return sortComponents(components);
|
|
537
556
|
}
|
|
538
|
-
function
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
const after = options.after;
|
|
545
|
-
const state = {
|
|
546
|
-
seen: /* @__PURE__ */ new Set([start]),
|
|
547
|
-
value: [],
|
|
548
|
-
queue: [{ id: start, depth: 0 }],
|
|
549
|
-
resumed: after === void 0,
|
|
550
|
-
truncated: false
|
|
551
|
-
};
|
|
552
|
-
let visitedNodes = 0;
|
|
553
|
-
let inspectedEdges = 0;
|
|
554
|
-
for (let index = 0; index < state.queue.length; index += 1) {
|
|
555
|
-
options.signal?.throwIfAborted();
|
|
556
|
-
const current = state.queue[index];
|
|
557
|
-
visitedNodes += 1;
|
|
558
|
-
const expansion = expandSemanticNeighbors(graph, current.id, familyKinds, family, matches);
|
|
559
|
-
inspectedEdges += expansion.inspectedEdges;
|
|
560
|
-
if (appendSemanticExpansion(expansion, current.depth, maxDepth, limit, after, state))
|
|
561
|
-
break;
|
|
562
|
-
}
|
|
563
|
-
if (!state.resumed)
|
|
564
|
-
throw new TypeError(`Traversal cursor not found in sequence: ${after}`);
|
|
565
|
-
return {
|
|
566
|
-
value: state.value,
|
|
567
|
-
meta: {
|
|
568
|
-
visitedNodes,
|
|
569
|
-
inspectedEdges,
|
|
570
|
-
truncated: state.truncated,
|
|
571
|
-
nextCursor: state.value.at(-1)
|
|
572
|
-
}
|
|
573
|
-
};
|
|
557
|
+
function stronglyConnectedComponents(nodes, adjacency) {
|
|
558
|
+
const reverse = createAdjacency(nodes);
|
|
559
|
+
for (const [source, targets] of adjacency)
|
|
560
|
+
for (const target of targets)
|
|
561
|
+
appendNeighbor(reverse, target, source);
|
|
562
|
+
return collectReverseComponents(computeFinishingOrder(nodes, adjacency), reverse);
|
|
574
563
|
}
|
|
575
|
-
function
|
|
576
|
-
|
|
577
|
-
|
|
564
|
+
function buildExecutionAdjacency(graph, registry) {
|
|
565
|
+
const adjacency = createAdjacency(graph.nodes());
|
|
566
|
+
for (const edge of graph.edges()) {
|
|
567
|
+
const definition = registry.require(edge.kind);
|
|
568
|
+
if (!definition.ordering)
|
|
569
|
+
continue;
|
|
570
|
+
const sourceFirst = (definition.precedence ?? "source_before_target") === "source_before_target";
|
|
571
|
+
appendNeighbor(adjacency, sourceFirst ? edge.source : edge.target, sourceFirst ? edge.target : edge.source);
|
|
572
|
+
}
|
|
573
|
+
return adjacency;
|
|
578
574
|
}
|
|
579
|
-
function
|
|
580
|
-
const
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
} else {
|
|
597
|
-
state.queue.push({ nodes, nodeSet, edges });
|
|
575
|
+
function topologicalLayers(nodes, adjacency) {
|
|
576
|
+
const indegree = new Map(nodes.map((node) => [node, 0]));
|
|
577
|
+
for (const targets of adjacency.values())
|
|
578
|
+
for (const target of targets)
|
|
579
|
+
indegree.set(target, indegree.get(target) + 1);
|
|
580
|
+
let frontier = nodes.filter((node) => indegree.get(node) === 0).sort();
|
|
581
|
+
const layers = [];
|
|
582
|
+
while (frontier.length > 0) {
|
|
583
|
+
layers.push(frontier);
|
|
584
|
+
const next = [];
|
|
585
|
+
for (const source of frontier) {
|
|
586
|
+
for (const target of adjacency.get(source)) {
|
|
587
|
+
const remaining = indegree.get(target) - 1;
|
|
588
|
+
indegree.set(target, remaining);
|
|
589
|
+
if (remaining === 0)
|
|
590
|
+
next.push(target);
|
|
591
|
+
}
|
|
598
592
|
}
|
|
593
|
+
frontier = next.sort();
|
|
599
594
|
}
|
|
600
|
-
return
|
|
601
|
-
}
|
|
602
|
-
function hierarchyAncestors(graph, id, options = {}) {
|
|
603
|
-
return boundedSemanticWalk(graph, id, options, "hierarchy", (row, definition) => hierarchyParentEndpoint(row.edge, definition) === row.id);
|
|
604
|
-
}
|
|
605
|
-
function hierarchyDescendants(graph, id, options = {}) {
|
|
606
|
-
return boundedSemanticWalk(graph, id, options, "hierarchy", (row, definition, nodeId) => hierarchyParentEndpoint(row.edge, definition) === nodeId);
|
|
607
|
-
}
|
|
608
|
-
function orderingPredecessors(graph, id, options = {}) {
|
|
609
|
-
return boundedSemanticWalk(graph, id, options, "ordering", (row, definition) => orderingPredecessorEndpoint(row.edge, definition) === row.id);
|
|
610
|
-
}
|
|
611
|
-
function orderingSuccessors(graph, id, options = {}) {
|
|
612
|
-
return boundedSemanticWalk(graph, id, options, "ordering", (row, definition, nodeId) => orderingPredecessorEndpoint(row.edge, definition) === nodeId);
|
|
595
|
+
return layers;
|
|
613
596
|
}
|
|
614
|
-
function
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
597
|
+
function longestPath(order, adjacency) {
|
|
598
|
+
const depth = new Map(order.map((node) => [node, 0]));
|
|
599
|
+
const parent = /* @__PURE__ */ new Map();
|
|
600
|
+
for (const source of order) {
|
|
601
|
+
for (const target of adjacency.get(source)) {
|
|
602
|
+
if (!depth.has(target))
|
|
603
|
+
continue;
|
|
604
|
+
const candidate = depth.get(source) + 1;
|
|
605
|
+
const currentParent = parent.get(target);
|
|
606
|
+
if (candidate > depth.get(target) || candidate === depth.get(target) && (currentParent === void 0 || source.localeCompare(currentParent) < 0)) {
|
|
607
|
+
depth.set(target, candidate);
|
|
608
|
+
parent.set(target, source);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
const end = [...order].sort((left, right) => depth.get(right) - depth.get(left) || left.localeCompare(right))[0];
|
|
613
|
+
const path4 = end === void 0 ? [] : [end];
|
|
614
|
+
while (path4[0] !== void 0 && parent.has(path4[0]))
|
|
615
|
+
path4.unshift(parent.get(path4[0]));
|
|
616
|
+
return { depth: Object.fromEntries(depth), path: path4 };
|
|
617
|
+
}
|
|
618
|
+
function reconstructImpactPath(root, target, parents) {
|
|
619
|
+
const path4 = [target];
|
|
620
|
+
let cursor = target;
|
|
621
|
+
while (cursor !== root) {
|
|
622
|
+
cursor = parents.get(cursor);
|
|
623
|
+
path4.push(cursor);
|
|
624
|
+
}
|
|
625
|
+
return path4.reverse();
|
|
626
|
+
}
|
|
627
|
+
function analyzeRelationshipExecution(graph, options = {}) {
|
|
628
|
+
const registry = options.registry ?? createRelationshipKindRegistry();
|
|
629
|
+
const nodes = [...graph.nodes()];
|
|
630
|
+
const adjacency = buildExecutionAdjacency(graph, registry);
|
|
631
|
+
const layers = topologicalLayers(nodes, adjacency);
|
|
632
|
+
const order = layers.flat();
|
|
633
|
+
const acyclic = order.length === nodes.length;
|
|
634
|
+
const cycles = acyclic ? [] : stronglyConnectedComponents(nodes, adjacency).filter((component) => component.length > 1 || adjacency.get(component[0]).has(component[0]));
|
|
635
|
+
const longest = longestPath(order, adjacency);
|
|
636
|
+
return {
|
|
637
|
+
exact: true,
|
|
638
|
+
acyclic,
|
|
639
|
+
order,
|
|
640
|
+
layers,
|
|
641
|
+
frontier: layers[0] ?? [],
|
|
642
|
+
depth: longest.depth,
|
|
643
|
+
criticalPath: longest.path,
|
|
644
|
+
criticalPathLength: Math.max(0, longest.path.length - 1),
|
|
645
|
+
cycles,
|
|
646
|
+
provenance: { algorithm: "kahn-longest-path", edgeFamily: "ordering" }
|
|
619
647
|
};
|
|
648
|
+
}
|
|
649
|
+
function analyzeGraphImpact(graph, root, options = {}) {
|
|
650
|
+
const direction = options.direction ?? "outgoing";
|
|
651
|
+
const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;
|
|
652
|
+
const limit = options.limit ?? Number.POSITIVE_INFINITY;
|
|
653
|
+
const queue = [{ id: root, depth: 0 }];
|
|
654
|
+
const seen = /* @__PURE__ */ new Set([root]);
|
|
655
|
+
const parents = /* @__PURE__ */ new Map();
|
|
656
|
+
const affected = [];
|
|
620
657
|
let visitedNodes = 0;
|
|
658
|
+
let inspectedEdges = 0;
|
|
621
659
|
let truncated = false;
|
|
622
|
-
|
|
623
|
-
for (let index = 0; index < state.queue.length; index += 1) {
|
|
660
|
+
traversal: for (let index = 0; index < queue.length; index += 1) {
|
|
624
661
|
options.signal?.throwIfAborted();
|
|
625
|
-
|
|
626
|
-
truncated = true;
|
|
627
|
-
break;
|
|
628
|
-
}
|
|
629
|
-
const partial = state.queue[index];
|
|
662
|
+
const current = queue[index];
|
|
630
663
|
visitedNodes += 1;
|
|
631
|
-
|
|
632
|
-
|
|
664
|
+
const adjacent = graph.adjacency(current.id, {
|
|
665
|
+
direction,
|
|
666
|
+
kinds: options.kinds,
|
|
667
|
+
signal: options.signal
|
|
668
|
+
});
|
|
669
|
+
inspectedEdges += adjacent.meta.inspectedEdges;
|
|
670
|
+
if (current.depth >= maxDepth) {
|
|
671
|
+
if (adjacent.value.some((id) => !seen.has(id)))
|
|
633
672
|
truncated = true;
|
|
634
673
|
continue;
|
|
635
674
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
675
|
+
for (const id of adjacent.value) {
|
|
676
|
+
if (seen.has(id))
|
|
677
|
+
continue;
|
|
678
|
+
if (affected.length >= limit) {
|
|
679
|
+
truncated = true;
|
|
680
|
+
break traversal;
|
|
681
|
+
}
|
|
682
|
+
seen.add(id);
|
|
683
|
+
parents.set(id, current.id);
|
|
684
|
+
const depth = current.depth + 1;
|
|
685
|
+
affected.push({
|
|
686
|
+
id,
|
|
687
|
+
distance: depth,
|
|
688
|
+
path: reconstructImpactPath(root, id, parents)
|
|
689
|
+
});
|
|
690
|
+
queue.push({ id, depth });
|
|
639
691
|
}
|
|
640
692
|
}
|
|
641
693
|
return {
|
|
642
|
-
|
|
643
|
-
|
|
694
|
+
root,
|
|
695
|
+
affected,
|
|
696
|
+
exact: true,
|
|
697
|
+
truncated,
|
|
698
|
+
cost: { visitedNodes, inspectedEdges }
|
|
644
699
|
};
|
|
645
700
|
}
|
|
646
|
-
function
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const
|
|
650
|
-
const maxVisitedPaths = options.maxVisitedPaths ?? DEFAULT_MAX_VISITED_PATHS;
|
|
651
|
-
const maxDepth = options.maxDepth ?? DEFAULT_PATH_MAX_DEPTH;
|
|
652
|
-
assertPathBound("maxPaths", maxPaths);
|
|
653
|
-
assertPathBound("maxVisitedPaths", maxVisitedPaths);
|
|
654
|
-
assertPathBound("maxDepth", maxDepth);
|
|
655
|
-
const direction = options.direction ?? "outgoing";
|
|
656
|
-
options.signal?.throwIfAborted();
|
|
657
|
-
for (const kind of options.kinds ?? [])
|
|
658
|
-
graph.registry().require(kind);
|
|
659
|
-
if (source === target) {
|
|
660
|
-
if (maxPaths === 0) {
|
|
661
|
-
return {
|
|
662
|
-
value: [],
|
|
663
|
-
meta: { visitedNodes: 1, inspectedEdges: 0, truncated: true }
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
return {
|
|
667
|
-
value: [{ nodes: [source], edges: [], length: 0 }],
|
|
668
|
-
meta: { visitedNodes: 1, inspectedEdges: 0, truncated: false }
|
|
669
|
-
};
|
|
670
|
-
}
|
|
671
|
-
return enumerateNonZeroRelationshipPaths(graph, source, target, options, maxPaths, maxVisitedPaths, maxDepth, direction);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
// dist/sdk/graph/analytics.js
|
|
675
|
-
var DEFAULT_MAX_ITERATIONS = 16;
|
|
676
|
-
var DEFAULT_MIN_COMMUNITY_SIZE = 2;
|
|
677
|
-
var DEFAULT_REDUNDANCY_MAX_DEPTH = 8;
|
|
678
|
-
function assertPositiveBound(name, value) {
|
|
679
|
-
if (!Number.isInteger(value) || value < 1)
|
|
680
|
-
throw new TypeError(`Invalid ${name} bound: ${String(value)}`);
|
|
681
|
-
}
|
|
682
|
-
function buildUndirectedAdjacency(graph, kinds) {
|
|
683
|
-
const registry = graph.registry();
|
|
684
|
-
const wanted = kinds === void 0 ? void 0 : new Set(kinds.map((kind) => registry.require(kind).kind));
|
|
685
|
-
const adjacency = /* @__PURE__ */ new Map();
|
|
701
|
+
function analyzeKnowledgeGraph(graph) {
|
|
702
|
+
const nodes = [...graph.nodes()];
|
|
703
|
+
const weak = createAdjacency(nodes);
|
|
704
|
+
const directed = createAdjacency(nodes);
|
|
686
705
|
for (const edge of graph.edges()) {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
appendAdjacency(adjacency, edge.source, edge.target);
|
|
696
|
-
appendAdjacency(adjacency, edge.target, edge.source);
|
|
697
|
-
}
|
|
698
|
-
for (const neighbors of adjacency.values())
|
|
699
|
-
neighbors.sort();
|
|
700
|
-
return adjacency;
|
|
701
|
-
}
|
|
702
|
-
function appendAdjacency(adjacency, from, to) {
|
|
703
|
-
const neighbors = adjacency.get(from);
|
|
704
|
-
if (neighbors === void 0)
|
|
705
|
-
adjacency.set(from, [to]);
|
|
706
|
-
else
|
|
707
|
-
neighbors.push(to);
|
|
708
|
-
}
|
|
709
|
-
function dominantNeighborLabel(neighbors, labels) {
|
|
710
|
-
const counts = /* @__PURE__ */ new Map();
|
|
711
|
-
for (const neighbor of neighbors) {
|
|
712
|
-
const label = labels.get(neighbor);
|
|
713
|
-
counts.set(label, (counts.get(label) ?? 0) + 1);
|
|
714
|
-
}
|
|
715
|
-
let best;
|
|
716
|
-
let bestCount = 0;
|
|
717
|
-
for (const [label, count] of counts) {
|
|
718
|
-
if (count > bestCount || count === bestCount && label < best) {
|
|
719
|
-
best = label;
|
|
720
|
-
bestCount = count;
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
return best;
|
|
724
|
-
}
|
|
725
|
-
function collectCommunities(labels, minSize) {
|
|
726
|
-
const groups = /* @__PURE__ */ new Map();
|
|
727
|
-
for (const [id, label] of labels) {
|
|
728
|
-
const members = groups.get(label);
|
|
729
|
-
if (members === void 0)
|
|
730
|
-
groups.set(label, [id]);
|
|
731
|
-
else
|
|
732
|
-
members.push(id);
|
|
733
|
-
}
|
|
734
|
-
const communities = [];
|
|
735
|
-
for (const members of groups.values()) {
|
|
736
|
-
if (members.length < minSize)
|
|
706
|
+
appendNeighbor(weak, edge.source, edge.target);
|
|
707
|
+
appendNeighbor(weak, edge.target, edge.source);
|
|
708
|
+
appendNeighbor(directed, edge.source, edge.target);
|
|
709
|
+
}
|
|
710
|
+
const components = [];
|
|
711
|
+
const visited = /* @__PURE__ */ new Set();
|
|
712
|
+
for (const start of nodes) {
|
|
713
|
+
if (visited.has(start))
|
|
737
714
|
continue;
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
const minSize = options.minSize ?? DEFAULT_MIN_COMMUNITY_SIZE;
|
|
750
|
-
assertPositiveBound("maxIterations", maxIterations);
|
|
751
|
-
assertPositiveBound("minSize", minSize);
|
|
752
|
-
const adjacency = buildUndirectedAdjacency(graph, options.kinds);
|
|
753
|
-
const nodes = graph.nodes();
|
|
754
|
-
const labels = new Map(nodes.map((id) => [id, id]));
|
|
755
|
-
let iterations = 0;
|
|
756
|
-
let converged = false;
|
|
757
|
-
let visitedNodes = 0;
|
|
758
|
-
let inspectedEdges = 0;
|
|
759
|
-
while (iterations < maxIterations && !converged) {
|
|
760
|
-
options.signal?.throwIfAborted();
|
|
761
|
-
iterations += 1;
|
|
762
|
-
converged = true;
|
|
763
|
-
for (const id of nodes) {
|
|
764
|
-
visitedNodes += 1;
|
|
765
|
-
const neighbors = adjacency.get(id);
|
|
766
|
-
if (neighbors === void 0)
|
|
767
|
-
continue;
|
|
768
|
-
inspectedEdges += neighbors.length;
|
|
769
|
-
const dominant = dominantNeighborLabel(neighbors, labels);
|
|
770
|
-
if (dominant !== labels.get(id)) {
|
|
771
|
-
labels.set(id, dominant);
|
|
772
|
-
converged = false;
|
|
715
|
+
const component = [];
|
|
716
|
+
const stack = [start];
|
|
717
|
+
visited.add(start);
|
|
718
|
+
while (stack.length > 0) {
|
|
719
|
+
const current = stack.pop();
|
|
720
|
+
component.push(current);
|
|
721
|
+
for (const neighbor of weak.get(current)) {
|
|
722
|
+
if (visited.has(neighbor))
|
|
723
|
+
continue;
|
|
724
|
+
visited.add(neighbor);
|
|
725
|
+
stack.push(neighbor);
|
|
773
726
|
}
|
|
774
727
|
}
|
|
728
|
+
components.push(component);
|
|
775
729
|
}
|
|
730
|
+
const degrees = nodes.map((id) => ({ id, degree: weak.get(id).size }));
|
|
731
|
+
const maximum = Math.max(0, ...degrees.map(({ degree }) => degree));
|
|
776
732
|
return {
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
733
|
+
components: sortComponents(components),
|
|
734
|
+
stronglyConnected: stronglyConnectedComponents(nodes, directed),
|
|
735
|
+
orphans: degrees.filter(({ degree }) => degree === 0).map(({ id }) => id),
|
|
736
|
+
hubs: degrees.filter(({ degree }) => degree > 0 && degree === maximum),
|
|
737
|
+
exact: true,
|
|
738
|
+
provenance: { algorithm: "component-degree", edgeFamily: "all" }
|
|
783
739
|
};
|
|
784
740
|
}
|
|
785
|
-
function
|
|
786
|
-
|
|
741
|
+
function compareRelationshipSnapshots(before, after) {
|
|
742
|
+
const earlier = new Map(before.edges.map((edge) => [relationshipEdgeKey(edge), edge]));
|
|
743
|
+
const later = new Map(after.edges.map((edge) => [relationshipEdgeKey(edge), edge]));
|
|
744
|
+
return {
|
|
745
|
+
fromVersion: before.version,
|
|
746
|
+
toVersion: after.version,
|
|
747
|
+
added: [...later].filter(([key]) => !earlier.has(key)).map(([, edge]) => edge),
|
|
748
|
+
removed: [...earlier].filter(([key]) => !later.has(key)).map(([, edge]) => edge),
|
|
749
|
+
unchangedCount: [...earlier.keys()].filter((key) => later.has(key)).length,
|
|
750
|
+
exact: true
|
|
751
|
+
};
|
|
787
752
|
}
|
|
788
|
-
|
|
789
|
-
|
|
753
|
+
|
|
754
|
+
// dist/sdk/graph/centrality.js
|
|
755
|
+
function roundScore(value) {
|
|
756
|
+
return Math.round(value * 1e6) / 1e6;
|
|
757
|
+
}
|
|
758
|
+
function addToSetMap(map, key, value) {
|
|
759
|
+
const set = map.get(key);
|
|
760
|
+
if (set === void 0)
|
|
761
|
+
map.set(key, /* @__PURE__ */ new Set([value]));
|
|
762
|
+
else
|
|
763
|
+
set.add(value);
|
|
790
764
|
}
|
|
791
|
-
function
|
|
792
|
-
const
|
|
793
|
-
|
|
765
|
+
function buildSimpleUndirectedAdjacency(graph, kinds) {
|
|
766
|
+
const sets = new Map(graph.nodes().map((id) => [id, /* @__PURE__ */ new Set()]));
|
|
767
|
+
forEachMatchedRelationshipEdge(graph, kinds, (edge) => {
|
|
768
|
+
sets.get(edge.source).add(edge.target);
|
|
769
|
+
sets.get(edge.target).add(edge.source);
|
|
770
|
+
});
|
|
771
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
772
|
+
for (const [id, neighbors] of sets)
|
|
773
|
+
adjacency.set(id, [...neighbors].sort());
|
|
774
|
+
return adjacency;
|
|
794
775
|
}
|
|
795
|
-
function
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
776
|
+
function collectOrderingDegrees(graph, kinds) {
|
|
777
|
+
const incoming = /* @__PURE__ */ new Map();
|
|
778
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
779
|
+
forEachMatchedRelationshipEdge(graph, kinds, (edge, definition) => {
|
|
780
|
+
if (!definition.ordering)
|
|
781
|
+
return;
|
|
782
|
+
const { predecessor, successor } = orientOrderingEdge(edge, definition);
|
|
783
|
+
addToSetMap(outgoing, predecessor, successor);
|
|
784
|
+
addToSetMap(incoming, successor, predecessor);
|
|
785
|
+
});
|
|
786
|
+
return { incoming, outgoing };
|
|
787
|
+
}
|
|
788
|
+
function brandesShortestPaths(source, adjacency, cost) {
|
|
789
|
+
const distance = /* @__PURE__ */ new Map([[source, 0]]);
|
|
790
|
+
const sigma = /* @__PURE__ */ new Map([[source, 1]]);
|
|
791
|
+
const predecessors = /* @__PURE__ */ new Map();
|
|
792
|
+
const stack = [];
|
|
793
|
+
const queue = [source];
|
|
794
|
+
let reachableCount = 0;
|
|
795
|
+
let distanceSum = 0;
|
|
796
|
+
for (let index = 0; index < queue.length; index += 1) {
|
|
797
|
+
const node = queue[index];
|
|
798
|
+
cost.visitedNodes += 1;
|
|
799
|
+
stack.push(node);
|
|
800
|
+
const nodeDistance = distance.get(node);
|
|
801
|
+
if (node !== source) {
|
|
802
|
+
reachableCount += 1;
|
|
803
|
+
distanceSum += nodeDistance;
|
|
804
|
+
}
|
|
805
|
+
for (const neighbor of adjacency.get(node)) {
|
|
806
|
+
cost.inspectedEdges += 1;
|
|
807
|
+
if (!distance.has(neighbor)) {
|
|
808
|
+
distance.set(neighbor, nodeDistance + 1);
|
|
809
|
+
queue.push(neighbor);
|
|
810
|
+
}
|
|
811
|
+
if (distance.get(neighbor) === nodeDistance + 1) {
|
|
812
|
+
sigma.set(neighbor, (sigma.get(neighbor) ?? 0) + sigma.get(node));
|
|
813
|
+
const predecessorList = predecessors.get(neighbor);
|
|
814
|
+
if (predecessorList === void 0)
|
|
815
|
+
predecessors.set(neighbor, [node]);
|
|
816
|
+
else
|
|
817
|
+
predecessorList.push(node);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
805
820
|
}
|
|
806
|
-
return
|
|
821
|
+
return { stack, sigma, predecessors, reachableCount, distanceSum };
|
|
807
822
|
}
|
|
808
|
-
function
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
const
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
const key = transitiveFamilyKey(definition);
|
|
816
|
-
if (wanted !== void 0 && !wanted.has(key))
|
|
817
|
-
continue;
|
|
818
|
-
const oriented = orientTransitiveEdge(edge, definition);
|
|
819
|
-
if (oriented.from === oriented.to)
|
|
820
|
-
continue;
|
|
821
|
-
let family = families.get(key);
|
|
822
|
-
if (family === void 0) {
|
|
823
|
-
family = { adjacency: /* @__PURE__ */ new Map(), records: [] };
|
|
824
|
-
families.set(key, family);
|
|
823
|
+
function accumulateBetweenness(sweep, source, betweenness) {
|
|
824
|
+
const dependency = /* @__PURE__ */ new Map();
|
|
825
|
+
for (let index = sweep.stack.length - 1; index >= 0; index -= 1) {
|
|
826
|
+
const node = sweep.stack[index];
|
|
827
|
+
const share = (1 + (dependency.get(node) ?? 0)) / sweep.sigma.get(node);
|
|
828
|
+
for (const predecessor of sweep.predecessors.get(node) ?? []) {
|
|
829
|
+
dependency.set(predecessor, (dependency.get(predecessor) ?? 0) + sweep.sigma.get(predecessor) * share);
|
|
825
830
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
family.adjacency.set(oriented.from, /* @__PURE__ */ new Set([oriented.to]));
|
|
829
|
-
else
|
|
830
|
-
targets.add(oriented.to);
|
|
831
|
-
family.records.push({ ...oriented, edge });
|
|
832
|
-
}
|
|
833
|
-
return families;
|
|
834
|
-
}
|
|
835
|
-
function sortedFamilyAdjacency(family) {
|
|
836
|
-
const sorted = /* @__PURE__ */ new Map();
|
|
837
|
-
for (const [from, targets] of family.adjacency)
|
|
838
|
-
sorted.set(from, [...targets].sort());
|
|
839
|
-
return sorted;
|
|
840
|
-
}
|
|
841
|
-
function reconstructWitness(parents, from, tail, head) {
|
|
842
|
-
const witness = [head];
|
|
843
|
-
for (let node = tail; node !== from; node = parents.get(node))
|
|
844
|
-
witness.push(node);
|
|
845
|
-
witness.push(from);
|
|
846
|
-
return witness.reverse();
|
|
847
|
-
}
|
|
848
|
-
function expandWitnessFrontier(adjacency, record, current, parents, queue, cost) {
|
|
849
|
-
for (const next of adjacency.get(current.id) ?? []) {
|
|
850
|
-
cost.inspectedEdges += 1;
|
|
851
|
-
if (current.depth === 0 && next === record.to)
|
|
852
|
-
continue;
|
|
853
|
-
if (parents.has(next))
|
|
854
|
-
continue;
|
|
855
|
-
parents.set(next, current.id);
|
|
856
|
-
if (next === record.to)
|
|
857
|
-
return reconstructWitness(parents, record.from, current.id, next);
|
|
858
|
-
queue.push({ id: next, depth: current.depth + 1 });
|
|
831
|
+
if (node !== source)
|
|
832
|
+
betweenness.set(node, (betweenness.get(node) ?? 0) + (dependency.get(node) ?? 0));
|
|
859
833
|
}
|
|
860
|
-
return void 0;
|
|
861
834
|
}
|
|
862
|
-
function
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
const current = queue[index];
|
|
867
|
-
cost.visitedNodes += 1;
|
|
868
|
-
if (current.depth >= maxDepth)
|
|
869
|
-
continue;
|
|
870
|
-
const witness = expandWitnessFrontier(adjacency, record, current, parents, queue, cost);
|
|
871
|
-
if (witness !== void 0)
|
|
872
|
-
return witness;
|
|
873
|
-
}
|
|
874
|
-
return void 0;
|
|
835
|
+
function wassermanFaustCloseness(sweep, nodeCount) {
|
|
836
|
+
if (nodeCount <= 1 || sweep.reachableCount === 0)
|
|
837
|
+
return 0;
|
|
838
|
+
return sweep.reachableCount / (nodeCount - 1) * (sweep.reachableCount / sweep.distanceSum);
|
|
875
839
|
}
|
|
876
|
-
function
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
840
|
+
function centralityRow(id, adjacency, directed, betweenness, closeness) {
|
|
841
|
+
return {
|
|
842
|
+
id,
|
|
843
|
+
degree: adjacency.get(id).length,
|
|
844
|
+
inDegree: directed.incoming.get(id)?.size ?? 0,
|
|
845
|
+
outDegree: directed.outgoing.get(id)?.size ?? 0,
|
|
846
|
+
// Undirected betweenness double-counts each ordered pair; halve it.
|
|
847
|
+
betweenness: roundScore((betweenness.get(id) ?? 0) / 2),
|
|
848
|
+
// Every node is a sweep source, so closeness is always populated.
|
|
849
|
+
closeness: roundScore(closeness.get(id))
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
function computeRelationshipCentrality(graph, options = {}) {
|
|
853
|
+
const adjacency = buildSimpleUndirectedAdjacency(graph, options.kinds);
|
|
854
|
+
const directed = collectOrderingDegrees(graph, options.kinds);
|
|
855
|
+
const nodes = graph.nodes();
|
|
856
|
+
const betweenness = /* @__PURE__ */ new Map();
|
|
857
|
+
const closeness = /* @__PURE__ */ new Map();
|
|
885
858
|
const cost = { visitedNodes: 0, inspectedEdges: 0 };
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
const
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
options.signal?.throwIfAborted();
|
|
892
|
-
const witness = findWitnessPath(adjacency, record, maxDepth, cost);
|
|
893
|
-
if (witness === void 0)
|
|
894
|
-
continue;
|
|
895
|
-
if (value.length >= limit) {
|
|
896
|
-
truncated = true;
|
|
897
|
-
break scan;
|
|
898
|
-
}
|
|
899
|
-
value.push({ edge: record.edge, witness });
|
|
900
|
-
}
|
|
859
|
+
for (const source of nodes) {
|
|
860
|
+
options.signal?.throwIfAborted();
|
|
861
|
+
const sweep = brandesShortestPaths(source, adjacency, cost);
|
|
862
|
+
closeness.set(source, wassermanFaustCloseness(sweep, nodes.length));
|
|
863
|
+
accumulateBetweenness(sweep, source, betweenness);
|
|
901
864
|
}
|
|
865
|
+
let degreeSum = 0;
|
|
866
|
+
for (const neighbors of adjacency.values())
|
|
867
|
+
degreeSum += neighbors.length;
|
|
868
|
+
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));
|
|
902
869
|
return {
|
|
903
|
-
value,
|
|
870
|
+
value: { nodeCount: nodes.length, edgeCount: degreeSum / 2, rows },
|
|
904
871
|
meta: {
|
|
905
872
|
visitedNodes: cost.visitedNodes,
|
|
906
873
|
inspectedEdges: cost.inspectedEdges,
|
|
907
|
-
truncated
|
|
874
|
+
truncated: false
|
|
908
875
|
}
|
|
909
876
|
};
|
|
910
877
|
}
|
|
911
|
-
function
|
|
912
|
-
|
|
913
|
-
const nexts = [];
|
|
914
|
-
for (const row of rows) {
|
|
915
|
-
if (row.id === id || nextSet.has(row.id))
|
|
916
|
-
continue;
|
|
917
|
-
if (!state.seen.has(row.id)) {
|
|
918
|
-
if (depth >= maxDepth) {
|
|
919
|
-
state.truncated = true;
|
|
920
|
-
continue;
|
|
921
|
-
}
|
|
922
|
-
state.seen.add(row.id);
|
|
923
|
-
state.queue.push({ id: row.id, depth: depth + 1 });
|
|
924
|
-
}
|
|
925
|
-
nextSet.add(row.id);
|
|
926
|
-
nexts.push(row.id);
|
|
927
|
-
let incoming = state.predecessors.get(row.id);
|
|
928
|
-
if (incoming === void 0) {
|
|
929
|
-
incoming = /* @__PURE__ */ new Set();
|
|
930
|
-
state.predecessors.set(row.id, incoming);
|
|
931
|
-
}
|
|
932
|
-
incoming.add(id);
|
|
933
|
-
}
|
|
934
|
-
return nexts;
|
|
878
|
+
function orderedBridge(left, right) {
|
|
879
|
+
return left <= right ? { source: left, target: right } : { source: right, target: left };
|
|
935
880
|
}
|
|
936
|
-
function
|
|
937
|
-
const
|
|
938
|
-
const
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
};
|
|
947
|
-
let inspectedEdges = 0;
|
|
948
|
-
for (let index = 0; index < state.queue.length; index += 1) {
|
|
949
|
-
options.signal?.throwIfAborted();
|
|
950
|
-
const { id, depth } = state.queue[index];
|
|
951
|
-
order.push(id);
|
|
952
|
-
const rows = graph.neighborEdges(id, {
|
|
953
|
-
direction,
|
|
954
|
-
...options.kinds === void 0 ? {} : { kinds: options.kinds }
|
|
955
|
-
});
|
|
956
|
-
inspectedEdges += rows.meta.inspectedEdges;
|
|
957
|
-
successors.set(id, expandReachableNode(id, depth, rows.value, maxDepth, state));
|
|
881
|
+
function advanceCutFrame(frame, adjacency, state) {
|
|
882
|
+
const neighbors = adjacency.get(frame.node);
|
|
883
|
+
const neighbor = neighbors[frame.neighborIndex];
|
|
884
|
+
frame.neighborIndex += 1;
|
|
885
|
+
state.inspectedEdges += 1;
|
|
886
|
+
if (neighbor === frame.parent)
|
|
887
|
+
return void 0;
|
|
888
|
+
if (state.discovery.has(neighbor)) {
|
|
889
|
+
state.low.set(frame.node, Math.min(state.low.get(frame.node), state.discovery.get(neighbor)));
|
|
890
|
+
return void 0;
|
|
958
891
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
truncated: state.truncated
|
|
965
|
-
};
|
|
892
|
+
frame.children += 1;
|
|
893
|
+
state.discovery.set(neighbor, state.timer);
|
|
894
|
+
state.low.set(neighbor, state.timer);
|
|
895
|
+
state.timer += 1;
|
|
896
|
+
return { node: neighbor, parent: frame.node, neighborIndex: 0, children: 0 };
|
|
966
897
|
}
|
|
967
|
-
function
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
898
|
+
function retreatCutFrame(frame, root, state) {
|
|
899
|
+
if (frame.parent === null) {
|
|
900
|
+
if (frame.children > 1)
|
|
901
|
+
state.articulation.add(frame.node);
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
const parent = frame.parent;
|
|
905
|
+
const childLow = state.low.get(frame.node);
|
|
906
|
+
state.low.set(parent, Math.min(state.low.get(parent), childLow));
|
|
907
|
+
if (parent !== root && childLow >= state.discovery.get(parent))
|
|
908
|
+
state.articulation.add(parent);
|
|
909
|
+
if (childLow > state.discovery.get(parent))
|
|
910
|
+
state.bridges.push(orderedBridge(parent, frame.node));
|
|
911
|
+
}
|
|
912
|
+
function searchComponentCuts(root, adjacency, state, signal) {
|
|
913
|
+
state.discovery.set(root, state.timer);
|
|
914
|
+
state.low.set(root, state.timer);
|
|
915
|
+
state.timer += 1;
|
|
916
|
+
const stack = [
|
|
917
|
+
{ node: root, parent: null, neighborIndex: 0, children: 0 }
|
|
918
|
+
];
|
|
971
919
|
while (stack.length > 0) {
|
|
920
|
+
signal?.throwIfAborted();
|
|
972
921
|
const frame = stack.at(-1);
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
if (!visited.has(next)) {
|
|
978
|
-
visited.add(next);
|
|
979
|
-
stack.push({ id: next, index: 0 });
|
|
980
|
-
}
|
|
922
|
+
if (frame.neighborIndex < adjacency.get(frame.node).length) {
|
|
923
|
+
const child = advanceCutFrame(frame, adjacency, state);
|
|
924
|
+
if (child !== void 0)
|
|
925
|
+
stack.push(child);
|
|
981
926
|
} else {
|
|
982
|
-
|
|
927
|
+
retreatCutFrame(frame, root, state);
|
|
983
928
|
stack.pop();
|
|
984
929
|
}
|
|
985
930
|
}
|
|
986
|
-
return postorder.reverse();
|
|
987
931
|
}
|
|
988
|
-
function
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
let candidate;
|
|
1001
|
-
for (const pred of [...predecessors].sort()) {
|
|
1002
|
-
if (!idom.has(pred))
|
|
1003
|
-
continue;
|
|
1004
|
-
candidate = candidate === void 0 ? pred : intersectDominators(candidate, pred, idom, ordinal);
|
|
1005
|
-
}
|
|
1006
|
-
return candidate;
|
|
1007
|
-
}
|
|
1008
|
-
function solveImmediateDominators(subgraph, root, order, ordinal, signal) {
|
|
1009
|
-
const idom = /* @__PURE__ */ new Map([[root, root]]);
|
|
1010
|
-
let changed = true;
|
|
1011
|
-
while (changed) {
|
|
1012
|
-
changed = false;
|
|
1013
|
-
for (const id of order) {
|
|
1014
|
-
signal?.throwIfAborted();
|
|
1015
|
-
if (id === root)
|
|
1016
|
-
continue;
|
|
1017
|
-
const candidate = dominatorCandidate(subgraph.predecessors.get(id), idom, ordinal);
|
|
1018
|
-
if (candidate !== void 0 && idom.get(id) !== candidate) {
|
|
1019
|
-
idom.set(id, candidate);
|
|
1020
|
-
changed = true;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
return idom;
|
|
1025
|
-
}
|
|
1026
|
-
function computeRelationshipDominators(graph, root, options = {}) {
|
|
1027
|
-
if (!graph.hasNode(root))
|
|
1028
|
-
throw new TypeError(`Relationship node not found: ${root}`);
|
|
1029
|
-
if (options.maxDepth !== void 0 && (!Number.isInteger(options.maxDepth) || options.maxDepth < 0))
|
|
1030
|
-
throw new TypeError(`Invalid maxDepth bound: ${String(options.maxDepth)}`);
|
|
1031
|
-
const subgraph = indexReachableSubgraph(graph, root, options);
|
|
1032
|
-
const order = reversePostorder(subgraph, root);
|
|
1033
|
-
const ordinal = new Map(order.map((id, index) => [id, index]));
|
|
1034
|
-
const idom = solveImmediateDominators(subgraph, root, order, ordinal, options.signal);
|
|
1035
|
-
const subtreeSizes = new Map(order.map((id) => [id, 1]));
|
|
1036
|
-
for (let index = order.length - 1; index >= 0; index -= 1) {
|
|
1037
|
-
const id = order[index];
|
|
1038
|
-
if (id === root)
|
|
932
|
+
function findRelationshipCutStructure(graph, options = {}) {
|
|
933
|
+
const adjacency = buildSimpleUndirectedAdjacency(graph, options.kinds);
|
|
934
|
+
const state = {
|
|
935
|
+
discovery: /* @__PURE__ */ new Map(),
|
|
936
|
+
low: /* @__PURE__ */ new Map(),
|
|
937
|
+
timer: 0,
|
|
938
|
+
articulation: /* @__PURE__ */ new Set(),
|
|
939
|
+
bridges: [],
|
|
940
|
+
inspectedEdges: 0
|
|
941
|
+
};
|
|
942
|
+
for (const root of graph.nodes()) {
|
|
943
|
+
if (state.discovery.has(root))
|
|
1039
944
|
continue;
|
|
1040
|
-
|
|
1041
|
-
subtreeSizes.set(parent, subtreeSizes.get(parent) + subtreeSizes.get(id));
|
|
945
|
+
searchComponentCuts(root, adjacency, state, options.signal);
|
|
1042
946
|
}
|
|
1043
|
-
const rows = order.filter((id) => id !== root).map((id) => ({
|
|
1044
|
-
id,
|
|
1045
|
-
idom: idom.get(id),
|
|
1046
|
-
dominatedCount: subtreeSizes.get(id) - 1
|
|
1047
|
-
})).sort((left, right) => right.dominatedCount - left.dominatedCount || left.id.localeCompare(right.id));
|
|
1048
947
|
return {
|
|
1049
|
-
value: {
|
|
948
|
+
value: {
|
|
949
|
+
articulationPoints: [...state.articulation].sort(),
|
|
950
|
+
bridges: state.bridges.sort((left, right) => left.source.localeCompare(right.source) || left.target.localeCompare(right.target))
|
|
951
|
+
},
|
|
1050
952
|
meta: {
|
|
1051
|
-
visitedNodes:
|
|
1052
|
-
inspectedEdges:
|
|
1053
|
-
truncated:
|
|
953
|
+
visitedNodes: state.discovery.size,
|
|
954
|
+
inspectedEdges: state.inspectedEdges,
|
|
955
|
+
truncated: false
|
|
1054
956
|
}
|
|
1055
957
|
};
|
|
1056
958
|
}
|
|
1057
959
|
|
|
1058
|
-
// dist/sdk/graph/
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
};
|
|
1065
|
-
function buildFinding(code, severity, policy, describe, subjects, maxSampleSize, remediation) {
|
|
1066
|
-
const sorted = [...subjects].sort((left, right) => left.localeCompare(right));
|
|
1067
|
-
return {
|
|
1068
|
-
code,
|
|
1069
|
-
severity,
|
|
1070
|
-
policy,
|
|
1071
|
-
message: describe(sorted.length),
|
|
1072
|
-
count: sorted.length,
|
|
1073
|
-
sample: sorted.slice(0, maxSampleSize),
|
|
1074
|
-
sample_truncated: sorted.length > maxSampleSize,
|
|
1075
|
-
remediation
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1078
|
-
function buildOrderingAdjacency(assembly) {
|
|
1079
|
-
const registry = assembly.graph.registry();
|
|
1080
|
-
const successors = /* @__PURE__ */ new Map();
|
|
1081
|
-
for (const edge of assembly.graph.edges()) {
|
|
960
|
+
// dist/sdk/graph/scheduling.js
|
|
961
|
+
function collectOrderingParticipation(graph) {
|
|
962
|
+
const registry = graph.registry();
|
|
963
|
+
const forward = /* @__PURE__ */ new Map();
|
|
964
|
+
const participants = /* @__PURE__ */ new Set();
|
|
965
|
+
for (const edge of graph.edges()) {
|
|
1082
966
|
const definition = registry.require(edge.kind);
|
|
1083
967
|
if (!definition.ordering)
|
|
1084
968
|
continue;
|
|
1085
|
-
const
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
969
|
+
const { predecessor, successor } = orientOrderingEdge(edge, definition);
|
|
970
|
+
participants.add(predecessor);
|
|
971
|
+
participants.add(successor);
|
|
972
|
+
if (predecessor === successor)
|
|
973
|
+
continue;
|
|
974
|
+
const targets = forward.get(predecessor);
|
|
975
|
+
if (targets === void 0)
|
|
976
|
+
forward.set(predecessor, /* @__PURE__ */ new Set([successor]));
|
|
1089
977
|
else
|
|
1090
|
-
|
|
1091
|
-
}
|
|
1092
|
-
for (const adjacent of successors.values())
|
|
1093
|
-
adjacent.sort((left, right) => left.localeCompare(right));
|
|
1094
|
-
return successors;
|
|
1095
|
-
}
|
|
1096
|
-
function registerTarjanNode(node, state) {
|
|
1097
|
-
state.indexes.set(node, state.nextIndex);
|
|
1098
|
-
state.lowLinks.set(node, state.nextIndex);
|
|
1099
|
-
state.nextIndex += 1;
|
|
1100
|
-
state.stack.push(node);
|
|
1101
|
-
state.onStack.add(node);
|
|
1102
|
-
}
|
|
1103
|
-
function visitNextTarjanNeighbor(frame, frames, successors, state) {
|
|
1104
|
-
const neighbors = successors.get(frame.node) ?? [];
|
|
1105
|
-
if (frame.neighborIndex >= neighbors.length)
|
|
1106
|
-
return false;
|
|
1107
|
-
const neighbor = neighbors[frame.neighborIndex];
|
|
1108
|
-
frame.neighborIndex += 1;
|
|
1109
|
-
if (!state.indexes.has(neighbor)) {
|
|
1110
|
-
registerTarjanNode(neighbor, state);
|
|
1111
|
-
frames.push({ node: neighbor, neighborIndex: 0 });
|
|
1112
|
-
} else if (state.onStack.has(neighbor)) {
|
|
1113
|
-
state.lowLinks.set(frame.node, Math.min(state.lowLinks.get(frame.node), state.indexes.get(neighbor)));
|
|
978
|
+
targets.add(successor);
|
|
1114
979
|
}
|
|
1115
|
-
return
|
|
980
|
+
return { forward, participants };
|
|
1116
981
|
}
|
|
1117
|
-
function
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
while (true) {
|
|
1126
|
-
const member = state.stack.pop();
|
|
1127
|
-
state.onStack.delete(member);
|
|
1128
|
-
component.push(member);
|
|
1129
|
-
if (member === frame.node)
|
|
1130
|
-
break;
|
|
982
|
+
function latestFinishFor(successors, acyclic, latestStart, makespan) {
|
|
983
|
+
if (successors === void 0)
|
|
984
|
+
return makespan;
|
|
985
|
+
let bound = makespan;
|
|
986
|
+
for (const successor of successors) {
|
|
987
|
+
if (!acyclic.has(successor))
|
|
988
|
+
continue;
|
|
989
|
+
bound = Math.min(bound, latestStart.get(successor));
|
|
1131
990
|
}
|
|
1132
|
-
|
|
1133
|
-
state.components.push(component.sort((left, right) => left.localeCompare(right)));
|
|
991
|
+
return bound;
|
|
1134
992
|
}
|
|
1135
|
-
function
|
|
1136
|
-
const
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
993
|
+
function scheduleRow(id, earliestStart, latestStart) {
|
|
994
|
+
const slack = latestStart - earliestStart;
|
|
995
|
+
return {
|
|
996
|
+
id,
|
|
997
|
+
earliestStart,
|
|
998
|
+
earliestFinish: earliestStart + 1,
|
|
999
|
+
latestStart,
|
|
1000
|
+
latestFinish: latestStart + 1,
|
|
1001
|
+
slack,
|
|
1002
|
+
critical: slack === 0
|
|
1143
1003
|
};
|
|
1144
|
-
const roots = [...successors.keys()].sort((left, right) => left.localeCompare(right));
|
|
1145
|
-
for (const root of roots) {
|
|
1146
|
-
if (state.indexes.has(root))
|
|
1147
|
-
continue;
|
|
1148
|
-
const frames = [{ node: root, neighborIndex: 0 }];
|
|
1149
|
-
registerTarjanNode(root, state);
|
|
1150
|
-
while (frames.length > 0) {
|
|
1151
|
-
const frame = frames.at(-1);
|
|
1152
|
-
if (visitNextTarjanNeighbor(frame, frames, successors, state))
|
|
1153
|
-
continue;
|
|
1154
|
-
completeTarjanFrame(frame, frames, successors, state);
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
return state.components.sort((left, right) => left[0].localeCompare(right[0]));
|
|
1158
1004
|
}
|
|
1159
|
-
function
|
|
1160
|
-
|
|
1005
|
+
function computeScheduleRows(topoParticipants, participation, depth, acyclic, makespan) {
|
|
1006
|
+
const latestStart = /* @__PURE__ */ new Map();
|
|
1007
|
+
for (let index = topoParticipants.length - 1; index >= 0; index -= 1) {
|
|
1008
|
+
const id = topoParticipants[index];
|
|
1009
|
+
const finish = latestFinishFor(participation.forward.get(id), acyclic, latestStart, makespan);
|
|
1010
|
+
latestStart.set(id, finish - 1);
|
|
1011
|
+
}
|
|
1012
|
+
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));
|
|
1161
1013
|
}
|
|
1162
|
-
function
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
const
|
|
1169
|
-
const
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
const orderingAdjacency = buildOrderingAdjacency(assembly);
|
|
1187
|
-
for (const cycle of collectOrderingCycles(orderingAdjacency)) {
|
|
1188
|
-
const active = cycle.some((member) => isActiveAuditMember(member, nodeStates));
|
|
1189
|
-
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."));
|
|
1190
|
-
}
|
|
1191
|
-
const predecessorsByNode = /* @__PURE__ */ new Map();
|
|
1192
|
-
for (const [predecessor, adjacent] of orderingAdjacency)
|
|
1193
|
-
for (const successor of adjacent) {
|
|
1194
|
-
const predecessors = predecessorsByNode.get(successor);
|
|
1195
|
-
if (predecessors)
|
|
1196
|
-
predecessors.push(predecessor);
|
|
1197
|
-
else
|
|
1198
|
-
predecessorsByNode.set(successor, [predecessor]);
|
|
1199
|
-
}
|
|
1200
|
-
const staleLifecycleBlocks = [...nodeStates.values()].filter((state) => !state.missing && !state.terminal && isBlocked(state.status) && !(predecessorsByNode.get(state.id) ?? []).some((predecessor) => {
|
|
1201
|
-
const predecessorState = nodeStates.get(predecessor);
|
|
1202
|
-
return predecessorState === void 0 || !predecessorState.terminal;
|
|
1203
|
-
})).map((state) => state.id);
|
|
1204
|
-
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.");
|
|
1205
|
-
return findings;
|
|
1206
|
-
}
|
|
1207
|
-
function formatDuplicateEdgeGroup(group) {
|
|
1208
|
-
const kinds = group.edges.map((edge) => edge.kind).sort((left, right) => left.localeCompare(right));
|
|
1209
|
-
return `${group.from} -> ${group.to} (${kinds.join(" + ")})`;
|
|
1210
|
-
}
|
|
1211
|
-
function collectDuplicateRelationshipEdgeGroups(assembly) {
|
|
1212
|
-
const registry = assembly.graph.registry();
|
|
1213
|
-
const groups = /* @__PURE__ */ new Map();
|
|
1214
|
-
for (const edge of assembly.graph.edges()) {
|
|
1215
|
-
const definition = registry.require(edge.kind);
|
|
1216
|
-
if (!isTransitiveKind(definition))
|
|
1217
|
-
continue;
|
|
1218
|
-
const oriented = orientTransitiveEdge(edge, definition);
|
|
1219
|
-
if (oriented.from === oriented.to)
|
|
1220
|
-
continue;
|
|
1221
|
-
const key = `${transitiveFamilyKey(definition)}::${oriented.from}::${oriented.to}`;
|
|
1222
|
-
const group = groups.get(key);
|
|
1223
|
-
if (group)
|
|
1224
|
-
group.edges.push(edge);
|
|
1225
|
-
else
|
|
1226
|
-
groups.set(key, { ...oriented, edges: [edge] });
|
|
1227
|
-
}
|
|
1228
|
-
const duplicated = [...groups.values()].filter((group) => group.edges.length >= 2);
|
|
1229
|
-
for (const group of duplicated)
|
|
1230
|
-
group.edges.sort((left, right) => left.kind.localeCompare(right.kind));
|
|
1231
|
-
return duplicated.sort((left, right) => left.from.localeCompare(right.from) || left.to.localeCompare(right.to));
|
|
1232
|
-
}
|
|
1233
|
-
function collectDuplicateEdgeFindings(assembly, nodeStates, maxSampleSize) {
|
|
1234
|
-
const active = [];
|
|
1235
|
-
const legacy = [];
|
|
1236
|
-
for (const group of collectDuplicateRelationshipEdgeGroups(assembly)) {
|
|
1237
|
-
const subjects = isActiveAuditMember(group.from, nodeStates) || isActiveAuditMember(group.to, nodeStates) ? active : legacy;
|
|
1238
|
-
subjects.push(formatDuplicateEdgeGroup(group));
|
|
1239
|
-
}
|
|
1240
|
-
const findings = [];
|
|
1241
|
-
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.");
|
|
1242
|
-
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.");
|
|
1243
|
-
return findings;
|
|
1244
|
-
}
|
|
1245
|
-
function collectCoverageReport(assembly, nodeStates, exemptIsolates, maxSampleSize, edgesByKind) {
|
|
1246
|
-
let activeNodes = 0;
|
|
1247
|
-
let missingNodes = 0;
|
|
1248
|
-
let isolatedActiveNodes = 0;
|
|
1249
|
-
let degreeLeqOneActive = 0;
|
|
1250
|
-
const isolates = [];
|
|
1251
|
-
const sparse = [];
|
|
1252
|
-
for (const id of assembly.graph.nodes()) {
|
|
1253
|
-
const state = nodeStates.get(id);
|
|
1254
|
-
if (!state)
|
|
1255
|
-
continue;
|
|
1256
|
-
if (state.missing) {
|
|
1257
|
-
missingNodes += 1;
|
|
1258
|
-
continue;
|
|
1014
|
+
function analyzeRelationshipSchedule(graph, options = {}) {
|
|
1015
|
+
options.signal?.throwIfAborted();
|
|
1016
|
+
const execution = analyzeRelationshipExecution(graph, { registry: graph.registry() });
|
|
1017
|
+
const participation = collectOrderingParticipation(graph);
|
|
1018
|
+
const acyclic = new Set(execution.order);
|
|
1019
|
+
const topoParticipants = execution.order.filter((id) => participation.participants.has(id));
|
|
1020
|
+
const makespan = topoParticipants.reduce((peak, id) => Math.max(peak, execution.depth[id] + 1), 0);
|
|
1021
|
+
const rows = computeScheduleRows(topoParticipants, participation, execution.depth, acyclic, makespan);
|
|
1022
|
+
const scheduled = rows.length > 0;
|
|
1023
|
+
return {
|
|
1024
|
+
exact: true,
|
|
1025
|
+
acyclic: execution.acyclic,
|
|
1026
|
+
makespan,
|
|
1027
|
+
scheduledCount: rows.length,
|
|
1028
|
+
// A single-node execution "path" over a workspace with no order-bearing
|
|
1029
|
+
// edge is not a real critical path, so report it only when work is scheduled.
|
|
1030
|
+
criticalPath: scheduled ? execution.criticalPath : [],
|
|
1031
|
+
criticalPathLength: scheduled ? execution.criticalPathLength : 0,
|
|
1032
|
+
cycles: execution.cycles,
|
|
1033
|
+
rows,
|
|
1034
|
+
provenance: {
|
|
1035
|
+
algorithm: "critical-path-method",
|
|
1036
|
+
edgeFamily: "ordering",
|
|
1037
|
+
weighting: "unit"
|
|
1259
1038
|
}
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
// dist/sdk/graph/durable-cache.js
|
|
1043
|
+
import path from "node:path";
|
|
1044
|
+
var GRAPH_DURABLE_CACHE_VERSION = 1;
|
|
1045
|
+
var GRAPH_DURABLE_CACHE_MIN_ITEMS = 500;
|
|
1046
|
+
var MAX_DURABLE_RESULTS = 64;
|
|
1047
|
+
var DURABLE_GRAPH_CACHE_LOCK_ID = "graph-durable-cache";
|
|
1048
|
+
function acquireDurableGraphCacheLock(pmRoot) {
|
|
1049
|
+
return acquireLock(pmRoot, DURABLE_GRAPH_CACHE_LOCK_ID, 30, `graph-cache:${process.pid}`, false, false, 3e3);
|
|
1050
|
+
}
|
|
1051
|
+
function durableGraphCachePath(pmRoot) {
|
|
1052
|
+
return path.join(pmRoot, "runtime", "graph-cache.json");
|
|
1053
|
+
}
|
|
1054
|
+
function graphAuditBaselinePath(pmRoot) {
|
|
1055
|
+
return path.join(pmRoot, "runtime", "graph-audit-baseline.json");
|
|
1056
|
+
}
|
|
1057
|
+
function decodeEnvelope(raw) {
|
|
1058
|
+
if (raw === null)
|
|
1059
|
+
return void 0;
|
|
1060
|
+
try {
|
|
1061
|
+
const parsed = JSON.parse(raw);
|
|
1062
|
+
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))
|
|
1063
|
+
return void 0;
|
|
1064
|
+
return parsed;
|
|
1065
|
+
} catch {
|
|
1066
|
+
return void 0;
|
|
1275
1067
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1068
|
+
}
|
|
1069
|
+
async function openDurableGraphCache(pmRoot, fingerprint) {
|
|
1070
|
+
const raw = await readFileIfExists(durableGraphCachePath(pmRoot));
|
|
1071
|
+
const envelope = decodeEnvelope(raw);
|
|
1072
|
+
const fresh = envelope?.fingerprint === fingerprint;
|
|
1279
1073
|
return {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
edges: assembly.graph.edges().length,
|
|
1284
|
-
edges_by_kind: Object.fromEntries(Object.entries(edgesByKind).sort(([left], [right]) => left.localeCompare(right))),
|
|
1285
|
-
active_nodes: activeNodes,
|
|
1286
|
-
missing_nodes: missingNodes,
|
|
1287
|
-
isolated_active_nodes: isolatedActiveNodes,
|
|
1288
|
-
degree_leq_one_active_nodes: degreeLeqOneActive
|
|
1289
|
-
}
|
|
1074
|
+
exists: raw !== null,
|
|
1075
|
+
fresh,
|
|
1076
|
+
results: fresh ? envelope.results : {}
|
|
1290
1077
|
};
|
|
1291
1078
|
}
|
|
1292
|
-
function
|
|
1293
|
-
const
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1079
|
+
async function persistDurableGraphResult(pmRoot, fingerprint, view, queryKey, result) {
|
|
1080
|
+
const release = await acquireDurableGraphCacheLock(pmRoot);
|
|
1081
|
+
try {
|
|
1082
|
+
const envelope = decodeEnvelope(await readFileIfExists(durableGraphCachePath(pmRoot)));
|
|
1083
|
+
const results = envelope?.fingerprint === fingerprint ? envelope.results : {};
|
|
1084
|
+
delete results[queryKey];
|
|
1085
|
+
results[queryKey] = result;
|
|
1086
|
+
const keys = Object.keys(results);
|
|
1087
|
+
for (const stale of keys.slice(0, Math.max(0, keys.length - MAX_DURABLE_RESULTS)))
|
|
1088
|
+
delete results[stale];
|
|
1089
|
+
await writeFileAtomic(durableGraphCachePath(pmRoot), JSON.stringify({
|
|
1090
|
+
version: GRAPH_DURABLE_CACHE_VERSION,
|
|
1091
|
+
fingerprint,
|
|
1092
|
+
saved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1093
|
+
results
|
|
1094
|
+
}));
|
|
1095
|
+
view.results = results;
|
|
1096
|
+
} finally {
|
|
1097
|
+
await release();
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
async function clearDurableGraphCache(pmRoot) {
|
|
1101
|
+
const release = await acquireDurableGraphCacheLock(pmRoot);
|
|
1102
|
+
try {
|
|
1103
|
+
await removeFileIfExists(durableGraphCachePath(pmRoot));
|
|
1104
|
+
} finally {
|
|
1105
|
+
await release();
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
async function durableGraphCacheStatus(pmRoot, fingerprint) {
|
|
1109
|
+
const cachePath = durableGraphCachePath(pmRoot);
|
|
1110
|
+
const raw = await readFileIfExists(cachePath);
|
|
1111
|
+
const envelope = decodeEnvelope(raw);
|
|
1112
|
+
if (envelope === void 0)
|
|
1113
|
+
return { exists: raw !== null, fresh: false, entry_count: 0 };
|
|
1321
1114
|
return {
|
|
1322
|
-
|
|
1323
|
-
|
|
1115
|
+
exists: true,
|
|
1116
|
+
fresh: envelope.fingerprint === fingerprint,
|
|
1117
|
+
entry_count: Object.keys(envelope.results).length,
|
|
1118
|
+
fingerprint: envelope.fingerprint.slice(0, 12),
|
|
1119
|
+
saved_at: envelope.saved_at,
|
|
1120
|
+
bytes: Buffer.byteLength(raw, "utf8")
|
|
1324
1121
|
};
|
|
1325
1122
|
}
|
|
1123
|
+
function shouldPersistDurableGraphCache(itemCount, envelopeExists) {
|
|
1124
|
+
return envelopeExists || itemCount >= GRAPH_DURABLE_CACHE_MIN_ITEMS;
|
|
1125
|
+
}
|
|
1126
|
+
function isNonnegativeCountRecord(value) {
|
|
1127
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((count) => Number.isInteger(count) && count >= 0);
|
|
1128
|
+
}
|
|
1129
|
+
function isNonnegativeCoverageByTypeRecord(value) {
|
|
1130
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
1131
|
+
return false;
|
|
1132
|
+
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));
|
|
1133
|
+
}
|
|
1134
|
+
function decodeBaseline(raw) {
|
|
1135
|
+
if (raw === null)
|
|
1136
|
+
return void 0;
|
|
1137
|
+
try {
|
|
1138
|
+
const parsed = JSON.parse(raw);
|
|
1139
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
1140
|
+
return void 0;
|
|
1141
|
+
const snapshot = parsed;
|
|
1142
|
+
const profile = snapshot.profile;
|
|
1143
|
+
if (typeof snapshot.saved_at !== "string" || typeof snapshot.fingerprint !== "string" || !isNonnegativeCountRecord(snapshot.affected_subjects_by_code) || typeof profile !== "object" || profile === null || ![
|
|
1144
|
+
profile.nodes,
|
|
1145
|
+
profile.edges,
|
|
1146
|
+
profile.active_nodes,
|
|
1147
|
+
profile.missing_nodes,
|
|
1148
|
+
profile.isolated_active_nodes,
|
|
1149
|
+
profile.degree_leq_one_active_nodes
|
|
1150
|
+
].every((value) => Number.isInteger(value) && value >= 0) || !isNonnegativeCountRecord(profile.edges_by_kind) || profile.coverage_by_type !== void 0 && !isNonnegativeCoverageByTypeRecord(profile.coverage_by_type))
|
|
1151
|
+
return void 0;
|
|
1152
|
+
return {
|
|
1153
|
+
...snapshot,
|
|
1154
|
+
profile: {
|
|
1155
|
+
...profile,
|
|
1156
|
+
coverage_by_type: profile.coverage_by_type ?? {}
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
} catch {
|
|
1160
|
+
return void 0;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
async function loadGraphAuditBaseline(pmRoot) {
|
|
1164
|
+
return decodeBaseline(await readFileIfExists(graphAuditBaselinePath(pmRoot)));
|
|
1165
|
+
}
|
|
1166
|
+
async function saveGraphAuditBaseline(pmRoot, snapshot) {
|
|
1167
|
+
await writeFileAtomic(graphAuditBaselinePath(pmRoot), JSON.stringify(snapshot));
|
|
1168
|
+
}
|
|
1326
1169
|
|
|
1327
1170
|
// dist/sdk/graph/remediation.js
|
|
1328
1171
|
var FINDING_STEP_TEMPLATES = {
|
|
@@ -1364,6 +1207,16 @@ var FINDING_STEP_TEMPLATES = {
|
|
|
1364
1207
|
confidence: "high",
|
|
1365
1208
|
rationale: "Duplicated spellings between terminal items are historical noise; waive or batch changelog-safe cleanup."
|
|
1366
1209
|
},
|
|
1210
|
+
duplicate_dependency_row: {
|
|
1211
|
+
op: "remove",
|
|
1212
|
+
confidence: "high",
|
|
1213
|
+
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."
|
|
1214
|
+
},
|
|
1215
|
+
legacy_duplicate_dependency_row: {
|
|
1216
|
+
op: "waive",
|
|
1217
|
+
confidence: "high",
|
|
1218
|
+
rationale: "Repeated identical rows on terminal holders are storage noise; waive or clean up only in a changelog-safe closed-item batch."
|
|
1219
|
+
},
|
|
1367
1220
|
stale_lifecycle_block: {
|
|
1368
1221
|
op: "investigate",
|
|
1369
1222
|
confidence: "medium",
|
|
@@ -1543,10 +1396,10 @@ function runGraphPaths(root, target, invocation) {
|
|
|
1543
1396
|
count: result.value.length,
|
|
1544
1397
|
...projectQueryMeta(result.meta),
|
|
1545
1398
|
...invocation.summary ? {} : {
|
|
1546
|
-
paths: result.value.map((
|
|
1547
|
-
nodes:
|
|
1548
|
-
kinds:
|
|
1549
|
-
length:
|
|
1399
|
+
paths: result.value.map((path4) => ({
|
|
1400
|
+
nodes: path4.nodes,
|
|
1401
|
+
kinds: path4.edges.map((edge) => edge.kind),
|
|
1402
|
+
length: path4.length
|
|
1550
1403
|
}))
|
|
1551
1404
|
}
|
|
1552
1405
|
};
|
|
@@ -1611,7 +1464,8 @@ function runGraphAudit(invocation, isTerminal) {
|
|
|
1611
1464
|
const report = auditWorkspaceRelationshipGraph(invocation.assembly, {
|
|
1612
1465
|
isTerminal,
|
|
1613
1466
|
...invocation.sample === void 0 ? {} : { maxSampleSize: invocation.sample },
|
|
1614
|
-
...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates }
|
|
1467
|
+
...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates },
|
|
1468
|
+
...invocation.exemptIsolateTypes.length === 0 ? {} : { isolateExemptTypes: invocation.exemptIsolateTypes }
|
|
1615
1469
|
});
|
|
1616
1470
|
const bySeverity = {};
|
|
1617
1471
|
const byCode = {};
|
|
@@ -1713,13 +1567,87 @@ function runGraphDominators(root, invocation) {
|
|
|
1713
1567
|
}
|
|
1714
1568
|
};
|
|
1715
1569
|
}
|
|
1570
|
+
function runGraphSlack(invocation) {
|
|
1571
|
+
const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
|
|
1572
|
+
const analysis = analyzeRelationshipSchedule(invocation.assembly.graph);
|
|
1573
|
+
const criticalCount = analysis.rows.filter((row) => row.critical).length;
|
|
1574
|
+
return {
|
|
1575
|
+
subcommand: "slack",
|
|
1576
|
+
acyclic: analysis.acyclic,
|
|
1577
|
+
makespan: analysis.makespan,
|
|
1578
|
+
scheduled_count: analysis.scheduledCount,
|
|
1579
|
+
critical_count: criticalCount,
|
|
1580
|
+
critical_path_length: analysis.criticalPathLength,
|
|
1581
|
+
cycle_count: analysis.cycles.length,
|
|
1582
|
+
truncated: analysis.rows.length > limit,
|
|
1583
|
+
...invocation.summary ? {} : {
|
|
1584
|
+
critical_path: analysis.criticalPath,
|
|
1585
|
+
rows: analysis.rows.slice(0, limit).map((row) => ({
|
|
1586
|
+
id: row.id,
|
|
1587
|
+
earliest_start: row.earliestStart,
|
|
1588
|
+
latest_start: row.latestStart,
|
|
1589
|
+
slack: row.slack,
|
|
1590
|
+
critical: row.critical
|
|
1591
|
+
}))
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
function runGraphCentrality(invocation) {
|
|
1596
|
+
const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
|
|
1597
|
+
const result = computeRelationshipCentrality(invocation.assembly.graph, {
|
|
1598
|
+
...invocation.kinds === void 0 ? {} : { kinds: invocation.kinds }
|
|
1599
|
+
});
|
|
1600
|
+
const analysis = result.value;
|
|
1601
|
+
return {
|
|
1602
|
+
subcommand: "centrality",
|
|
1603
|
+
node_count: analysis.nodeCount,
|
|
1604
|
+
edge_count: analysis.edgeCount,
|
|
1605
|
+
truncated: analysis.rows.length > limit,
|
|
1606
|
+
cost: {
|
|
1607
|
+
visited_nodes: result.meta.visitedNodes,
|
|
1608
|
+
inspected_edges: result.meta.inspectedEdges
|
|
1609
|
+
},
|
|
1610
|
+
...invocation.summary ? {} : {
|
|
1611
|
+
rows: analysis.rows.slice(0, limit).map((row) => ({
|
|
1612
|
+
id: row.id,
|
|
1613
|
+
degree: row.degree,
|
|
1614
|
+
in_degree: row.inDegree,
|
|
1615
|
+
out_degree: row.outDegree,
|
|
1616
|
+
betweenness: row.betweenness,
|
|
1617
|
+
closeness: row.closeness
|
|
1618
|
+
}))
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
function runGraphArticulation(invocation) {
|
|
1623
|
+
const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
|
|
1624
|
+
const result = findRelationshipCutStructure(invocation.assembly.graph, {
|
|
1625
|
+
...invocation.kinds === void 0 ? {} : { kinds: invocation.kinds }
|
|
1626
|
+
});
|
|
1627
|
+
const { articulationPoints, bridges } = result.value;
|
|
1628
|
+
return {
|
|
1629
|
+
subcommand: "articulation",
|
|
1630
|
+
articulation_count: articulationPoints.length,
|
|
1631
|
+
bridge_count: bridges.length,
|
|
1632
|
+
truncated: articulationPoints.length > limit || bridges.length > limit,
|
|
1633
|
+
cost: {
|
|
1634
|
+
visited_nodes: result.meta.visitedNodes,
|
|
1635
|
+
inspected_edges: result.meta.inspectedEdges
|
|
1636
|
+
},
|
|
1637
|
+
...invocation.summary ? {} : {
|
|
1638
|
+
articulation_points: articulationPoints.slice(0, limit),
|
|
1639
|
+
bridges: bridges.slice(0, limit)
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1716
1643
|
function runGraphPlan(invocation, isTerminal) {
|
|
1717
1644
|
const limit = invocation.limit ?? DEFAULT_SAMPLE_LIMIT;
|
|
1718
1645
|
const plan = planRelationshipRemediation(invocation.assembly, {
|
|
1719
1646
|
isTerminal,
|
|
1720
1647
|
redundancyLimit: limit,
|
|
1721
1648
|
...invocation.sample === void 0 ? {} : { maxSampleSize: invocation.sample },
|
|
1722
|
-
...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates }
|
|
1649
|
+
...invocation.exemptIsolates.length === 0 ? {} : { exemptIsolates: invocation.exemptIsolates },
|
|
1650
|
+
...invocation.exemptIsolateTypes.length === 0 ? {} : { isolateExemptTypes: invocation.exemptIsolateTypes }
|
|
1723
1651
|
});
|
|
1724
1652
|
const byOp = {};
|
|
1725
1653
|
const byCode = {};
|
|
@@ -1758,6 +1686,9 @@ function buildGraphQueryKey(subcommand, root, pathsTarget, invocation) {
|
|
|
1758
1686
|
exemptIsolates: [
|
|
1759
1687
|
...new Set(invocation.exemptIsolates.map((id) => id.toLowerCase()))
|
|
1760
1688
|
].sort(),
|
|
1689
|
+
exemptIsolateTypes: [
|
|
1690
|
+
...new Set(invocation.exemptIsolateTypes.map((type) => type.toLowerCase()))
|
|
1691
|
+
].sort(),
|
|
1761
1692
|
summary: invocation.summary
|
|
1762
1693
|
});
|
|
1763
1694
|
}
|
|
@@ -1774,12 +1705,82 @@ function executeGraphSubcommand(subcommand, root, pathsTarget, invocation, isTer
|
|
|
1774
1705
|
return runGraphRedundancy(invocation);
|
|
1775
1706
|
if (subcommand === "dominators")
|
|
1776
1707
|
return runGraphDominators(root, invocation);
|
|
1708
|
+
if (subcommand === "slack")
|
|
1709
|
+
return runGraphSlack(invocation);
|
|
1710
|
+
if (subcommand === "centrality")
|
|
1711
|
+
return runGraphCentrality(invocation);
|
|
1712
|
+
if (subcommand === "articulation")
|
|
1713
|
+
return runGraphArticulation(invocation);
|
|
1777
1714
|
if (subcommand === "paths")
|
|
1778
1715
|
return runGraphPaths(root, pathsTarget, invocation);
|
|
1779
1716
|
if (subcommand === "impact")
|
|
1780
1717
|
return runGraphImpact(root, invocation);
|
|
1781
1718
|
return runGraphTraversal(subcommand, root, invocation);
|
|
1782
1719
|
}
|
|
1720
|
+
function assertGraphFlagScope(subcommand, options) {
|
|
1721
|
+
if (subcommand !== "index" && (options.rebuild === true || options.clear === true))
|
|
1722
|
+
throw new PmCliError("--rebuild and --clear apply only to graph index.", EXIT_CODE.USAGE);
|
|
1723
|
+
if (subcommand !== "audit" && options.saveBaseline === true)
|
|
1724
|
+
throw new PmCliError("--save-baseline applies only to graph audit.", EXIT_CODE.USAGE);
|
|
1725
|
+
if (subcommand === "slack" && options.kind !== void 0)
|
|
1726
|
+
throw new PmCliError("graph slack analyzes every ordering kind; --kind is not supported.", EXIT_CODE.USAGE);
|
|
1727
|
+
if (options.rebuild === true && options.clear === true)
|
|
1728
|
+
throw new PmCliError("graph index accepts either --rebuild or --clear, not both.", EXIT_CODE.USAGE);
|
|
1729
|
+
}
|
|
1730
|
+
async function runGraphIndex(pmRoot, fingerprint, invocation, itemCount, isTerminal, options) {
|
|
1731
|
+
let action = "status";
|
|
1732
|
+
if (options.clear === true) {
|
|
1733
|
+
await clearDurableGraphCache(pmRoot);
|
|
1734
|
+
action = "cleared";
|
|
1735
|
+
}
|
|
1736
|
+
if (options.rebuild === true) {
|
|
1737
|
+
await clearDurableGraphCache(pmRoot);
|
|
1738
|
+
const view = await openDurableGraphCache(pmRoot, fingerprint);
|
|
1739
|
+
const warmInvocation = {
|
|
1740
|
+
assembly: invocation.assembly,
|
|
1741
|
+
direction: "both",
|
|
1742
|
+
exemptIsolates: [],
|
|
1743
|
+
exemptIsolateTypes: [],
|
|
1744
|
+
saveBaseline: false,
|
|
1745
|
+
summary: true
|
|
1746
|
+
};
|
|
1747
|
+
for (const warm of ["analyze", "audit"]) {
|
|
1748
|
+
await persistDurableGraphResult(pmRoot, fingerprint, view, buildGraphQueryKey(warm, void 0, void 0, warmInvocation), executeGraphSubcommand(warm, void 0, void 0, warmInvocation, isTerminal));
|
|
1749
|
+
}
|
|
1750
|
+
action = "rebuilt";
|
|
1751
|
+
}
|
|
1752
|
+
const status = await durableGraphCacheStatus(pmRoot, fingerprint);
|
|
1753
|
+
return {
|
|
1754
|
+
subcommand: "index",
|
|
1755
|
+
action,
|
|
1756
|
+
state: status.exists ? status.fresh ? "fresh" : "stale" : "absent",
|
|
1757
|
+
entry_count: status.entry_count,
|
|
1758
|
+
item_count: itemCount,
|
|
1759
|
+
min_items_threshold: GRAPH_DURABLE_CACHE_MIN_ITEMS,
|
|
1760
|
+
persist_enabled: shouldPersistDurableGraphCache(itemCount, status.exists),
|
|
1761
|
+
current_fingerprint: fingerprint.slice(0, 12),
|
|
1762
|
+
...status.saved_at === void 0 ? {} : { saved_at: status.saved_at },
|
|
1763
|
+
...status.bytes === void 0 ? {} : { bytes: status.bytes }
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
async function applyAuditBaseline(pmRoot, fingerprint, audit, saveBaseline) {
|
|
1767
|
+
const current = {
|
|
1768
|
+
saved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1769
|
+
fingerprint,
|
|
1770
|
+
affected_subjects_by_code: audit.affected_subjects_by_code,
|
|
1771
|
+
profile: audit.profile
|
|
1772
|
+
};
|
|
1773
|
+
const stored = await loadGraphAuditBaseline(pmRoot);
|
|
1774
|
+
if (saveBaseline)
|
|
1775
|
+
await saveGraphAuditBaseline(pmRoot, current);
|
|
1776
|
+
return stored === void 0 ? audit : { ...audit, baseline: diffRelationshipAuditSnapshots(stored, current) };
|
|
1777
|
+
}
|
|
1778
|
+
async function persistDurableGraphResultBestEffort(pmRoot, fingerprint, view, queryKey, result) {
|
|
1779
|
+
try {
|
|
1780
|
+
await persistDurableGraphResult(pmRoot, fingerprint, view, queryKey, result);
|
|
1781
|
+
} catch {
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1783
1784
|
async function runGraph(subcommandRaw, id, target, options, global) {
|
|
1784
1785
|
const subcommand = parseGraphSubcommand(subcommandRaw, id, target);
|
|
1785
1786
|
const pmRoot = resolvePmRoot(process.cwd(), global.path);
|
|
@@ -1791,8 +1792,10 @@ async function runGraph(subcommandRaw, id, target, options, global) {
|
|
|
1791
1792
|
const items = await listAllItemMetadataLight(pmRoot, settings.item_format, typeRegistry.type_to_folder, void 0, settings.schema);
|
|
1792
1793
|
const statusRegistry = resolveRuntimeStatusRegistry(settings.schema);
|
|
1793
1794
|
const isTerminal = (status) => isTerminalStatus(status, statusRegistry);
|
|
1794
|
-
|
|
1795
|
-
const
|
|
1795
|
+
assertGraphFlagScope(subcommand, options);
|
|
1796
|
+
const relationshipRegistry = resolveWorkspaceRelationshipKindRegistry();
|
|
1797
|
+
const kinds = parseKinds(options.kind, relationshipRegistry);
|
|
1798
|
+
const lookup = workspaceGraphCache().lookup(pmRoot, computeWorkspaceGraphFingerprint(items, isTerminal, relationshipRegistry), () => assembleWorkspaceRelationshipGraph(items, isTerminal, relationshipRegistry));
|
|
1796
1799
|
const invocation = {
|
|
1797
1800
|
assembly: lookup.assembly,
|
|
1798
1801
|
...kinds === void 0 ? {} : { kinds },
|
|
@@ -1803,17 +1806,31 @@ async function runGraph(subcommandRaw, id, target, options, global) {
|
|
|
1803
1806
|
maxPaths: parsePositiveInteger(options.maxPaths, "max-paths"),
|
|
1804
1807
|
sample: parsePositiveInteger(options.sample, "sample"),
|
|
1805
1808
|
exemptIsolates: normalizeIdList(options.exemptIsolate),
|
|
1809
|
+
exemptIsolateTypes: normalizeIdList(options.exemptIsolateType),
|
|
1810
|
+
saveBaseline: options.saveBaseline === true,
|
|
1806
1811
|
summary: options.summary === true
|
|
1807
1812
|
};
|
|
1813
|
+
if (subcommand === "index") {
|
|
1814
|
+
return runGraphIndex(pmRoot, lookup.fingerprint, invocation, items.length, isTerminal, options);
|
|
1815
|
+
}
|
|
1808
1816
|
const root = ROOTED_SUBCOMMANDS.has(subcommand) ? canonicalizeGraphId(invocation.assembly, id) : void 0;
|
|
1809
1817
|
const pathsTarget = subcommand === "paths" ? canonicalizeGraphId(invocation.assembly, target) : void 0;
|
|
1810
|
-
const
|
|
1818
|
+
const queryKey = buildGraphQueryKey(subcommand, root, pathsTarget, invocation);
|
|
1819
|
+
const durableView = await openDurableGraphCache(pmRoot, lookup.fingerprint);
|
|
1820
|
+
const durableValue = durableView.results[queryKey];
|
|
1821
|
+
const memo = lookup.memoize(queryKey, () => durableValue !== void 0 ? structuredClone(durableValue) : executeGraphSubcommand(subcommand, root, pathsTarget, invocation, isTerminal));
|
|
1822
|
+
const persistEnabled = shouldPersistDurableGraphCache(items.length, durableView.exists);
|
|
1823
|
+
if (!memo.reused && durableValue === void 0 && persistEnabled) {
|
|
1824
|
+
await persistDurableGraphResultBestEffort(pmRoot, lookup.fingerprint, durableView, queryKey, memo.value);
|
|
1825
|
+
}
|
|
1826
|
+
const value = memo.value.subcommand === "audit" ? await applyAuditBaseline(pmRoot, lookup.fingerprint, memo.value, invocation.saveBaseline) : memo.value;
|
|
1811
1827
|
return {
|
|
1812
|
-
...
|
|
1828
|
+
...value,
|
|
1813
1829
|
cache: {
|
|
1814
1830
|
fingerprint: lookup.fingerprint.slice(0, 12),
|
|
1815
1831
|
assembly: lookup.assemblyReused ? "hit" : "miss",
|
|
1816
|
-
result: memo.reused ? "hit" : "miss"
|
|
1832
|
+
result: memo.reused ? "hit" : "miss",
|
|
1833
|
+
durable: durableValue !== void 0 ? "hit" : persistEnabled ? "miss" : "off"
|
|
1817
1834
|
}
|
|
1818
1835
|
};
|
|
1819
1836
|
}
|
|
@@ -2207,7 +2224,7 @@ async function runGet(id, global, options = {}) {
|
|
|
2207
2224
|
|
|
2208
2225
|
// dist/sdk/query/search.js
|
|
2209
2226
|
import fs from "node:fs/promises";
|
|
2210
|
-
import
|
|
2227
|
+
import path2 from "node:path";
|
|
2211
2228
|
|
|
2212
2229
|
// dist/core/shared/text-normalization.js
|
|
2213
2230
|
function normalizeLowercaseWhitespace(value) {
|
|
@@ -3109,7 +3126,7 @@ function collectLinkedPaths(item) {
|
|
|
3109
3126
|
return [...deduped.values()];
|
|
3110
3127
|
}
|
|
3111
3128
|
async function resolveContainmentRoot(root) {
|
|
3112
|
-
const resolved =
|
|
3129
|
+
const resolved = path2.resolve(root);
|
|
3113
3130
|
try {
|
|
3114
3131
|
const realpathRoot = await fs.realpath(resolved);
|
|
3115
3132
|
return {
|
|
@@ -3138,7 +3155,7 @@ async function loadLinkedCorpus(document, roots) {
|
|
|
3138
3155
|
if (!containmentRoot) {
|
|
3139
3156
|
continue;
|
|
3140
3157
|
}
|
|
3141
|
-
const resolved =
|
|
3158
|
+
const resolved = path2.resolve(containmentRoot.resolved, linkedPath.path);
|
|
3142
3159
|
if (!isPathWithinDirectory(containmentRoot.resolved, resolved)) {
|
|
3143
3160
|
continue;
|
|
3144
3161
|
}
|
|
@@ -3960,7 +3977,7 @@ async function loadDocuments(pmRoot, itemFormat, typeToFolder, schema) {
|
|
|
3960
3977
|
try {
|
|
3961
3978
|
return await tryRead(alternatePath, alternateFormat);
|
|
3962
3979
|
} catch {
|
|
3963
|
-
listWarnings.push(`item_list_item_read_failed:${
|
|
3980
|
+
listWarnings.push(`item_list_item_read_failed:${path2.relative(pmRoot, alternatePath)}`);
|
|
3964
3981
|
return "";
|
|
3965
3982
|
}
|
|
3966
3983
|
}
|
|
@@ -4465,7 +4482,7 @@ async function runSearch(rawQuery, rawOptions, global) {
|
|
|
4465
4482
|
|
|
4466
4483
|
// dist/sdk/eval.js
|
|
4467
4484
|
import fs2 from "node:fs/promises";
|
|
4468
|
-
import
|
|
4485
|
+
import path3 from "node:path";
|
|
4469
4486
|
|
|
4470
4487
|
// dist/core/search/eval.js
|
|
4471
4488
|
var DEFAULT_EVAL_K = 10;
|
|
@@ -4604,7 +4621,7 @@ function parseEvalQuerySet(raw) {
|
|
|
4604
4621
|
}
|
|
4605
4622
|
|
|
4606
4623
|
// dist/sdk/eval.js
|
|
4607
|
-
var DEFAULT_EVAL_QUERIES_RELATIVE_PATH =
|
|
4624
|
+
var DEFAULT_EVAL_QUERIES_RELATIVE_PATH = path3.join("search", "eval-queries.json");
|
|
4608
4625
|
var VALID_EVAL_MODES2 = /* @__PURE__ */ new Set([
|
|
4609
4626
|
"keyword",
|
|
4610
4627
|
"semantic",
|
|
@@ -4685,7 +4702,7 @@ var validateEvalQuerySet = (parsed) => {
|
|
|
4685
4702
|
}
|
|
4686
4703
|
};
|
|
4687
4704
|
var loadEvalQuerySet = async (queriesPath) => validateEvalQuerySet(parseEvalQuerySetJson(await readEvalQuerySetFile(queriesPath), queriesPath));
|
|
4688
|
-
var resolveEvalQueriesPath = (pmRoot, queries) => queries ?
|
|
4705
|
+
var resolveEvalQueriesPath = (pmRoot, queries) => queries ? path3.resolve(process.cwd(), queries) : path3.join(pmRoot, DEFAULT_EVAL_QUERIES_RELATIVE_PATH);
|
|
4689
4706
|
var evaluateEvalQuery = async (evalQuery, defaultMode, k, global) => {
|
|
4690
4707
|
const mode = evalQuery.mode ?? defaultMode;
|
|
4691
4708
|
const searchResult = await runSearch(evalQuery.query, { mode, limit: String(k), fields: "id" }, global);
|
|
@@ -4743,17 +4760,24 @@ var runEval = async (options, global) => {
|
|
|
4743
4760
|
|
|
4744
4761
|
export {
|
|
4745
4762
|
runAggregate,
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4763
|
+
analyzeRelationshipExecution,
|
|
4764
|
+
analyzeGraphImpact,
|
|
4765
|
+
analyzeKnowledgeGraph,
|
|
4766
|
+
compareRelationshipSnapshots,
|
|
4767
|
+
computeRelationshipCentrality,
|
|
4768
|
+
findRelationshipCutStructure,
|
|
4769
|
+
analyzeRelationshipSchedule,
|
|
4770
|
+
GRAPH_DURABLE_CACHE_VERSION,
|
|
4771
|
+
GRAPH_DURABLE_CACHE_MIN_ITEMS,
|
|
4772
|
+
durableGraphCachePath,
|
|
4773
|
+
graphAuditBaselinePath,
|
|
4774
|
+
openDurableGraphCache,
|
|
4775
|
+
persistDurableGraphResult,
|
|
4776
|
+
clearDurableGraphCache,
|
|
4777
|
+
durableGraphCacheStatus,
|
|
4778
|
+
shouldPersistDurableGraphCache,
|
|
4779
|
+
loadGraphAuditBaseline,
|
|
4780
|
+
saveGraphAuditBaseline,
|
|
4757
4781
|
planRelationshipRemediation,
|
|
4758
4782
|
parseGraphSubcommand,
|
|
4759
4783
|
runGraph,
|
|
@@ -4767,6 +4791,6 @@ export {
|
|
|
4767
4791
|
DEFAULT_EVAL_QUERIES_RELATIVE_PATH,
|
|
4768
4792
|
runEval
|
|
4769
4793
|
};
|
|
4770
|
-
//# sourceMappingURL=chunk-
|
|
4794
|
+
//# sourceMappingURL=chunk-NUF7ROFH.js.map
|
|
4771
4795
|
|
|
4772
|
-
//# debugId=
|
|
4796
|
+
//# debugId=405abecd-c7c4-543d-be2a-eb3e5168def7
|