@unbrained/pm-cli 2026.7.21 → 2026.7.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/CHANGELOG.md +25 -0
- package/dist/cli/bundle-integrity.js +3 -3
- package/dist/cli/bundle-integrity.js.map +1 -1
- package/dist/cli/commands/contracts.d.ts +5 -0
- package/dist/cli/commands/contracts.js +8 -6
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/copy.js +36 -20
- package/dist/cli/commands/copy.js.map +1 -1
- package/dist/cli/commands/create.js +48 -24
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/merge.d.ts +1 -1
- package/dist/cli/commands/merge.js +3 -3
- package/dist/cli/commands/merge.js.map +1 -1
- package/dist/cli/commands/restore.js +40 -22
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/update.js +12 -9
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/extension-command-help.js +3 -4
- package/dist/cli/extension-command-help.js.map +1 -1
- package/dist/cli/main.d.ts +3 -2
- package/dist/cli/main.js +6 -6
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +33 -21
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +63 -37
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/registration-helpers.d.ts +2 -0
- package/dist/cli/registration-helpers.js +3 -2
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli-bundle/bundle-manifest.json +349 -341
- package/dist/cli-bundle/chunks/{append-7OVFYR3C.js → append-CYMA7RJT.js} +5 -5
- package/dist/cli-bundle/chunks/append-H53CAPMP.js +11 -0
- package/dist/cli-bundle/chunks/{chunk-PFNHX655.js → chunk-2P7OK4WG.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-EJDGV4GR.js → chunk-3EBGHNNQ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-DZRV2OPA.js → chunk-3EDFN3VV.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ZOY5K4D3.js → chunk-3PWJWLLQ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VXOOB6YX.js → chunk-3SJAR3CY.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-GTLCVJOE.js → chunk-3WVKMF2A.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-LAV26CQG.js → chunk-42SYYKA4.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-NLR32VFS.js → chunk-4IXLNV7W.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BKIAH72N.js → chunk-4LTPHDKA.js} +39 -23
- package/dist/cli-bundle/chunks/chunk-4LTPHDKA.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-ABWCF646.js → chunk-4YTQVO3V.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-E5XMKOSB.js → chunk-5EBRMHI6.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-IY6VZ3IW.js → chunk-5FAG2JUC.js} +320 -62
- package/dist/cli-bundle/chunks/chunk-5FAG2JUC.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GKX4NJ7U.js → chunk-5K5LHZZX.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-T6PPNM7V.js → chunk-5K7BOAB6.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-4QOB7L7I.js → chunk-5MUZ54G2.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-SF3DT5HJ.js → chunk-5QME4KX2.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-RMF7LMBS.js → chunk-6PDGFY3P.js} +27 -17
- package/dist/cli-bundle/chunks/{chunk-RMF7LMBS.js.map → chunk-6PDGFY3P.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TRSHFPRZ.js → chunk-6PM6CPPP.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-O4BCOJTZ.js → chunk-7AHRY3ZB.js} +21 -16
- package/dist/cli-bundle/chunks/chunk-7AHRY3ZB.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-OR42SO64.js → chunk-7B36A3VT.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-QWRVBJ4D.js → chunk-7OR2YKKD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FPBMLYPI.js → chunk-7QUV54XX.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-WWNL6WMH.js → chunk-7WXW6JHG.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BXNDKOR2.js → chunk-A2VL5SVG.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-AXGDUXJW.js +5 -0
- package/dist/cli-bundle/chunks/{chunk-IAQE32BI.js → chunk-B2AVNGG3.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-K36WV5J6.js → chunk-B7O44UBR.js} +71 -8
- package/dist/cli-bundle/chunks/chunk-B7O44UBR.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-HCEBZNC3.js → chunk-BRMPF2RM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-Z7VWXXJM.js → chunk-BTNKMF2A.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-KH44WBAT.js → chunk-CD4643VW.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-OWXOPDHD.js → chunk-CJEEC5O4.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-PZC2FUOQ.js → chunk-CTPKCZCF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7W2UAXXT.js → chunk-D4OBQVL3.js} +10 -10
- package/dist/cli-bundle/chunks/{chunk-EWJWSNRU.js → chunk-DM4TYC2A.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-VJQG4BIM.js → chunk-DSFTAQ7T.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-AELMUANP.js → chunk-DVB6SQU7.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KBLZ3AA5.js → chunk-E3ZWOFSO.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-EP25DV6P.js +9 -0
- package/dist/cli-bundle/chunks/{chunk-GTK4DTEW.js → chunk-F4VCB4WY.js} +10 -10
- package/dist/cli-bundle/chunks/{chunk-V22ZPOKN.js → chunk-F4XAQUQA.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-QOOTOD3W.js → chunk-FGR6IBAF.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-JSLT7WVE.js → chunk-FKBMT2Q6.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-QIH77CAG.js → chunk-G5RLSSIX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-P7MTHPJQ.js → chunk-GEKRVH3G.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-2L6ZP22J.js → chunk-GSP6IZFU.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-ATBCUC7Y.js → chunk-H3MDK2VU.js} +48 -30
- package/dist/cli-bundle/chunks/chunk-H3MDK2VU.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-ZVZGXPQ5.js → chunk-HYZZM3Q2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XJTABV3X.js → chunk-IBWG3OSH.js} +22 -17
- package/dist/cli-bundle/chunks/chunk-IBWG3OSH.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-4XGJLADW.js → chunk-IHY5SX7O.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UCBDQI5E.js → chunk-IMU7JLUI.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-Z75ONV25.js → chunk-IPAQAJWB.js} +77 -7
- package/dist/cli-bundle/chunks/chunk-IPAQAJWB.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-7RW4JCU2.js → chunk-IQCD6OO3.js} +25 -13
- package/dist/cli-bundle/chunks/chunk-IQCD6OO3.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-YQWCZ5AC.js → chunk-J3ZKFEDM.js} +38 -22
- package/dist/cli-bundle/chunks/chunk-J3ZKFEDM.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-PEQGTJ5Q.js → chunk-JCLXCGIL.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-GROYI4RB.js → chunk-JLTHOYR7.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-JHJSFOAM.js → chunk-JMPVHM44.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-MATHDCGG.js → chunk-JWYG36RV.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-ZTVA4KLN.js → chunk-KEGVMZNA.js} +28 -16
- package/dist/cli-bundle/chunks/chunk-KEGVMZNA.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-VLRGDBLY.js → chunk-KEHOPUHH.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-K55VMLSS.js → chunk-KJ4ZF35M.js} +63 -13
- package/dist/cli-bundle/chunks/chunk-KJ4ZF35M.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-CPX275C6.js → chunk-KPCZL2YK.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-POG76WWZ.js → chunk-L7DZV6EZ.js} +319 -61
- package/dist/cli-bundle/chunks/chunk-L7DZV6EZ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-FO6OSVEN.js → chunk-LANV45W2.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-LVC72YRD.js → chunk-LC5ZUXWE.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-SY4SFZSD.js → chunk-LE522OXA.js} +55 -30
- package/dist/cli-bundle/chunks/chunk-LE522OXA.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-TVYYO5A7.js → chunk-MBHYQYCS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FJIFFBJX.js → chunk-MROP2RNT.js} +66 -74
- package/dist/cli-bundle/chunks/chunk-MROP2RNT.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-7656MAUL.js → chunk-MUAJHL2R.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-R3P6FZJW.js → chunk-N6QCY2AX.js} +43 -25
- package/dist/cli-bundle/chunks/chunk-N6QCY2AX.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-7WCE6Y64.js → chunk-NUQCSV4P.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SZVB53Y3.js → chunk-O3GFE2PX.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-OY7DMU5P.js → chunk-O43LEUSD.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-AMJPSANK.js → chunk-O7RH6BWP.js} +103 -44
- package/dist/cli-bundle/chunks/chunk-O7RH6BWP.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-NUF7ROFH.js → chunk-OODR5KYF.js} +26 -27
- package/dist/cli-bundle/chunks/chunk-OODR5KYF.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-LZYP423P.js → chunk-OZ25YD4Q.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-VZIZB6QH.js → chunk-PKYKQCTJ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-UZLJOEAC.js → chunk-PMRED6QZ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-ADBTSVGK.js → chunk-PPATPPI6.js} +65 -73
- package/dist/cli-bundle/chunks/chunk-PPATPPI6.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-K4CI6Y45.js → chunk-PWGJCP2V.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-UVN66B3M.js → chunk-Q3Z2Y5WJ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-RNPZYNHS.js → chunk-Q6YZ3VCI.js} +104 -45
- package/dist/cli-bundle/chunks/chunk-Q6YZ3VCI.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-7DOJC3HS.js → chunk-QE5EUHKN.js} +28 -18
- package/dist/cli-bundle/chunks/chunk-QE5EUHKN.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-AS4SAZ5R.js → chunk-QKMMWESK.js} +25 -26
- package/dist/cli-bundle/chunks/chunk-QKMMWESK.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-R7QV7ICM.js → chunk-QSXN2FAN.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-5NTE36LD.js → chunk-RBECHH5K.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-JXCW2TI2.js → chunk-RPNC7M63.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-ICDAQ4TD.js → chunk-S2QQNTA6.js} +26 -14
- package/dist/cli-bundle/chunks/chunk-S2QQNTA6.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-JFD5LPMI.js → chunk-SP3BAXFF.js} +29 -17
- package/dist/cli-bundle/chunks/chunk-SP3BAXFF.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-F2LBF7XJ.js → chunk-SUSFH6F7.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-VHXHVTUU.js → chunk-TDOPC7UY.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-HYW67VJ5.js → chunk-TLF52ZDP.js} +30 -25
- package/dist/cli-bundle/chunks/chunk-TLF52ZDP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-FSE2IKJQ.js → chunk-TWHG646K.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-OCUBRA6D.js → chunk-U7U7WGEC.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-PONKZPCJ.js → chunk-UFRVIIJ2.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-VNTCM3VW.js → chunk-VKX2VZZH.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-7AVEY74G.js → chunk-VTOCZ343.js} +29 -24
- package/dist/cli-bundle/chunks/chunk-VTOCZ343.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-6JUTHVQS.js → chunk-W2JDNTN3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-PQSEQD6E.js → chunk-W35PHE44.js} +62 -12
- package/dist/cli-bundle/chunks/chunk-W35PHE44.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-4QSQ6XDK.js → chunk-WT4KXBUD.js} +68 -31
- package/dist/cli-bundle/chunks/chunk-WT4KXBUD.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-RPESLSO5.js → chunk-XC5RVKHH.js} +69 -32
- package/dist/cli-bundle/chunks/chunk-XC5RVKHH.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-QG4GFLQ6.js → chunk-XD6UF2NB.js} +42 -24
- package/dist/cli-bundle/chunks/chunk-XD6UF2NB.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-AF2CCM5U.js → chunk-XKRVX4B3.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-JGUKMMRS.js → chunk-XN4NQZJK.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-3P7UJQOX.js → chunk-YKFMLQNK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-YCIUJJOD.js → chunk-YKWKMGL7.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-TOBGV45Y.js → chunk-YUKIFPWK.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-72LQ4TKV.js → chunk-YYEZEP3E.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-X3W65QK3.js → chunk-ZEY3XSZQ.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-MWQ2HC2A.js → chunk-ZKOQHLJP.js} +59 -34
- package/dist/cli-bundle/chunks/chunk-ZKOQHLJP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-QJIKE24M.js → chunk-ZQ3UMKWE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4PUUNQDV.js → chunk-ZVVEWHWK.js} +58 -33
- package/dist/cli-bundle/chunks/chunk-ZVVEWHWK.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-OG5DVFMA.js → chunk-ZXE6SNKO.js} +5 -5
- package/dist/cli-bundle/chunks/close-GAUIGOQC.js +12 -0
- package/dist/cli-bundle/chunks/{close-QEMOYZN3.js → close-SJIEKNY4.js} +5 -5
- package/dist/cli-bundle/chunks/{close-many-RZVTUGBG.js → close-many-B6AIC5OQ.js} +15 -14
- package/dist/cli-bundle/chunks/close-many-QCINT6I2.js +24 -0
- package/dist/cli-bundle/chunks/comments-4SK5EUEJ.js +13 -0
- package/dist/cli-bundle/chunks/{comments-TPU7QRBL.js → comments-DM5KV2RS.js} +7 -7
- package/dist/cli-bundle/chunks/copy-4KCCLTYQ.js +10 -0
- package/dist/cli-bundle/chunks/{copy-DKTSSCK7.js → copy-HEP5SZHB.js} +5 -4
- package/dist/cli-bundle/chunks/create-BDKQFPRE.js +30 -0
- package/dist/cli-bundle/chunks/{create-EIFBIVNQ.js → create-VCGBCYL2.js} +11 -10
- package/dist/cli-bundle/chunks/delete-JWDXPR3H.js +10 -0
- package/dist/cli-bundle/chunks/{delete-LCS3VPDH.js → delete-ZSPBTVJD.js} +4 -4
- package/dist/cli-bundle/chunks/{deps-YG7UF3VR.js → deps-BZTWWOIE.js} +6 -6
- package/dist/cli-bundle/chunks/{deps-UH5EQQUY.js → deps-OVAJOQIE.js} +6 -6
- package/dist/cli-bundle/chunks/{docs-G32TK6XS.js → docs-3GFMSWLL.js} +6 -6
- package/dist/cli-bundle/chunks/docs-SY2NPT6Y.js +14 -0
- package/dist/cli-bundle/chunks/{files-4ALMCSKB.js → files-2SEL4QIU.js} +6 -6
- package/dist/cli-bundle/chunks/{files-3H32UQ4K.js → files-FYMMJGNN.js} +6 -6
- package/dist/cli-bundle/chunks/focus-4A27YJ2Z.js +10 -0
- package/dist/cli-bundle/chunks/{focus-7SOUT5PZ.js → focus-TEUJKTAT.js} +5 -5
- package/dist/cli-bundle/chunks/history-compact-7QOKL2NB.js +16 -0
- package/dist/cli-bundle/chunks/{history-compact-77BT2LUB.js → history-compact-U7A37VR6.js} +6 -6
- package/dist/cli-bundle/chunks/{history-redact-LJPZPNFA.js → history-redact-TNKUO4ZE.js} +4 -4
- package/dist/cli-bundle/chunks/{history-redact-PWTTJ3XS.js → history-redact-ZWRUWQY3.js} +4 -4
- package/dist/cli-bundle/chunks/{history-repair-I7CBNCV3.js → history-repair-6IU5VWHN.js} +7 -7
- package/dist/cli-bundle/chunks/history-repair-GWCGJUM2.js +17 -0
- package/dist/cli-bundle/chunks/learnings-DDFAUUX3.js +13 -0
- package/dist/cli-bundle/chunks/{learnings-KTYW3AL7.js → learnings-GOEZXMKL.js} +7 -7
- package/dist/cli-bundle/chunks/{notes-ZERD3KB2.js → notes-BZWODAEK.js} +7 -7
- package/dist/cli-bundle/chunks/notes-OBJ6FL36.js +13 -0
- package/dist/cli-bundle/chunks/{plan-OFJUBIM5.js → plan-V57VQTAG.js} +12 -11
- package/dist/cli-bundle/chunks/plan-ZMOBD6FX.js +27 -0
- package/dist/cli-bundle/chunks/{profile-3THJPIQY.js → profile-BG3N4ETA.js} +9 -9
- package/dist/cli-bundle/chunks/{profile-XEZAMMBW.js → profile-XLM45FKV.js} +9 -9
- package/dist/cli-bundle/chunks/{register-list-query-BR435Q2H.js → register-list-query-EYYNTGMF.js} +48 -38
- package/dist/cli-bundle/chunks/register-list-query-EYYNTGMF.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-list-query-RWTWLOBE.js → register-list-query-WGXJPXXY.js} +47 -37
- package/dist/cli-bundle/chunks/register-list-query-WGXJPXXY.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-HLWC2WNP.js → register-mutation-3YSDDVOL.js} +131 -105
- package/dist/cli-bundle/chunks/register-mutation-3YSDDVOL.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-mutation-ZJX5AZM5.js → register-mutation-VDGUMMUY.js} +131 -105
- package/dist/cli-bundle/chunks/register-mutation-VDGUMMUY.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-operations-744YBJMV.js → register-operations-H4URGAHX.js} +36 -35
- package/dist/cli-bundle/chunks/{register-operations-744YBJMV.js.map → register-operations-H4URGAHX.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-operations-UEBJH6AN.js → register-operations-HSO7X77D.js} +34 -33
- package/dist/cli-bundle/chunks/{register-operations-UEBJH6AN.js.map → register-operations-HSO7X77D.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-setup-5DA4UZXI.js → register-setup-HZ2KKXK4.js} +13 -13
- package/dist/cli-bundle/chunks/{register-setup-6H25M3BH.js → register-setup-WCBKJ3H3.js} +13 -13
- package/dist/cli-bundle/chunks/{restore-6TDVSATY.js → restore-3NGRFDPX.js} +7 -6
- package/dist/cli-bundle/chunks/restore-LNVNUWHE.js +15 -0
- package/dist/cli-bundle/chunks/{schema-TPVTIJPO.js → schema-LMFZ742C.js} +6 -6
- package/dist/cli-bundle/chunks/{schema-HFXFSGPG.js → schema-O34O33UW.js} +6 -6
- package/dist/cli-bundle/chunks/update-BN6VZSYX.js +24 -0
- package/dist/cli-bundle/chunks/{update-LJZCL5SI.js → update-FDLPLKOB.js} +14 -13
- package/dist/cli-bundle/chunks/update-many-WCKOPN3K.js +35 -0
- package/dist/cli-bundle/chunks/update-many-WCKOPN3K.js.map +7 -0
- package/dist/cli-bundle/chunks/update-many-X6DVGOMM.js +39 -0
- package/dist/cli-bundle/chunks/update-many-X6DVGOMM.js.map +1 -0
- package/dist/cli-bundle/main.js +65 -64
- package/dist/cli-bundle/main.js.map +2 -2
- package/dist/cli-bundle/sdk-runtime.js +53 -52
- package/dist/cli-bundle/sdk-testing.js +6 -6
- package/dist/cli-bundle/sdk.js +362 -56
- package/dist/cli-bundle/sdk.js.map +4 -4
- package/dist/cli.js +10 -4
- package/dist/cli.js.map +1 -1
- package/dist/core/diagnostics/remediation.js +7 -2
- package/dist/core/diagnostics/remediation.js.map +1 -1
- package/dist/core/search/background-refresh.d.ts +3 -1
- package/dist/core/search/background-refresh.js +34 -6
- package/dist/core/search/background-refresh.js.map +1 -1
- package/dist/core/search/cache.js +28 -5
- package/dist/core/search/cache.js.map +1 -1
- package/dist/core/shared/constants.d.ts +2 -0
- package/dist/core/shared/constants.js +29 -24
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/store/item-metadata-cache.d.ts +32 -1
- package/dist/core/store/item-metadata-cache.js +289 -21
- package/dist/core/store/item-metadata-cache.js.map +1 -1
- package/dist/core/store/item-store.js +71 -34
- package/dist/core/store/item-store.js.map +1 -1
- package/dist/core/store/settings.js +9 -3
- package/dist/core/store/settings.js.map +1 -1
- package/dist/sdk/cli-bootstrap.js +68 -76
- package/dist/sdk/cli-bootstrap.js.map +1 -1
- package/dist/sdk/compile-cache.d.ts +16 -0
- package/dist/sdk/compile-cache.js +73 -0
- package/dist/sdk/compile-cache.js.map +1 -0
- package/dist/sdk/context-relevance.d.ts +16 -1
- package/dist/sdk/context-relevance.js +20 -8
- package/dist/sdk/context-relevance.js.map +1 -1
- package/dist/sdk/context-signal-store.d.ts +77 -0
- package/dist/sdk/context-signal-store.js +201 -0
- package/dist/sdk/context-signal-store.js.map +1 -0
- package/dist/sdk/dependency-provenance.d.ts +12 -0
- package/dist/sdk/dependency-provenance.js +38 -0
- package/dist/sdk/dependency-provenance.js.map +1 -0
- package/dist/sdk/governance/storage-integrity.d.ts +1 -1
- package/dist/sdk/governance/storage-integrity.js +47 -6
- package/dist/sdk/governance/storage-integrity.js.map +1 -1
- package/dist/sdk/graph/assembly.d.ts +2 -0
- package/dist/sdk/graph/assembly.js +51 -4
- package/dist/sdk/graph/assembly.js.map +1 -1
- package/dist/sdk/graph/run.js +12 -13
- package/dist/sdk/graph/run.js.map +1 -1
- package/dist/sdk/index.d.ts +5 -0
- package/dist/sdk/index.js +7 -2
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/item-metadata-index.d.ts +11 -0
- package/dist/sdk/item-metadata-index.js +15 -0
- package/dist/sdk/item-metadata-index.js.map +1 -0
- package/dist/sdk/merge/index.d.ts +1 -0
- package/dist/sdk/merge/index.js +3 -2
- package/dist/sdk/merge/index.js.map +1 -1
- package/dist/sdk/merge/install.js +25 -9
- package/dist/sdk/merge/install.js.map +1 -1
- package/dist/sdk/merge/reconcile.d.ts +46 -0
- package/dist/sdk/merge/reconcile.js +46 -0
- package/dist/sdk/merge/reconcile.js.map +1 -0
- package/dist/sdk/query/list.d.ts +5 -4
- package/dist/sdk/query/list.js +22 -14
- package/dist/sdk/query/list.js.map +1 -1
- package/dist/sdk/relationship-history.d.ts +30 -0
- package/dist/sdk/relationship-history.js +75 -7
- package/dist/sdk/relationship-history.js.map +1 -1
- package/dist/sdk/relationship-migration.d.ts +42 -0
- package/dist/sdk/relationship-migration.js +78 -0
- package/dist/sdk/relationship-migration.js.map +1 -0
- package/dist/sdk/structured-mutations.js +4 -25
- package/dist/sdk/structured-mutations.js.map +1 -1
- package/docs/COMMANDS.md +26 -3
- package/docs/CONFIGURATION.md +1 -1
- package/docs/MERGE_SAFETY.md +14 -5
- package/docs/PERFORMANCE.md +28 -0
- package/docs/RELATIONSHIP_GRAPH.md +47 -1
- package/docs/SDK.md +78 -5
- package/marketplace.json +2 -2
- package/package.json +2 -2
- 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-codex/.codex-plugin/plugin.json +1 -1
- package/dist/cli-bundle/chunks/append-DFETHAZL.js +0 -11
- package/dist/cli-bundle/chunks/chunk-4PUUNQDV.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-4QSQ6XDK.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7AVEY74G.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-7DOJC3HS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7RW4JCU2.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ADBTSVGK.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-AMJPSANK.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-AS4SAZ5R.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ATBCUC7Y.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-BKIAH72N.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-FJIFFBJX.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-HYW67VJ5.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-ICDAQ4TD.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-IY6VZ3IW.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-JFD5LPMI.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-K36WV5J6.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-K55VMLSS.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-MWQ2HC2A.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-NUF7ROFH.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-O4BCOJTZ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-POG76WWZ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-PQSEQD6E.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-QG4GFLQ6.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-R3P6FZJW.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-RNPZYNHS.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-RPESLSO5.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SY4SFZSD.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-XJTABV3X.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-YQWCZ5AC.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-Z75ONV25.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ZTVA4KLN.js.map +0 -7
- package/dist/cli-bundle/chunks/close-O5QVZ6ET.js +0 -12
- package/dist/cli-bundle/chunks/close-many-5RZXVN4J.js +0 -23
- package/dist/cli-bundle/chunks/comments-Z4KV6FU3.js +0 -13
- package/dist/cli-bundle/chunks/copy-M7DDI6LS.js +0 -9
- package/dist/cli-bundle/chunks/create-RGSPN5GD.js +0 -29
- package/dist/cli-bundle/chunks/delete-MD7YXQLH.js +0 -10
- package/dist/cli-bundle/chunks/docs-JWWNRC27.js +0 -14
- package/dist/cli-bundle/chunks/focus-DRQ6FQH6.js +0 -10
- package/dist/cli-bundle/chunks/history-compact-VCKGTX64.js +0 -16
- package/dist/cli-bundle/chunks/history-repair-YTDZRK5E.js +0 -17
- package/dist/cli-bundle/chunks/learnings-CYNOICKR.js +0 -13
- package/dist/cli-bundle/chunks/notes-FGO63FXL.js +0 -13
- package/dist/cli-bundle/chunks/plan-SGCDDTYR.js +0 -26
- package/dist/cli-bundle/chunks/register-list-query-BR435Q2H.js.map +0 -1
- package/dist/cli-bundle/chunks/register-list-query-RWTWLOBE.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-HLWC2WNP.js.map +0 -1
- package/dist/cli-bundle/chunks/register-mutation-ZJX5AZM5.js.map +0 -7
- package/dist/cli-bundle/chunks/restore-RSL7C7LO.js +0 -14
- package/dist/cli-bundle/chunks/update-SIA7LH5Y.js +0 -23
- package/dist/cli-bundle/chunks/update-many-BDBZVGQL.js +0 -38
- package/dist/cli-bundle/chunks/update-many-MOY3A5B3.js +0 -34
- /package/dist/cli-bundle/chunks/{append-7OVFYR3C.js.map → append-CYMA7RJT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-DFETHAZL.js.map → append-H53CAPMP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PFNHX655.js.map → chunk-2P7OK4WG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EJDGV4GR.js.map → chunk-3EBGHNNQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DZRV2OPA.js.map → chunk-3EDFN3VV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZOY5K4D3.js.map → chunk-3PWJWLLQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VXOOB6YX.js.map → chunk-3SJAR3CY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GTLCVJOE.js.map → chunk-3WVKMF2A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LAV26CQG.js.map → chunk-42SYYKA4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NLR32VFS.js.map → chunk-4IXLNV7W.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ABWCF646.js.map → chunk-4YTQVO3V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-E5XMKOSB.js.map → chunk-5EBRMHI6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GKX4NJ7U.js.map → chunk-5K5LHZZX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-T6PPNM7V.js.map → chunk-5K7BOAB6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4QOB7L7I.js.map → chunk-5MUZ54G2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SF3DT5HJ.js.map → chunk-5QME4KX2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TRSHFPRZ.js.map → chunk-6PM6CPPP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OR42SO64.js.map → chunk-7B36A3VT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QWRVBJ4D.js.map → chunk-7OR2YKKD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FPBMLYPI.js.map → chunk-7QUV54XX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-WWNL6WMH.js.map → chunk-7WXW6JHG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BXNDKOR2.js.map → chunk-A2VL5SVG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-QEMOYZN3.js.map → chunk-AXGDUXJW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IAQE32BI.js.map → chunk-B2AVNGG3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HCEBZNC3.js.map → chunk-BRMPF2RM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-Z7VWXXJM.js.map → chunk-BTNKMF2A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KH44WBAT.js.map → chunk-CD4643VW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OWXOPDHD.js.map → chunk-CJEEC5O4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PZC2FUOQ.js.map → chunk-CTPKCZCF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7W2UAXXT.js.map → chunk-D4OBQVL3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EWJWSNRU.js.map → chunk-DM4TYC2A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VJQG4BIM.js.map → chunk-DSFTAQ7T.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AELMUANP.js.map → chunk-DVB6SQU7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KBLZ3AA5.js.map → chunk-E3ZWOFSO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-O5QVZ6ET.js.map → chunk-EP25DV6P.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GTK4DTEW.js.map → chunk-F4VCB4WY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-V22ZPOKN.js.map → chunk-F4XAQUQA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QOOTOD3W.js.map → chunk-FGR6IBAF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JSLT7WVE.js.map → chunk-FKBMT2Q6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QIH77CAG.js.map → chunk-G5RLSSIX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-P7MTHPJQ.js.map → chunk-GEKRVH3G.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2L6ZP22J.js.map → chunk-GSP6IZFU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZVZGXPQ5.js.map → chunk-HYZZM3Q2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4XGJLADW.js.map → chunk-IHY5SX7O.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UCBDQI5E.js.map → chunk-IMU7JLUI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PEQGTJ5Q.js.map → chunk-JCLXCGIL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GROYI4RB.js.map → chunk-JLTHOYR7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JHJSFOAM.js.map → chunk-JMPVHM44.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-MATHDCGG.js.map → chunk-JWYG36RV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VLRGDBLY.js.map → chunk-KEHOPUHH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CPX275C6.js.map → chunk-KPCZL2YK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FO6OSVEN.js.map → chunk-LANV45W2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LVC72YRD.js.map → chunk-LC5ZUXWE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TVYYO5A7.js.map → chunk-MBHYQYCS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7656MAUL.js.map → chunk-MUAJHL2R.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7WCE6Y64.js.map → chunk-NUQCSV4P.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SZVB53Y3.js.map → chunk-O3GFE2PX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OY7DMU5P.js.map → chunk-O43LEUSD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LZYP423P.js.map → chunk-OZ25YD4Q.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VZIZB6QH.js.map → chunk-PKYKQCTJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UZLJOEAC.js.map → chunk-PMRED6QZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-K4CI6Y45.js.map → chunk-PWGJCP2V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UVN66B3M.js.map → chunk-Q3Z2Y5WJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-R7QV7ICM.js.map → chunk-QSXN2FAN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-5NTE36LD.js.map → chunk-RBECHH5K.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JXCW2TI2.js.map → chunk-RPNC7M63.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-F2LBF7XJ.js.map → chunk-SUSFH6F7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VHXHVTUU.js.map → chunk-TDOPC7UY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FSE2IKJQ.js.map → chunk-TWHG646K.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OCUBRA6D.js.map → chunk-U7U7WGEC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-PONKZPCJ.js.map → chunk-UFRVIIJ2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VNTCM3VW.js.map → chunk-VKX2VZZH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6JUTHVQS.js.map → chunk-W2JDNTN3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AF2CCM5U.js.map → chunk-XKRVX4B3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JGUKMMRS.js.map → chunk-XN4NQZJK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3P7UJQOX.js.map → chunk-YKFMLQNK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-YCIUJJOD.js.map → chunk-YKWKMGL7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TOBGV45Y.js.map → chunk-YUKIFPWK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-72LQ4TKV.js.map → chunk-YYEZEP3E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-X3W65QK3.js.map → chunk-ZEY3XSZQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QJIKE24M.js.map → chunk-ZQ3UMKWE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OG5DVFMA.js.map → chunk-ZXE6SNKO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-5RZXVN4J.js.map → close-GAUIGOQC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-RZVTUGBG.js.map → close-SJIEKNY4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-TPU7QRBL.js.map → close-many-B6AIC5OQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-Z4KV6FU3.js.map → close-many-QCINT6I2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-M7DDI6LS.js.map → comments-4SK5EUEJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-DKTSSCK7.js.map → comments-DM5KV2RS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-RGSPN5GD.js.map → copy-4KCCLTYQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-EIFBIVNQ.js.map → copy-HEP5SZHB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-MD7YXQLH.js.map → create-BDKQFPRE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-LCS3VPDH.js.map → create-VCGBCYL2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-YG7UF3VR.js.map → delete-JWDXPR3H.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-UH5EQQUY.js.map → delete-ZSPBTVJD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-JWWNRC27.js.map → deps-BZTWWOIE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-G32TK6XS.js.map → deps-OVAJOQIE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-3H32UQ4K.js.map → docs-3GFMSWLL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-4ALMCSKB.js.map → docs-SY2NPT6Y.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-DRQ6FQH6.js.map → files-2SEL4QIU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-7SOUT5PZ.js.map → files-FYMMJGNN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-VCKGTX64.js.map → focus-4A27YJ2Z.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-77BT2LUB.js.map → focus-TEUJKTAT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-PWTTJ3XS.js.map → history-compact-7QOKL2NB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-LJPZPNFA.js.map → history-compact-U7A37VR6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-I7CBNCV3.js.map → history-redact-TNKUO4ZE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-YTDZRK5E.js.map → history-redact-ZWRUWQY3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-KTYW3AL7.js.map → history-repair-6IU5VWHN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-CYNOICKR.js.map → history-repair-GWCGJUM2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-FGO63FXL.js.map → learnings-DDFAUUX3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-ZERD3KB2.js.map → learnings-GOEZXMKL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-OFJUBIM5.js.map → notes-BZWODAEK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-SGCDDTYR.js.map → notes-OBJ6FL36.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-3THJPIQY.js.map → plan-V57VQTAG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-XEZAMMBW.js.map → plan-ZMOBD6FX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-6TDVSATY.js.map → profile-BG3N4ETA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-RSL7C7LO.js.map → profile-XLM45FKV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-5DA4UZXI.js.map → register-setup-HZ2KKXK4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{register-setup-6H25M3BH.js.map → register-setup-WCBKJ3H3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-TPVTIJPO.js.map → restore-3NGRFDPX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-HFXFSGPG.js.map → restore-LNVNUWHE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-LJZCL5SI.js.map → schema-LMFZ742C.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-SIA7LH5Y.js.map → schema-O34O33UW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-MOY3A5B3.js.map → update-BN6VZSYX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-BDBZVGQL.js.map → update-FDLPLKOB.js.map} +0 -0
|
@@ -83,6 +83,27 @@ export interface RelationshipEventStoreOptions extends RelationshipEventLogOptio
|
|
|
83
83
|
/** Optional JSONL path relative to the tracker root. */
|
|
84
84
|
relativePath?: string;
|
|
85
85
|
}
|
|
86
|
+
/** Collision policy applied while publishing a durable event batch. */
|
|
87
|
+
export type RelationshipExistingEventPolicy = "error" | "skip_identical";
|
|
88
|
+
/** Controls for one atomic durable relationship-event batch. */
|
|
89
|
+
export interface RelationshipEventBatchOptions {
|
|
90
|
+
/**
|
|
91
|
+
* Existing event ids fail by default. Migration resume flows may skip an id
|
|
92
|
+
* only when every persisted semantic field is identical to the input.
|
|
93
|
+
*/
|
|
94
|
+
existingEventPolicy?: RelationshipExistingEventPolicy;
|
|
95
|
+
}
|
|
96
|
+
/** Result of one validated, atomic durable relationship-event batch. */
|
|
97
|
+
export interface RelationshipEventBatchResult {
|
|
98
|
+
/** Durable stream version observed while holding the writer lock. */
|
|
99
|
+
version_before: number;
|
|
100
|
+
/** Durable stream version after the atomic publication. */
|
|
101
|
+
version_after: number;
|
|
102
|
+
/** Immutable sequenced events newly published by this call. */
|
|
103
|
+
appended: readonly RelationshipEvent[];
|
|
104
|
+
/** Existing byte-equivalent event ids skipped by resume mode. */
|
|
105
|
+
skipped_event_ids: readonly string[];
|
|
106
|
+
}
|
|
86
107
|
/**
|
|
87
108
|
* Append-only in-memory reference ledger. Durable adapters can persist the
|
|
88
109
|
* returned immutable events while reusing the same replay and validation model.
|
|
@@ -133,6 +154,15 @@ export declare class RelationshipEventStore {
|
|
|
133
154
|
currentVersion(): Promise<number>;
|
|
134
155
|
/** Append one event after refreshing under the shared workspace lock. */
|
|
135
156
|
append(input: RelationshipEventInput): Promise<RelationshipEvent>;
|
|
157
|
+
/**
|
|
158
|
+
* Validate and publish a relationship-event batch as one durable replacement.
|
|
159
|
+
* The shared writer lock covers refresh, collision checks, full in-memory
|
|
160
|
+
* validation, and atomic rename. A validation or filesystem failure therefore
|
|
161
|
+
* leaves the previous JSONL stream byte-for-byte unchanged. This path is
|
|
162
|
+
* intended for migrations and bulk imports; latency-sensitive single events
|
|
163
|
+
* should continue to use {@link append} and its O_APPEND write.
|
|
164
|
+
*/
|
|
165
|
+
appendBatch(inputs: readonly RelationshipEventInput[], options?: RelationshipEventBatchOptions): Promise<RelationshipEventBatchResult>;
|
|
136
166
|
/** Refresh from durable history and materialize an exact validated snapshot. */
|
|
137
167
|
snapshot(options?: Parameters<RelationshipEventLog["snapshot"]>[0]): Promise<RelationshipSnapshot>;
|
|
138
168
|
/** Refresh from durable history and page immutable events. */
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* optimistic concurrency, deterministic replay, snapshots, and cursor pages.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c2ea8300-fc2a-5562-ba56-f5364990f479")}catch(e){}}();
|
|
9
9
|
import { createQueryFingerprint, decodeQueryCursorState, paginateQueryRows, } from "./pagination.js";
|
|
10
10
|
import { constants } from "node:fs";
|
|
11
11
|
import { lstat, mkdir, open } from "node:fs/promises";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import { acquireLock } from "../core/lock/lock.js";
|
|
14
|
+
import { writeFileAtomic } from "../core/fs/fs-utils.js";
|
|
15
|
+
import { stableStringify } from "../core/shared/serialization.js";
|
|
14
16
|
import { RelationshipGraph, createRelationshipKindRegistry, } from "./relationships.js";
|
|
15
17
|
function requiredText(value, field) {
|
|
16
18
|
if (typeof value !== "string" || value.trim().length === 0)
|
|
@@ -320,7 +322,7 @@ async function loadRelationshipEventLog(target, nodes, registry) {
|
|
|
320
322
|
}
|
|
321
323
|
catch (error) {
|
|
322
324
|
if (error.code === "ENOENT")
|
|
323
|
-
return log;
|
|
325
|
+
return { log, raw: "" };
|
|
324
326
|
throw error;
|
|
325
327
|
}
|
|
326
328
|
finally {
|
|
@@ -351,7 +353,22 @@ async function loadRelationshipEventLog(target, nodes, registry) {
|
|
|
351
353
|
expectedVersion: log.version,
|
|
352
354
|
});
|
|
353
355
|
}
|
|
354
|
-
return log;
|
|
356
|
+
return { log, raw };
|
|
357
|
+
}
|
|
358
|
+
/** Return whether an existing immutable event exactly represents one input. */
|
|
359
|
+
function relationshipEventMatchesInput(event, input, nodes, registry) {
|
|
360
|
+
const timestamp = Date.parse(input.timestamp);
|
|
361
|
+
let edge;
|
|
362
|
+
if (input.action !== "remove" && input.edge !== undefined)
|
|
363
|
+
edge = new RelationshipGraph(nodes, [input.edge], registry).edges()[0];
|
|
364
|
+
return (event.eventId === input.eventId.trim() &&
|
|
365
|
+
event.relationshipId === input.relationshipId.trim() &&
|
|
366
|
+
event.action === input.action &&
|
|
367
|
+
event.author === input.author.trim() &&
|
|
368
|
+
Number.isFinite(timestamp) &&
|
|
369
|
+
event.timestamp === new Date(timestamp).toISOString() &&
|
|
370
|
+
event.reason === (input.reason?.trim() || undefined) &&
|
|
371
|
+
stableStringify(event.edge) === stableStringify(edge));
|
|
355
372
|
}
|
|
356
373
|
/**
|
|
357
374
|
* Lock-serialized durable JSONL adapter for {@link RelationshipEventLog}.
|
|
@@ -378,7 +395,7 @@ export class RelationshipEventStore {
|
|
|
378
395
|
const release = await acquireRelationshipStoreLock(options.pmRoot);
|
|
379
396
|
try {
|
|
380
397
|
await resolveRelationshipEventStorePath(options.pmRoot, target);
|
|
381
|
-
const log = await loadRelationshipEventLog(target, nodes, options.registry);
|
|
398
|
+
const { log } = await loadRelationshipEventLog(target, nodes, options.registry);
|
|
382
399
|
return new RelationshipEventStore(options, nodes, target, log);
|
|
383
400
|
}
|
|
384
401
|
finally {
|
|
@@ -399,7 +416,7 @@ export class RelationshipEventStore {
|
|
|
399
416
|
const release = await acquireRelationshipStoreLock(this.#pmRoot);
|
|
400
417
|
try {
|
|
401
418
|
const target = await resolveRelationshipEventStorePath(this.#pmRoot, this.#path);
|
|
402
|
-
const refreshed = await loadRelationshipEventLog(target, this.#nodes, this.#registry);
|
|
419
|
+
const { log: refreshed } = await loadRelationshipEventLog(target, this.#nodes, this.#registry);
|
|
403
420
|
const event = refreshed.append(input);
|
|
404
421
|
await mkdir(path.dirname(target), { recursive: true });
|
|
405
422
|
await resolveRelationshipEventStorePath(this.#pmRoot, target);
|
|
@@ -420,6 +437,57 @@ export class RelationshipEventStore {
|
|
|
420
437
|
await release();
|
|
421
438
|
}
|
|
422
439
|
}
|
|
440
|
+
/**
|
|
441
|
+
* Validate and publish a relationship-event batch as one durable replacement.
|
|
442
|
+
* The shared writer lock covers refresh, collision checks, full in-memory
|
|
443
|
+
* validation, and atomic rename. A validation or filesystem failure therefore
|
|
444
|
+
* leaves the previous JSONL stream byte-for-byte unchanged. This path is
|
|
445
|
+
* intended for migrations and bulk imports; latency-sensitive single events
|
|
446
|
+
* should continue to use {@link append} and its O_APPEND write.
|
|
447
|
+
*/
|
|
448
|
+
async appendBatch(inputs, options = {}) {
|
|
449
|
+
const release = await acquireRelationshipStoreLock(this.#pmRoot);
|
|
450
|
+
try {
|
|
451
|
+
const target = await resolveRelationshipEventStorePath(this.#pmRoot, this.#path);
|
|
452
|
+
const { log: refreshed, raw } = await loadRelationshipEventLog(target, this.#nodes, this.#registry);
|
|
453
|
+
const versionBefore = refreshed.version;
|
|
454
|
+
const existing = new Map(refreshed.events().map((event) => [event.eventId, event]));
|
|
455
|
+
const appended = [];
|
|
456
|
+
const skippedEventIds = [];
|
|
457
|
+
for (const input of inputs) {
|
|
458
|
+
const eventId = input.eventId.trim();
|
|
459
|
+
const stored = existing.get(eventId);
|
|
460
|
+
if (stored !== undefined) {
|
|
461
|
+
if (options.existingEventPolicy === "skip_identical" &&
|
|
462
|
+
relationshipEventMatchesInput(stored, input, this.#nodes, this.#registry)) {
|
|
463
|
+
skippedEventIds.push(stored.eventId);
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (options.existingEventPolicy === "skip_identical")
|
|
467
|
+
throw new TypeError(`Relationship event id collision with different content: ${eventId}`);
|
|
468
|
+
}
|
|
469
|
+
const event = refreshed.append(input);
|
|
470
|
+
existing.set(event.eventId, event);
|
|
471
|
+
appended.push(event);
|
|
472
|
+
}
|
|
473
|
+
if (appended.length > 0) {
|
|
474
|
+
const prefix = raw.length === 0 || raw.endsWith("\n") ? raw : `${raw}\n`;
|
|
475
|
+
await mkdir(path.dirname(target), { recursive: true });
|
|
476
|
+
await resolveRelationshipEventStorePath(this.#pmRoot, target);
|
|
477
|
+
await writeFileAtomic(target, `${prefix}${appended.map((event) => JSON.stringify(event)).join("\n")}\n`);
|
|
478
|
+
}
|
|
479
|
+
this.#log = refreshed;
|
|
480
|
+
return Object.freeze({
|
|
481
|
+
version_before: versionBefore,
|
|
482
|
+
version_after: refreshed.version,
|
|
483
|
+
appended: Object.freeze(appended),
|
|
484
|
+
skipped_event_ids: Object.freeze(skippedEventIds),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
finally {
|
|
488
|
+
await release();
|
|
489
|
+
}
|
|
490
|
+
}
|
|
423
491
|
/** Refresh from durable history and materialize an exact validated snapshot. */
|
|
424
492
|
async snapshot(options = {}) {
|
|
425
493
|
this.#log = await this.#refreshFromDurableHistory();
|
|
@@ -448,7 +516,7 @@ export class RelationshipEventStore {
|
|
|
448
516
|
const release = await acquireRelationshipStoreLock(this.#pmRoot);
|
|
449
517
|
try {
|
|
450
518
|
const target = await resolveRelationshipEventStorePath(this.#pmRoot, this.#path);
|
|
451
|
-
return await loadRelationshipEventLog(target, this.#nodes, this.#registry);
|
|
519
|
+
return (await loadRelationshipEventLog(target, this.#nodes, this.#registry)).log;
|
|
452
520
|
}
|
|
453
521
|
finally {
|
|
454
522
|
await release();
|
|
@@ -456,4 +524,4 @@ export class RelationshipEventStore {
|
|
|
456
524
|
}
|
|
457
525
|
}
|
|
458
526
|
//# sourceMappingURL=relationship-history.js.map
|
|
459
|
-
//# debugId=
|
|
527
|
+
//# debugId=c2ea8300-fc2a-5562-ba56-f5364990f479
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relationship-history.js","sources":["sdk/relationship-history.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/relationship-history\n *\n * Provides an append-only, storage-independent relationship event ledger with\n * optimistic concurrency, deterministic replay, snapshots, and cursor pages.\n */\nimport {\n createQueryFingerprint,\n decodeQueryCursorState,\n paginateQueryRows,\n} from \"./pagination.js\";\nimport { constants } from \"node:fs\";\nimport { lstat, mkdir, open, type FileHandle } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { acquireLock } from \"../core/lock/lock.js\";\nimport {\n RelationshipGraph,\n RelationshipKindRegistry,\n createRelationshipKindRegistry,\n type RelationshipEdge,\n} from \"./relationships.js\";\n\n/** Mutation kinds retained in the immutable relationship event stream. */\nexport type RelationshipEventAction = \"add\" | \"remove\" | \"supersede\";\n\n/** Caller-authored relationship mutation before its sequence is assigned. */\nexport interface RelationshipEventInput {\n /** Globally unique idempotency key for this event. */\n eventId: string;\n /** Stable logical relationship identifier across superseding events. */\n relationshipId: string;\n /** Append, remove, or replace the logical relationship. */\n action: RelationshipEventAction;\n /** Edge required for add and supersede actions. */\n edge?: RelationshipEdge;\n /** Attributable actor responsible for the mutation. */\n author: string;\n /** Valid event-time timestamp. */\n timestamp: string;\n /** Optional optimistic concurrency precondition. */\n expectedVersion?: number;\n /** Optional human-readable mutation rationale. */\n reason?: string;\n}\n\n/** One immutable sequenced relationship mutation. */\nexport interface RelationshipEvent extends Omit<\n RelationshipEventInput,\n \"expectedVersion\"\n> {\n /** One-based append sequence assigned by the ledger. */\n sequence: number;\n}\n\n/** Point-in-time materialized relationship view. */\nexport interface RelationshipSnapshot {\n /** Final event sequence included in this snapshot. */\n version: number;\n /** Timestamp of the final included event, when one exists. */\n asOf?: string;\n /** Deterministic active edge materialization. */\n edges: readonly RelationshipEdge[];\n /** Immutable graph query view over the active edges. */\n graph: RelationshipGraph;\n}\n\n/** Stable cursor page over a fixed relationship event-log version. */\nexport interface RelationshipEventPage {\n /** Log version against which this page was produced. */\n version: number;\n /** Events in append order. */\n events: RelationshipEvent[];\n /** Whether another event page exists. */\n hasMore: boolean;\n /** Opaque continuation cursor when another page exists. */\n nextCursor?: string;\n}\n\n/** Bounded controls for deterministic relationship-event batch iteration. */\nexport interface RelationshipEventStreamOptions {\n /** One-based first event version to include. */\n fromVersion?: number;\n /** One-based final event version to include. */\n toVersion?: number;\n /** Maximum number of events yielded in each immutable batch. */\n batchSize?: number;\n}\n\n/** Result of folding an immutable relationship-event prefix into domain state. */\nexport interface RelationshipEventProjection<State> {\n /** Final projected state returned by the caller-owned reducer. */\n state: State;\n /** Final event sequence included in the projection. */\n version: number;\n /** Number of events processed by this projection. */\n processed: number;\n /** Timestamp of the final included event, when one exists. */\n asOf?: string;\n}\n\n/** Pure reducer used to derive application state from relationship events. */\nexport type RelationshipEventReducer<State> = (\n state: State,\n event: RelationshipEvent,\n) => State;\n\n/** Construction controls for the in-memory reference ledger. */\nexport interface RelationshipEventLogOptions {\n /** Registry defining edge semantics and cardinality. */\n registry?: RelationshipKindRegistry;\n}\n\n/** Filesystem controls for the durable relationship event store. */\nexport interface RelationshipEventStoreOptions extends RelationshipEventLogOptions {\n /** Tracker root that owns the relationship history directory. */\n pmRoot: string;\n /** Fixed node universe validated by every replay and append. */\n nodes: Iterable<string>;\n /** Optional JSONL path relative to the tracker root. */\n relativePath?: string;\n}\n\ninterface RelationshipCardinalityIndexes {\n identities: Map<string, string>;\n outgoingOne: Map<string, string>;\n incomingOne: Map<string, string>;\n}\n\nfunction requiredText(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0)\n throw new TypeError(`Relationship event ${field} must be non-empty`);\n return value.trim();\n}\n\nfunction edgeIdentity(\n edge: RelationshipEdge,\n registry: RelationshipKindRegistry,\n): string {\n const definition = registry.require(edge.kind);\n const endpoints =\n definition.direction === \"undirected\"\n ? [edge.source, edge.target].sort().join(\"\\u0000\")\n : `${edge.source}\\u0000${edge.target}`;\n return `${definition.kind}\\u0000${endpoints}`;\n}\n\nfunction freezeEdge(edge: RelationshipEdge): RelationshipEdge {\n return Object.freeze({\n ...edge,\n ...(edge.payload === undefined\n ? {}\n : { payload: Object.freeze(structuredClone(edge.payload)) }),\n });\n}\n\nfunction assertCardinality(\n candidate: RelationshipEdge,\n excludeRelationshipId: string,\n registry: RelationshipKindRegistry,\n indexes: RelationshipCardinalityIndexes,\n): void {\n const definition = registry.require(candidate.kind);\n const outgoingOwner = indexes.outgoingOne.get(\n `${definition.kind}\\u0000${candidate.source}`,\n );\n if (outgoingOwner !== undefined && outgoingOwner !== excludeRelationshipId)\n throw new TypeError(\n `Relationship outgoing cardinality exceeded for ${definition.kind}`,\n );\n const incomingOwner = indexes.incomingOne.get(\n `${definition.kind}\\u0000${candidate.target}`,\n );\n if (incomingOwner !== undefined && incomingOwner !== excludeRelationshipId)\n throw new TypeError(\n `Relationship incoming cardinality exceeded for ${definition.kind}`,\n );\n const identity = edgeIdentity(candidate, registry);\n const identityOwner = indexes.identities.get(identity);\n if (identityOwner !== undefined && identityOwner !== excludeRelationshipId)\n throw new TypeError(`Relationship edge already active: ${identity}`);\n}\n\nfunction replayEvents(\n events: readonly RelationshipEvent[],\n): Map<string, RelationshipEdge> {\n const active = new Map<string, RelationshipEdge>();\n for (const event of events) {\n if (event.action === \"remove\") active.delete(event.relationshipId);\n else active.set(event.relationshipId, event.edge!);\n }\n return active;\n}\n\nfunction normalizeEventHeader(\n input: RelationshipEventInput,\n currentVersion: number,\n eventIds: ReadonlySet<string>,\n): {\n eventId: string;\n relationshipId: string;\n author: string;\n timestamp: string;\n} {\n if (\n input.expectedVersion !== undefined &&\n input.expectedVersion !== currentVersion\n )\n throw new TypeError(\n `Relationship event version conflict: expected ${input.expectedVersion}, current ${currentVersion}`,\n );\n const eventId = requiredText(input.eventId, \"eventId\");\n if (eventIds.has(eventId))\n throw new TypeError(`Relationship event already exists: ${eventId}`);\n if (\n input.action !== \"add\" &&\n input.action !== \"remove\" &&\n input.action !== \"supersede\"\n )\n throw new TypeError(`Unknown relationship event action: ${input.action}`);\n if (!Number.isFinite(Date.parse(input.timestamp)))\n throw new TypeError(\"Relationship event timestamp must be valid\");\n return {\n eventId,\n relationshipId: requiredText(input.relationshipId, \"relationshipId\"),\n author: requiredText(input.author, \"author\"),\n timestamp: new Date(input.timestamp).toISOString(),\n };\n}\n\nfunction resolveMutationEdge(\n input: RelationshipEventInput,\n relationshipId: string,\n active: ReadonlyMap<string, RelationshipEdge>,\n nodes: ReadonlySet<string>,\n registry: RelationshipKindRegistry,\n indexes: RelationshipCardinalityIndexes,\n): RelationshipEdge | undefined {\n const isActive = active.has(relationshipId);\n if (input.action === \"add\" && isActive)\n throw new TypeError(`Relationship is already active: ${relationshipId}`);\n if (input.action !== \"add\" && !isActive)\n throw new TypeError(`Relationship is not active: ${relationshipId}`);\n if (input.action === \"remove\") return undefined;\n if (!input.edge)\n throw new TypeError(`Relationship ${input.action} event requires an edge`);\n const source =\n typeof input.edge.source === \"string\" ? input.edge.source.trim() : \"\";\n const target =\n typeof input.edge.target === \"string\" ? input.edge.target.trim() : \"\";\n if (!nodes.has(source) || !nodes.has(target))\n throw new TypeError(\n `Relationship endpoint not found: ${source} -> ${target}`,\n );\n const canonical = new RelationshipGraph(\n [source, target],\n [input.edge],\n registry,\n ).edges()[0]!;\n assertCardinality(canonical, relationshipId, registry, indexes);\n return freezeEdge(canonical);\n}\n\n/**\n * Append-only in-memory reference ledger. Durable adapters can persist the\n * returned immutable events while reusing the same replay and validation model.\n */\nexport class RelationshipEventLog {\n readonly #nodes: ReadonlySet<string>;\n readonly #registry: RelationshipKindRegistry;\n readonly #events: RelationshipEvent[] = [];\n readonly #eventIds = new Set<string>();\n readonly #active = new Map<string, RelationshipEdge>();\n readonly #cardinalityIndexes: RelationshipCardinalityIndexes = {\n identities: new Map(),\n outgoingOne: new Map(),\n incomingOne: new Map(),\n };\n\n /** Create an empty relationship ledger for a fixed node universe. */\n public constructor(\n nodes: Iterable<string>,\n options: RelationshipEventLogOptions = {},\n ) {\n this.#nodes = new Set(\n [...nodes]\n .filter((node): node is string => typeof node === \"string\")\n .map((node) => node.trim())\n .filter(Boolean),\n );\n this.#registry = options.registry ?? createRelationshipKindRegistry();\n }\n\n /** Current append sequence. */\n public get version(): number {\n return this.#events.length;\n }\n\n /** Return an immutable copy of the full event stream. */\n public events(): readonly RelationshipEvent[] {\n return Object.freeze([...this.#events]);\n }\n\n /**\n * Iterate a stable event prefix in immutable, bounded batches. Consumers can\n * build streaming projections without copying or exposing the mutable ledger.\n * `fromVersion === toVersion + 1` is the intentional empty checkpoint range;\n * larger watermarks are rejected as invalid for the selected prefix.\n */\n public *stream(\n options: RelationshipEventStreamOptions = {},\n ): Generator<readonly RelationshipEvent[]> {\n const fromVersion = options.fromVersion ?? 1;\n const toVersion = options.toVersion ?? this.version;\n const batchSize = options.batchSize ?? 100;\n if (!Number.isInteger(fromVersion) || fromVersion < 1)\n throw new TypeError(\n \"Relationship event stream fromVersion must be positive\",\n );\n if (\n !Number.isInteger(toVersion) ||\n toVersion < 0 ||\n toVersion > this.version\n )\n throw new TypeError(\n `Relationship event stream toVersion out of range: ${toVersion}`,\n );\n if (!Number.isInteger(batchSize) || batchSize < 1)\n throw new TypeError(\n \"Relationship event stream batchSize must be positive\",\n );\n if (fromVersion > toVersion + 1)\n throw new TypeError(\n \"Relationship event stream fromVersion exceeds the selected prefix\",\n );\n for (let offset = fromVersion - 1; offset < toVersion; offset += batchSize) {\n yield Object.freeze(\n this.#events.slice(offset, Math.min(offset + batchSize, toVersion)),\n );\n }\n }\n\n /** Fold a selected immutable event prefix into caller-owned domain state. */\n public project<State>(\n initialState: State,\n reducer: RelationshipEventReducer<State>,\n options: Omit<RelationshipEventStreamOptions, \"batchSize\"> = {},\n ): RelationshipEventProjection<State> {\n if (typeof reducer !== \"function\")\n throw new TypeError(\"Relationship event projection requires a reducer\");\n let state = initialState;\n let processed = 0;\n let finalEvent: RelationshipEvent | undefined;\n for (const batch of this.stream({ ...options, batchSize: 256 })) {\n for (const event of batch) {\n state = reducer(state, event);\n processed += 1;\n finalEvent = event;\n }\n }\n return Object.freeze({\n state,\n version: finalEvent?.sequence ?? Math.max(0, (options.fromVersion ?? 1) - 1),\n processed,\n ...(finalEvent === undefined ? {} : { asOf: finalEvent.timestamp }),\n });\n }\n\n /** Add one active relationship to constant-time validation indexes. */\n #indexActive(relationshipId: string, edge: RelationshipEdge): void {\n const definition = this.#registry.require(edge.kind);\n this.#cardinalityIndexes.identities.set(\n edgeIdentity(edge, this.#registry),\n relationshipId,\n );\n if (definition.outgoing === \"one\")\n this.#cardinalityIndexes.outgoingOne.set(\n `${definition.kind}\\u0000${edge.source}`,\n relationshipId,\n );\n if (definition.incoming === \"one\")\n this.#cardinalityIndexes.incomingOne.set(\n `${definition.kind}\\u0000${edge.target}`,\n relationshipId,\n );\n }\n\n /** Remove one superseded or deleted relationship from validation indexes. */\n #unindexActive(edge: RelationshipEdge): void {\n const definition = this.#registry.require(edge.kind);\n this.#cardinalityIndexes.identities.delete(\n edgeIdentity(edge, this.#registry),\n );\n if (definition.outgoing === \"one\")\n this.#cardinalityIndexes.outgoingOne.delete(\n `${definition.kind}\\u0000${edge.source}`,\n );\n if (definition.incoming === \"one\")\n this.#cardinalityIndexes.incomingOne.delete(\n `${definition.kind}\\u0000${edge.target}`,\n );\n }\n\n /** Validate and append one attributable relationship mutation. */\n public append(input: RelationshipEventInput): RelationshipEvent {\n const header = normalizeEventHeader(input, this.version, this.#eventIds);\n const previous = this.#active.get(header.relationshipId);\n const edge = resolveMutationEdge(\n input,\n header.relationshipId,\n this.#active,\n this.#nodes,\n this.#registry,\n this.#cardinalityIndexes,\n );\n\n const event = Object.freeze({\n eventId: header.eventId,\n relationshipId: header.relationshipId,\n action: input.action,\n ...(edge === undefined ? {} : { edge }),\n author: header.author,\n timestamp: header.timestamp,\n ...(input.reason?.trim() ? { reason: input.reason.trim() } : {}),\n sequence: this.version + 1,\n }) satisfies RelationshipEvent;\n this.#events.push(event);\n this.#eventIds.add(header.eventId);\n if (previous) this.#unindexActive(previous);\n if (input.action === \"remove\") this.#active.delete(header.relationshipId);\n else {\n this.#active.set(header.relationshipId, edge!);\n this.#indexActive(header.relationshipId, edge!);\n }\n return event;\n }\n\n /** Materialize an exact point-in-time graph without mutating the ledger. */\n public snapshot(\n options: {\n atVersion?: number;\n atTimestamp?: string;\n } = {},\n ): RelationshipSnapshot {\n if (options.atVersion !== undefined && options.atTimestamp !== undefined)\n throw new TypeError(\"Relationship snapshot accepts one target\");\n let included: RelationshipEvent[];\n if (options.atTimestamp !== undefined) {\n const timestamp = Date.parse(options.atTimestamp);\n if (!Number.isFinite(timestamp))\n throw new TypeError(\"Relationship snapshot timestamp must be valid\");\n let lastIndex = -1;\n for (let index = this.#events.length - 1; index >= 0; index -= 1) {\n if (Date.parse(this.#events[index]!.timestamp) > timestamp) continue;\n lastIndex = index;\n break;\n }\n included = lastIndex === -1 ? [] : this.#events.slice(0, lastIndex + 1);\n } else {\n const version = options.atVersion ?? this.version;\n if (!Number.isInteger(version) || version < 0 || version > this.version)\n throw new TypeError(\n `Relationship snapshot version out of range: ${version}`,\n );\n included = this.#events.slice(0, version);\n }\n const active = replayEvents(included);\n const graph = new RelationshipGraph(\n this.#nodes,\n active.values(),\n this.#registry,\n );\n return Object.freeze({\n version: included.length,\n ...(included.at(-1) ? { asOf: included.at(-1)!.timestamp } : {}),\n edges: graph.edges(),\n graph,\n });\n }\n\n /** Page the immutable event stream with a cursor bound to this log version. */\n public page(options: {\n limit: number;\n cursor?: string;\n }): RelationshipEventPage {\n if (!Number.isInteger(options.limit) || options.limit < 1)\n throw new TypeError(\"Relationship event page limit must be positive\");\n const fingerprint = createQueryFingerprint(\"relationship-events\", {\n order: \"append-sequence\",\n });\n const snapshot =\n options.cursor === undefined\n ? this.version\n : Number(decodeQueryCursorState(options.cursor, fingerprint).snapshot);\n if (\n !Number.isSafeInteger(snapshot) ||\n snapshot < 0 ||\n snapshot > this.version\n )\n throw new TypeError(\n \"Relationship event cursor snapshot version is invalid\",\n );\n const page = paginateQueryRows(this.#events.slice(0, snapshot), {\n cursor: options.cursor,\n fingerprint,\n limit: options.limit,\n readId: (event) => event.eventId,\n snapshot: String(snapshot),\n });\n return {\n version: snapshot,\n events: page.rows,\n hasMore: page.has_more,\n ...(page.next_cursor ? { nextCursor: page.next_cursor } : {}),\n };\n }\n}\n\nconst RELATIONSHIP_STORE_LOCK_ID = \"relationship-event-store\";\nconst RELATIONSHIP_NOFOLLOW_FLAG = constants.O_NOFOLLOW;\n\nfunction acquireRelationshipStoreLock(\n pmRoot: string,\n): Promise<() => Promise<void>> {\n return acquireLock(\n pmRoot,\n RELATIONSHIP_STORE_LOCK_ID,\n 30,\n `relationship-store:${process.pid}`,\n false,\n false,\n 3_000,\n );\n}\n\nasync function resolveRelationshipEventStorePath(\n pmRoot: string,\n relativePath = \"relationships/events.jsonl\",\n): Promise<string> {\n const root = path.resolve(pmRoot);\n const target = path.resolve(root, relativePath);\n const relative = path.relative(root, target);\n if (relative.length === 0)\n throw new TypeError(\n \"Relationship event path must name a file within the tracker root\",\n );\n if (\n relative === \"..\" ||\n relative.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relative)\n )\n throw new TypeError(\n \"Relationship event path must stay within the tracker root\",\n );\n await mkdir(root, { recursive: true });\n const rootStats = await lstat(root);\n if (rootStats.isSymbolicLink())\n throw new TypeError(\n \"Relationship event tracker root must not be a symbolic link\",\n );\n let current = root;\n for (const segment of relative.split(path.sep)) {\n current = path.join(current, segment);\n try {\n if ((await lstat(current)).isSymbolicLink())\n throw new TypeError(\n \"Relationship event path must not contain symbolic links\",\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") break;\n throw error;\n }\n }\n return target;\n}\n\nasync function loadRelationshipEventLog(\n target: string,\n nodes: readonly string[],\n registry: RelationshipKindRegistry | undefined,\n): Promise<RelationshipEventLog> {\n const log = new RelationshipEventLog(nodes, { registry });\n let raw: string;\n let handle: FileHandle | undefined;\n try {\n handle = await open(\n target,\n constants.O_RDONLY | RELATIONSHIP_NOFOLLOW_FLAG,\n );\n raw = await handle.readFile(\"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return log;\n throw error;\n } finally {\n await handle?.close();\n }\n const lines = raw.split(\"\\n\");\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index]!.trim();\n if (!line) continue;\n let stored: RelationshipEvent;\n try {\n stored = JSON.parse(line) as RelationshipEvent;\n } catch {\n throw new TypeError(\n `Invalid relationship event JSONL at line ${index + 1}`,\n );\n }\n if (stored.sequence !== log.version + 1)\n throw new TypeError(\n `Invalid relationship event sequence at line ${index + 1}`,\n );\n log.append({\n eventId: stored.eventId,\n relationshipId: stored.relationshipId,\n action: stored.action,\n ...(stored.edge === undefined ? {} : { edge: stored.edge }),\n author: stored.author,\n timestamp: stored.timestamp,\n ...(stored.reason === undefined ? {} : { reason: stored.reason }),\n expectedVersion: log.version,\n });\n }\n return log;\n}\n\n/**\n * Lock-serialized durable JSONL adapter for {@link RelationshipEventLog}.\n * Every append replays the current stream while holding the workspace lock, so\n * independent processes share optimistic versions without lost updates.\n */\nexport class RelationshipEventStore {\n readonly #pmRoot: string;\n readonly #nodes: readonly string[];\n readonly #registry: RelationshipKindRegistry | undefined;\n readonly #path: string;\n #log: RelationshipEventLog;\n\n private constructor(\n options: RelationshipEventStoreOptions,\n nodes: readonly string[],\n target: string,\n log: RelationshipEventLog,\n ) {\n this.#pmRoot = options.pmRoot;\n this.#nodes = nodes;\n this.#registry = options.registry;\n this.#path = target;\n this.#log = log;\n }\n\n /** Open and validate an existing stream or create an empty store view. */\n public static async open(\n options: RelationshipEventStoreOptions,\n ): Promise<RelationshipEventStore> {\n const nodes = Object.freeze([...options.nodes]);\n const target = await resolveRelationshipEventStorePath(\n options.pmRoot,\n options.relativePath,\n );\n const release = await acquireRelationshipStoreLock(options.pmRoot);\n try {\n await resolveRelationshipEventStorePath(options.pmRoot, target);\n const log = await loadRelationshipEventLog(\n target,\n nodes,\n options.registry,\n );\n return new RelationshipEventStore(options, nodes, target, log);\n } finally {\n await release();\n }\n }\n\n /** Absolute JSONL path, exposed for diagnostics and backup tooling. */\n public get path(): string {\n return this.#path;\n }\n\n /** Refresh from durable history and return the current validated append sequence. */\n public async currentVersion(): Promise<number> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.version;\n }\n\n /** Append one event after refreshing under the shared workspace lock. */\n public async append(\n input: RelationshipEventInput,\n ): Promise<RelationshipEvent> {\n const release = await acquireRelationshipStoreLock(this.#pmRoot);\n try {\n const target = await resolveRelationshipEventStorePath(\n this.#pmRoot,\n this.#path,\n );\n const refreshed = await loadRelationshipEventLog(\n target,\n this.#nodes,\n this.#registry,\n );\n const event = refreshed.append(input);\n await mkdir(path.dirname(target), { recursive: true });\n await resolveRelationshipEventStorePath(this.#pmRoot, target);\n const handle = await open(\n target,\n constants.O_APPEND |\n constants.O_CREAT |\n constants.O_WRONLY |\n RELATIONSHIP_NOFOLLOW_FLAG,\n );\n try {\n await handle.appendFile(`${JSON.stringify(event)}\\n`, \"utf8\");\n } finally {\n await handle.close();\n }\n this.#log = refreshed;\n return event;\n } finally {\n await release();\n }\n }\n\n /** Refresh from durable history and materialize an exact validated snapshot. */\n public async snapshot(\n options: Parameters<RelationshipEventLog[\"snapshot\"]>[0] = {},\n ): Promise<RelationshipSnapshot> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.snapshot(options);\n }\n\n /** Refresh from durable history and page immutable events. */\n public async page(\n options: Parameters<RelationshipEventLog[\"page\"]>[0],\n ): Promise<RelationshipEventPage> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.page(options);\n }\n\n /**\n * Refresh once under the shared store lock, then stream a coherent immutable\n * prefix without holding the writer lock while the consumer processes batches.\n */\n public async *stream(\n options: RelationshipEventStreamOptions = {},\n ): AsyncGenerator<readonly RelationshipEvent[]> {\n this.#log = await this.#refreshFromDurableHistory();\n yield* this.#log.stream(options);\n }\n\n /** Refresh once and fold a coherent durable prefix into application state. */\n public async project<State>(\n initialState: State,\n reducer: RelationshipEventReducer<State>,\n options: Omit<RelationshipEventStreamOptions, \"batchSize\"> = {},\n ): Promise<RelationshipEventProjection<State>> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.project(initialState, reducer, options);\n }\n\n /** Serialize a durable refresh with writers so readers never observe a torn JSONL tail. */\n async #refreshFromDurableHistory(): Promise<RelationshipEventLog> {\n const release = await acquireRelationshipStoreLock(this.#pmRoot);\n try {\n const target = await resolveRelationshipEventStorePath(\n this.#pmRoot,\n this.#path,\n );\n return await loadRelationshipEventLog(\n target,\n this.#nodes,\n this.#registry,\n );\n } finally {\n await release();\n }\n }\n}\n"],"names":[],"mappings":"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","debugId":"b00bbd6d-eb0d-5fbf-8f87-456d479e7807"}
|
|
1
|
+
{"version":3,"file":"relationship-history.js","sources":["sdk/relationship-history.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/relationship-history\n *\n * Provides an append-only, storage-independent relationship event ledger with\n * optimistic concurrency, deterministic replay, snapshots, and cursor pages.\n */\nimport {\n createQueryFingerprint,\n decodeQueryCursorState,\n paginateQueryRows,\n} from \"./pagination.js\";\nimport { constants } from \"node:fs\";\nimport { lstat, mkdir, open, type FileHandle } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { acquireLock } from \"../core/lock/lock.js\";\nimport { writeFileAtomic } from \"../core/fs/fs-utils.js\";\nimport { stableStringify } from \"../core/shared/serialization.js\";\nimport {\n RelationshipGraph,\n RelationshipKindRegistry,\n createRelationshipKindRegistry,\n type RelationshipEdge,\n} from \"./relationships.js\";\n\n/** Mutation kinds retained in the immutable relationship event stream. */\nexport type RelationshipEventAction = \"add\" | \"remove\" | \"supersede\";\n\n/** Caller-authored relationship mutation before its sequence is assigned. */\nexport interface RelationshipEventInput {\n /** Globally unique idempotency key for this event. */\n eventId: string;\n /** Stable logical relationship identifier across superseding events. */\n relationshipId: string;\n /** Append, remove, or replace the logical relationship. */\n action: RelationshipEventAction;\n /** Edge required for add and supersede actions. */\n edge?: RelationshipEdge;\n /** Attributable actor responsible for the mutation. */\n author: string;\n /** Valid event-time timestamp. */\n timestamp: string;\n /** Optional optimistic concurrency precondition. */\n expectedVersion?: number;\n /** Optional human-readable mutation rationale. */\n reason?: string;\n}\n\n/** One immutable sequenced relationship mutation. */\nexport interface RelationshipEvent extends Omit<\n RelationshipEventInput,\n \"expectedVersion\"\n> {\n /** One-based append sequence assigned by the ledger. */\n sequence: number;\n}\n\n/** Point-in-time materialized relationship view. */\nexport interface RelationshipSnapshot {\n /** Final event sequence included in this snapshot. */\n version: number;\n /** Timestamp of the final included event, when one exists. */\n asOf?: string;\n /** Deterministic active edge materialization. */\n edges: readonly RelationshipEdge[];\n /** Immutable graph query view over the active edges. */\n graph: RelationshipGraph;\n}\n\n/** Stable cursor page over a fixed relationship event-log version. */\nexport interface RelationshipEventPage {\n /** Log version against which this page was produced. */\n version: number;\n /** Events in append order. */\n events: RelationshipEvent[];\n /** Whether another event page exists. */\n hasMore: boolean;\n /** Opaque continuation cursor when another page exists. */\n nextCursor?: string;\n}\n\n/** Bounded controls for deterministic relationship-event batch iteration. */\nexport interface RelationshipEventStreamOptions {\n /** One-based first event version to include. */\n fromVersion?: number;\n /** One-based final event version to include. */\n toVersion?: number;\n /** Maximum number of events yielded in each immutable batch. */\n batchSize?: number;\n}\n\n/** Result of folding an immutable relationship-event prefix into domain state. */\nexport interface RelationshipEventProjection<State> {\n /** Final projected state returned by the caller-owned reducer. */\n state: State;\n /** Final event sequence included in the projection. */\n version: number;\n /** Number of events processed by this projection. */\n processed: number;\n /** Timestamp of the final included event, when one exists. */\n asOf?: string;\n}\n\n/** Pure reducer used to derive application state from relationship events. */\nexport type RelationshipEventReducer<State> = (\n state: State,\n event: RelationshipEvent,\n) => State;\n\n/** Construction controls for the in-memory reference ledger. */\nexport interface RelationshipEventLogOptions {\n /** Registry defining edge semantics and cardinality. */\n registry?: RelationshipKindRegistry;\n}\n\n/** Filesystem controls for the durable relationship event store. */\nexport interface RelationshipEventStoreOptions extends RelationshipEventLogOptions {\n /** Tracker root that owns the relationship history directory. */\n pmRoot: string;\n /** Fixed node universe validated by every replay and append. */\n nodes: Iterable<string>;\n /** Optional JSONL path relative to the tracker root. */\n relativePath?: string;\n}\n\n/** Collision policy applied while publishing a durable event batch. */\nexport type RelationshipExistingEventPolicy = \"error\" | \"skip_identical\";\n\n/** Controls for one atomic durable relationship-event batch. */\nexport interface RelationshipEventBatchOptions {\n /**\n * Existing event ids fail by default. Migration resume flows may skip an id\n * only when every persisted semantic field is identical to the input.\n */\n existingEventPolicy?: RelationshipExistingEventPolicy;\n}\n\n/** Result of one validated, atomic durable relationship-event batch. */\nexport interface RelationshipEventBatchResult {\n /** Durable stream version observed while holding the writer lock. */\n version_before: number;\n /** Durable stream version after the atomic publication. */\n version_after: number;\n /** Immutable sequenced events newly published by this call. */\n appended: readonly RelationshipEvent[];\n /** Existing byte-equivalent event ids skipped by resume mode. */\n skipped_event_ids: readonly string[];\n}\n\ninterface RelationshipCardinalityIndexes {\n identities: Map<string, string>;\n outgoingOne: Map<string, string>;\n incomingOne: Map<string, string>;\n}\n\nfunction requiredText(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0)\n throw new TypeError(`Relationship event ${field} must be non-empty`);\n return value.trim();\n}\n\nfunction edgeIdentity(\n edge: RelationshipEdge,\n registry: RelationshipKindRegistry,\n): string {\n const definition = registry.require(edge.kind);\n const endpoints =\n definition.direction === \"undirected\"\n ? [edge.source, edge.target].sort().join(\"\\u0000\")\n : `${edge.source}\\u0000${edge.target}`;\n return `${definition.kind}\\u0000${endpoints}`;\n}\n\nfunction freezeEdge(edge: RelationshipEdge): RelationshipEdge {\n return Object.freeze({\n ...edge,\n ...(edge.payload === undefined\n ? {}\n : { payload: Object.freeze(structuredClone(edge.payload)) }),\n });\n}\n\nfunction assertCardinality(\n candidate: RelationshipEdge,\n excludeRelationshipId: string,\n registry: RelationshipKindRegistry,\n indexes: RelationshipCardinalityIndexes,\n): void {\n const definition = registry.require(candidate.kind);\n const outgoingOwner = indexes.outgoingOne.get(\n `${definition.kind}\\u0000${candidate.source}`,\n );\n if (outgoingOwner !== undefined && outgoingOwner !== excludeRelationshipId)\n throw new TypeError(\n `Relationship outgoing cardinality exceeded for ${definition.kind}`,\n );\n const incomingOwner = indexes.incomingOne.get(\n `${definition.kind}\\u0000${candidate.target}`,\n );\n if (incomingOwner !== undefined && incomingOwner !== excludeRelationshipId)\n throw new TypeError(\n `Relationship incoming cardinality exceeded for ${definition.kind}`,\n );\n const identity = edgeIdentity(candidate, registry);\n const identityOwner = indexes.identities.get(identity);\n if (identityOwner !== undefined && identityOwner !== excludeRelationshipId)\n throw new TypeError(`Relationship edge already active: ${identity}`);\n}\n\nfunction replayEvents(\n events: readonly RelationshipEvent[],\n): Map<string, RelationshipEdge> {\n const active = new Map<string, RelationshipEdge>();\n for (const event of events) {\n if (event.action === \"remove\") active.delete(event.relationshipId);\n else active.set(event.relationshipId, event.edge!);\n }\n return active;\n}\n\nfunction normalizeEventHeader(\n input: RelationshipEventInput,\n currentVersion: number,\n eventIds: ReadonlySet<string>,\n): {\n eventId: string;\n relationshipId: string;\n author: string;\n timestamp: string;\n} {\n if (\n input.expectedVersion !== undefined &&\n input.expectedVersion !== currentVersion\n )\n throw new TypeError(\n `Relationship event version conflict: expected ${input.expectedVersion}, current ${currentVersion}`,\n );\n const eventId = requiredText(input.eventId, \"eventId\");\n if (eventIds.has(eventId))\n throw new TypeError(`Relationship event already exists: ${eventId}`);\n if (\n input.action !== \"add\" &&\n input.action !== \"remove\" &&\n input.action !== \"supersede\"\n )\n throw new TypeError(`Unknown relationship event action: ${input.action}`);\n if (!Number.isFinite(Date.parse(input.timestamp)))\n throw new TypeError(\"Relationship event timestamp must be valid\");\n return {\n eventId,\n relationshipId: requiredText(input.relationshipId, \"relationshipId\"),\n author: requiredText(input.author, \"author\"),\n timestamp: new Date(input.timestamp).toISOString(),\n };\n}\n\nfunction resolveMutationEdge(\n input: RelationshipEventInput,\n relationshipId: string,\n active: ReadonlyMap<string, RelationshipEdge>,\n nodes: ReadonlySet<string>,\n registry: RelationshipKindRegistry,\n indexes: RelationshipCardinalityIndexes,\n): RelationshipEdge | undefined {\n const isActive = active.has(relationshipId);\n if (input.action === \"add\" && isActive)\n throw new TypeError(`Relationship is already active: ${relationshipId}`);\n if (input.action !== \"add\" && !isActive)\n throw new TypeError(`Relationship is not active: ${relationshipId}`);\n if (input.action === \"remove\") return undefined;\n if (!input.edge)\n throw new TypeError(`Relationship ${input.action} event requires an edge`);\n const source =\n typeof input.edge.source === \"string\" ? input.edge.source.trim() : \"\";\n const target =\n typeof input.edge.target === \"string\" ? input.edge.target.trim() : \"\";\n if (!nodes.has(source) || !nodes.has(target))\n throw new TypeError(\n `Relationship endpoint not found: ${source} -> ${target}`,\n );\n const canonical = new RelationshipGraph(\n [source, target],\n [input.edge],\n registry,\n ).edges()[0]!;\n assertCardinality(canonical, relationshipId, registry, indexes);\n return freezeEdge(canonical);\n}\n\n/**\n * Append-only in-memory reference ledger. Durable adapters can persist the\n * returned immutable events while reusing the same replay and validation model.\n */\nexport class RelationshipEventLog {\n readonly #nodes: ReadonlySet<string>;\n readonly #registry: RelationshipKindRegistry;\n readonly #events: RelationshipEvent[] = [];\n readonly #eventIds = new Set<string>();\n readonly #active = new Map<string, RelationshipEdge>();\n readonly #cardinalityIndexes: RelationshipCardinalityIndexes = {\n identities: new Map(),\n outgoingOne: new Map(),\n incomingOne: new Map(),\n };\n\n /** Create an empty relationship ledger for a fixed node universe. */\n public constructor(\n nodes: Iterable<string>,\n options: RelationshipEventLogOptions = {},\n ) {\n this.#nodes = new Set(\n [...nodes]\n .filter((node): node is string => typeof node === \"string\")\n .map((node) => node.trim())\n .filter(Boolean),\n );\n this.#registry = options.registry ?? createRelationshipKindRegistry();\n }\n\n /** Current append sequence. */\n public get version(): number {\n return this.#events.length;\n }\n\n /** Return an immutable copy of the full event stream. */\n public events(): readonly RelationshipEvent[] {\n return Object.freeze([...this.#events]);\n }\n\n /**\n * Iterate a stable event prefix in immutable, bounded batches. Consumers can\n * build streaming projections without copying or exposing the mutable ledger.\n * `fromVersion === toVersion + 1` is the intentional empty checkpoint range;\n * larger watermarks are rejected as invalid for the selected prefix.\n */\n public *stream(\n options: RelationshipEventStreamOptions = {},\n ): Generator<readonly RelationshipEvent[]> {\n const fromVersion = options.fromVersion ?? 1;\n const toVersion = options.toVersion ?? this.version;\n const batchSize = options.batchSize ?? 100;\n if (!Number.isInteger(fromVersion) || fromVersion < 1)\n throw new TypeError(\n \"Relationship event stream fromVersion must be positive\",\n );\n if (\n !Number.isInteger(toVersion) ||\n toVersion < 0 ||\n toVersion > this.version\n )\n throw new TypeError(\n `Relationship event stream toVersion out of range: ${toVersion}`,\n );\n if (!Number.isInteger(batchSize) || batchSize < 1)\n throw new TypeError(\n \"Relationship event stream batchSize must be positive\",\n );\n if (fromVersion > toVersion + 1)\n throw new TypeError(\n \"Relationship event stream fromVersion exceeds the selected prefix\",\n );\n for (let offset = fromVersion - 1; offset < toVersion; offset += batchSize) {\n yield Object.freeze(\n this.#events.slice(offset, Math.min(offset + batchSize, toVersion)),\n );\n }\n }\n\n /** Fold a selected immutable event prefix into caller-owned domain state. */\n public project<State>(\n initialState: State,\n reducer: RelationshipEventReducer<State>,\n options: Omit<RelationshipEventStreamOptions, \"batchSize\"> = {},\n ): RelationshipEventProjection<State> {\n if (typeof reducer !== \"function\")\n throw new TypeError(\"Relationship event projection requires a reducer\");\n let state = initialState;\n let processed = 0;\n let finalEvent: RelationshipEvent | undefined;\n for (const batch of this.stream({ ...options, batchSize: 256 })) {\n for (const event of batch) {\n state = reducer(state, event);\n processed += 1;\n finalEvent = event;\n }\n }\n return Object.freeze({\n state,\n version: finalEvent?.sequence ?? Math.max(0, (options.fromVersion ?? 1) - 1),\n processed,\n ...(finalEvent === undefined ? {} : { asOf: finalEvent.timestamp }),\n });\n }\n\n /** Add one active relationship to constant-time validation indexes. */\n #indexActive(relationshipId: string, edge: RelationshipEdge): void {\n const definition = this.#registry.require(edge.kind);\n this.#cardinalityIndexes.identities.set(\n edgeIdentity(edge, this.#registry),\n relationshipId,\n );\n if (definition.outgoing === \"one\")\n this.#cardinalityIndexes.outgoingOne.set(\n `${definition.kind}\\u0000${edge.source}`,\n relationshipId,\n );\n if (definition.incoming === \"one\")\n this.#cardinalityIndexes.incomingOne.set(\n `${definition.kind}\\u0000${edge.target}`,\n relationshipId,\n );\n }\n\n /** Remove one superseded or deleted relationship from validation indexes. */\n #unindexActive(edge: RelationshipEdge): void {\n const definition = this.#registry.require(edge.kind);\n this.#cardinalityIndexes.identities.delete(\n edgeIdentity(edge, this.#registry),\n );\n if (definition.outgoing === \"one\")\n this.#cardinalityIndexes.outgoingOne.delete(\n `${definition.kind}\\u0000${edge.source}`,\n );\n if (definition.incoming === \"one\")\n this.#cardinalityIndexes.incomingOne.delete(\n `${definition.kind}\\u0000${edge.target}`,\n );\n }\n\n /** Validate and append one attributable relationship mutation. */\n public append(input: RelationshipEventInput): RelationshipEvent {\n const header = normalizeEventHeader(input, this.version, this.#eventIds);\n const previous = this.#active.get(header.relationshipId);\n const edge = resolveMutationEdge(\n input,\n header.relationshipId,\n this.#active,\n this.#nodes,\n this.#registry,\n this.#cardinalityIndexes,\n );\n\n const event = Object.freeze({\n eventId: header.eventId,\n relationshipId: header.relationshipId,\n action: input.action,\n ...(edge === undefined ? {} : { edge }),\n author: header.author,\n timestamp: header.timestamp,\n ...(input.reason?.trim() ? { reason: input.reason.trim() } : {}),\n sequence: this.version + 1,\n }) satisfies RelationshipEvent;\n this.#events.push(event);\n this.#eventIds.add(header.eventId);\n if (previous) this.#unindexActive(previous);\n if (input.action === \"remove\") this.#active.delete(header.relationshipId);\n else {\n this.#active.set(header.relationshipId, edge!);\n this.#indexActive(header.relationshipId, edge!);\n }\n return event;\n }\n\n /** Materialize an exact point-in-time graph without mutating the ledger. */\n public snapshot(\n options: {\n atVersion?: number;\n atTimestamp?: string;\n } = {},\n ): RelationshipSnapshot {\n if (options.atVersion !== undefined && options.atTimestamp !== undefined)\n throw new TypeError(\"Relationship snapshot accepts one target\");\n let included: RelationshipEvent[];\n if (options.atTimestamp !== undefined) {\n const timestamp = Date.parse(options.atTimestamp);\n if (!Number.isFinite(timestamp))\n throw new TypeError(\"Relationship snapshot timestamp must be valid\");\n let lastIndex = -1;\n for (let index = this.#events.length - 1; index >= 0; index -= 1) {\n if (Date.parse(this.#events[index]!.timestamp) > timestamp) continue;\n lastIndex = index;\n break;\n }\n included = lastIndex === -1 ? [] : this.#events.slice(0, lastIndex + 1);\n } else {\n const version = options.atVersion ?? this.version;\n if (!Number.isInteger(version) || version < 0 || version > this.version)\n throw new TypeError(\n `Relationship snapshot version out of range: ${version}`,\n );\n included = this.#events.slice(0, version);\n }\n const active = replayEvents(included);\n const graph = new RelationshipGraph(\n this.#nodes,\n active.values(),\n this.#registry,\n );\n return Object.freeze({\n version: included.length,\n ...(included.at(-1) ? { asOf: included.at(-1)!.timestamp } : {}),\n edges: graph.edges(),\n graph,\n });\n }\n\n /** Page the immutable event stream with a cursor bound to this log version. */\n public page(options: {\n limit: number;\n cursor?: string;\n }): RelationshipEventPage {\n if (!Number.isInteger(options.limit) || options.limit < 1)\n throw new TypeError(\"Relationship event page limit must be positive\");\n const fingerprint = createQueryFingerprint(\"relationship-events\", {\n order: \"append-sequence\",\n });\n const snapshot =\n options.cursor === undefined\n ? this.version\n : Number(decodeQueryCursorState(options.cursor, fingerprint).snapshot);\n if (\n !Number.isSafeInteger(snapshot) ||\n snapshot < 0 ||\n snapshot > this.version\n )\n throw new TypeError(\n \"Relationship event cursor snapshot version is invalid\",\n );\n const page = paginateQueryRows(this.#events.slice(0, snapshot), {\n cursor: options.cursor,\n fingerprint,\n limit: options.limit,\n readId: (event) => event.eventId,\n snapshot: String(snapshot),\n });\n return {\n version: snapshot,\n events: page.rows,\n hasMore: page.has_more,\n ...(page.next_cursor ? { nextCursor: page.next_cursor } : {}),\n };\n }\n}\n\nconst RELATIONSHIP_STORE_LOCK_ID = \"relationship-event-store\";\nconst RELATIONSHIP_NOFOLLOW_FLAG = constants.O_NOFOLLOW;\n\nfunction acquireRelationshipStoreLock(\n pmRoot: string,\n): Promise<() => Promise<void>> {\n return acquireLock(\n pmRoot,\n RELATIONSHIP_STORE_LOCK_ID,\n 30,\n `relationship-store:${process.pid}`,\n false,\n false,\n 3_000,\n );\n}\n\nasync function resolveRelationshipEventStorePath(\n pmRoot: string,\n relativePath = \"relationships/events.jsonl\",\n): Promise<string> {\n const root = path.resolve(pmRoot);\n const target = path.resolve(root, relativePath);\n const relative = path.relative(root, target);\n if (relative.length === 0)\n throw new TypeError(\n \"Relationship event path must name a file within the tracker root\",\n );\n if (\n relative === \"..\" ||\n relative.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relative)\n )\n throw new TypeError(\n \"Relationship event path must stay within the tracker root\",\n );\n await mkdir(root, { recursive: true });\n const rootStats = await lstat(root);\n if (rootStats.isSymbolicLink())\n throw new TypeError(\n \"Relationship event tracker root must not be a symbolic link\",\n );\n let current = root;\n for (const segment of relative.split(path.sep)) {\n current = path.join(current, segment);\n try {\n if ((await lstat(current)).isSymbolicLink())\n throw new TypeError(\n \"Relationship event path must not contain symbolic links\",\n );\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") break;\n throw error;\n }\n }\n return target;\n}\n\nasync function loadRelationshipEventLog(\n target: string,\n nodes: readonly string[],\n registry: RelationshipKindRegistry | undefined,\n): Promise<{ log: RelationshipEventLog; raw: string }> {\n const log = new RelationshipEventLog(nodes, { registry });\n let raw: string;\n let handle: FileHandle | undefined;\n try {\n handle = await open(\n target,\n constants.O_RDONLY | RELATIONSHIP_NOFOLLOW_FLAG,\n );\n raw = await handle.readFile(\"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\")\n return { log, raw: \"\" };\n throw error;\n } finally {\n await handle?.close();\n }\n const lines = raw.split(\"\\n\");\n for (let index = 0; index < lines.length; index += 1) {\n const line = lines[index]!.trim();\n if (!line) continue;\n let stored: RelationshipEvent;\n try {\n stored = JSON.parse(line) as RelationshipEvent;\n } catch {\n throw new TypeError(\n `Invalid relationship event JSONL at line ${index + 1}`,\n );\n }\n if (stored.sequence !== log.version + 1)\n throw new TypeError(\n `Invalid relationship event sequence at line ${index + 1}`,\n );\n log.append({\n eventId: stored.eventId,\n relationshipId: stored.relationshipId,\n action: stored.action,\n ...(stored.edge === undefined ? {} : { edge: stored.edge }),\n author: stored.author,\n timestamp: stored.timestamp,\n ...(stored.reason === undefined ? {} : { reason: stored.reason }),\n expectedVersion: log.version,\n });\n }\n return { log, raw };\n}\n\n/** Return whether an existing immutable event exactly represents one input. */\nfunction relationshipEventMatchesInput(\n event: RelationshipEvent,\n input: RelationshipEventInput,\n nodes: readonly string[],\n registry: RelationshipKindRegistry | undefined,\n): boolean {\n const timestamp = Date.parse(input.timestamp);\n let edge: RelationshipEdge | undefined;\n if (input.action !== \"remove\" && input.edge !== undefined)\n edge = new RelationshipGraph(nodes, [input.edge], registry).edges()[0];\n return (\n event.eventId === input.eventId.trim() &&\n event.relationshipId === input.relationshipId.trim() &&\n event.action === input.action &&\n event.author === input.author.trim() &&\n Number.isFinite(timestamp) &&\n event.timestamp === new Date(timestamp).toISOString() &&\n event.reason === (input.reason?.trim() || undefined) &&\n stableStringify(event.edge) === stableStringify(edge)\n );\n}\n\n/**\n * Lock-serialized durable JSONL adapter for {@link RelationshipEventLog}.\n * Every append replays the current stream while holding the workspace lock, so\n * independent processes share optimistic versions without lost updates.\n */\nexport class RelationshipEventStore {\n readonly #pmRoot: string;\n readonly #nodes: readonly string[];\n readonly #registry: RelationshipKindRegistry | undefined;\n readonly #path: string;\n #log: RelationshipEventLog;\n\n private constructor(\n options: RelationshipEventStoreOptions,\n nodes: readonly string[],\n target: string,\n log: RelationshipEventLog,\n ) {\n this.#pmRoot = options.pmRoot;\n this.#nodes = nodes;\n this.#registry = options.registry;\n this.#path = target;\n this.#log = log;\n }\n\n /** Open and validate an existing stream or create an empty store view. */\n public static async open(\n options: RelationshipEventStoreOptions,\n ): Promise<RelationshipEventStore> {\n const nodes = Object.freeze([...options.nodes]);\n const target = await resolveRelationshipEventStorePath(\n options.pmRoot,\n options.relativePath,\n );\n const release = await acquireRelationshipStoreLock(options.pmRoot);\n try {\n await resolveRelationshipEventStorePath(options.pmRoot, target);\n const { log } = await loadRelationshipEventLog(\n target,\n nodes,\n options.registry,\n );\n return new RelationshipEventStore(options, nodes, target, log);\n } finally {\n await release();\n }\n }\n\n /** Absolute JSONL path, exposed for diagnostics and backup tooling. */\n public get path(): string {\n return this.#path;\n }\n\n /** Refresh from durable history and return the current validated append sequence. */\n public async currentVersion(): Promise<number> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.version;\n }\n\n /** Append one event after refreshing under the shared workspace lock. */\n public async append(\n input: RelationshipEventInput,\n ): Promise<RelationshipEvent> {\n const release = await acquireRelationshipStoreLock(this.#pmRoot);\n try {\n const target = await resolveRelationshipEventStorePath(\n this.#pmRoot,\n this.#path,\n );\n const { log: refreshed } = await loadRelationshipEventLog(\n target,\n this.#nodes,\n this.#registry,\n );\n const event = refreshed.append(input);\n await mkdir(path.dirname(target), { recursive: true });\n await resolveRelationshipEventStorePath(this.#pmRoot, target);\n const handle = await open(\n target,\n constants.O_APPEND |\n constants.O_CREAT |\n constants.O_WRONLY |\n RELATIONSHIP_NOFOLLOW_FLAG,\n );\n try {\n await handle.appendFile(`${JSON.stringify(event)}\\n`, \"utf8\");\n } finally {\n await handle.close();\n }\n this.#log = refreshed;\n return event;\n } finally {\n await release();\n }\n }\n\n /**\n * Validate and publish a relationship-event batch as one durable replacement.\n * The shared writer lock covers refresh, collision checks, full in-memory\n * validation, and atomic rename. A validation or filesystem failure therefore\n * leaves the previous JSONL stream byte-for-byte unchanged. This path is\n * intended for migrations and bulk imports; latency-sensitive single events\n * should continue to use {@link append} and its O_APPEND write.\n */\n public async appendBatch(\n inputs: readonly RelationshipEventInput[],\n options: RelationshipEventBatchOptions = {},\n ): Promise<RelationshipEventBatchResult> {\n const release = await acquireRelationshipStoreLock(this.#pmRoot);\n try {\n const target = await resolveRelationshipEventStorePath(\n this.#pmRoot,\n this.#path,\n );\n const { log: refreshed, raw } = await loadRelationshipEventLog(\n target,\n this.#nodes,\n this.#registry,\n );\n const versionBefore = refreshed.version;\n const existing = new Map(\n refreshed.events().map((event) => [event.eventId, event]),\n );\n const appended: RelationshipEvent[] = [];\n const skippedEventIds: string[] = [];\n for (const input of inputs) {\n const eventId = input.eventId.trim();\n const stored = existing.get(eventId);\n if (stored !== undefined) {\n if (\n options.existingEventPolicy === \"skip_identical\" &&\n relationshipEventMatchesInput(\n stored,\n input,\n this.#nodes,\n this.#registry,\n )\n ) {\n skippedEventIds.push(stored.eventId);\n continue;\n }\n if (options.existingEventPolicy === \"skip_identical\")\n throw new TypeError(\n `Relationship event id collision with different content: ${eventId}`,\n );\n }\n const event = refreshed.append(input);\n existing.set(event.eventId, event);\n appended.push(event);\n }\n if (appended.length > 0) {\n const prefix = raw.length === 0 || raw.endsWith(\"\\n\") ? raw : `${raw}\\n`;\n await mkdir(path.dirname(target), { recursive: true });\n await resolveRelationshipEventStorePath(this.#pmRoot, target);\n await writeFileAtomic(\n target,\n `${prefix}${appended.map((event) => JSON.stringify(event)).join(\"\\n\")}\\n`,\n );\n }\n this.#log = refreshed;\n return Object.freeze({\n version_before: versionBefore,\n version_after: refreshed.version,\n appended: Object.freeze(appended),\n skipped_event_ids: Object.freeze(skippedEventIds),\n });\n } finally {\n await release();\n }\n }\n\n /** Refresh from durable history and materialize an exact validated snapshot. */\n public async snapshot(\n options: Parameters<RelationshipEventLog[\"snapshot\"]>[0] = {},\n ): Promise<RelationshipSnapshot> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.snapshot(options);\n }\n\n /** Refresh from durable history and page immutable events. */\n public async page(\n options: Parameters<RelationshipEventLog[\"page\"]>[0],\n ): Promise<RelationshipEventPage> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.page(options);\n }\n\n /**\n * Refresh once under the shared store lock, then stream a coherent immutable\n * prefix without holding the writer lock while the consumer processes batches.\n */\n public async *stream(\n options: RelationshipEventStreamOptions = {},\n ): AsyncGenerator<readonly RelationshipEvent[]> {\n this.#log = await this.#refreshFromDurableHistory();\n yield* this.#log.stream(options);\n }\n\n /** Refresh once and fold a coherent durable prefix into application state. */\n public async project<State>(\n initialState: State,\n reducer: RelationshipEventReducer<State>,\n options: Omit<RelationshipEventStreamOptions, \"batchSize\"> = {},\n ): Promise<RelationshipEventProjection<State>> {\n this.#log = await this.#refreshFromDurableHistory();\n return this.#log.project(initialState, reducer, options);\n }\n\n /** Serialize a durable refresh with writers so readers never observe a torn JSONL tail. */\n async #refreshFromDurableHistory(): Promise<RelationshipEventLog> {\n const release = await acquireRelationshipStoreLock(this.#pmRoot);\n try {\n const target = await resolveRelationshipEventStorePath(\n this.#pmRoot,\n this.#path,\n );\n return (\n await loadRelationshipEventLog(\n target,\n this.#nodes,\n this.#registry,\n )\n ).log;\n } finally {\n await release();\n }\n }\n}\n"],"names":[],"mappings":"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","debugId":"c2ea8300-fc2a-5562-ba56-f5364990f479"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type WorkspaceRelationshipItem } from "./graph/assembly.js";
|
|
2
|
+
import type { RelationshipEventInput } from "./relationship-history.js";
|
|
3
|
+
import type { RelationshipKindRegistry } from "./relationships.js";
|
|
4
|
+
/** Controls for deterministic legacy relationship-event planning. */
|
|
5
|
+
export interface RelationshipEventBackfillOptions {
|
|
6
|
+
/** Stable migration identity retained in generated event and relationship ids. */
|
|
7
|
+
migrationId: string;
|
|
8
|
+
/** Attributable actor responsible for the migration. */
|
|
9
|
+
author: string;
|
|
10
|
+
/** Valid event timestamp shared by the deterministic migration batch. */
|
|
11
|
+
timestamp: string;
|
|
12
|
+
/** Optional custom relationship ontology used during legacy normalization. */
|
|
13
|
+
registry?: RelationshipKindRegistry;
|
|
14
|
+
/** Event ids already committed by an earlier partial or concurrent run. */
|
|
15
|
+
existingEventIds?: Iterable<string>;
|
|
16
|
+
}
|
|
17
|
+
/** Deterministic migration plan plus compact governance evidence. */
|
|
18
|
+
export interface RelationshipEventBackfillPlan {
|
|
19
|
+
/** Caller-provided stable migration identity. */
|
|
20
|
+
migration_id: string;
|
|
21
|
+
/** SHA-256 identity of the complete normalized plan before resume filtering. */
|
|
22
|
+
fingerprint: string;
|
|
23
|
+
/** Fixed node universe required when opening a relationship event store. */
|
|
24
|
+
nodes: readonly string[];
|
|
25
|
+
/** Missing deterministic events that remain to be committed. */
|
|
26
|
+
events: readonly RelationshipEventInput[];
|
|
27
|
+
/** Total unique normalized edges represented by the complete plan. */
|
|
28
|
+
edge_count: number;
|
|
29
|
+
/** Events omitted because their deterministic ids already exist. */
|
|
30
|
+
skipped_existing_count: number;
|
|
31
|
+
/** Duplicate raw dependency identities found before graph deduplication. */
|
|
32
|
+
duplicate_dependency_rows: number;
|
|
33
|
+
/** Missing internal references retained as explicit placeholder nodes. */
|
|
34
|
+
dangling_reference_count: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Convert legacy item relationship fields into an immutable deterministic event
|
|
38
|
+
* batch. Input order does not affect ids, fingerprints, or event order.
|
|
39
|
+
* Dangling internal targets and external dependency targets become explicit
|
|
40
|
+
* nodes so replay never silently drops contextual edges.
|
|
41
|
+
*/
|
|
42
|
+
export declare function planRelationshipEventBackfill(items: readonly WorkspaceRelationshipItem[], options: RelationshipEventBackfillOptions): RelationshipEventBackfillPlan;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module sdk/relationship-migration
|
|
3
|
+
*
|
|
4
|
+
* Plans deterministic, resumable migration of legacy item hierarchy and
|
|
5
|
+
* dependency fields into the immutable relationship-event platform. Planning
|
|
6
|
+
* is storage-independent and side-effect free: callers can inspect governance
|
|
7
|
+
* evidence, persist the event batch through {@link RelationshipEventStore}, or
|
|
8
|
+
* feed the same plan into another conforming durable adapter.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
!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]="f9779cc4-d1b9-5b9c-ad7c-69d125261898")}catch(e){}}();
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
13
|
+
import { assembleWorkspaceRelationshipGraph, } from "./graph/assembly.js";
|
|
14
|
+
/** Validate and normalize one required migration text field. */
|
|
15
|
+
function requiredMigrationText(value, field) {
|
|
16
|
+
if (typeof value !== "string" || value.trim().length === 0)
|
|
17
|
+
throw new TypeError(`Relationship backfill ${field} must be non-empty`);
|
|
18
|
+
return value.trim();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert legacy item relationship fields into an immutable deterministic event
|
|
22
|
+
* batch. Input order does not affect ids, fingerprints, or event order.
|
|
23
|
+
* Dangling internal targets and external dependency targets become explicit
|
|
24
|
+
* nodes so replay never silently drops contextual edges.
|
|
25
|
+
*/
|
|
26
|
+
export function planRelationshipEventBackfill(items, options) {
|
|
27
|
+
const migrationId = requiredMigrationText(options.migrationId, "migrationId");
|
|
28
|
+
const author = requiredMigrationText(options.author, "author");
|
|
29
|
+
const parsedTimestamp = Date.parse(options.timestamp);
|
|
30
|
+
if (!Number.isFinite(parsedTimestamp))
|
|
31
|
+
throw new TypeError("Relationship backfill timestamp must be valid");
|
|
32
|
+
const timestamp = new Date(parsedTimestamp).toISOString();
|
|
33
|
+
const assembly = assembleWorkspaceRelationshipGraph(items, undefined, options.registry);
|
|
34
|
+
const nodes = assembly.graph.nodes();
|
|
35
|
+
const completeEvents = assembly.graph.edges().map((edge) => {
|
|
36
|
+
const digest = createHash("sha256")
|
|
37
|
+
.update(JSON.stringify([
|
|
38
|
+
migrationId,
|
|
39
|
+
edge.kind,
|
|
40
|
+
edge.source,
|
|
41
|
+
edge.target,
|
|
42
|
+
edge.createdAt ?? null,
|
|
43
|
+
edge.author ?? null,
|
|
44
|
+
edge.payload ?? null,
|
|
45
|
+
]))
|
|
46
|
+
.digest("hex")
|
|
47
|
+
.slice(0, 24);
|
|
48
|
+
return Object.freeze({
|
|
49
|
+
eventId: `backfill:${migrationId}:${digest}`,
|
|
50
|
+
relationshipId: `migration:${migrationId}:${digest}`,
|
|
51
|
+
action: "add",
|
|
52
|
+
edge,
|
|
53
|
+
author,
|
|
54
|
+
timestamp,
|
|
55
|
+
reason: `Backfill ${migrationId} from legacy item metadata`,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
const fingerprint = createHash("sha256")
|
|
59
|
+
.update(JSON.stringify({ migrationId, nodes, events: completeEvents }))
|
|
60
|
+
.digest("hex");
|
|
61
|
+
const existingEventIds = new Set([...(options.existingEventIds ?? [])]
|
|
62
|
+
.filter((id) => typeof id === "string")
|
|
63
|
+
.map((id) => id.trim())
|
|
64
|
+
.filter(Boolean));
|
|
65
|
+
const events = completeEvents.filter((event) => !existingEventIds.has(event.eventId));
|
|
66
|
+
return Object.freeze({
|
|
67
|
+
migration_id: migrationId,
|
|
68
|
+
fingerprint,
|
|
69
|
+
nodes,
|
|
70
|
+
events: Object.freeze(events),
|
|
71
|
+
edge_count: completeEvents.length,
|
|
72
|
+
skipped_existing_count: completeEvents.length - events.length,
|
|
73
|
+
duplicate_dependency_rows: assembly.duplicateRows.length,
|
|
74
|
+
dangling_reference_count: assembly.dangling.active.length + assembly.dangling.legacy_terminal.length,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=relationship-migration.js.map
|
|
78
|
+
//# debugId=f9779cc4-d1b9-5b9c-ad7c-69d125261898
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-migration.js","sources":["sdk/relationship-migration.ts"],"sourceRoot":"/","sourcesContent":["/**\n * @module sdk/relationship-migration\n *\n * Plans deterministic, resumable migration of legacy item hierarchy and\n * dependency fields into the immutable relationship-event platform. Planning\n * is storage-independent and side-effect free: callers can inspect governance\n * evidence, persist the event batch through {@link RelationshipEventStore}, or\n * feed the same plan into another conforming durable adapter.\n */\nimport { createHash } from \"node:crypto\";\nimport {\n assembleWorkspaceRelationshipGraph,\n type WorkspaceRelationshipItem,\n} from \"./graph/assembly.js\";\nimport type { RelationshipEventInput } from \"./relationship-history.js\";\nimport type { RelationshipKindRegistry } from \"./relationships.js\";\n\n/** Controls for deterministic legacy relationship-event planning. */\nexport interface RelationshipEventBackfillOptions {\n /** Stable migration identity retained in generated event and relationship ids. */\n migrationId: string;\n /** Attributable actor responsible for the migration. */\n author: string;\n /** Valid event timestamp shared by the deterministic migration batch. */\n timestamp: string;\n /** Optional custom relationship ontology used during legacy normalization. */\n registry?: RelationshipKindRegistry;\n /** Event ids already committed by an earlier partial or concurrent run. */\n existingEventIds?: Iterable<string>;\n}\n\n/** Deterministic migration plan plus compact governance evidence. */\nexport interface RelationshipEventBackfillPlan {\n /** Caller-provided stable migration identity. */\n migration_id: string;\n /** SHA-256 identity of the complete normalized plan before resume filtering. */\n fingerprint: string;\n /** Fixed node universe required when opening a relationship event store. */\n nodes: readonly string[];\n /** Missing deterministic events that remain to be committed. */\n events: readonly RelationshipEventInput[];\n /** Total unique normalized edges represented by the complete plan. */\n edge_count: number;\n /** Events omitted because their deterministic ids already exist. */\n skipped_existing_count: number;\n /** Duplicate raw dependency identities found before graph deduplication. */\n duplicate_dependency_rows: number;\n /** Missing internal references retained as explicit placeholder nodes. */\n dangling_reference_count: number;\n}\n\n/** Validate and normalize one required migration text field. */\nfunction requiredMigrationText(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim().length === 0)\n throw new TypeError(`Relationship backfill ${field} must be non-empty`);\n return value.trim();\n}\n\n/**\n * Convert legacy item relationship fields into an immutable deterministic event\n * batch. Input order does not affect ids, fingerprints, or event order.\n * Dangling internal targets and external dependency targets become explicit\n * nodes so replay never silently drops contextual edges.\n */\nexport function planRelationshipEventBackfill(\n items: readonly WorkspaceRelationshipItem[],\n options: RelationshipEventBackfillOptions,\n): RelationshipEventBackfillPlan {\n const migrationId = requiredMigrationText(options.migrationId, \"migrationId\");\n const author = requiredMigrationText(options.author, \"author\");\n const parsedTimestamp = Date.parse(options.timestamp);\n if (!Number.isFinite(parsedTimestamp))\n throw new TypeError(\"Relationship backfill timestamp must be valid\");\n const timestamp = new Date(parsedTimestamp).toISOString();\n const assembly = assembleWorkspaceRelationshipGraph(\n items,\n undefined,\n options.registry,\n );\n const nodes = assembly.graph.nodes();\n const completeEvents = assembly.graph.edges().map((edge) => {\n const digest = createHash(\"sha256\")\n .update(\n JSON.stringify([\n migrationId,\n edge.kind,\n edge.source,\n edge.target,\n edge.createdAt ?? null,\n edge.author ?? null,\n edge.payload ?? null,\n ]),\n )\n .digest(\"hex\")\n .slice(0, 24);\n return Object.freeze({\n eventId: `backfill:${migrationId}:${digest}`,\n relationshipId: `migration:${migrationId}:${digest}`,\n action: \"add\" as const,\n edge,\n author,\n timestamp,\n reason: `Backfill ${migrationId} from legacy item metadata`,\n });\n });\n const fingerprint = createHash(\"sha256\")\n .update(JSON.stringify({ migrationId, nodes, events: completeEvents }))\n .digest(\"hex\");\n const existingEventIds = new Set(\n [...(options.existingEventIds ?? [])]\n .filter((id): id is string => typeof id === \"string\")\n .map((id) => id.trim())\n .filter(Boolean),\n );\n const events = completeEvents.filter(\n (event) => !existingEventIds.has(event.eventId),\n );\n return Object.freeze({\n migration_id: migrationId,\n fingerprint,\n nodes,\n events: Object.freeze(events),\n edge_count: completeEvents.length,\n skipped_existing_count: completeEvents.length - events.length,\n duplicate_dependency_rows: assembly.duplicateRows.length,\n dangling_reference_count:\n assembly.dangling.active.length + assembly.dangling.legacy_terminal.length,\n });\n}\n"],"names":[],"mappings":"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","debugId":"f9779cc4-d1b9-5b9c-ad7c-69d125261898"}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* transaction contract and normalizes full item documents for CLI round trips.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
9
|
-
import { EXIT_CODE } from "../core/shared/constants.js";
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d482b64e-460e-515c-9dcd-43c6210167d2")}catch(e){}}();
|
|
9
|
+
import { EXIT_CODE, ITEM_PROJECT_CONTEXT_KEYS, } from "../core/shared/constants.js";
|
|
10
10
|
import { PmCliError } from "../core/shared/errors.js";
|
|
11
11
|
import { levenshteinDistanceWithinLimit } from "../core/shared/levenshtein.js";
|
|
12
12
|
import { CLOSE_FLAG_CONTRACTS } from "./cli-contracts/flag-contracts.js";
|
|
@@ -44,29 +44,8 @@ const ITEM_FIELD_KEYS = new Set([
|
|
|
44
44
|
"definition_of_ready",
|
|
45
45
|
"order",
|
|
46
46
|
"rank",
|
|
47
|
-
"goal",
|
|
48
|
-
"objective",
|
|
49
|
-
"value",
|
|
50
|
-
"impact",
|
|
51
|
-
"outcome",
|
|
52
|
-
"why_now",
|
|
53
47
|
"assignee",
|
|
54
|
-
|
|
55
|
-
"reviewer",
|
|
56
|
-
"risk",
|
|
57
|
-
"confidence",
|
|
58
|
-
"sprint",
|
|
59
|
-
"release",
|
|
60
|
-
"blocked_by",
|
|
61
|
-
"blocked_reason",
|
|
62
|
-
"unblock_note",
|
|
63
|
-
"reporter",
|
|
64
|
-
"severity",
|
|
65
|
-
"environment",
|
|
66
|
-
"repro_steps",
|
|
67
|
-
"resolution",
|
|
68
|
-
"expected_result",
|
|
69
|
-
"actual_result",
|
|
48
|
+
...ITEM_PROJECT_CONTEXT_KEYS,
|
|
70
49
|
"affected_version",
|
|
71
50
|
"fixed_version",
|
|
72
51
|
"component",
|
|
@@ -372,4 +351,4 @@ export function validateItemMutationRows(value) {
|
|
|
372
351
|
return parseItemMutationBatch(JSON.stringify(value));
|
|
373
352
|
}
|
|
374
353
|
//# sourceMappingURL=structured-mutations.js.map
|
|
375
|
-
//# debugId=
|
|
354
|
+
//# debugId=d482b64e-460e-515c-9dcd-43c6210167d2
|