@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","sources":["sdk/graph/analytics.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/graph/analytics\n *\n * Structural graph analytics beyond exact components: deterministic\n * label-propagation community detection over the undirected relationship\n * structure, transitively redundant edge discovery over ordering and\n * hierarchy families, and dominator (bottleneck) analysis over one node's\n * reachable subgraph. Every analysis is deterministic, cancellable, bounded,\n * and reports exact cost metadata so agents can budget follow-up reads\n * without re-scanning the workspace.\n */\nimport {\n RelationshipGraph,\n type RelationshipEdge,\n type RelationshipKindDefinition,\n type RelationshipNeighborEdge,\n type RelationshipQueryResult,\n type RelationshipTraversalDirection,\n} from \"../relationships.js\";\nimport {\n hierarchyParentEndpoint,\n orderingPredecessorEndpoint,\n} from \"./traversal.js\";\n\n/** Default label-propagation sweeps before reporting non-convergence. */\nconst DEFAULT_MAX_ITERATIONS = 16;\n/** Default minimum member count for a reported community. */\nconst DEFAULT_MIN_COMMUNITY_SIZE = 2;\n/** Default witness-path depth searched per candidate redundant edge. */\nconst DEFAULT_REDUNDANCY_MAX_DEPTH = 8;\n\n/** One detected relationship community. */\nexport interface RelationshipCommunity {\n /** Lexicographically smallest member id, naming the community. */\n representative: string;\n /** Total member count. */\n size: number;\n /** Sorted member node ids. */\n members: string[];\n}\n\n/** Bounded community-detection controls. */\nexport interface GraphCommunityOptions {\n /** Registered relationship kinds whose edges define adjacency. */\n kinds?: readonly string[];\n /** Maximum label-propagation sweeps before reporting non-convergence; defaults to 16. */\n maxIterations?: number;\n /** Minimum member count for a reported community; defaults to 2. */\n minSize?: number;\n /** Abort signal checked once per sweep. */\n signal?: AbortSignal;\n}\n\n/** Deterministic label-propagation community analysis. */\nexport interface RelationshipCommunityAnalysis {\n /** Detected communities, largest first and by representative within equal size. */\n communities: RelationshipCommunity[];\n /** Label-propagation sweeps executed. */\n iterations: number;\n /** Whether labels stabilized before the iteration bound stopped the sweep. */\n converged: boolean;\n}\n\n/** One stored edge implied by a longer same-family witness path. */\nexport interface RedundantRelationshipEdge {\n /** The stored redundant edge in its original spelling. */\n edge: RelationshipEdge;\n /** Semantic-orientation witness node path proving the implication, endpoints inclusive. */\n witness: string[];\n}\n\n/** Bounded redundancy-scan controls. */\nexport interface GraphRedundancyOptions {\n /** Directed ordering or hierarchy kinds to scan; defaults to every eligible registered kind. */\n kinds?: readonly string[];\n /** Maximum witness-path depth searched per edge; defaults to 8. */\n maxDepth?: number;\n /** Maximum reported redundant edges. */\n limit?: number;\n /** Abort signal checked once per scanned edge. */\n signal?: AbortSignal;\n}\n\n/** One reachable node with its immediate dominator and gating weight. */\nexport interface RelationshipDominatorRow {\n /** Reachable node id. */\n id: string;\n /** Immediate dominator appearing on every root-to-node path. */\n idom: string;\n /** Nodes strictly dominated by this node — its dominator-subtree size minus itself. */\n dominatedCount: number;\n}\n\n/** Bounded dominator-analysis controls. */\nexport interface GraphDominatorOptions {\n /** Registered relationship kinds whose edges define reachability. */\n kinds?: readonly string[];\n /** Traversal direction relative to each visited node; defaults to \"outgoing\". */\n direction?: RelationshipTraversalDirection;\n /** Maximum reachability depth from the root as a non-negative integer. */\n maxDepth?: number;\n /** Abort signal checked once per processed node. */\n signal?: AbortSignal;\n}\n\n/** Dominator-tree analysis of one node's reachable subgraph. */\nexport interface RelationshipDominatorAnalysis {\n /** Analyzed root id. */\n root: string;\n /** Reachable node count including the root. */\n reachableCount: number;\n /** Non-root reachable rows sorted by gating weight, then id. */\n rows: RelationshipDominatorRow[];\n}\n\n/** Require a positive integer for one analytics bound. */\nfunction assertPositiveBound(name: string, value: number): void {\n if (!Number.isInteger(value) || value < 1)\n throw new TypeError(`Invalid ${name} bound: ${String(value)}`);\n}\n\n/** Build the deterministic undirected adjacency restricted to canonicalized kinds. */\nfunction buildUndirectedAdjacency(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n): Map<string, string[]> {\n const registry = graph.registry();\n const wanted =\n kinds === undefined\n ? undefined\n : new Set(kinds.map((kind) => registry.require(kind).kind));\n const adjacency = new Map<string, string[]>();\n for (const edge of graph.edges()) {\n if (edge.source === edge.target) continue;\n if (wanted !== undefined) {\n const definition = registry.require(edge.kind);\n const matches =\n wanted.has(definition.kind) ||\n (definition.inverse !== undefined && wanted.has(definition.inverse));\n if (!matches) continue;\n }\n appendAdjacency(adjacency, edge.source, edge.target);\n appendAdjacency(adjacency, edge.target, edge.source);\n }\n for (const neighbors of adjacency.values()) neighbors.sort();\n return adjacency;\n}\n\n/** Append one neighbor to a node's adjacency list, creating the list on demand. */\nfunction appendAdjacency(\n adjacency: Map<string, string[]>,\n from: string,\n to: string,\n): void {\n const neighbors = adjacency.get(from);\n if (neighbors === undefined) adjacency.set(from, [to]);\n else neighbors.push(to);\n}\n\n/** Adopt the most frequent neighbor label with lexicographic tie-breaking. */\nfunction dominantNeighborLabel(\n neighbors: readonly string[],\n labels: Map<string, string>,\n): string {\n const counts = new Map<string, number>();\n for (const neighbor of neighbors) {\n const label = labels.get(neighbor)!;\n counts.set(label, (counts.get(label) ?? 0) + 1);\n }\n let best: string | undefined;\n let bestCount = 0;\n for (const [label, count] of counts) {\n if (count > bestCount || (count === bestCount && label < best!)) {\n best = label;\n bestCount = count;\n }\n }\n return best!;\n}\n\n/** Group stabilized labels into sorted communities meeting the size floor. */\nfunction collectCommunities(\n labels: Map<string, string>,\n minSize: number,\n): RelationshipCommunity[] {\n const groups = new Map<string, string[]>();\n for (const [id, label] of labels) {\n const members = groups.get(label);\n if (members === undefined) groups.set(label, [id]);\n else members.push(id);\n }\n const communities: RelationshipCommunity[] = [];\n for (const members of groups.values()) {\n if (members.length < minSize) continue;\n members.sort();\n communities.push({\n representative: members[0]!,\n size: members.length,\n members,\n });\n }\n return communities.sort(\n (left, right) =>\n right.size - left.size ||\n left.representative.localeCompare(right.representative),\n );\n}\n\n/**\n * Detect communities with deterministic asynchronous label propagation: nodes\n * are swept in sorted order, each adopting the most frequent label among its\n * neighbors with lexicographic tie-breaking, until labels stabilize or the\n * iteration bound stops the sweep. Adjacency is undirected — every\n * participating edge connects both endpoints symmetrically and parallel edges\n * weight their neighbor. `meta.truncated` reports non-convergence.\n */\nexport function detectRelationshipCommunities(\n graph: RelationshipGraph,\n options: GraphCommunityOptions = {},\n): RelationshipQueryResult<RelationshipCommunityAnalysis> {\n const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n const minSize = options.minSize ?? DEFAULT_MIN_COMMUNITY_SIZE;\n assertPositiveBound(\"maxIterations\", maxIterations);\n assertPositiveBound(\"minSize\", minSize);\n const adjacency = buildUndirectedAdjacency(graph, options.kinds);\n const nodes = graph.nodes();\n const labels = new Map(nodes.map((id) => [id, id]));\n let iterations = 0;\n let converged = false;\n let visitedNodes = 0;\n let inspectedEdges = 0;\n while (iterations < maxIterations && !converged) {\n options.signal?.throwIfAborted();\n iterations += 1;\n converged = true;\n for (const id of nodes) {\n visitedNodes += 1;\n const neighbors = adjacency.get(id);\n if (neighbors === undefined) continue;\n inspectedEdges += neighbors.length;\n const dominant = dominantNeighborLabel(neighbors, labels);\n if (dominant !== labels.get(id)) {\n labels.set(id, dominant);\n converged = false;\n }\n }\n }\n return {\n value: {\n communities: collectCommunities(labels, minSize),\n iterations,\n converged,\n },\n meta: { visitedNodes, inspectedEdges, truncated: !converged },\n };\n}\n\n/** Decide whether a kind carries transitive semantics eligible for redundancy and duplicate analysis. */\nexport function isTransitiveKind(definition: RelationshipKindDefinition): boolean {\n return (\n definition.direction === \"directed\" &&\n (definition.ordering || definition.hierarchy)\n );\n}\n\n/** Family grouping key joining a directed kind with its inverse spelling. */\nexport function transitiveFamilyKey(definition: RelationshipKindDefinition): string {\n return definition.inverse !== undefined &&\n definition.inverse < definition.kind\n ? definition.inverse\n : definition.kind;\n}\n\n/** Orient one transitive edge into its semantic forward direction. */\nexport function orientTransitiveEdge(\n edge: RelationshipEdge,\n definition: RelationshipKindDefinition,\n): { from: string; to: string } {\n // Hierarchy families flow child -> parent; ordering families flow\n // predecessor -> successor, so inverse spellings land in one relation.\n const head = definition.hierarchy\n ? hierarchyParentEndpoint(edge, definition)\n : edge.source === orderingPredecessorEndpoint(edge, definition)\n ? edge.target\n : edge.source;\n return head === edge.target\n ? { from: edge.source, to: edge.target }\n : { from: edge.target, to: edge.source };\n}\n\n/** One semantically oriented transitive edge retaining its stored spelling. */\ninterface OrientedTransitiveEdge {\n /** Semantic tail node. */\n from: string;\n /** Semantic head node. */\n to: string;\n /** Original stored edge. */\n edge: RelationshipEdge;\n}\n\n/** Per-family oriented edges and their deterministic forward adjacency. */\ninterface TransitiveFamily {\n /** Deduplicated forward adjacency in semantic orientation, sorted after collection. */\n adjacency: Map<string, Set<string>>;\n /** Oriented edges in deterministic stored order. */\n records: OrientedTransitiveEdge[];\n}\n\n/** Resolve explicit redundancy kind filters into their family keys. */\nfunction resolveRedundancyFamilies(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n): Set<string> | undefined {\n if (kinds === undefined) return undefined;\n const registry = graph.registry();\n const families = new Set<string>();\n for (const kind of kinds) {\n const definition = registry.require(kind);\n if (!isTransitiveKind(definition))\n throw new TypeError(\n `Relationship kind ${definition.kind} is not a directed ordering or hierarchy kind`,\n );\n families.add(transitiveFamilyKey(definition));\n }\n return families;\n}\n\n/** Group eligible stored edges into oriented per-family scan structures. */\nfunction collectTransitiveFamilies(\n graph: RelationshipGraph,\n wanted: Set<string> | undefined,\n): Map<string, TransitiveFamily> {\n const registry = graph.registry();\n const families = new Map<string, TransitiveFamily>();\n for (const edge of graph.edges()) {\n const definition = registry.require(edge.kind);\n if (!isTransitiveKind(definition)) continue;\n const key = transitiveFamilyKey(definition);\n if (wanted !== undefined && !wanted.has(key)) continue;\n const oriented = orientTransitiveEdge(edge, definition);\n if (oriented.from === oriented.to) continue;\n let family = families.get(key);\n if (family === undefined) {\n family = { adjacency: new Map(), records: [] };\n families.set(key, family);\n }\n const targets = family.adjacency.get(oriented.from);\n if (targets === undefined)\n family.adjacency.set(oriented.from, new Set([oriented.to]));\n else targets.add(oriented.to);\n family.records.push({ ...oriented, edge });\n }\n return families;\n}\n\n/** Freeze one family's adjacency sets into deterministic sorted lists. */\nfunction sortedFamilyAdjacency(\n family: TransitiveFamily,\n): Map<string, readonly string[]> {\n const sorted = new Map<string, readonly string[]>();\n for (const [from, targets] of family.adjacency)\n sorted.set(from, [...targets].sort());\n return sorted;\n}\n\n/** Rebuild the witness node path from breadth-first parent pointers. */\nfunction reconstructWitness(\n parents: Map<string, string>,\n from: string,\n tail: string,\n head: string,\n): string[] {\n const witness = [head];\n for (let node = tail; node !== from; node = parents.get(node)!)\n witness.push(node);\n witness.push(from);\n return witness.reverse();\n}\n\n/** Expand one witness frontier node; return the completed witness when the head is reached. */\nfunction expandWitnessFrontier(\n adjacency: Map<string, readonly string[]>,\n record: OrientedTransitiveEdge,\n current: { id: string; depth: number },\n parents: Map<string, string>,\n queue: { id: string; depth: number }[],\n cost: { visitedNodes: number; inspectedEdges: number },\n): string[] | undefined {\n for (const next of adjacency.get(current.id) ?? []) {\n cost.inspectedEdges += 1;\n // Skip the direct edge under test; deeper hops may still reach the head.\n if (current.depth === 0 && next === record.to) continue;\n if (parents.has(next)) continue;\n parents.set(next, current.id);\n if (next === record.to)\n return reconstructWitness(parents, record.from, current.id, next);\n queue.push({ id: next, depth: current.depth + 1 });\n }\n return undefined;\n}\n\n/** Search one bounded same-family witness path that implies a direct edge. */\nfunction findWitnessPath(\n adjacency: Map<string, readonly string[]>,\n record: OrientedTransitiveEdge,\n maxDepth: number,\n cost: { visitedNodes: number; inspectedEdges: number },\n): string[] | undefined {\n const parents = new Map<string, string>([[record.from, record.from]]);\n const queue = [{ id: record.from, depth: 0 }];\n for (let index = 0; index < queue.length; index += 1) {\n const current = queue[index]!;\n cost.visitedNodes += 1;\n if (current.depth >= maxDepth) continue;\n const witness = expandWitnessFrontier(\n adjacency,\n record,\n current,\n parents,\n queue,\n cost,\n );\n if (witness !== undefined) return witness;\n }\n return undefined;\n}\n\n/**\n * Find stored edges implied by a longer path of the same semantic family —\n * the transitive-reduction view of ordering and hierarchy relations. Each\n * family joins a directed kind with its inverse spelling in semantic\n * orientation, so `blocked_by` and `blocks` witness each other. The witness\n * search is breadth-first, shortest and lexicographic first, bounded by\n * `maxDepth` per edge; `meta.truncated` reports only the `limit` bound.\n */\nexport function findRedundantRelationshipEdges(\n graph: RelationshipGraph,\n options: GraphRedundancyOptions = {},\n): RelationshipQueryResult<RedundantRelationshipEdge[]> {\n const maxDepth = options.maxDepth ?? DEFAULT_REDUNDANCY_MAX_DEPTH;\n assertPositiveBound(\"maxDepth\", maxDepth);\n if (options.limit !== undefined) assertPositiveBound(\"limit\", options.limit);\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n const wanted = resolveRedundancyFamilies(graph, options.kinds);\n const families = collectTransitiveFamilies(graph, wanted);\n const value: RedundantRelationshipEdge[] = [];\n const cost = { visitedNodes: 0, inspectedEdges: 0 };\n let truncated = false;\n scan: for (const key of [...families.keys()].sort()) {\n const family = families.get(key)!;\n const adjacency = sortedFamilyAdjacency(family);\n for (const record of family.records) {\n options.signal?.throwIfAborted();\n const witness = findWitnessPath(adjacency, record, maxDepth, cost);\n if (witness === undefined) continue;\n if (value.length >= limit) {\n truncated = true;\n break scan;\n }\n value.push({ edge: record.edge, witness });\n }\n }\n return {\n value,\n meta: {\n visitedNodes: cost.visitedNodes,\n inspectedEdges: cost.inspectedEdges,\n truncated,\n },\n };\n}\n\n/** Reachability index of one root's directed subgraph. */\ninterface ReachableSubgraph {\n /** Reachable node ids in breadth-first discovery order. */\n order: string[];\n /** Deterministic successor lists per reachable node. */\n successors: Map<string, string[]>;\n /** Reachable predecessor sets per reachable node. */\n predecessors: Map<string, Set<string>>;\n /** Candidate edges inspected while indexing. */\n inspectedEdges: number;\n /** Whether the depth bound excluded reachable nodes. */\n truncated: boolean;\n}\n\n/** Mutable frontier state threaded through bounded reachability expansion. */\ninterface ReachabilityState {\n /** Nodes already discovered. */\n seen: Set<string>;\n /** Pending breadth-first nodes and their depths. */\n queue: { id: string; depth: number }[];\n /** Reachable predecessor sets per discovered node. */\n predecessors: Map<string, Set<string>>;\n /** Whether the depth bound excluded reachable nodes. */\n truncated: boolean;\n}\n\n/** Expand one node's neighbor rows into successors, predecessors, and frontier work. */\nfunction expandReachableNode(\n id: string,\n depth: number,\n rows: readonly RelationshipNeighborEdge[],\n maxDepth: number,\n state: ReachabilityState,\n): string[] {\n const nextSet = new Set<string>();\n const nexts: string[] = [];\n for (const row of rows) {\n if (row.id === id || nextSet.has(row.id)) continue;\n if (!state.seen.has(row.id)) {\n // A depth-boundary node keeps its edges to already-indexed nodes but\n // may not discover new ones; excluded discoveries mark truncation.\n if (depth >= maxDepth) {\n state.truncated = true;\n continue;\n }\n state.seen.add(row.id);\n state.queue.push({ id: row.id, depth: depth + 1 });\n }\n nextSet.add(row.id);\n nexts.push(row.id);\n let incoming = state.predecessors.get(row.id);\n if (incoming === undefined) {\n incoming = new Set();\n state.predecessors.set(row.id, incoming);\n }\n incoming.add(id);\n }\n return nexts;\n}\n\n/** Index the bounded reachable subgraph used by dominator analysis. */\nfunction indexReachableSubgraph(\n graph: RelationshipGraph,\n root: string,\n options: GraphDominatorOptions,\n): ReachableSubgraph {\n const direction = options.direction ?? \"outgoing\";\n const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;\n const order: string[] = [];\n const successors = new Map<string, string[]>();\n const state: ReachabilityState = {\n seen: new Set([root]),\n queue: [{ id: root, depth: 0 }],\n predecessors: new Map(),\n truncated: false,\n };\n let inspectedEdges = 0;\n for (let index = 0; index < state.queue.length; index += 1) {\n options.signal?.throwIfAborted();\n const { id, depth } = state.queue[index]!;\n order.push(id);\n const rows = graph.neighborEdges(id, {\n direction,\n ...(options.kinds === undefined ? {} : { kinds: options.kinds }),\n });\n inspectedEdges += rows.meta.inspectedEdges;\n successors.set(id, expandReachableNode(id, depth, rows.value, maxDepth, state));\n }\n return {\n order,\n successors,\n predecessors: state.predecessors,\n inspectedEdges,\n truncated: state.truncated,\n };\n}\n\n/** Compute the deterministic reverse postorder of one reachable subgraph. */\nfunction reversePostorder(subgraph: ReachableSubgraph, root: string): string[] {\n const postorder: string[] = [];\n const visited = new Set([root]);\n const stack = [{ id: root, index: 0 }];\n while (stack.length > 0) {\n const frame = stack.at(-1)!;\n const nexts = subgraph.successors.get(frame.id)!;\n if (frame.index < nexts.length) {\n const next = nexts[frame.index]!;\n frame.index += 1;\n if (!visited.has(next)) {\n visited.add(next);\n stack.push({ id: next, index: 0 });\n }\n } else {\n postorder.push(frame.id);\n stack.pop();\n }\n }\n return postorder.reverse();\n}\n\n/** Walk two dominator-tree fingers to their common ancestor by reverse-postorder number. */\nfunction intersectDominators(\n left: string,\n right: string,\n idom: Map<string, string>,\n ordinal: Map<string, number>,\n): string {\n let first = left;\n let second = right;\n while (first !== second) {\n while (ordinal.get(first)! > ordinal.get(second)!) first = idom.get(first)!;\n while (ordinal.get(second)! > ordinal.get(first)!) second = idom.get(second)!;\n }\n return first;\n}\n\n/** Fold one node's processed predecessors into its dominator candidate. */\nfunction dominatorCandidate(\n predecessors: ReadonlySet<string>,\n idom: Map<string, string>,\n ordinal: Map<string, number>,\n): string | undefined {\n let candidate: string | undefined;\n for (const pred of [...predecessors].sort()) {\n if (!idom.has(pred)) continue;\n candidate =\n candidate === undefined\n ? pred\n : intersectDominators(candidate, pred, idom, ordinal);\n }\n return candidate;\n}\n\n/** Run the Cooper–Harvey–Kennedy fixed-point over one reverse postorder. */\nfunction solveImmediateDominators(\n subgraph: ReachableSubgraph,\n root: string,\n order: readonly string[],\n ordinal: Map<string, number>,\n signal: AbortSignal | undefined,\n): Map<string, string> {\n const idom = new Map<string, string>([[root, root]]);\n let changed = true;\n while (changed) {\n changed = false;\n for (const id of order) {\n signal?.throwIfAborted();\n if (id === root) continue;\n // Every non-root node in the order was discovered through at least one\n // predecessor, so the set is always present.\n const candidate = dominatorCandidate(\n subgraph.predecessors.get(id)!,\n idom,\n ordinal,\n );\n if (candidate !== undefined && idom.get(id) !== candidate) {\n idom.set(id, candidate);\n changed = true;\n }\n }\n }\n return idom;\n}\n\n/**\n * Compute immediate dominators and gating weights over one node's reachable\n * subgraph using the Cooper–Harvey–Kennedy fixed-point. A node dominates the\n * work that every path from the root must pass through it to reach, so rows\n * with a positive `dominatedCount` are the structural bottlenecks of the\n * root's blast radius. Rows sort by gating weight, then id; `meta.truncated`\n * reports when the `maxDepth` bound excluded reachable nodes.\n */\nexport function computeRelationshipDominators(\n graph: RelationshipGraph,\n root: string,\n options: GraphDominatorOptions = {},\n): RelationshipQueryResult<RelationshipDominatorAnalysis> {\n if (!graph.hasNode(root))\n throw new TypeError(`Relationship node not found: ${root}`);\n if (\n options.maxDepth !== undefined &&\n (!Number.isInteger(options.maxDepth) || options.maxDepth < 0)\n )\n throw new TypeError(`Invalid maxDepth bound: ${String(options.maxDepth)}`);\n const subgraph = indexReachableSubgraph(graph, root, options);\n const order = reversePostorder(subgraph, root);\n const ordinal = new Map(order.map((id, index) => [id, index]));\n const idom = solveImmediateDominators(\n subgraph,\n root,\n order,\n ordinal,\n options.signal,\n );\n const subtreeSizes = new Map(order.map((id) => [id, 1]));\n for (let index = order.length - 1; index >= 0; index -= 1) {\n const id = order[index]!;\n if (id === root) continue;\n const parent = idom.get(id)!;\n subtreeSizes.set(parent, subtreeSizes.get(parent)! + subtreeSizes.get(id)!);\n }\n const rows = order\n .filter((id) => id !== root)\n .map((id) => ({\n id,\n idom: idom.get(id)!,\n dominatedCount: subtreeSizes.get(id)! - 1,\n }))\n .sort(\n (left, right) =>\n right.dominatedCount - left.dominatedCount ||\n left.id.localeCompare(right.id),\n );\n return {\n value: { root, reachableCount: subgraph.order.length, rows },\n meta: {\n visitedNodes: subgraph.order.length,\n inspectedEdges: subgraph.inspectedEdges,\n truncated: subgraph.truncated,\n },\n };\n}\n"],"names":[],"mappings":"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","debugId":"19fa7ddd-c396-5fd4-a720-522218a7b11a"}
|
|
1
|
+
{"version":3,"file":"analytics.js","sources":["sdk/graph/analytics.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/graph/analytics\n *\n * Structural graph analytics beyond exact components: deterministic\n * label-propagation community detection over the undirected relationship\n * structure, transitively redundant edge discovery over ordering and\n * hierarchy families, and dominator (bottleneck) analysis over one node's\n * reachable subgraph. Every analysis is deterministic, cancellable, bounded,\n * and reports exact cost metadata so agents can budget follow-up reads\n * without re-scanning the workspace.\n */\nimport {\n RelationshipGraph,\n type RelationshipEdge,\n type RelationshipKindDefinition,\n type RelationshipNeighborEdge,\n type RelationshipQueryResult,\n type RelationshipTraversalDirection,\n} from \"../relationships.js\";\nimport {\n hierarchyParentEndpoint,\n orderingPredecessorEndpoint,\n} from \"./traversal.js\";\n\n/** Default label-propagation sweeps before reporting non-convergence. */\nconst DEFAULT_MAX_ITERATIONS = 16;\n/** Default minimum member count for a reported community. */\nconst DEFAULT_MIN_COMMUNITY_SIZE = 2;\n/** Default witness-path depth searched per candidate redundant edge. */\nconst DEFAULT_REDUNDANCY_MAX_DEPTH = 8;\n\n/** One detected relationship community. */\nexport interface RelationshipCommunity {\n /** Lexicographically smallest member id, naming the community. */\n representative: string;\n /** Total member count. */\n size: number;\n /** Sorted member node ids. */\n members: string[];\n}\n\n/** Bounded community-detection controls. */\nexport interface GraphCommunityOptions {\n /** Registered relationship kinds whose edges define adjacency. */\n kinds?: readonly string[];\n /** Maximum label-propagation sweeps before reporting non-convergence; defaults to 16. */\n maxIterations?: number;\n /** Minimum member count for a reported community; defaults to 2. */\n minSize?: number;\n /** Abort signal checked once per sweep. */\n signal?: AbortSignal;\n}\n\n/** Deterministic label-propagation community analysis. */\nexport interface RelationshipCommunityAnalysis {\n /** Detected communities, largest first and by representative within equal size. */\n communities: RelationshipCommunity[];\n /** Label-propagation sweeps executed. */\n iterations: number;\n /** Whether labels stabilized before the iteration bound stopped the sweep. */\n converged: boolean;\n}\n\n/** One stored edge implied by a longer same-family witness path. */\nexport interface RedundantRelationshipEdge {\n /** The stored redundant edge in its original spelling. */\n edge: RelationshipEdge;\n /** Semantic-orientation witness node path proving the implication, endpoints inclusive. */\n witness: string[];\n}\n\n/** Bounded redundancy-scan controls. */\nexport interface GraphRedundancyOptions {\n /** Directed ordering or hierarchy kinds to scan; defaults to every eligible registered kind. */\n kinds?: readonly string[];\n /** Maximum witness-path depth searched per edge; defaults to 8. */\n maxDepth?: number;\n /** Maximum reported redundant edges. */\n limit?: number;\n /** Abort signal checked once per scanned edge. */\n signal?: AbortSignal;\n}\n\n/** One reachable node with its immediate dominator and gating weight. */\nexport interface RelationshipDominatorRow {\n /** Reachable node id. */\n id: string;\n /** Immediate dominator appearing on every root-to-node path. */\n idom: string;\n /** Nodes strictly dominated by this node — its dominator-subtree size minus itself. */\n dominatedCount: number;\n}\n\n/** Bounded dominator-analysis controls. */\nexport interface GraphDominatorOptions {\n /** Registered relationship kinds whose edges define reachability. */\n kinds?: readonly string[];\n /** Traversal direction relative to each visited node; defaults to \"outgoing\". */\n direction?: RelationshipTraversalDirection;\n /** Maximum reachability depth from the root as a non-negative integer. */\n maxDepth?: number;\n /** Abort signal checked once per processed node. */\n signal?: AbortSignal;\n}\n\n/** Dominator-tree analysis of one node's reachable subgraph. */\nexport interface RelationshipDominatorAnalysis {\n /** Analyzed root id. */\n root: string;\n /** Reachable node count including the root. */\n reachableCount: number;\n /** Non-root reachable rows sorted by gating weight, then id. */\n rows: RelationshipDominatorRow[];\n}\n\n/** Require a positive integer for one analytics bound. */\nfunction assertPositiveBound(name: string, value: number): void {\n if (!Number.isInteger(value) || value < 1)\n throw new TypeError(`Invalid ${name} bound: ${String(value)}`);\n}\n\n/**\n * Invoke `visit` once per canonical-kind-matched edge, skipping self-loops.\n * Kind filters resolve to canonical spelling and match either the requested\n * kind or its inverse so directed families are selected by either spelling. The\n * resolved definition is passed alongside the edge so callers can distinguish\n * directed and undirected families. This is the single edge-selection primitive\n * shared by community, centrality, cut-structure, and degree builders.\n */\nexport function forEachMatchedRelationshipEdge(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n visit: (\n edge: RelationshipEdge,\n definition: RelationshipKindDefinition,\n ) => void,\n): void {\n const registry = graph.registry();\n const wanted =\n kinds === undefined\n ? undefined\n : new Set(kinds.map((kind) => registry.require(kind).kind));\n for (const edge of graph.edges()) {\n if (edge.source === edge.target) continue;\n const definition = registry.require(edge.kind);\n if (\n wanted !== undefined &&\n !(\n wanted.has(definition.kind) ||\n (definition.inverse !== undefined && wanted.has(definition.inverse))\n )\n )\n continue;\n visit(edge, definition);\n }\n}\n\n/** Build the deterministic undirected multiset adjacency restricted to canonicalized kinds. */\nfunction buildUndirectedAdjacency(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n): Map<string, string[]> {\n const adjacency = new Map<string, string[]>();\n forEachMatchedRelationshipEdge(graph, kinds, (edge) => {\n appendAdjacency(adjacency, edge.source, edge.target);\n appendAdjacency(adjacency, edge.target, edge.source);\n });\n for (const neighbors of adjacency.values()) neighbors.sort();\n return adjacency;\n}\n\n/** Append one neighbor to a node's adjacency list, creating the list on demand. */\nfunction appendAdjacency(\n adjacency: Map<string, string[]>,\n from: string,\n to: string,\n): void {\n const neighbors = adjacency.get(from);\n if (neighbors === undefined) adjacency.set(from, [to]);\n else neighbors.push(to);\n}\n\n/** Adopt the most frequent neighbor label with lexicographic tie-breaking. */\nfunction dominantNeighborLabel(\n neighbors: readonly string[],\n labels: Map<string, string>,\n): string {\n const counts = new Map<string, number>();\n for (const neighbor of neighbors) {\n const label = labels.get(neighbor)!;\n counts.set(label, (counts.get(label) ?? 0) + 1);\n }\n let best: string | undefined;\n let bestCount = 0;\n for (const [label, count] of counts) {\n if (count > bestCount || (count === bestCount && label < best!)) {\n best = label;\n bestCount = count;\n }\n }\n return best!;\n}\n\n/** Group stabilized labels into sorted communities meeting the size floor. */\nfunction collectCommunities(\n labels: Map<string, string>,\n minSize: number,\n): RelationshipCommunity[] {\n const groups = new Map<string, string[]>();\n for (const [id, label] of labels) {\n const members = groups.get(label);\n if (members === undefined) groups.set(label, [id]);\n else members.push(id);\n }\n const communities: RelationshipCommunity[] = [];\n for (const members of groups.values()) {\n if (members.length < minSize) continue;\n members.sort();\n communities.push({\n representative: members[0]!,\n size: members.length,\n members,\n });\n }\n return communities.sort(\n (left, right) =>\n right.size - left.size ||\n left.representative.localeCompare(right.representative),\n );\n}\n\n/**\n * Detect communities with deterministic asynchronous label propagation: nodes\n * are swept in sorted order, each adopting the most frequent label among its\n * neighbors with lexicographic tie-breaking, until labels stabilize or the\n * iteration bound stops the sweep. Adjacency is undirected — every\n * participating edge connects both endpoints symmetrically and parallel edges\n * weight their neighbor. `meta.truncated` reports non-convergence.\n */\nexport function detectRelationshipCommunities(\n graph: RelationshipGraph,\n options: GraphCommunityOptions = {},\n): RelationshipQueryResult<RelationshipCommunityAnalysis> {\n const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n const minSize = options.minSize ?? DEFAULT_MIN_COMMUNITY_SIZE;\n assertPositiveBound(\"maxIterations\", maxIterations);\n assertPositiveBound(\"minSize\", minSize);\n const adjacency = buildUndirectedAdjacency(graph, options.kinds);\n const nodes = graph.nodes();\n const labels = new Map(nodes.map((id) => [id, id]));\n let iterations = 0;\n let converged = false;\n let visitedNodes = 0;\n let inspectedEdges = 0;\n while (iterations < maxIterations && !converged) {\n options.signal?.throwIfAborted();\n iterations += 1;\n converged = true;\n for (const id of nodes) {\n visitedNodes += 1;\n const neighbors = adjacency.get(id);\n if (neighbors === undefined) continue;\n inspectedEdges += neighbors.length;\n const dominant = dominantNeighborLabel(neighbors, labels);\n if (dominant !== labels.get(id)) {\n labels.set(id, dominant);\n converged = false;\n }\n }\n }\n return {\n value: {\n communities: collectCommunities(labels, minSize),\n iterations,\n converged,\n },\n meta: { visitedNodes, inspectedEdges, truncated: !converged },\n };\n}\n\n/** Decide whether a kind carries transitive semantics eligible for redundancy and duplicate analysis. */\nexport function isTransitiveKind(definition: RelationshipKindDefinition): boolean {\n return (\n definition.direction === \"directed\" &&\n (definition.ordering || definition.hierarchy)\n );\n}\n\n/** Family grouping key joining a directed kind with its inverse spelling. */\nexport function transitiveFamilyKey(definition: RelationshipKindDefinition): string {\n return definition.inverse !== undefined &&\n definition.inverse < definition.kind\n ? definition.inverse\n : definition.kind;\n}\n\n/** Orient one transitive edge into its semantic forward direction. */\nexport function orientTransitiveEdge(\n edge: RelationshipEdge,\n definition: RelationshipKindDefinition,\n): { from: string; to: string } {\n // Hierarchy families flow child -> parent; ordering families flow\n // predecessor -> successor, so inverse spellings land in one relation.\n const head = definition.hierarchy\n ? hierarchyParentEndpoint(edge, definition)\n : edge.source === orderingPredecessorEndpoint(edge, definition)\n ? edge.target\n : edge.source;\n return head === edge.target\n ? { from: edge.source, to: edge.target }\n : { from: edge.target, to: edge.source };\n}\n\n/** One semantically oriented transitive edge retaining its stored spelling. */\ninterface OrientedTransitiveEdge {\n /** Semantic tail node. */\n from: string;\n /** Semantic head node. */\n to: string;\n /** Original stored edge. */\n edge: RelationshipEdge;\n}\n\n/** Per-family oriented edges and their deterministic forward adjacency. */\ninterface TransitiveFamily {\n /** Deduplicated forward adjacency in semantic orientation, sorted after collection. */\n adjacency: Map<string, Set<string>>;\n /** Oriented edges in deterministic stored order. */\n records: OrientedTransitiveEdge[];\n}\n\n/** Resolve explicit redundancy kind filters into their family keys. */\nfunction resolveRedundancyFamilies(\n graph: RelationshipGraph,\n kinds: readonly string[] | undefined,\n): Set<string> | undefined {\n if (kinds === undefined) return undefined;\n const registry = graph.registry();\n const families = new Set<string>();\n for (const kind of kinds) {\n const definition = registry.require(kind);\n if (!isTransitiveKind(definition))\n throw new TypeError(\n `Relationship kind ${definition.kind} is not a directed ordering or hierarchy kind`,\n );\n families.add(transitiveFamilyKey(definition));\n }\n return families;\n}\n\n/** Group eligible stored edges into oriented per-family scan structures. */\nfunction collectTransitiveFamilies(\n graph: RelationshipGraph,\n wanted: Set<string> | undefined,\n): Map<string, TransitiveFamily> {\n const registry = graph.registry();\n const families = new Map<string, TransitiveFamily>();\n for (const edge of graph.edges()) {\n const definition = registry.require(edge.kind);\n if (!isTransitiveKind(definition)) continue;\n const key = transitiveFamilyKey(definition);\n if (wanted !== undefined && !wanted.has(key)) continue;\n const oriented = orientTransitiveEdge(edge, definition);\n if (oriented.from === oriented.to) continue;\n let family = families.get(key);\n if (family === undefined) {\n family = { adjacency: new Map(), records: [] };\n families.set(key, family);\n }\n const targets = family.adjacency.get(oriented.from);\n if (targets === undefined)\n family.adjacency.set(oriented.from, new Set([oriented.to]));\n else targets.add(oriented.to);\n family.records.push({ ...oriented, edge });\n }\n return families;\n}\n\n/** Freeze one family's adjacency sets into deterministic sorted lists. */\nfunction sortedFamilyAdjacency(\n family: TransitiveFamily,\n): Map<string, readonly string[]> {\n const sorted = new Map<string, readonly string[]>();\n for (const [from, targets] of family.adjacency)\n sorted.set(from, [...targets].sort());\n return sorted;\n}\n\n/** Rebuild the witness node path from breadth-first parent pointers. */\nfunction reconstructWitness(\n parents: Map<string, string>,\n from: string,\n tail: string,\n head: string,\n): string[] {\n const witness = [head];\n for (let node = tail; node !== from; node = parents.get(node)!)\n witness.push(node);\n witness.push(from);\n return witness.reverse();\n}\n\n/** Expand one witness frontier node; return the completed witness when the head is reached. */\nfunction expandWitnessFrontier(\n adjacency: Map<string, readonly string[]>,\n record: OrientedTransitiveEdge,\n current: { id: string; depth: number },\n parents: Map<string, string>,\n queue: { id: string; depth: number }[],\n cost: { visitedNodes: number; inspectedEdges: number },\n): string[] | undefined {\n for (const next of adjacency.get(current.id) ?? []) {\n cost.inspectedEdges += 1;\n // Skip the direct edge under test; deeper hops may still reach the head.\n if (current.depth === 0 && next === record.to) continue;\n if (parents.has(next)) continue;\n parents.set(next, current.id);\n if (next === record.to)\n return reconstructWitness(parents, record.from, current.id, next);\n queue.push({ id: next, depth: current.depth + 1 });\n }\n return undefined;\n}\n\n/** Search one bounded same-family witness path that implies a direct edge. */\nfunction findWitnessPath(\n adjacency: Map<string, readonly string[]>,\n record: OrientedTransitiveEdge,\n maxDepth: number,\n cost: { visitedNodes: number; inspectedEdges: number },\n): string[] | undefined {\n const parents = new Map<string, string>([[record.from, record.from]]);\n const queue = [{ id: record.from, depth: 0 }];\n for (let index = 0; index < queue.length; index += 1) {\n const current = queue[index]!;\n cost.visitedNodes += 1;\n if (current.depth >= maxDepth) continue;\n const witness = expandWitnessFrontier(\n adjacency,\n record,\n current,\n parents,\n queue,\n cost,\n );\n if (witness !== undefined) return witness;\n }\n return undefined;\n}\n\n/**\n * Find stored edges implied by a longer path of the same semantic family —\n * the transitive-reduction view of ordering and hierarchy relations. Each\n * family joins a directed kind with its inverse spelling in semantic\n * orientation, so `blocked_by` and `blocks` witness each other. The witness\n * search is breadth-first, shortest and lexicographic first, bounded by\n * `maxDepth` per edge; `meta.truncated` reports only the `limit` bound.\n */\nexport function findRedundantRelationshipEdges(\n graph: RelationshipGraph,\n options: GraphRedundancyOptions = {},\n): RelationshipQueryResult<RedundantRelationshipEdge[]> {\n const maxDepth = options.maxDepth ?? DEFAULT_REDUNDANCY_MAX_DEPTH;\n assertPositiveBound(\"maxDepth\", maxDepth);\n if (options.limit !== undefined) assertPositiveBound(\"limit\", options.limit);\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n const wanted = resolveRedundancyFamilies(graph, options.kinds);\n const families = collectTransitiveFamilies(graph, wanted);\n const value: RedundantRelationshipEdge[] = [];\n const cost = { visitedNodes: 0, inspectedEdges: 0 };\n let truncated = false;\n scan: for (const key of [...families.keys()].sort()) {\n const family = families.get(key)!;\n const adjacency = sortedFamilyAdjacency(family);\n for (const record of family.records) {\n options.signal?.throwIfAborted();\n const witness = findWitnessPath(adjacency, record, maxDepth, cost);\n if (witness === undefined) continue;\n if (value.length >= limit) {\n truncated = true;\n break scan;\n }\n value.push({ edge: record.edge, witness });\n }\n }\n return {\n value,\n meta: {\n visitedNodes: cost.visitedNodes,\n inspectedEdges: cost.inspectedEdges,\n truncated,\n },\n };\n}\n\n/** Reachability index of one root's directed subgraph. */\ninterface ReachableSubgraph {\n /** Reachable node ids in breadth-first discovery order. */\n order: string[];\n /** Deterministic successor lists per reachable node. */\n successors: Map<string, string[]>;\n /** Reachable predecessor sets per reachable node. */\n predecessors: Map<string, Set<string>>;\n /** Candidate edges inspected while indexing. */\n inspectedEdges: number;\n /** Whether the depth bound excluded reachable nodes. */\n truncated: boolean;\n}\n\n/** Mutable frontier state threaded through bounded reachability expansion. */\ninterface ReachabilityState {\n /** Nodes already discovered. */\n seen: Set<string>;\n /** Pending breadth-first nodes and their depths. */\n queue: { id: string; depth: number }[];\n /** Reachable predecessor sets per discovered node. */\n predecessors: Map<string, Set<string>>;\n /** Whether the depth bound excluded reachable nodes. */\n truncated: boolean;\n}\n\n/** Expand one node's neighbor rows into successors, predecessors, and frontier work. */\nfunction expandReachableNode(\n id: string,\n depth: number,\n rows: readonly RelationshipNeighborEdge[],\n maxDepth: number,\n state: ReachabilityState,\n): string[] {\n const nextSet = new Set<string>();\n const nexts: string[] = [];\n for (const row of rows) {\n if (row.id === id || nextSet.has(row.id)) continue;\n if (!state.seen.has(row.id)) {\n // A depth-boundary node keeps its edges to already-indexed nodes but\n // may not discover new ones; excluded discoveries mark truncation.\n if (depth >= maxDepth) {\n state.truncated = true;\n continue;\n }\n state.seen.add(row.id);\n state.queue.push({ id: row.id, depth: depth + 1 });\n }\n nextSet.add(row.id);\n nexts.push(row.id);\n let incoming = state.predecessors.get(row.id);\n if (incoming === undefined) {\n incoming = new Set();\n state.predecessors.set(row.id, incoming);\n }\n incoming.add(id);\n }\n return nexts;\n}\n\n/** Index the bounded reachable subgraph used by dominator analysis. */\nfunction indexReachableSubgraph(\n graph: RelationshipGraph,\n root: string,\n options: GraphDominatorOptions,\n): ReachableSubgraph {\n const direction = options.direction ?? \"outgoing\";\n const maxDepth = options.maxDepth ?? Number.POSITIVE_INFINITY;\n const order: string[] = [];\n const successors = new Map<string, string[]>();\n const state: ReachabilityState = {\n seen: new Set([root]),\n queue: [{ id: root, depth: 0 }],\n predecessors: new Map(),\n truncated: false,\n };\n let inspectedEdges = 0;\n for (let index = 0; index < state.queue.length; index += 1) {\n options.signal?.throwIfAborted();\n const { id, depth } = state.queue[index]!;\n order.push(id);\n const rows = graph.neighborEdges(id, {\n direction,\n ...(options.kinds === undefined ? {} : { kinds: options.kinds }),\n });\n inspectedEdges += rows.meta.inspectedEdges;\n successors.set(id, expandReachableNode(id, depth, rows.value, maxDepth, state));\n }\n return {\n order,\n successors,\n predecessors: state.predecessors,\n inspectedEdges,\n truncated: state.truncated,\n };\n}\n\n/** Compute the deterministic reverse postorder of one reachable subgraph. */\nfunction reversePostorder(subgraph: ReachableSubgraph, root: string): string[] {\n const postorder: string[] = [];\n const visited = new Set([root]);\n const stack = [{ id: root, index: 0 }];\n while (stack.length > 0) {\n const frame = stack.at(-1)!;\n const nexts = subgraph.successors.get(frame.id)!;\n if (frame.index < nexts.length) {\n const next = nexts[frame.index]!;\n frame.index += 1;\n if (!visited.has(next)) {\n visited.add(next);\n stack.push({ id: next, index: 0 });\n }\n } else {\n postorder.push(frame.id);\n stack.pop();\n }\n }\n return postorder.reverse();\n}\n\n/** Walk two dominator-tree fingers to their common ancestor by reverse-postorder number. */\nfunction intersectDominators(\n left: string,\n right: string,\n idom: Map<string, string>,\n ordinal: Map<string, number>,\n): string {\n let first = left;\n let second = right;\n while (first !== second) {\n while (ordinal.get(first)! > ordinal.get(second)!) first = idom.get(first)!;\n while (ordinal.get(second)! > ordinal.get(first)!) second = idom.get(second)!;\n }\n return first;\n}\n\n/** Fold one node's processed predecessors into its dominator candidate. */\nfunction dominatorCandidate(\n predecessors: ReadonlySet<string>,\n idom: Map<string, string>,\n ordinal: Map<string, number>,\n): string | undefined {\n let candidate: string | undefined;\n for (const pred of [...predecessors].sort()) {\n if (!idom.has(pred)) continue;\n candidate =\n candidate === undefined\n ? pred\n : intersectDominators(candidate, pred, idom, ordinal);\n }\n return candidate;\n}\n\n/** Run the Cooper–Harvey–Kennedy fixed-point over one reverse postorder. */\nfunction solveImmediateDominators(\n subgraph: ReachableSubgraph,\n root: string,\n order: readonly string[],\n ordinal: Map<string, number>,\n signal: AbortSignal | undefined,\n): Map<string, string> {\n const idom = new Map<string, string>([[root, root]]);\n let changed = true;\n while (changed) {\n changed = false;\n for (const id of order) {\n signal?.throwIfAborted();\n if (id === root) continue;\n // Every non-root node in the order was discovered through at least one\n // predecessor, so the set is always present.\n const candidate = dominatorCandidate(\n subgraph.predecessors.get(id)!,\n idom,\n ordinal,\n );\n if (candidate !== undefined && idom.get(id) !== candidate) {\n idom.set(id, candidate);\n changed = true;\n }\n }\n }\n return idom;\n}\n\n/**\n * Compute immediate dominators and gating weights over one node's reachable\n * subgraph using the Cooper–Harvey–Kennedy fixed-point. A node dominates the\n * work that every path from the root must pass through it to reach, so rows\n * with a positive `dominatedCount` are the structural bottlenecks of the\n * root's blast radius. Rows sort by gating weight, then id; `meta.truncated`\n * reports when the `maxDepth` bound excluded reachable nodes.\n */\nexport function computeRelationshipDominators(\n graph: RelationshipGraph,\n root: string,\n options: GraphDominatorOptions = {},\n): RelationshipQueryResult<RelationshipDominatorAnalysis> {\n if (!graph.hasNode(root))\n throw new TypeError(`Relationship node not found: ${root}`);\n if (\n options.maxDepth !== undefined &&\n (!Number.isInteger(options.maxDepth) || options.maxDepth < 0)\n )\n throw new TypeError(`Invalid maxDepth bound: ${String(options.maxDepth)}`);\n const subgraph = indexReachableSubgraph(graph, root, options);\n const order = reversePostorder(subgraph, root);\n const ordinal = new Map(order.map((id, index) => [id, index]));\n const idom = solveImmediateDominators(\n subgraph,\n root,\n order,\n ordinal,\n options.signal,\n );\n const subtreeSizes = new Map(order.map((id) => [id, 1]));\n for (let index = order.length - 1; index >= 0; index -= 1) {\n const id = order[index]!;\n if (id === root) continue;\n const parent = idom.get(id)!;\n subtreeSizes.set(parent, subtreeSizes.get(parent)! + subtreeSizes.get(id)!);\n }\n const rows = order\n .filter((id) => id !== root)\n .map((id) => ({\n id,\n idom: idom.get(id)!,\n dominatedCount: subtreeSizes.get(id)! - 1,\n }))\n .sort(\n (left, right) =>\n right.dominatedCount - left.dominatedCount ||\n left.id.localeCompare(right.id),\n );\n return {\n value: { root, reachableCount: subgraph.order.length, rows },\n meta: {\n visitedNodes: subgraph.order.length,\n inspectedEdges: subgraph.inspectedEdges,\n truncated: subgraph.truncated,\n },\n };\n}\n"],"names":[],"mappings":"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","debugId":"e7884ad6-98e5-5ed6-93a0-ffba254fe174"}
|
|
@@ -52,6 +52,39 @@ export interface DanglingDependencyReferenceSummary {
|
|
|
52
52
|
/** Legacy sentinel rows across active and terminal holders, called out separately from typo-like ids. */
|
|
53
53
|
no_active_blocker_sentinels: DanglingDependencyReference[];
|
|
54
54
|
}
|
|
55
|
+
/** Normalize a graph target while removing the historical no-blocker marker. */
|
|
56
|
+
export declare function normalizeDependencyGraphTarget(target: unknown): string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the default workspace relationship-kind registry: the built-in kinds
|
|
59
|
+
* merged with every active extension-contributed relationship-kind
|
|
60
|
+
* registration. Assembly, mutation advisories, and standalone graph consumers
|
|
61
|
+
* share this resolution so custom ordering semantics apply identically on
|
|
62
|
+
* every surface.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveWorkspaceRelationshipKindRegistry(): RelationshipKindRegistry;
|
|
65
|
+
/** One raw stored dependency row duplicated verbatim on a single holder. */
|
|
66
|
+
export interface DuplicateDependencyRow {
|
|
67
|
+
/** Item that stores the duplicated row. */
|
|
68
|
+
holder_id: string;
|
|
69
|
+
/** Referenced target id in its first stored spelling. */
|
|
70
|
+
target_id: string;
|
|
71
|
+
/** Stored relationship kind shared by every duplicate occurrence. */
|
|
72
|
+
kind: string;
|
|
73
|
+
/** Total stored occurrences of the identical row (always >= 2). */
|
|
74
|
+
occurrences: number;
|
|
75
|
+
/** Current lifecycle status of the holder. */
|
|
76
|
+
holder_status: ItemStatus;
|
|
77
|
+
/** Whether the holder is terminal and the duplication is historical debt. */
|
|
78
|
+
legacy_terminal: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Collect raw stored dependency rows whose exact identity — holder, kind, and
|
|
82
|
+
* case-insensitive target — appears more than once on one item. Graph
|
|
83
|
+
* construction deduplicates these by edge identity, so the assembled graph and
|
|
84
|
+
* every projection built on it cannot see them; this pre-assembly scan is the
|
|
85
|
+
* only surface that reports the storage-layer defect.
|
|
86
|
+
*/
|
|
87
|
+
export declare function collectDuplicateDependencyRows(items: readonly DependencyReferenceHolder[], isTerminal?: (status: ItemStatus) => boolean): DuplicateDependencyRow[];
|
|
55
88
|
/**
|
|
56
89
|
* Classify missing hierarchy and dependency targets without mutating their holders.
|
|
57
90
|
*
|
|
@@ -66,6 +99,8 @@ export declare function collectMissingDependencyTargetIds(dangling: DanglingDepe
|
|
|
66
99
|
export interface WorkspaceRelationshipItem extends DependencyReferenceHolder {
|
|
67
100
|
/** Human-readable title projected into per-node details. */
|
|
68
101
|
title: string;
|
|
102
|
+
/** Optional item type powering per-type coverage profiles and policies. */
|
|
103
|
+
type?: string;
|
|
69
104
|
}
|
|
70
105
|
/** Compact node projection paired with the assembled graph. */
|
|
71
106
|
export interface WorkspaceRelationshipNodeDetails {
|
|
@@ -75,6 +110,8 @@ export interface WorkspaceRelationshipNodeDetails {
|
|
|
75
110
|
title: string;
|
|
76
111
|
/** Lifecycle status, or the `missing` marker status for absent endpoints. */
|
|
77
112
|
status: string;
|
|
113
|
+
/** Item type when the source item declared one; absent on missing placeholders. */
|
|
114
|
+
type?: string;
|
|
78
115
|
}
|
|
79
116
|
/** Assembled workspace relationship graph with governance side-products. */
|
|
80
117
|
export interface WorkspaceRelationshipAssembly {
|
|
@@ -86,6 +123,8 @@ export interface WorkspaceRelationshipAssembly {
|
|
|
86
123
|
missingIdSet: Set<string>;
|
|
87
124
|
/** Dangling-reference classification computed during assembly. */
|
|
88
125
|
dangling: DanglingDependencyReferenceSummary;
|
|
126
|
+
/** Raw same-identity duplicated dependency rows found before graph dedup. */
|
|
127
|
+
duplicateRows: DuplicateDependencyRow[];
|
|
89
128
|
}
|
|
90
129
|
/**
|
|
91
130
|
* Build the shared workspace relationship graph including missing placeholder
|
|
@@ -1,5 +1,5 @@
|
|
|
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]="208d0dcd-c6b6-5959-acdb-6969b1005edd")}catch(e){}}();
|
|
3
3
|
import { getActiveExtensionRegistrations } from "../../core/extensions/index.js";
|
|
4
4
|
import { RelationshipGraph, createRelationshipKindRegistry, } from "../relationships.js";
|
|
5
5
|
/** Normalize a decoded reference target and reject empty legacy placeholders. */
|
|
@@ -13,12 +13,96 @@ function normalizeDependencyReferenceTarget(target) {
|
|
|
13
13
|
return normalized;
|
|
14
14
|
}
|
|
15
15
|
/** Normalize a graph target while removing the historical no-blocker marker. */
|
|
16
|
-
function normalizeDependencyGraphTarget(target) {
|
|
16
|
+
export function normalizeDependencyGraphTarget(target) {
|
|
17
17
|
const normalized = normalizeDependencyReferenceTarget(target);
|
|
18
18
|
return normalized?.toLowerCase() === "no-active-blocker"
|
|
19
19
|
? undefined
|
|
20
20
|
: normalized;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the default workspace relationship-kind registry: the built-in kinds
|
|
24
|
+
* merged with every active extension-contributed relationship-kind
|
|
25
|
+
* registration. Assembly, mutation advisories, and standalone graph consumers
|
|
26
|
+
* share this resolution so custom ordering semantics apply identically on
|
|
27
|
+
* every surface.
|
|
28
|
+
*/
|
|
29
|
+
export function resolveWorkspaceRelationshipKindRegistry() {
|
|
30
|
+
const registry = createRelationshipKindRegistry();
|
|
31
|
+
for (const registration of getActiveExtensionRegistrations()
|
|
32
|
+
?.relationship_kinds ?? []) {
|
|
33
|
+
for (const definition of registration.definitions) {
|
|
34
|
+
registry.register(definition);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return registry;
|
|
38
|
+
}
|
|
39
|
+
/** Compare text case-insensitively with an exact-spelling deterministic tie-breaker. */
|
|
40
|
+
function compareCaseFoldedText(left, right) {
|
|
41
|
+
const normalizedLeft = left.toLowerCase();
|
|
42
|
+
const normalizedRight = right.toLowerCase();
|
|
43
|
+
if (normalizedLeft !== normalizedRight)
|
|
44
|
+
return normalizedLeft < normalizedRight ? -1 : 1;
|
|
45
|
+
if (left !== right)
|
|
46
|
+
return left < right ? -1 : 1;
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
/** Count one holder's dependency rows by their case-insensitive kind-plus-target identity. */
|
|
50
|
+
function countDependencyRowIdentities(item) {
|
|
51
|
+
const occurrences = new Map();
|
|
52
|
+
for (const dependency of item.dependencies ?? []) {
|
|
53
|
+
if (typeof dependency !== "object" || dependency === null)
|
|
54
|
+
continue;
|
|
55
|
+
const legacyDependency = dependency;
|
|
56
|
+
const target = normalizeDependencyReferenceTarget(legacyDependency.id);
|
|
57
|
+
if (!target)
|
|
58
|
+
continue;
|
|
59
|
+
const kind = typeof legacyDependency.kind === "string"
|
|
60
|
+
? legacyDependency.kind
|
|
61
|
+
: "related";
|
|
62
|
+
const key = `${kind}\u0000${target.toLowerCase()}`;
|
|
63
|
+
const existing = occurrences.get(key);
|
|
64
|
+
if (existing)
|
|
65
|
+
existing.count += 1;
|
|
66
|
+
else
|
|
67
|
+
occurrences.set(key, { target_id: target, kind, count: 1 });
|
|
68
|
+
}
|
|
69
|
+
return occurrences;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Collect raw stored dependency rows whose exact identity — holder, kind, and
|
|
73
|
+
* case-insensitive target — appears more than once on one item. Graph
|
|
74
|
+
* construction deduplicates these by edge identity, so the assembled graph and
|
|
75
|
+
* every projection built on it cannot see them; this pre-assembly scan is the
|
|
76
|
+
* only surface that reports the storage-layer defect.
|
|
77
|
+
*/
|
|
78
|
+
export function collectDuplicateDependencyRows(items, isTerminal = (status) => status === "closed" || status === "canceled") {
|
|
79
|
+
const rows = [];
|
|
80
|
+
for (const item of items) {
|
|
81
|
+
if (typeof item?.id !== "string" || item.id.trim().length === 0)
|
|
82
|
+
continue;
|
|
83
|
+
for (const entry of countDependencyRowIdentities(item).values()) {
|
|
84
|
+
if (entry.count < 2)
|
|
85
|
+
continue;
|
|
86
|
+
rows.push({
|
|
87
|
+
holder_id: item.id.trim(),
|
|
88
|
+
target_id: entry.target_id,
|
|
89
|
+
kind: entry.kind,
|
|
90
|
+
occurrences: entry.count,
|
|
91
|
+
holder_status: item.status,
|
|
92
|
+
legacy_terminal: isTerminal(item.status),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return rows.sort((left, right) => {
|
|
97
|
+
const holderCompare = compareCaseFoldedText(left.holder_id, right.holder_id);
|
|
98
|
+
if (holderCompare !== 0)
|
|
99
|
+
return holderCompare;
|
|
100
|
+
const targetCompare = compareCaseFoldedText(left.target_id, right.target_id);
|
|
101
|
+
if (targetCompare !== 0)
|
|
102
|
+
return targetCompare;
|
|
103
|
+
return compareCaseFoldedText(left.kind, right.kind);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
22
106
|
/**
|
|
23
107
|
* Classify missing hierarchy and dependency targets without mutating their holders.
|
|
24
108
|
*
|
|
@@ -93,15 +177,7 @@ export function collectMissingDependencyTargetIds(dangling) {
|
|
|
93
177
|
* once per query surface.
|
|
94
178
|
*/
|
|
95
179
|
export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry) {
|
|
96
|
-
const relationshipRegistry = registry ??
|
|
97
|
-
if (registry === undefined) {
|
|
98
|
-
// Preserve compatibility with activation payloads produced before this registry existed.
|
|
99
|
-
for (const registration of getActiveExtensionRegistrations()?.relationship_kinds ?? []) {
|
|
100
|
-
for (const definition of registration.definitions) {
|
|
101
|
-
relationshipRegistry.register(definition);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
180
|
+
const relationshipRegistry = registry ?? resolveWorkspaceRelationshipKindRegistry();
|
|
105
181
|
const safeItems = items.filter((item) => typeof item?.id === "string" && item.id.trim().length > 0);
|
|
106
182
|
const canonicalIds = new Map(safeItems.map((item) => [item.id.trim().toLowerCase(), item.id.trim()]));
|
|
107
183
|
const dangling = collectDanglingDependencyReferences(safeItems, isTerminal);
|
|
@@ -141,6 +217,9 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
141
217
|
id: item.id.trim(),
|
|
142
218
|
title: item.title,
|
|
143
219
|
status: item.status,
|
|
220
|
+
...(typeof item.type === "string" && item.type.trim().length > 0
|
|
221
|
+
? { type: item.type.trim() }
|
|
222
|
+
: {}),
|
|
144
223
|
})),
|
|
145
224
|
...missingIds.map((id) => ({
|
|
146
225
|
id,
|
|
@@ -150,7 +229,8 @@ export function assembleWorkspaceRelationshipGraph(items, isTerminal, registry)
|
|
|
150
229
|
],
|
|
151
230
|
missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),
|
|
152
231
|
dangling,
|
|
232
|
+
duplicateRows: collectDuplicateDependencyRows(safeItems, isTerminal),
|
|
153
233
|
};
|
|
154
234
|
}
|
|
155
235
|
//# sourceMappingURL=assembly.js.map
|
|
156
|
-
//# debugId=
|
|
236
|
+
//# debugId=208d0dcd-c6b6-5959-acdb-6969b1005edd
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assembly.js","sources":["sdk/graph/assembly.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/graph/assembly\n *\n * Builds the shared workspace relationship graph consumed by dependency\n * queries, bounded context packets, impact analysis, and governance audits.\n * Assembly normalizes hierarchy, legacy scalar blockers, and structured\n * dependency edges into one deterministic {@link RelationshipGraph}, classifies\n * dangling references without mutating their holders, and materializes missing\n * endpoints as placeholder nodes so bounded traversals can explain absent work\n * instead of silently dropping it.\n */\nimport type { Dependency, ItemStatus } from \"../../types/index.js\";\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport {\n RelationshipGraph,\n createRelationshipKindRegistry,\n type RelationshipKindRegistry,\n} from \"../relationships.js\";\n\n/** Minimal item shape inspected by dependency-reference governance. */\nexport interface DependencyReferenceHolder {\n /** Stable item identifier. */\n id: string;\n /** Lifecycle status used to separate actionable work from historical debt. */\n status: ItemStatus;\n /** Optional hierarchy parent reference. */\n parent?: string;\n /** Optional legacy scalar blocker reference. */\n blocked_by?: string;\n /** Structured dependency edges. */\n dependencies?: Dependency[];\n}\n\n/** Storage surface that contributed a normalized dependency reference. */\nexport type DependencyReferenceSource = \"parent\" | \"blocked_by\" | \"dependency\";\n\n/** One normalized dependency reference whose target is absent from the tracker. */\nexport interface DanglingDependencyReference {\n /** Item that owns the reference. */\n holder_id: string;\n /** Missing referenced item id or legacy sentinel. */\n target_id: string;\n /** Relationship field or dependency kind. */\n kind: string;\n /** Storage surface that owns the reference and determines its remediation. */\n source: DependencyReferenceSource;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and therefore historical, non-actionable debt. */\n legacy_terminal: boolean;\n /** Whether the target is the pre-structured-dependency `no-active-blocker` sentinel. */\n no_active_blocker_sentinel: boolean;\n}\n\n/** Actionable and historical partitions returned by dependency-reference governance. */\nexport interface DanglingDependencyReferenceSummary {\n /** Missing references held by active items; these may affect scheduling and should gate validation. */\n active: DanglingDependencyReference[];\n /** Missing references held only by terminal items; retained as informational history debt. */\n legacy_terminal: DanglingDependencyReference[];\n /** Legacy sentinel rows across active and terminal holders, called out separately from typo-like ids. */\n no_active_blocker_sentinels: DanglingDependencyReference[];\n}\n\n/** Normalize a decoded reference target and reject empty legacy placeholders. */\nfunction normalizeDependencyReferenceTarget(\n target: unknown,\n): string | undefined {\n if (typeof target !== \"string\") return undefined;\n const normalized = target.trim();\n if (\n !normalized ||\n [\"none\", \"null\", \"n/a\", \"na\"].includes(normalized.toLowerCase())\n )\n return undefined;\n return normalized;\n}\n\n/** Normalize a graph target while removing the historical no-blocker marker. */\nfunction normalizeDependencyGraphTarget(target: unknown): string | undefined {\n const normalized = normalizeDependencyReferenceTarget(target);\n return normalized?.toLowerCase() === \"no-active-blocker\"\n ? undefined\n : normalized;\n}\n\n/**\n * Classify missing hierarchy and dependency targets without mutating their holders.\n *\n * Consumers provide the workspace's terminal-status predicate so custom lifecycle\n * schemas receive the same active-versus-historical behavior as the built-in\n * closed/canceled statuses.\n */\nexport function collectDanglingDependencyReferences(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DanglingDependencyReferenceSummary {\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const knownIds = new Set(\n safeItems.map((item) => item.id.trim().toLowerCase()),\n );\n const rows = new Map<string, DanglingDependencyReference>();\n const addReference = (\n item: DependencyReferenceHolder,\n target: unknown,\n kind: string,\n source: DependencyReferenceSource,\n ): void => {\n const normalized = normalizeDependencyReferenceTarget(target);\n if (!normalized || knownIds.has(normalized.toLowerCase())) {\n return;\n }\n const row: DanglingDependencyReference = {\n holder_id: item.id.trim(),\n target_id: normalized,\n kind,\n source,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n no_active_blocker_sentinel:\n normalized.toLowerCase() === \"no-active-blocker\",\n };\n rows.set(\n `${row.holder_id}::${row.target_id}::${row.kind}::${row.source}`,\n row,\n );\n };\n for (const item of safeItems) {\n addReference(item, item.parent, \"parent\", \"parent\");\n addReference(item, item.blocked_by, \"blocked_by\", \"blocked_by\");\n for (const dependency of item.dependencies ?? []) {\n // Public SDK callers may supply legacy or JSON-decoded payloads that do\n // not yet satisfy the current structured dependency contract.\n if (typeof dependency !== \"object\" || dependency === null) {\n continue;\n }\n const legacyDependency = dependency as Partial<Dependency>;\n addReference(\n item,\n legacyDependency.id,\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\",\n \"dependency\",\n );\n }\n }\n const sorted = [...rows.values()].sort(\n (left, right) =>\n left.holder_id.localeCompare(right.holder_id) ||\n left.target_id.localeCompare(right.target_id) ||\n left.kind.localeCompare(right.kind) ||\n left.source.localeCompare(right.source),\n );\n const legacyTerminal = sorted.filter((row) => row.legacy_terminal);\n return {\n active: sorted.filter((row) => !row.legacy_terminal),\n legacy_terminal: legacyTerminal,\n no_active_blocker_sentinels: sorted.filter(\n (row) => row.no_active_blocker_sentinel,\n ),\n };\n}\n\n/** Return unique real missing targets while excluding the legacy no-blocker sentinel. */\nexport function collectMissingDependencyTargetIds(\n dangling: DanglingDependencyReferenceSummary,\n): string[] {\n const targets = new Map<string, string>();\n for (const reference of [...dangling.active, ...dangling.legacy_terminal]) {\n if (reference.no_active_blocker_sentinel) continue;\n const target = reference.target_id.trim();\n const key = target.toLowerCase();\n if (!targets.has(key)) targets.set(key, target);\n }\n return [...targets.values()].sort((left, right) => left.localeCompare(right));\n}\n\n/** Item shape accepted by workspace relationship-graph assembly. */\nexport interface WorkspaceRelationshipItem extends DependencyReferenceHolder {\n /** Human-readable title projected into per-node details. */\n title: string;\n}\n\n/** Compact node projection paired with the assembled graph. */\nexport interface WorkspaceRelationshipNodeDetails {\n /** Stable node identifier. */\n id: string;\n /** Human-readable node title, or a `[missing]` marker for absent endpoints. */\n title: string;\n /** Lifecycle status, or the `missing` marker status for absent endpoints. */\n status: string;\n}\n\n/** Assembled workspace relationship graph with governance side-products. */\nexport interface WorkspaceRelationshipAssembly {\n /** Deterministic relationship graph including missing placeholder nodes. */\n graph: RelationshipGraph;\n /** Per-node compact details covering real and missing nodes. */\n details: WorkspaceRelationshipNodeDetails[];\n /** Lowercased identifiers of materialized missing endpoints. */\n missingIdSet: Set<string>;\n /** Dangling-reference classification computed during assembly. */\n dangling: DanglingDependencyReferenceSummary;\n}\n\n/**\n * Build the shared workspace relationship graph including missing placeholder\n * nodes. One assembly serves every bounded query in an invocation — dependency\n * trees, context packets, impact analysis, path enumeration, and governance\n * audits — so the full-workspace normalization cost is paid once instead of\n * once per query surface.\n */\nexport function assembleWorkspaceRelationshipGraph(\n items: readonly WorkspaceRelationshipItem[],\n isTerminal?: (status: ItemStatus) => boolean,\n registry?: RelationshipKindRegistry,\n): WorkspaceRelationshipAssembly {\n const relationshipRegistry = registry ?? createRelationshipKindRegistry();\n if (registry === undefined) {\n // Preserve compatibility with activation payloads produced before this registry existed.\n for (const registration of\n getActiveExtensionRegistrations()?.relationship_kinds ?? []) {\n for (const definition of registration.definitions) {\n relationshipRegistry.register(definition);\n }\n }\n }\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const canonicalIds = new Map(\n safeItems.map((item) => [item.id.trim().toLowerCase(), item.id.trim()]),\n );\n const dangling = collectDanglingDependencyReferences(safeItems, isTerminal);\n const missingIds = collectMissingDependencyTargetIds(dangling);\n for (const id of missingIds) canonicalIds.set(id.toLowerCase(), id);\n const graphItems = safeItems.map((item) => {\n const parent = normalizeDependencyGraphTarget(item.parent);\n const blocker = normalizeDependencyGraphTarget(item.blocked_by);\n const dependencies = (item.dependencies ?? []).flatMap((rawDependency) => {\n if (typeof rawDependency !== \"object\" || rawDependency === null)\n return [];\n const dependency = rawDependency as Partial<Dependency>;\n const target = normalizeDependencyGraphTarget(dependency.id);\n if (!target) return [];\n return [\n {\n id: canonicalIds.get(target.toLowerCase())!,\n kind:\n typeof dependency.kind === \"string\" ? dependency.kind : \"related\",\n },\n ];\n });\n return {\n id: item.id.trim(),\n ...(parent ? { parent: canonicalIds.get(parent.toLowerCase())! } : {}),\n ...(blocker\n ? { blocked_by: canonicalIds.get(blocker.toLowerCase())! }\n : {}),\n dependencies,\n };\n });\n return {\n graph: RelationshipGraph.fromItems(\n [...graphItems, ...missingIds.map((id) => ({ id }))],\n relationshipRegistry,\n ),\n details: [\n ...safeItems.map((item) => ({\n id: item.id.trim(),\n title: item.title,\n status: item.status,\n })),\n ...missingIds.map((id) => ({\n id,\n title: `[missing] ${id}`,\n status: \"missing\",\n })),\n ],\n missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),\n dangling,\n };\n}\n"],"names":[],"mappings":"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","debugId":"987f91a5-6f98-55f4-b39b-5fb8b816c95a"}
|
|
1
|
+
{"version":3,"file":"assembly.js","sources":["sdk/graph/assembly.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/graph/assembly\n *\n * Builds the shared workspace relationship graph consumed by dependency\n * queries, bounded context packets, impact analysis, and governance audits.\n * Assembly normalizes hierarchy, legacy scalar blockers, and structured\n * dependency edges into one deterministic {@link RelationshipGraph}, classifies\n * dangling references without mutating their holders, and materializes missing\n * endpoints as placeholder nodes so bounded traversals can explain absent work\n * instead of silently dropping it.\n */\nimport type { Dependency, ItemStatus } from \"../../types/index.js\";\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport {\n RelationshipGraph,\n createRelationshipKindRegistry,\n type RelationshipKindRegistry,\n} from \"../relationships.js\";\n\n/** Minimal item shape inspected by dependency-reference governance. */\nexport interface DependencyReferenceHolder {\n /** Stable item identifier. */\n id: string;\n /** Lifecycle status used to separate actionable work from historical debt. */\n status: ItemStatus;\n /** Optional hierarchy parent reference. */\n parent?: string;\n /** Optional legacy scalar blocker reference. */\n blocked_by?: string;\n /** Structured dependency edges. */\n dependencies?: Dependency[];\n}\n\n/** Storage surface that contributed a normalized dependency reference. */\nexport type DependencyReferenceSource = \"parent\" | \"blocked_by\" | \"dependency\";\n\n/** One normalized dependency reference whose target is absent from the tracker. */\nexport interface DanglingDependencyReference {\n /** Item that owns the reference. */\n holder_id: string;\n /** Missing referenced item id or legacy sentinel. */\n target_id: string;\n /** Relationship field or dependency kind. */\n kind: string;\n /** Storage surface that owns the reference and determines its remediation. */\n source: DependencyReferenceSource;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and therefore historical, non-actionable debt. */\n legacy_terminal: boolean;\n /** Whether the target is the pre-structured-dependency `no-active-blocker` sentinel. */\n no_active_blocker_sentinel: boolean;\n}\n\n/** Actionable and historical partitions returned by dependency-reference governance. */\nexport interface DanglingDependencyReferenceSummary {\n /** Missing references held by active items; these may affect scheduling and should gate validation. */\n active: DanglingDependencyReference[];\n /** Missing references held only by terminal items; retained as informational history debt. */\n legacy_terminal: DanglingDependencyReference[];\n /** Legacy sentinel rows across active and terminal holders, called out separately from typo-like ids. */\n no_active_blocker_sentinels: DanglingDependencyReference[];\n}\n\n/** Normalize a decoded reference target and reject empty legacy placeholders. */\nfunction normalizeDependencyReferenceTarget(\n target: unknown,\n): string | undefined {\n if (typeof target !== \"string\") return undefined;\n const normalized = target.trim();\n if (\n !normalized ||\n [\"none\", \"null\", \"n/a\", \"na\"].includes(normalized.toLowerCase())\n )\n return undefined;\n return normalized;\n}\n\n/** Normalize a graph target while removing the historical no-blocker marker. */\nexport function normalizeDependencyGraphTarget(\n target: unknown,\n): string | undefined {\n const normalized = normalizeDependencyReferenceTarget(target);\n return normalized?.toLowerCase() === \"no-active-blocker\"\n ? undefined\n : normalized;\n}\n\n/**\n * Resolve the default workspace relationship-kind registry: the built-in kinds\n * merged with every active extension-contributed relationship-kind\n * registration. Assembly, mutation advisories, and standalone graph consumers\n * share this resolution so custom ordering semantics apply identically on\n * every surface.\n */\nexport function resolveWorkspaceRelationshipKindRegistry(): RelationshipKindRegistry {\n const registry = createRelationshipKindRegistry();\n for (const registration of getActiveExtensionRegistrations()\n ?.relationship_kinds ?? []) {\n for (const definition of registration.definitions) {\n registry.register(definition);\n }\n }\n return registry;\n}\n\n/** One raw stored dependency row duplicated verbatim on a single holder. */\nexport interface DuplicateDependencyRow {\n /** Item that stores the duplicated row. */\n holder_id: string;\n /** Referenced target id in its first stored spelling. */\n target_id: string;\n /** Stored relationship kind shared by every duplicate occurrence. */\n kind: string;\n /** Total stored occurrences of the identical row (always >= 2). */\n occurrences: number;\n /** Current lifecycle status of the holder. */\n holder_status: ItemStatus;\n /** Whether the holder is terminal and the duplication is historical debt. */\n legacy_terminal: boolean;\n}\n\n/** Compare text case-insensitively with an exact-spelling deterministic tie-breaker. */\nfunction compareCaseFoldedText(left: string, right: string): number {\n const normalizedLeft = left.toLowerCase();\n const normalizedRight = right.toLowerCase();\n if (normalizedLeft !== normalizedRight)\n return normalizedLeft < normalizedRight ? -1 : 1;\n if (left !== right) return left < right ? -1 : 1;\n return 0;\n}\n\n/** Count one holder's dependency rows by their case-insensitive kind-plus-target identity. */\nfunction countDependencyRowIdentities(\n item: DependencyReferenceHolder,\n): Map<string, { target_id: string; kind: string; count: number }> {\n const occurrences = new Map<\n string,\n { target_id: string; kind: string; count: number }\n >();\n for (const dependency of item.dependencies ?? []) {\n if (typeof dependency !== \"object\" || dependency === null) continue;\n const legacyDependency = dependency as Partial<Dependency>;\n const target = normalizeDependencyReferenceTarget(legacyDependency.id);\n if (!target) continue;\n const kind =\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\";\n const key = `${kind}\\u0000${target.toLowerCase()}`;\n const existing = occurrences.get(key);\n if (existing) existing.count += 1;\n else occurrences.set(key, { target_id: target, kind, count: 1 });\n }\n return occurrences;\n}\n\n/**\n * Collect raw stored dependency rows whose exact identity — holder, kind, and\n * case-insensitive target — appears more than once on one item. Graph\n * construction deduplicates these by edge identity, so the assembled graph and\n * every projection built on it cannot see them; this pre-assembly scan is the\n * only surface that reports the storage-layer defect.\n */\nexport function collectDuplicateDependencyRows(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DuplicateDependencyRow[] {\n const rows: DuplicateDependencyRow[] = [];\n for (const item of items) {\n if (typeof item?.id !== \"string\" || item.id.trim().length === 0) continue;\n for (const entry of countDependencyRowIdentities(item).values()) {\n if (entry.count < 2) continue;\n rows.push({\n holder_id: item.id.trim(),\n target_id: entry.target_id,\n kind: entry.kind,\n occurrences: entry.count,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n });\n }\n }\n return rows.sort((left, right) => {\n const holderCompare = compareCaseFoldedText(\n left.holder_id,\n right.holder_id,\n );\n if (holderCompare !== 0) return holderCompare;\n const targetCompare = compareCaseFoldedText(\n left.target_id,\n right.target_id,\n );\n if (targetCompare !== 0) return targetCompare;\n return compareCaseFoldedText(left.kind, right.kind);\n });\n}\n\n/**\n * Classify missing hierarchy and dependency targets without mutating their holders.\n *\n * Consumers provide the workspace's terminal-status predicate so custom lifecycle\n * schemas receive the same active-versus-historical behavior as the built-in\n * closed/canceled statuses.\n */\nexport function collectDanglingDependencyReferences(\n items: readonly DependencyReferenceHolder[],\n isTerminal: (status: ItemStatus) => boolean = (status) =>\n status === \"closed\" || status === \"canceled\",\n): DanglingDependencyReferenceSummary {\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const knownIds = new Set(\n safeItems.map((item) => item.id.trim().toLowerCase()),\n );\n const rows = new Map<string, DanglingDependencyReference>();\n const addReference = (\n item: DependencyReferenceHolder,\n target: unknown,\n kind: string,\n source: DependencyReferenceSource,\n ): void => {\n const normalized = normalizeDependencyReferenceTarget(target);\n if (!normalized || knownIds.has(normalized.toLowerCase())) {\n return;\n }\n const row: DanglingDependencyReference = {\n holder_id: item.id.trim(),\n target_id: normalized,\n kind,\n source,\n holder_status: item.status,\n legacy_terminal: isTerminal(item.status),\n no_active_blocker_sentinel:\n normalized.toLowerCase() === \"no-active-blocker\",\n };\n rows.set(\n `${row.holder_id}::${row.target_id}::${row.kind}::${row.source}`,\n row,\n );\n };\n for (const item of safeItems) {\n addReference(item, item.parent, \"parent\", \"parent\");\n addReference(item, item.blocked_by, \"blocked_by\", \"blocked_by\");\n for (const dependency of item.dependencies ?? []) {\n // Public SDK callers may supply legacy or JSON-decoded payloads that do\n // not yet satisfy the current structured dependency contract.\n if (typeof dependency !== \"object\" || dependency === null) {\n continue;\n }\n const legacyDependency = dependency as Partial<Dependency>;\n addReference(\n item,\n legacyDependency.id,\n typeof legacyDependency.kind === \"string\"\n ? legacyDependency.kind\n : \"related\",\n \"dependency\",\n );\n }\n }\n const sorted = [...rows.values()].sort(\n (left, right) =>\n left.holder_id.localeCompare(right.holder_id) ||\n left.target_id.localeCompare(right.target_id) ||\n left.kind.localeCompare(right.kind) ||\n left.source.localeCompare(right.source),\n );\n const legacyTerminal = sorted.filter((row) => row.legacy_terminal);\n return {\n active: sorted.filter((row) => !row.legacy_terminal),\n legacy_terminal: legacyTerminal,\n no_active_blocker_sentinels: sorted.filter(\n (row) => row.no_active_blocker_sentinel,\n ),\n };\n}\n\n/** Return unique real missing targets while excluding the legacy no-blocker sentinel. */\nexport function collectMissingDependencyTargetIds(\n dangling: DanglingDependencyReferenceSummary,\n): string[] {\n const targets = new Map<string, string>();\n for (const reference of [...dangling.active, ...dangling.legacy_terminal]) {\n if (reference.no_active_blocker_sentinel) continue;\n const target = reference.target_id.trim();\n const key = target.toLowerCase();\n if (!targets.has(key)) targets.set(key, target);\n }\n return [...targets.values()].sort((left, right) => left.localeCompare(right));\n}\n\n/** Item shape accepted by workspace relationship-graph assembly. */\nexport interface WorkspaceRelationshipItem extends DependencyReferenceHolder {\n /** Human-readable title projected into per-node details. */\n title: string;\n /** Optional item type powering per-type coverage profiles and policies. */\n type?: string;\n}\n\n/** Compact node projection paired with the assembled graph. */\nexport interface WorkspaceRelationshipNodeDetails {\n /** Stable node identifier. */\n id: string;\n /** Human-readable node title, or a `[missing]` marker for absent endpoints. */\n title: string;\n /** Lifecycle status, or the `missing` marker status for absent endpoints. */\n status: string;\n /** Item type when the source item declared one; absent on missing placeholders. */\n type?: string;\n}\n\n/** Assembled workspace relationship graph with governance side-products. */\nexport interface WorkspaceRelationshipAssembly {\n /** Deterministic relationship graph including missing placeholder nodes. */\n graph: RelationshipGraph;\n /** Per-node compact details covering real and missing nodes. */\n details: WorkspaceRelationshipNodeDetails[];\n /** Lowercased identifiers of materialized missing endpoints. */\n missingIdSet: Set<string>;\n /** Dangling-reference classification computed during assembly. */\n dangling: DanglingDependencyReferenceSummary;\n /** Raw same-identity duplicated dependency rows found before graph dedup. */\n duplicateRows: DuplicateDependencyRow[];\n}\n\n/**\n * Build the shared workspace relationship graph including missing placeholder\n * nodes. One assembly serves every bounded query in an invocation — dependency\n * trees, context packets, impact analysis, path enumeration, and governance\n * audits — so the full-workspace normalization cost is paid once instead of\n * once per query surface.\n */\nexport function assembleWorkspaceRelationshipGraph(\n items: readonly WorkspaceRelationshipItem[],\n isTerminal?: (status: ItemStatus) => boolean,\n registry?: RelationshipKindRegistry,\n): WorkspaceRelationshipAssembly {\n const relationshipRegistry =\n registry ?? resolveWorkspaceRelationshipKindRegistry();\n const safeItems = items.filter(\n (item) => typeof item?.id === \"string\" && item.id.trim().length > 0,\n );\n const canonicalIds = new Map(\n safeItems.map((item) => [item.id.trim().toLowerCase(), item.id.trim()]),\n );\n const dangling = collectDanglingDependencyReferences(safeItems, isTerminal);\n const missingIds = collectMissingDependencyTargetIds(dangling);\n for (const id of missingIds) canonicalIds.set(id.toLowerCase(), id);\n const graphItems = safeItems.map((item) => {\n const parent = normalizeDependencyGraphTarget(item.parent);\n const blocker = normalizeDependencyGraphTarget(item.blocked_by);\n const dependencies = (item.dependencies ?? []).flatMap((rawDependency) => {\n if (typeof rawDependency !== \"object\" || rawDependency === null)\n return [];\n const dependency = rawDependency as Partial<Dependency>;\n const target = normalizeDependencyGraphTarget(dependency.id);\n if (!target) return [];\n return [\n {\n id: canonicalIds.get(target.toLowerCase())!,\n kind:\n typeof dependency.kind === \"string\" ? dependency.kind : \"related\",\n },\n ];\n });\n return {\n id: item.id.trim(),\n ...(parent ? { parent: canonicalIds.get(parent.toLowerCase())! } : {}),\n ...(blocker\n ? { blocked_by: canonicalIds.get(blocker.toLowerCase())! }\n : {}),\n dependencies,\n };\n });\n return {\n graph: RelationshipGraph.fromItems(\n [...graphItems, ...missingIds.map((id) => ({ id }))],\n relationshipRegistry,\n ),\n details: [\n ...safeItems.map((item) => ({\n id: item.id.trim(),\n title: item.title,\n status: item.status,\n ...(typeof item.type === \"string\" && item.type.trim().length > 0\n ? { type: item.type.trim() }\n : {}),\n })),\n ...missingIds.map((id) => ({\n id,\n title: `[missing] ${id}`,\n status: \"missing\",\n })),\n ],\n missingIdSet: new Set(missingIds.map((id) => id.toLowerCase())),\n dangling,\n duplicateRows: collectDuplicateDependencyRows(safeItems, isTerminal),\n };\n}\n"],"names":[],"mappings":"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","debugId":"208d0dcd-c6b6-5959-acdb-6969b1005edd"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ItemStatus } from "../../types/index.js";
|
|
2
|
+
import { type RelationshipKindRegistry } from "../relationships.js";
|
|
2
3
|
import type { WorkspaceRelationshipAssembly, WorkspaceRelationshipItem } from "./assembly.js";
|
|
3
4
|
/** Cache observability attached to graph result envelopes. */
|
|
4
5
|
export interface GraphCacheMetadata {
|
|
@@ -8,6 +9,8 @@ export interface GraphCacheMetadata {
|
|
|
8
9
|
assembly: "hit" | "miss";
|
|
9
10
|
/** Whether the full query result was reused from cache. */
|
|
10
11
|
result: "hit" | "miss";
|
|
12
|
+
/** Durable cross-process index disposition: answered from it, missed it, or persistence disabled for this workspace. Absent on surfaces that never consult the durable index. */
|
|
13
|
+
durable?: "hit" | "miss" | "off";
|
|
11
14
|
}
|
|
12
15
|
/**
|
|
13
16
|
* Compute the deterministic workspace graph fingerprint for one item snapshot.
|
|
@@ -16,7 +19,7 @@ export interface GraphCacheMetadata {
|
|
|
16
19
|
* folded in so schema changes to lifecycle semantics invalidate cached
|
|
17
20
|
* assemblies even when raw statuses are unchanged.
|
|
18
21
|
*/
|
|
19
|
-
export declare function computeWorkspaceGraphFingerprint(items: readonly WorkspaceRelationshipItem[], isTerminal?: (status: ItemStatus) => boolean): string;
|
|
22
|
+
export declare function computeWorkspaceGraphFingerprint(items: readonly WorkspaceRelationshipItem[], isTerminal?: (status: ItemStatus) => boolean, registry?: RelationshipKindRegistry): string;
|
|
20
23
|
/** One resolved cache lookup bound to a workspace snapshot. */
|
|
21
24
|
export interface WorkspaceGraphCacheLookup {
|
|
22
25
|
/** The (possibly reused) workspace assembly. */
|
package/dist/sdk/graph/cache.js
CHANGED
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
* reports hit/miss observability so envelopes can explain their freshness.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
!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]="
|
|
16
|
+
!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]="2131cf48-7b5e-5b17-bb53-65e8bf485100")}catch(e){}}();
|
|
17
17
|
import { createHash } from "node:crypto";
|
|
18
|
+
import { stableStringify } from "../../core/shared/serialization.js";
|
|
19
|
+
import { createRelationshipKindRegistry, } from "../relationships.js";
|
|
18
20
|
/** Default memoized query results retained per workspace entry. */
|
|
19
21
|
const DEFAULT_MAX_RESULTS_PER_WORKSPACE = 64;
|
|
20
22
|
/** Default workspace entries retained by one cache instance. */
|
|
@@ -38,6 +40,9 @@ function fingerprintLine(item, isTerminal) {
|
|
|
38
40
|
item.title,
|
|
39
41
|
item.status,
|
|
40
42
|
isTerminal(item.status) ? "1" : "0",
|
|
43
|
+
// Per-type coverage profiles make the item type a projection input, so a
|
|
44
|
+
// retype must invalidate cached assemblies and memoized audit results.
|
|
45
|
+
typeof item.type === "string" ? item.type.trim() : "",
|
|
41
46
|
item.parent ?? "",
|
|
42
47
|
item.blocked_by ?? "",
|
|
43
48
|
dependencies,
|
|
@@ -50,14 +55,22 @@ function fingerprintLine(item, isTerminal) {
|
|
|
50
55
|
* folded in so schema changes to lifecycle semantics invalidate cached
|
|
51
56
|
* assemblies even when raw statuses are unchanged.
|
|
52
57
|
*/
|
|
53
|
-
export function computeWorkspaceGraphFingerprint(items, isTerminal = (status) => status === "closed" || status === "canceled") {
|
|
58
|
+
export function computeWorkspaceGraphFingerprint(items, isTerminal = (status) => status === "closed" || status === "canceled", registry = createRelationshipKindRegistry()) {
|
|
54
59
|
const lines = items
|
|
55
60
|
.filter((item) => typeof item?.id === "string" && item.id.trim().length > 0)
|
|
56
61
|
.map((item) => fingerprintLine(item, isTerminal))
|
|
57
62
|
.sort();
|
|
63
|
+
const relationshipSemantics = registry
|
|
64
|
+
.list()
|
|
65
|
+
.map((definition) => stableStringify(definition))
|
|
66
|
+
.sort();
|
|
58
67
|
// Separate fields and records with control characters no stored field can
|
|
59
68
|
// contain unescaped, so adjacent free-text fields can never collide.
|
|
60
|
-
return createHash("sha256")
|
|
69
|
+
return createHash("sha256")
|
|
70
|
+
.update(lines.join("\u0001"))
|
|
71
|
+
.update("\u0002")
|
|
72
|
+
.update(relationshipSemantics.join("\u0001"))
|
|
73
|
+
.digest("hex");
|
|
61
74
|
}
|
|
62
75
|
/** Validate one optional positive-integer cache bound, applying its default. */
|
|
63
76
|
function requirePositiveCacheBound(name, value, fallback) {
|
|
@@ -145,4 +158,4 @@ export function resetWorkspaceGraphCache() {
|
|
|
145
158
|
sharedCache.clear();
|
|
146
159
|
}
|
|
147
160
|
//# sourceMappingURL=cache.js.map
|
|
148
|
-
//# debugId=
|
|
161
|
+
//# debugId=2131cf48-7b5e-5b17-bb53-65e8bf485100
|