@unbrained/pm-cli 2026.7.19 → 2026.7.20
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/AGENTS.md +2 -0
- package/CHANGELOG.md +36 -0
- package/dist/cli/commands/append.js +13 -6
- package/dist/cli/commands/append.js.map +1 -1
- package/dist/cli/commands/calendar.d.ts +1 -1
- package/dist/cli/commands/calendar.js +2 -2
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/comments.js +2 -5
- package/dist/cli/commands/comments.js.map +1 -1
- package/dist/cli/commands/completion.js +11 -3
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/context.d.ts +1 -1
- package/dist/cli/commands/context.js +2 -2
- package/dist/cli/commands/context.js.map +1 -1
- package/dist/cli/commands/contracts.js +4 -3
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/copy.js +5 -3
- package/dist/cli/commands/copy.js.map +1 -1
- package/dist/cli/commands/create.d.ts +3 -1
- package/dist/cli/commands/create.js +5 -3
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/merge.d.ts +8 -0
- package/dist/cli/commands/merge.js +12 -0
- package/dist/cli/commands/merge.js.map +1 -0
- package/dist/cli/commands/plan.d.ts +1 -1
- package/dist/cli/commands/plan.js +2 -2
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/update-many.d.ts +5 -0
- package/dist/cli/commands/update-many.js +81 -6
- package/dist/cli/commands/update-many.js.map +1 -1
- package/dist/cli/commands/update.d.ts +5 -1
- package/dist/cli/commands/update.js +50 -4
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/register-list-query.js +14 -2
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +61 -2
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +5 -3
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/registration-helpers.js +4 -2
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli-bundle/bundle-manifest.json +365 -333
- package/dist/cli-bundle/chunks/{append-MBXHNWSX.js → append-E6V54WOQ.js} +5 -5
- package/dist/cli-bundle/chunks/append-NNJ3EFIT.js +11 -0
- package/dist/cli-bundle/chunks/{chunk-M4B4RK4J.js → chunk-2BO4CA46.js} +14 -238
- package/dist/cli-bundle/chunks/{chunk-M4B4RK4J.js.map → chunk-2BO4CA46.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-MQOSMBWV.js → chunk-3AO5VSDR.js} +25 -6
- package/dist/cli-bundle/chunks/chunk-3AO5VSDR.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-ODEIDKGW.js → chunk-3LPFHE3P.js} +596 -154
- package/dist/cli-bundle/chunks/chunk-3LPFHE3P.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-YGEA4CLH.js → chunk-3MCTMJXI.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-N7FCFJ76.js → chunk-3P7UJQOX.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-7B7IHMLH.js → chunk-3VY6MIEO.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-3EZZTFL2.js → chunk-4F6BWJ4J.js} +51 -43
- package/dist/cli-bundle/chunks/chunk-4F6BWJ4J.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-VA3H7VVC.js → chunk-4L23AGQ7.js} +9 -7
- package/dist/cli-bundle/chunks/chunk-4L23AGQ7.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-5S6IZXK7.js → chunk-4U4Z6AHI.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-UOIFZ66L.js → chunk-4XGJLADW.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-SUNZKVAH.js → chunk-5IZJWSDB.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-QQ77W23U.js → chunk-5NTE36LD.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-EVAN5VJA.js → chunk-5OK4UGFV.js} +5 -8
- package/dist/cli-bundle/chunks/{chunk-EVAN5VJA.js.map → chunk-5OK4UGFV.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-H3YKUVDR.js → chunk-5UX66S6U.js} +26 -7
- package/dist/cli-bundle/chunks/chunk-5UX66S6U.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-KGPLSHJD.js → chunk-6C2ZZX5Z.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Q5NHJ6RO.js → chunk-6JUTHVQS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-NTS2RKHN.js → chunk-6VIJ7UA5.js} +15 -15
- package/dist/cli-bundle/chunks/{chunk-BBGR4FKQ.js → chunk-6XMUURSS.js} +6 -6
- package/dist/cli-bundle/chunks/chunk-6XMUURSS.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-XVB6BATY.js → chunk-72LQ4TKV.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-WCBB6VI3.js → chunk-7AVEY74G.js} +8 -5
- package/dist/cli-bundle/chunks/chunk-7AVEY74G.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-YG56M3NE.js → chunk-7DOJC3HS.js} +8 -8
- package/dist/cli-bundle/chunks/chunk-7DOJC3HS.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-KZ5AC6B5.js → chunk-7WCE6Y64.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-VQOG2ETB.js → chunk-AF2CCM5U.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-P24ZU5QV.js → chunk-AOEOYL3S.js} +49 -12
- package/dist/cli-bundle/chunks/chunk-AOEOYL3S.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-BZKE2O5V.js → chunk-BKIAH72N.js} +8 -6
- package/dist/cli-bundle/chunks/chunk-BKIAH72N.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-RWAIRGBC.js → chunk-C3KD7U3T.js} +12 -243
- package/dist/cli-bundle/chunks/chunk-C3KD7U3T.js.map +7 -0
- package/dist/cli-bundle/chunks/chunk-CFHAODHQ.js +334 -0
- package/dist/cli-bundle/chunks/chunk-CFHAODHQ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-TELI67UP.js → chunk-CQTQKUUV.js} +6 -9
- package/dist/cli-bundle/chunks/{chunk-TELI67UP.js.map → chunk-CQTQKUUV.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-ZUCBPXNA.js → chunk-D6NXDNP3.js} +5 -5
- package/dist/cli-bundle/chunks/chunk-D6NXDNP3.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-EAV3P54W.js → chunk-DAQ45GCS.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-6V4T4RD3.js → chunk-DVDBQA3B.js} +79 -22
- package/dist/cli-bundle/chunks/chunk-DVDBQA3B.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-E6LEMURX.js +249 -0
- package/dist/cli-bundle/chunks/chunk-E6LEMURX.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-ZF52NVRT.js → chunk-E7ICD63T.js} +131 -179
- package/dist/cli-bundle/chunks/chunk-E7ICD63T.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-RX53WHFI.js → chunk-EJDGV4GR.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-IXG5CMBR.js → chunk-FDHPAVVB.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-KAE727L2.js → chunk-FSRHYUDA.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-FSRHYUDA.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-46Z6FAVP.js → chunk-G3COA6GS.js} +51 -43
- package/dist/cli-bundle/chunks/chunk-G3COA6GS.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-A4FVWFZY.js → chunk-GFQP7HAZ.js} +8 -6
- package/dist/cli-bundle/chunks/chunk-GFQP7HAZ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-2XPDCXK5.js → chunk-GIQSU6S2.js} +6 -6
- package/dist/cli-bundle/chunks/chunk-GIQSU6S2.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-V4QHAMI5.js → chunk-GROYI4RB.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-77XFQRTD.js → chunk-GSJSM5BJ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-QYGK2XQ3.js → chunk-GTLCVJOE.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-VSQE43NO.js → chunk-GV2262OF.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-N2TEEOXJ.js → chunk-GVI6FAFG.js} +8 -6
- package/dist/cli-bundle/chunks/chunk-GVI6FAFG.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-A5EQPNV7.js → chunk-GVT754PX.js} +44 -3
- package/dist/cli-bundle/chunks/chunk-GVT754PX.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-Y2VSGFT4.js → chunk-HB3P4M52.js} +22 -7
- package/dist/cli-bundle/chunks/chunk-HB3P4M52.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-STBCBDKF.js → chunk-HCEBZNC3.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-EEECAV5M.js → chunk-HEWM6CEN.js} +80 -25
- package/dist/cli-bundle/chunks/chunk-HEWM6CEN.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GKCEEXMA.js → chunk-HQ3SB4CN.js} +21 -6
- package/dist/cli-bundle/chunks/{chunk-GKCEEXMA.js.map → chunk-HQ3SB4CN.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-U6RYD446.js → chunk-HRW7GF6T.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-D35WYXWC.js → chunk-HYW67VJ5.js} +6 -3
- package/dist/cli-bundle/chunks/chunk-HYW67VJ5.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-OKWJUL6F.js → chunk-I577UHC7.js} +16 -9
- package/dist/cli-bundle/chunks/{chunk-OKWJUL6F.js.map → chunk-I577UHC7.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XDWXPG2E.js → chunk-IAQE32BI.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-66SRNEBK.js → chunk-IJNK6WW2.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-INSTSQNZ.js +623 -0
- package/dist/cli-bundle/chunks/chunk-INSTSQNZ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-A3GAQLBH.js → chunk-IX677TRO.js} +75 -12
- package/dist/cli-bundle/chunks/chunk-IX677TRO.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-RLLOZAM2.js → chunk-IY6VZ3IW.js} +29 -8
- package/dist/cli-bundle/chunks/chunk-IY6VZ3IW.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-SVAWG7EE.js → chunk-J4FBIFU6.js} +45 -4
- package/dist/cli-bundle/chunks/chunk-J4FBIFU6.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-AGEBQRBG.js → chunk-JAPE62Y5.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-UWAQI3B7.js → chunk-JGUKMMRS.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UU6EP25G.js → chunk-JH2ZSLO3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-GRDK25BN.js → chunk-JHJSFOAM.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-FQO5THHM.js → chunk-JM6YAXTR.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-E7KBMWEF.js → chunk-JSLT7WVE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FIUTBFC6.js → chunk-K4CI6Y45.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IEMXESIS.js → chunk-KSPWRNVP.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-3QNUDDY2.js → chunk-KZEANWJS.js} +14 -12
- package/dist/cli-bundle/chunks/{chunk-3QNUDDY2.js.map → chunk-KZEANWJS.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BFJP4VYC.js → chunk-L7BH7IWU.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-2UCG5H6B.js → chunk-LPEYZRUR.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-FQF6VVPH.js → chunk-MYSS5H2A.js} +9 -7
- package/dist/cli-bundle/chunks/{chunk-FQF6VVPH.js.map → chunk-MYSS5H2A.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-IR3GOO6E.js → chunk-NHT3F4WZ.js} +15 -15
- package/dist/cli-bundle/chunks/{chunk-6BNV3G6C.js → chunk-NLR32VFS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-BDC4TW4B.js → chunk-OV7MSW3I.js} +15 -13
- package/dist/cli-bundle/chunks/chunk-OV7MSW3I.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-EI3UIMZM.js → chunk-OWXOPDHD.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-P7JTWYLH.js +246 -0
- package/dist/cli-bundle/chunks/chunk-P7JTWYLH.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-AQUNTB7G.js → chunk-PEQGTJ5Q.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-QFG4MB7P.js → chunk-POG76WWZ.js} +28 -7
- package/dist/cli-bundle/chunks/chunk-POG76WWZ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-MI3346YW.js → chunk-QANSTTC7.js} +129 -170
- package/dist/cli-bundle/chunks/chunk-QANSTTC7.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-T6MOTLOJ.js → chunk-QJKL5PHS.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SBW7EQC4.js → chunk-QLZ643FM.js} +76 -13
- package/dist/cli-bundle/chunks/chunk-QLZ643FM.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-XKVHL3MB.js → chunk-QWRVBJ4D.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-R3EWPG4A.js +106 -0
- package/dist/cli-bundle/chunks/chunk-R3EWPG4A.js.map +1 -0
- package/dist/cli-bundle/chunks/chunk-R5U2VZ3K.js +344 -0
- package/dist/cli-bundle/chunks/chunk-R5U2VZ3K.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-VFA5EIEN.js → chunk-R7QV7ICM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-NPEYH6CE.js → chunk-RDV4ZFYS.js} +12 -10
- package/dist/cli-bundle/chunks/{chunk-NPEYH6CE.js.map → chunk-RDV4ZFYS.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-K2L6FZBX.js → chunk-RJO3YAFM.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-YIC5NGXF.js → chunk-RMF7LMBS.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-YIC5NGXF.js.map → chunk-RMF7LMBS.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-MRXAHR4B.js → chunk-RZJLNXFG.js} +50 -13
- package/dist/cli-bundle/chunks/chunk-RZJLNXFG.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-DJAGYYCQ.js → chunk-SC2HMDGB.js} +19 -3
- package/dist/cli-bundle/chunks/chunk-SC2HMDGB.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-SGJB6PXA.js → chunk-SF3DT5HJ.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-SG74J6MV.js +604 -0
- package/dist/cli-bundle/chunks/chunk-SG74J6MV.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-Q3K5XPAQ.js → chunk-SR3JOATZ.js} +18 -2
- package/dist/cli-bundle/chunks/chunk-SR3JOATZ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-DUDLSQFG.js → chunk-SSKOQNMS.js} +14 -12
- package/dist/cli-bundle/chunks/{chunk-DUDLSQFG.js.map → chunk-SSKOQNMS.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-UNNCT5QY.js → chunk-SZVB53Y3.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-JBW2S2C6.js → chunk-T44FMVRL.js} +613 -157
- package/dist/cli-bundle/chunks/chunk-T44FMVRL.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GFZB5CLP.js → chunk-T6PPNM7V.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-UE7LK3RE.js → chunk-THAOZG4U.js} +9 -7
- package/dist/cli-bundle/chunks/chunk-THAOZG4U.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-IGBBTPM5.js → chunk-TOBGV45Y.js} +4 -4
- package/dist/cli-bundle/chunks/chunk-TOBGV45Y.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-W6IEJXNC.js → chunk-TVYYO5A7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-TYHJDFYW.js +109 -0
- package/dist/cli-bundle/chunks/chunk-TYHJDFYW.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-DOASIOQR.js → chunk-UQLXSG72.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-IDUTGRDM.js → chunk-URXVHN3L.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-URXVHN3L.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-7CHWLT2J.js → chunk-UVN66B3M.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-Q6JPYR7I.js → chunk-UX6SSO2I.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-JPWUZOMR.js → chunk-UZDQXNUB.js} +75 -20
- package/dist/cli-bundle/chunks/chunk-UZDQXNUB.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-OK7VSX3N.js → chunk-UZLJOEAC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-4PSJVGRE.js → chunk-VDO2JMD4.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-IRJ6F23W.js → chunk-VQIHNHMJ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-FQODDTE7.js → chunk-WUVEBQW6.js} +7 -5
- package/dist/cli-bundle/chunks/{chunk-FQODDTE7.js.map → chunk-WUVEBQW6.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-Q4PSG2GV.js → chunk-WVA4DVNV.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-Q4PSG2GV.js.map → chunk-WVA4DVNV.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-4M6RZJXF.js → chunk-WWNL6WMH.js} +3 -3
- package/dist/cli-bundle/chunks/chunk-WWNL6WMH.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-3KPNOZOH.js → chunk-X6K5XTTN.js} +78 -21
- package/dist/cli-bundle/chunks/chunk-X6K5XTTN.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-G33XIMRT.js → chunk-XJF7CDNH.js} +17 -10
- package/dist/cli-bundle/chunks/{chunk-G33XIMRT.js.map → chunk-XJF7CDNH.js.map} +1 -1
- package/dist/cli-bundle/chunks/{chunk-AR24KW26.js → chunk-YBT7O4KT.js} +17 -112
- package/dist/cli-bundle/chunks/chunk-YBT7O4KT.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-CZA2DXCV.js → chunk-YQQNAKW3.js} +17 -105
- package/dist/cli-bundle/chunks/chunk-YQQNAKW3.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-OKPZDH43.js → chunk-YQWCZ5AC.js} +7 -5
- package/dist/cli-bundle/chunks/{chunk-OKPZDH43.js.map → chunk-YQWCZ5AC.js.map} +2 -2
- package/dist/cli-bundle/chunks/{chunk-LT5UWU7H.js → chunk-ZOJ3LR7O.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-3HSRP6T2.js → chunk-ZOY5K4D3.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-XXWDEQ6O.js → chunk-ZV2NTVMJ.js} +4 -4
- package/dist/cli-bundle/chunks/{chunk-UW6HCMP2.js → chunk-ZYPFOO3L.js} +9 -9
- package/dist/cli-bundle/chunks/close-O5QVZ6ET.js +12 -0
- package/dist/cli-bundle/chunks/{close-7NWA3GLA.js → close-QEMOYZN3.js} +5 -5
- package/dist/cli-bundle/chunks/close-many-SDA426VT.js +24 -0
- package/dist/cli-bundle/chunks/{close-many-YALQ7AXS.js → close-many-UTZANOCQ.js} +15 -14
- package/dist/cli-bundle/chunks/{comments-SQIQ5WYR.js → comments-LZN6FXXC.js} +7 -7
- package/dist/cli-bundle/chunks/comments-VBQ345ND.js +13 -0
- package/dist/cli-bundle/chunks/{copy-YDAMENCP.js → copy-DKTSSCK7.js} +4 -4
- package/dist/cli-bundle/chunks/copy-M7DDI6LS.js +9 -0
- package/dist/cli-bundle/chunks/{create-JSL6CXU3.js → create-GG4RBCGC.js} +11 -11
- package/dist/cli-bundle/chunks/create-JBC5KUW6.js +29 -0
- package/dist/cli-bundle/chunks/{delete-IGVOZEU2.js → delete-LCS3VPDH.js} +4 -4
- package/dist/cli-bundle/chunks/delete-MD7YXQLH.js +10 -0
- package/dist/cli-bundle/chunks/{deps-BQAXUQAK.js → deps-DELOO4TL.js} +6 -6
- package/dist/cli-bundle/chunks/{deps-CBPPSS6J.js → deps-FI4O6NQS.js} +6 -6
- package/dist/cli-bundle/chunks/docs-2UYBP5D6.js +14 -0
- package/dist/cli-bundle/chunks/{docs-NS2AZWCN.js → docs-6Z2MP526.js} +6 -6
- package/dist/cli-bundle/chunks/{files-XUUBQ76I.js → files-HEUGSJZL.js} +6 -6
- package/dist/cli-bundle/chunks/{files-PVWEPT5J.js → files-HKEAN5MA.js} +6 -6
- package/dist/cli-bundle/chunks/{focus-DHBHKK3E.js → focus-7SOUT5PZ.js} +5 -5
- package/dist/cli-bundle/chunks/focus-DRQ6FQH6.js +10 -0
- package/dist/cli-bundle/chunks/history-compact-65YVN5DB.js +17 -0
- package/dist/cli-bundle/chunks/{history-compact-3TNPYVFG.js → history-compact-7NDVP3PT.js} +7 -6
- package/dist/cli-bundle/chunks/{history-redact-KKFDICCF.js → history-redact-7YBL4XSG.js} +5 -4
- package/dist/cli-bundle/chunks/{history-redact-ELRL73XN.js → history-redact-IZGNJBU4.js} +5 -4
- package/dist/cli-bundle/chunks/{history-repair-J7WKZFAG.js → history-repair-7M4PYQUH.js} +8 -6
- package/dist/cli-bundle/chunks/history-repair-GNGETJLI.js +18 -0
- package/dist/cli-bundle/chunks/learnings-3YXDRWFT.js +13 -0
- package/dist/cli-bundle/chunks/{learnings-X4D6JCCG.js → learnings-ALC6IMNL.js} +7 -7
- package/dist/cli-bundle/chunks/notes-7JMLQ447.js +13 -0
- package/dist/cli-bundle/chunks/{notes-UQC6VS6N.js → notes-JFCLTC5C.js} +7 -7
- package/dist/cli-bundle/chunks/plan-KOIPWVOZ.js +26 -0
- package/dist/cli-bundle/chunks/{plan-5GKRBJJO.js → plan-T3XB3WTK.js} +12 -12
- package/dist/cli-bundle/chunks/{profile-5PQAPCLF.js → profile-OILJHKUW.js} +12 -11
- package/dist/cli-bundle/chunks/{profile-CW4BD3FO.js → profile-RJXA7PGS.js} +12 -11
- package/dist/cli-bundle/chunks/{register-list-query-PHIPDFP2.js → register-list-query-CFVG75P3.js} +30 -21
- package/dist/cli-bundle/chunks/{register-list-query-PHIPDFP2.js.map → register-list-query-CFVG75P3.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-list-query-HTDQE6VI.js → register-list-query-E7UVY4TN.js} +29 -20
- package/dist/cli-bundle/chunks/{register-list-query-HTDQE6VI.js.map → register-list-query-E7UVY4TN.js.map} +2 -2
- package/dist/cli-bundle/chunks/{register-mutation-BLEWM5I6.js → register-mutation-4VJTXBZW.js} +86 -32
- package/dist/cli-bundle/chunks/register-mutation-4VJTXBZW.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-OTYHR7J6.js → register-mutation-IQ55E25C.js} +78 -33
- package/dist/cli-bundle/chunks/register-mutation-IQ55E25C.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-operations-AMCUFYEW.js → register-operations-AR7RMX4W.js} +42 -38
- package/dist/cli-bundle/chunks/register-operations-AR7RMX4W.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-operations-MRLHOZYR.js → register-operations-NOLZGORC.js} +41 -37
- package/dist/cli-bundle/chunks/register-operations-NOLZGORC.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-setup-ZVKTDL4G.js → register-setup-BB77VUEE.js} +17 -16
- package/dist/cli-bundle/chunks/{register-setup-ZVKTDL4G.js.map → register-setup-BB77VUEE.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-setup-N2FOSWAG.js → register-setup-EYZ7VTPZ.js} +15 -14
- package/dist/cli-bundle/chunks/{register-setup-N2FOSWAG.js.map → register-setup-EYZ7VTPZ.js.map} +1 -1
- package/dist/cli-bundle/chunks/restore-L6IAGOD7.js +15 -0
- package/dist/cli-bundle/chunks/{restore-HEQAG6EK.js → restore-ZH65GZFB.js} +7 -6
- package/dist/cli-bundle/chunks/{schema-Q5DAWJ2S.js → schema-4ERWM5QJ.js} +7 -6
- package/dist/cli-bundle/chunks/{schema-MAXAIHEC.js → schema-55DL3Q52.js} +7 -6
- package/dist/cli-bundle/chunks/{update-DWFXXJKP.js → update-FW6FKDOP.js} +15 -15
- package/dist/cli-bundle/chunks/update-TJHSPRPT.js +23 -0
- package/dist/cli-bundle/chunks/update-many-NNALYQCN.js +35 -0
- package/dist/cli-bundle/chunks/update-many-PWXX5WHO.js +39 -0
- package/dist/cli-bundle/main.js +62 -59
- package/dist/cli-bundle/main.js.map +1 -1
- package/dist/cli-bundle/sdk-runtime.js +62 -59
- package/dist/cli-bundle/sdk-testing.js +8 -8
- package/dist/cli-bundle/sdk.js +327 -57
- package/dist/cli-bundle/sdk.js.map +4 -4
- package/dist/core/config/nested-settings.d.ts +2 -0
- package/dist/core/config/nested-settings.js +18 -2
- package/dist/core/config/nested-settings.js.map +1 -1
- package/dist/core/diagnostics/remediation.js +38 -2
- package/dist/core/diagnostics/remediation.js.map +1 -1
- package/dist/core/extensions/extension-types.d.ts +1 -1
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/item/id.d.ts +19 -2
- package/dist/core/item/id.js +27 -6
- package/dist/core/item/id.js.map +1 -1
- package/dist/core/item/parse.d.ts +7 -0
- package/dist/core/item/parse.js +48 -2
- package/dist/core/item/parse.js.map +1 -1
- package/dist/core/schema/item-types-file.d.ts +2 -2
- package/dist/core/schema/item-types-file.js +2 -2
- package/dist/core/schema/item-types-file.js.map +1 -1
- package/dist/core/schema/runtime-schema.d.ts +3 -3
- package/dist/core/schema/runtime-schema.js +2 -2
- package/dist/core/schema/runtime-schema.js.map +1 -1
- package/dist/core/schema/type-workflows.d.ts +2 -2
- package/dist/core/schema/type-workflows.js +2 -2
- package/dist/core/schema/type-workflows.js.map +1 -1
- package/dist/core/shared/constants.js +5 -2
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/store/settings-validator.d.ts +4 -0
- package/dist/core/store/settings-validator.js +8 -2
- package/dist/core/store/settings-validator.js.map +1 -1
- package/dist/core/store/settings.js +8 -2
- package/dist/core/store/settings.js.map +1 -1
- package/dist/sdk/annotations.js +24 -2
- package/dist/sdk/annotations.js.map +1 -1
- package/dist/sdk/cli-bootstrap.d.ts +1 -1
- package/dist/sdk/cli-bootstrap.js +3 -3
- package/dist/sdk/cli-bootstrap.js.map +1 -1
- package/dist/sdk/cli-contracts/commander-mutation-options.js +22 -2
- package/dist/sdk/cli-contracts/commander-mutation-options.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.js +3 -2
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/flag-contracts.d.ts +2 -0
- package/dist/sdk/cli-contracts/flag-contracts.js +17 -2
- package/dist/sdk/cli-contracts/flag-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.d.ts +512 -0
- package/dist/sdk/cli-contracts/tool-option-contracts.js +21 -11
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +13 -3
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -0
- package/dist/sdk/cli-contracts/tool-schema.js +14 -10
- package/dist/sdk/cli-contracts/tool-schema.js.map +1 -1
- package/dist/sdk/cli-contracts/typed-action-inputs.d.ts +69 -0
- package/dist/sdk/cli-contracts/typed-action-inputs.js +5 -0
- package/dist/sdk/cli-contracts/typed-action-inputs.js.map +1 -0
- package/dist/sdk/cli-contracts.d.ts +4 -3
- package/dist/sdk/cli-contracts.js +5 -5
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/extension/describe.d.ts +1 -1
- package/dist/sdk/extension/describe.js +2 -2
- package/dist/sdk/extension/describe.js.map +1 -1
- package/dist/sdk/extension/install-runtime.js +5 -3
- package/dist/sdk/extension/install-runtime.js.map +1 -1
- package/dist/sdk/extension.d.ts +2 -2
- package/dist/sdk/extension.js +2 -2
- package/dist/sdk/extension.js.map +1 -1
- package/dist/sdk/governance/gc.d.ts +14 -1
- package/dist/sdk/governance/gc.js +38 -2
- package/dist/sdk/governance/gc.js.map +1 -1
- package/dist/sdk/governance/storage-integrity.d.ts +84 -0
- package/dist/sdk/governance/storage-integrity.js +240 -0
- package/dist/sdk/governance/storage-integrity.js.map +1 -0
- package/dist/sdk/governance/validate.d.ts +3 -1
- package/dist/sdk/governance/validate.js +56 -2
- package/dist/sdk/governance/validate.js.map +1 -1
- package/dist/sdk/history-read.d.ts +1 -1
- package/dist/sdk/history-read.js +2 -2
- package/dist/sdk/history-read.js.map +1 -1
- package/dist/sdk/history-repair.d.ts +36 -0
- package/dist/sdk/history-repair.js +69 -4
- package/dist/sdk/history-repair.js.map +1 -1
- package/dist/sdk/index.d.ts +5 -2
- package/dist/sdk/index.js +5 -2
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/init.js +3 -3
- package/dist/sdk/init.js.map +1 -1
- package/dist/sdk/item-transaction.d.ts +131 -0
- package/dist/sdk/item-transaction.js +280 -0
- package/dist/sdk/item-transaction.js.map +1 -0
- package/dist/sdk/merge/driver.d.ts +75 -0
- package/dist/sdk/merge/driver.js +166 -0
- package/dist/sdk/merge/driver.js.map +1 -0
- package/dist/sdk/merge/index.d.ts +11 -0
- package/dist/sdk/merge/index.js +15 -0
- package/dist/sdk/merge/index.js.map +1 -0
- package/dist/sdk/merge/install.d.ts +90 -0
- package/dist/sdk/merge/install.js +318 -0
- package/dist/sdk/merge/install.js.map +1 -0
- package/dist/sdk/merge/three-way.d.ts +126 -0
- package/dist/sdk/merge/three-way.js +545 -0
- package/dist/sdk/merge/three-way.js.map +1 -0
- package/dist/sdk/query/list.d.ts +19 -2
- package/dist/sdk/query/list.js +5 -2
- package/dist/sdk/query/list.js.map +1 -1
- package/dist/sdk/runtime.d.ts +17 -14
- package/dist/sdk/runtime.js +5 -5
- package/dist/sdk/runtime.js.map +1 -1
- package/dist/sdk/schema.d.ts +2 -2
- package/dist/sdk/schema.js +29 -2
- package/dist/sdk/schema.js.map +1 -1
- package/dist/sdk/stats.d.ts +1 -1
- package/dist/sdk/stats.js +2 -2
- package/dist/sdk/stats.js.map +1 -1
- package/dist/sdk/workspace-transaction-gc.d.ts +46 -0
- package/dist/sdk/workspace-transaction-gc.js +155 -0
- package/dist/sdk/workspace-transaction-gc.js.map +1 -0
- package/dist/sdk/workspace.d.ts +28 -4
- package/dist/sdk/workspace.js +61 -15
- package/dist/sdk/workspace.js.map +1 -1
- package/dist/types.d.ts +11 -7
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +58 -47
- package/docs/COMMANDS.md +7 -0
- package/docs/CONFIGURATION.md +2 -0
- package/docs/MERGE_SAFETY.md +99 -0
- package/docs/README.md +1 -0
- package/docs/SDK.md +56 -0
- package/marketplace.json +2 -2
- package/package.json +3 -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-XUYF7NON.js +0 -11
- package/dist/cli-bundle/chunks/chunk-2XPDCXK5.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-3EZZTFL2.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-3KPNOZOH.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-46Z6FAVP.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-4M6RZJXF.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-6V4T4RD3.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-A3GAQLBH.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-A4FVWFZY.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-A5EQPNV7.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-AR24KW26.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-BBGR4FKQ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-BDC4TW4B.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-BZKE2O5V.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-CZA2DXCV.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-D35WYXWC.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-DJAGYYCQ.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-EEECAV5M.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-H3YKUVDR.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-IDUTGRDM.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-IGBBTPM5.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-JBW2S2C6.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-JPWUZOMR.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-KAE727L2.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-MI3346YW.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-MQOSMBWV.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-MRXAHR4B.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-N2TEEOXJ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ODEIDKGW.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-P24ZU5QV.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-Q3K5XPAQ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-QFG4MB7P.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-RLLOZAM2.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-RWAIRGBC.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SBW7EQC4.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-SVAWG7EE.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-UE7LK3RE.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-VA3H7VVC.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-WCBB6VI3.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-Y2VSGFT4.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-YG56M3NE.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-ZF52NVRT.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ZUCBPXNA.js.map +0 -7
- package/dist/cli-bundle/chunks/close-ZZCDDWJT.js +0 -12
- package/dist/cli-bundle/chunks/close-many-QCZHFCON.js +0 -23
- package/dist/cli-bundle/chunks/comments-FMQNYPSZ.js +0 -13
- package/dist/cli-bundle/chunks/copy-GI3RCVZP.js +0 -9
- package/dist/cli-bundle/chunks/create-LXMLYJNM.js +0 -29
- package/dist/cli-bundle/chunks/delete-5DFAXJNI.js +0 -10
- package/dist/cli-bundle/chunks/docs-KCWPLQOV.js +0 -14
- package/dist/cli-bundle/chunks/focus-3EJVFI3D.js +0 -10
- package/dist/cli-bundle/chunks/history-compact-JHYVDYLW.js +0 -16
- package/dist/cli-bundle/chunks/history-repair-REMI7DDI.js +0 -16
- package/dist/cli-bundle/chunks/learnings-O6V5WDCV.js +0 -13
- package/dist/cli-bundle/chunks/notes-ZSZREWZA.js +0 -13
- package/dist/cli-bundle/chunks/plan-EZW2YDDY.js +0 -26
- package/dist/cli-bundle/chunks/register-mutation-BLEWM5I6.js.map +0 -7
- package/dist/cli-bundle/chunks/register-mutation-OTYHR7J6.js.map +0 -1
- package/dist/cli-bundle/chunks/register-operations-AMCUFYEW.js.map +0 -1
- package/dist/cli-bundle/chunks/register-operations-MRLHOZYR.js.map +0 -7
- package/dist/cli-bundle/chunks/restore-A55MLFAI.js +0 -14
- package/dist/cli-bundle/chunks/update-5DTSCWVF.js +0 -23
- package/dist/cli-bundle/chunks/update-many-6T4ZLZS7.js +0 -34
- package/dist/cli-bundle/chunks/update-many-MYRK6VBJ.js +0 -38
- /package/dist/cli-bundle/chunks/{append-MBXHNWSX.js.map → append-E6V54WOQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-XUYF7NON.js.map → append-NNJ3EFIT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-YGEA4CLH.js.map → chunk-3MCTMJXI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-N7FCFJ76.js.map → chunk-3P7UJQOX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7B7IHMLH.js.map → chunk-3VY6MIEO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-5S6IZXK7.js.map → chunk-4U4Z6AHI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UOIFZ66L.js.map → chunk-4XGJLADW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SUNZKVAH.js.map → chunk-5IZJWSDB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QQ77W23U.js.map → chunk-5NTE36LD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KGPLSHJD.js.map → chunk-6C2ZZX5Z.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-Q5NHJ6RO.js.map → chunk-6JUTHVQS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-NTS2RKHN.js.map → chunk-6VIJ7UA5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XVB6BATY.js.map → chunk-72LQ4TKV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KZ5AC6B5.js.map → chunk-7WCE6Y64.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VQOG2ETB.js.map → chunk-AF2CCM5U.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EAV3P54W.js.map → chunk-DAQ45GCS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RX53WHFI.js.map → chunk-EJDGV4GR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IXG5CMBR.js.map → chunk-FDHPAVVB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-V4QHAMI5.js.map → chunk-GROYI4RB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-77XFQRTD.js.map → chunk-GSJSM5BJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-QYGK2XQ3.js.map → chunk-GTLCVJOE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VSQE43NO.js.map → chunk-GV2262OF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-STBCBDKF.js.map → chunk-HCEBZNC3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-U6RYD446.js.map → chunk-HRW7GF6T.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XDWXPG2E.js.map → chunk-IAQE32BI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-66SRNEBK.js.map → chunk-IJNK6WW2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AGEBQRBG.js.map → chunk-JAPE62Y5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UWAQI3B7.js.map → chunk-JGUKMMRS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UU6EP25G.js.map → chunk-JH2ZSLO3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GRDK25BN.js.map → chunk-JHJSFOAM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FQO5THHM.js.map → chunk-JM6YAXTR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-E7KBMWEF.js.map → chunk-JSLT7WVE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FIUTBFC6.js.map → chunk-K4CI6Y45.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IEMXESIS.js.map → chunk-KSPWRNVP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BFJP4VYC.js.map → chunk-L7BH7IWU.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-2UCG5H6B.js.map → chunk-LPEYZRUR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IR3GOO6E.js.map → chunk-NHT3F4WZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-6BNV3G6C.js.map → chunk-NLR32VFS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-EI3UIMZM.js.map → chunk-OWXOPDHD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AQUNTB7G.js.map → chunk-PEQGTJ5Q.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-T6MOTLOJ.js.map → chunk-QJKL5PHS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XKVHL3MB.js.map → chunk-QWRVBJ4D.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VFA5EIEN.js.map → chunk-R7QV7ICM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-K2L6FZBX.js.map → chunk-RJO3YAFM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-SGJB6PXA.js.map → chunk-SF3DT5HJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UNNCT5QY.js.map → chunk-SZVB53Y3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GFZB5CLP.js.map → chunk-T6PPNM7V.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-W6IEJXNC.js.map → chunk-TVYYO5A7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DOASIOQR.js.map → chunk-UQLXSG72.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-7CHWLT2J.js.map → chunk-UVN66B3M.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-Q6JPYR7I.js.map → chunk-UX6SSO2I.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OK7VSX3N.js.map → chunk-UZLJOEAC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-4PSJVGRE.js.map → chunk-VDO2JMD4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-IRJ6F23W.js.map → chunk-VQIHNHMJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LT5UWU7H.js.map → chunk-ZOJ3LR7O.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3HSRP6T2.js.map → chunk-ZOY5K4D3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XXWDEQ6O.js.map → chunk-ZV2NTVMJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UW6HCMP2.js.map → chunk-ZYPFOO3L.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-ZZCDDWJT.js.map → close-O5QVZ6ET.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-7NWA3GLA.js.map → close-QEMOYZN3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-QCZHFCON.js.map → close-many-SDA426VT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-many-YALQ7AXS.js.map → close-many-UTZANOCQ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-SQIQ5WYR.js.map → comments-LZN6FXXC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-FMQNYPSZ.js.map → comments-VBQ345ND.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-YDAMENCP.js.map → copy-DKTSSCK7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{copy-GI3RCVZP.js.map → copy-M7DDI6LS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-JSL6CXU3.js.map → create-GG4RBCGC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-LXMLYJNM.js.map → create-JBC5KUW6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-IGVOZEU2.js.map → delete-LCS3VPDH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-5DFAXJNI.js.map → delete-MD7YXQLH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-BQAXUQAK.js.map → deps-DELOO4TL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-CBPPSS6J.js.map → deps-FI4O6NQS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-KCWPLQOV.js.map → docs-2UYBP5D6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-NS2AZWCN.js.map → docs-6Z2MP526.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-XUUBQ76I.js.map → files-HEUGSJZL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-PVWEPT5J.js.map → files-HKEAN5MA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-DHBHKK3E.js.map → focus-7SOUT5PZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{focus-3EJVFI3D.js.map → focus-DRQ6FQH6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-JHYVDYLW.js.map → history-compact-65YVN5DB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-compact-3TNPYVFG.js.map → history-compact-7NDVP3PT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-KKFDICCF.js.map → history-redact-7YBL4XSG.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-ELRL73XN.js.map → history-redact-IZGNJBU4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-J7WKZFAG.js.map → history-repair-7M4PYQUH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-REMI7DDI.js.map → history-repair-GNGETJLI.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-O6V5WDCV.js.map → learnings-3YXDRWFT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-X4D6JCCG.js.map → learnings-ALC6IMNL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-ZSZREWZA.js.map → notes-7JMLQ447.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-UQC6VS6N.js.map → notes-JFCLTC5C.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-EZW2YDDY.js.map → plan-KOIPWVOZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-5GKRBJJO.js.map → plan-T3XB3WTK.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-5PQAPCLF.js.map → profile-OILJHKUW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{profile-CW4BD3FO.js.map → profile-RJXA7PGS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-A55MLFAI.js.map → restore-L6IAGOD7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-HEQAG6EK.js.map → restore-ZH65GZFB.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-Q5DAWJ2S.js.map → schema-4ERWM5QJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-MAXAIHEC.js.map → schema-55DL3Q52.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-DWFXXJKP.js.map → update-FW6FKDOP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-5DTSCWVF.js.map → update-TJHSPRPT.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-6T4ZLZS7.js.map → update-many-NNALYQCN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-MYRK6VBJ.js.map → update-many-PWXX5WHO.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../sdk/merge/three-way.ts","../../../../../../../../sdk/merge/driver.ts"],"sourcesContent":["/**\n * @module sdk/merge/three-way\n *\n * Field-aware three-way merge primitives for every mergeable tracker artifact\n * class: append-only history JSONL streams, item documents (TOON or\n * JSON+Markdown), and key-level JSON configuration/schema files. These\n * primitives are pure (content in, content out) so the CLI merge driver, the\n * MCP surface, and package integrations all share one merge semantics\n * definition for multi-branch agent workflows.\n */\nimport {\n historyEntriesToRaw,\n reanchorHistoryEntries,\n} from \"../../core/history/replay.js\";\nimport {\n canonicalDocument,\n parseItemDocument,\n serializeItemDocument,\n type ItemDocumentFormatOptions,\n} from \"../../core/item/item-format.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport { findFirstMergeConflictMarker } from \"../../core/shared/conflict-markers.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { stableStringify } from \"../../core/shared/serialization.js\";\nimport { compareTimestampStrings } from \"../../core/shared/time.js\";\nimport type {\n HistoryEntry,\n ItemDocument,\n ItemMetadata,\n} from \"../../types/index.js\";\n\n/** Restricts which side of a three-way merge wins an unresolvable conflict. */\nexport type MergePreferredSide = \"ours\" | \"theirs\";\n\n/** Restricts the strategy labels reported by the history stream merge. */\nexport type HistoryMergeStrategy =\n | \"identical\"\n | \"fast_forward_ours\"\n | \"fast_forward_theirs\"\n | \"union_reanchor\";\n\n/** Documents the history stream merge result payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryMergeResult {\n /** Merged JSONL content ready to be written as the resolved history stream. */\n merged: string;\n /** Strategy the merge used: identical inputs, one-sided fast-forward, or a deterministic union with a re-anchored hash chain. */\n strategy: HistoryMergeStrategy;\n /** Number of entries shared by both sides before their streams diverged. */\n common_entries: number;\n /** Number of divergent entries contributed by the ours side. */\n entries_from_ours: number;\n /** Number of divergent entries contributed by the theirs side. */\n entries_from_theirs: number;\n /** Total entries in the merged stream. */\n entries_total: number;\n /** Whether the merged chain required hash re-anchoring (true for every union merge). */\n reanchored: boolean;\n}\n\nfunction parseHistoryJsonl(raw: string, label: string): HistoryEntry[] {\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n throw new PmCliError(\n `History merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}. Merge drivers must receive clean per-side versions.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n const entries: HistoryEntry[] = [];\n for (const [index, rawLine] of raw.split(/\\r?\\n/).entries()) {\n const line = rawLine.trim();\n if (!line) {\n continue;\n }\n try {\n const parsed = JSON.parse(line) as unknown;\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new TypeError(\"history entry must be an object\");\n }\n entries.push(parsed as HistoryEntry);\n } catch {\n throw new PmCliError(\n `History merge input (${label}) contains invalid JSON at line ${index + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n }\n return entries;\n}\n\nfunction historyEntryIdentity(entry: HistoryEntry): string {\n return stableStringify({\n ts: entry.ts,\n author: entry.author,\n op: entry.op,\n patch: entry.patch,\n message: entry.message ?? null,\n });\n}\n\nfunction commonHistoryPrefixLength(\n ours: HistoryEntry[],\n theirs: HistoryEntry[],\n): number {\n const limit = Math.min(ours.length, theirs.length);\n let shared = 0;\n while (\n shared < limit &&\n historyEntryIdentity(ours[shared]) === historyEntryIdentity(theirs[shared])\n ) {\n shared += 1;\n }\n return shared;\n}\n\n/**\n * Deterministically merge two diverged versions of one append-only history\n * JSONL stream. Identical streams and one-sided fast-forwards keep the winning\n * side byte-for-byte; genuinely diverged streams are merged as the shared\n * prefix plus both suffixes ordered by timestamp (ours-first on ties), then\n * hash re-anchored so the resulting chain verifies again. No side's events are\n * ever discarded: content divergence is preserved for the post-merge\n * reconciliation pass (`pm validate` + `pm history-repair`) instead of being\n * silently resolved by last-writer-wins.\n */\nexport function mergeHistoryStreams(\n baseRaw: string,\n oursRaw: string,\n theirsRaw: string,\n): HistoryMergeResult {\n parseHistoryJsonl(baseRaw, \"base\");\n const ours = parseHistoryJsonl(oursRaw, \"ours\");\n const theirs = parseHistoryJsonl(theirsRaw, \"theirs\");\n const shared = commonHistoryPrefixLength(ours, theirs);\n\n if (shared === ours.length && shared === theirs.length) {\n return {\n merged: historyEntriesToRaw(ours),\n strategy: \"identical\",\n common_entries: shared,\n entries_from_ours: 0,\n entries_from_theirs: 0,\n entries_total: ours.length,\n reanchored: false,\n };\n }\n if (shared === theirs.length) {\n return {\n merged: historyEntriesToRaw(ours),\n strategy: \"fast_forward_ours\",\n common_entries: shared,\n entries_from_ours: ours.length - shared,\n entries_from_theirs: 0,\n entries_total: ours.length,\n reanchored: false,\n };\n }\n if (shared === ours.length) {\n return {\n merged: historyEntriesToRaw(theirs),\n strategy: \"fast_forward_theirs\",\n common_entries: shared,\n entries_from_ours: 0,\n entries_from_theirs: theirs.length - shared,\n entries_total: theirs.length,\n reanchored: false,\n };\n }\n\n const oursSuffix = ours.slice(shared);\n const seenIdentities = new Set(oursSuffix.map(historyEntryIdentity));\n const theirsSuffix = theirs\n .slice(shared)\n .filter((entry) => !seenIdentities.has(historyEntryIdentity(entry)));\n const mergedSuffix = [...oursSuffix, ...theirsSuffix].sort((left, right) => {\n const byTs = compareTimestampStrings(left.ts, right.ts);\n if (byTs !== 0) {\n return byTs;\n }\n const leftFromOurs = seenIdentities.has(historyEntryIdentity(left));\n const rightFromOurs = seenIdentities.has(historyEntryIdentity(right));\n if (leftFromOurs !== rightFromOurs) {\n return Number(rightFromOurs) - Number(leftFromOurs);\n }\n return historyEntryIdentity(left).localeCompare(historyEntryIdentity(right));\n });\n const reanchored = reanchorHistoryEntries([\n ...ours.slice(0, shared),\n ...mergedSuffix,\n ]);\n return {\n merged: historyEntriesToRaw(reanchored.entries),\n strategy: \"union_reanchor\",\n common_entries: shared,\n entries_from_ours: oursSuffix.length,\n entries_from_theirs: theirsSuffix.length,\n entries_total: reanchored.entries.length,\n reanchored: true,\n };\n}\n\n/** Documents the relationship event stream merge result payload exchanged by command, SDK, and package integrations. */\nexport interface RelationshipStreamMergeResult {\n /** Merged JSONL content with consecutively renumbered `sequence` values, ready to be written as the resolved event store. */\n merged: string;\n /** Strategy the merge used: identical inputs, one-sided fast-forward, or a deterministic union with renumbered sequences. */\n strategy: HistoryMergeStrategy;\n /** Number of events shared by both sides before their streams diverged. */\n common_entries: number;\n /** Number of divergent events contributed by the ours side. */\n entries_from_ours: number;\n /** Number of divergent events contributed by the theirs side. */\n entries_from_theirs: number;\n /** Total events in the merged stream. */\n entries_total: number;\n /** Whether merged events required sequence renumbering (true for every union merge). */\n reanchored: boolean;\n}\n\ninterface RelationshipStreamEvent {\n /** Globally unique event identity used for prefix detection and suffix deduplication. */\n eventId: string;\n /** One-based append sequence; rewritten consecutively in the merged stream. */\n sequence: number;\n /** ISO timestamp used to order divergent suffixes deterministically. */\n timestamp?: string;\n /** Remaining event payload fields, preserved verbatim. */\n [key: string]: unknown;\n}\n\nfunction parseRelationshipJsonl(\n raw: string,\n label: string,\n): RelationshipStreamEvent[] {\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n throw new PmCliError(\n `Relationship merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}. Merge drivers must receive clean per-side versions.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n const events: RelationshipStreamEvent[] = [];\n for (const [index, rawLine] of raw.split(/\\r?\\n/).entries()) {\n const line = rawLine.trim();\n if (!line) {\n continue;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(line) as unknown;\n } catch {\n throw new PmCliError(\n `Relationship merge input (${label}) contains invalid JSON at line ${index + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n if (\n typeof parsed !== \"object\" ||\n parsed === null ||\n Array.isArray(parsed) ||\n typeof (parsed as { eventId?: unknown }).eventId !== \"string\" ||\n typeof (parsed as { sequence?: unknown }).sequence !== \"number\"\n ) {\n throw new PmCliError(\n `Relationship merge input (${label}) line ${index + 1} is not a relationship event (eventId + sequence required).`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n events.push(parsed as RelationshipStreamEvent);\n }\n return events;\n}\n\nfunction relationshipEventsToRaw(events: RelationshipStreamEvent[]): string {\n return events.length === 0\n ? \"\"\n : `${events.map((event) => JSON.stringify(event)).join(\"\\n\")}\\n`;\n}\n\nfunction renumberRelationshipEvents(\n events: RelationshipStreamEvent[],\n): RelationshipStreamEvent[] {\n return events.map((event, index) => ({ ...event, sequence: index + 1 }));\n}\n\n/**\n * Deterministically merge two diverged versions of one append-only\n * relationship event JSONL store. The store's loader enforces strictly\n * consecutive one-based `sequence` values, so a plain text union of two\n * diverged streams is always unreadable; this merge keeps the shared prefix,\n * unions both divergent suffixes by `eventId` (ordered by event timestamp,\n * ours-first on ties), and renumbers every merged sequence consecutively so\n * the resulting stream loads again. No side's events are ever discarded.\n */\nexport function mergeRelationshipEventStreams(\n baseRaw: string,\n oursRaw: string,\n theirsRaw: string,\n): RelationshipStreamMergeResult {\n parseRelationshipJsonl(baseRaw, \"base\");\n const ours = parseRelationshipJsonl(oursRaw, \"ours\");\n const theirs = parseRelationshipJsonl(theirsRaw, \"theirs\");\n const limit = Math.min(ours.length, theirs.length);\n let shared = 0;\n while (shared < limit && ours[shared].eventId === theirs[shared].eventId) {\n shared += 1;\n }\n\n if (shared === ours.length && shared === theirs.length) {\n return {\n merged: relationshipEventsToRaw(ours),\n strategy: \"identical\",\n common_entries: shared,\n entries_from_ours: 0,\n entries_from_theirs: 0,\n entries_total: ours.length,\n reanchored: false,\n };\n }\n if (shared === theirs.length) {\n return {\n merged: relationshipEventsToRaw(ours),\n strategy: \"fast_forward_ours\",\n common_entries: shared,\n entries_from_ours: ours.length - shared,\n entries_from_theirs: 0,\n entries_total: ours.length,\n reanchored: false,\n };\n }\n if (shared === ours.length) {\n return {\n merged: relationshipEventsToRaw(theirs),\n strategy: \"fast_forward_theirs\",\n common_entries: shared,\n entries_from_ours: 0,\n entries_from_theirs: theirs.length - shared,\n entries_total: theirs.length,\n reanchored: false,\n };\n }\n\n const oursSuffix = ours.slice(shared);\n const oursEventIds = new Set(oursSuffix.map((event) => event.eventId));\n const theirsSuffix = theirs\n .slice(shared)\n .filter((event) => !oursEventIds.has(event.eventId));\n const mergedSuffix = [...oursSuffix, ...theirsSuffix].sort((left, right) => {\n if (left.timestamp !== undefined && right.timestamp !== undefined) {\n const byTs = compareTimestampStrings(left.timestamp, right.timestamp);\n if (byTs !== 0) {\n return byTs;\n }\n } else if (left.timestamp === undefined && right.timestamp !== undefined) {\n return 1;\n } else if (left.timestamp !== undefined) {\n return -1;\n }\n const leftFromOurs = oursEventIds.has(left.eventId);\n const rightFromOurs = oursEventIds.has(right.eventId);\n if (leftFromOurs !== rightFromOurs) {\n return Number(rightFromOurs) - Number(leftFromOurs);\n }\n // Array.prototype.sort is stable: returning zero preserves each side's\n // original append order when its events share a timestamp.\n return 0;\n });\n const merged = renumberRelationshipEvents([\n ...ours.slice(0, shared),\n ...mergedSuffix,\n ]);\n return {\n merged: relationshipEventsToRaw(merged),\n strategy: \"union_reanchor\",\n common_entries: shared,\n entries_from_ours: oursSuffix.length,\n entries_from_theirs: theirsSuffix.length,\n entries_total: merged.length,\n reanchored: true,\n };\n}\n\n/**\n * Item metadata collections merged by element-identity set semantics instead\n * of whole-field three-way comparison: concurrent commutative appends from two\n * branches (notes on A, tags on B, a test run on each) must merge cleanly.\n * Element identity is the stable serialization of the normalized element, so\n * an element edited on one side counts as remove-old + add-new and both sides'\n * contributions survive. Plan collections are deliberately excluded: plan\n * steps carry cross-element ordering invariants that set-union would corrupt,\n * so they stay under scalar three-way semantics with explicit conflicts.\n */\nexport const ITEM_UNION_COLLECTION_FIELDS = [\n \"tags\",\n \"dependencies\",\n \"comments\",\n \"notes\",\n \"learnings\",\n \"files\",\n \"tests\",\n \"test_runs\",\n \"docs\",\n \"reminders\",\n \"events\",\n] as const;\n\n/** Item metadata fields resolved by deterministic latest-timestamp-wins instead of three-way conflict, so disjoint-field edits never conflict on the shared freshness scalar every mutation rewrites. */\nexport const ITEM_LATEST_TIMESTAMP_FIELDS = [\"updated_at\"] as const;\n\n/** Documents the item document merge result payload exchanged by command, SDK, and package integrations. */\nexport interface ItemDocumentMergeResult {\n /** Serialized merged item document (always parseable; count headers recomputed by canonical serialization). */\n merged: string;\n /** Metadata fields (plus `body`) where both sides changed to different values; resolved toward the preferred side. */\n conflict_fields: string[];\n /** Fields taken from the theirs side by clean three-way resolution. */\n fields_from_theirs: string[];\n /** Collection fields that merged by element-identity union. */\n union_fields: string[];\n /** Which side unresolvable conflicts were resolved toward. */\n preferred: MergePreferredSide;\n}\n\nfunction jsonEquals(left: unknown, right: unknown): boolean {\n return stableStringify(left ?? null) === stableStringify(right ?? null);\n}\n\nfunction unionCollection(\n base: unknown,\n ours: unknown,\n theirs: unknown,\n): unknown[] {\n const toEntries = (value: unknown): unknown[] =>\n Array.isArray(value) ? value : [];\n const baseIds = new Set(toEntries(base).map((entry) => stableStringify(entry)));\n const oursEntries = toEntries(ours);\n const oursIds = new Set(oursEntries.map((entry) => stableStringify(entry)));\n const theirsEntries = toEntries(theirs);\n const theirsIds = new Set(\n theirsEntries.map((entry) => stableStringify(entry)),\n );\n const merged = oursEntries.filter((entry) => {\n const identity = stableStringify(entry);\n // An element kept by ours survives unless theirs deleted it (present in\n // base, absent from theirs).\n return !baseIds.has(identity) || theirsIds.has(identity);\n });\n for (const entry of theirsEntries) {\n const identity = stableStringify(entry);\n if (!oursIds.has(identity) && !baseIds.has(identity)) {\n merged.push(entry);\n }\n }\n return merged;\n}\n\nfunction latestTimestamp(ours: unknown, theirs: unknown): unknown {\n return compareTimestampStrings(String(ours), String(theirs)) >= 0\n ? ours\n : theirs;\n}\n\ninterface ScalarMergeOutcome {\n value: unknown;\n from_theirs: boolean;\n conflict: boolean;\n}\n\nfunction mergeScalarThreeWay(\n base: unknown,\n ours: unknown,\n theirs: unknown,\n preferred: MergePreferredSide,\n): ScalarMergeOutcome {\n if (jsonEquals(ours, theirs)) {\n return { value: ours, from_theirs: false, conflict: false };\n }\n if (jsonEquals(base, ours)) {\n return { value: theirs, from_theirs: true, conflict: false };\n }\n if (jsonEquals(base, theirs)) {\n return { value: ours, from_theirs: false, conflict: false };\n }\n return {\n value: preferred === \"theirs\" ? theirs : ours,\n from_theirs: preferred === \"theirs\",\n conflict: true,\n };\n}\n\nfunction toMetadataRecord(document: ItemDocument): Record<string, unknown> {\n return { ...(document.metadata as unknown as Record<string, unknown>) };\n}\n\nfunction parseItemMergeSide(\n raw: string,\n label: string,\n options: ItemDocumentFormatOptions,\n): ItemDocument {\n try {\n return canonicalDocument(parseItemDocument(raw, options), options);\n } catch (error) {\n throw new PmCliError(\n `Item merge input (${label}) is not a readable item document: ${String(error)}`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n}\n\ninterface ItemMetadataMergeAccumulator {\n /** Merged metadata values keyed by canonical field name. */\n merged: Record<string, unknown>;\n /** Scalar fields where both sides diverged from the base. */\n conflictFields: string[];\n /** Scalar fields cleanly selected from the other branch. */\n fieldsFromTheirs: string[];\n /** Collection fields whose final union differs from ours. */\n unionFields: string[];\n}\n\nfunction mergeItemMetadataRecords(\n baseRecord: Record<string, unknown>,\n oursRecord: Record<string, unknown>,\n theirsRecord: Record<string, unknown>,\n preferred: MergePreferredSide,\n): ItemMetadataMergeAccumulator {\n const unionFieldSet = new Set<string>(ITEM_UNION_COLLECTION_FIELDS);\n const latestFieldSet = new Set<string>(ITEM_LATEST_TIMESTAMP_FIELDS);\n const fieldNames = [\n ...new Set([...Object.keys(oursRecord), ...Object.keys(theirsRecord)]),\n ].sort((left, right) => left.localeCompare(right));\n const accumulator: ItemMetadataMergeAccumulator = {\n merged: {},\n conflictFields: [],\n fieldsFromTheirs: [],\n unionFields: [],\n };\n\n for (const field of fieldNames) {\n const baseValue = baseRecord[field];\n const oursValue = oursRecord[field];\n const theirsValue = theirsRecord[field];\n if (unionFieldSet.has(field)) {\n const union = unionCollection(baseValue, oursValue, theirsValue);\n // `fieldNames` is derived from both records' own keys, so a collection\n // reached here is declared by at least one side. Preserve even an empty\n // result (`tags` is required) so serialization never drops it.\n accumulator.merged[field] = union;\n if (!jsonEquals(union, oursValue)) {\n accumulator.unionFields.push(field);\n }\n continue;\n }\n if (latestFieldSet.has(field)) {\n accumulator.merged[field] = latestTimestamp(oursValue, theirsValue);\n continue;\n }\n const outcome = mergeScalarThreeWay(\n baseValue,\n oursValue,\n theirsValue,\n preferred,\n );\n if (outcome.value !== undefined) {\n accumulator.merged[field] = outcome.value;\n }\n if (outcome.conflict) {\n accumulator.conflictFields.push(field);\n } else if (outcome.from_theirs) {\n accumulator.fieldsFromTheirs.push(field);\n }\n }\n return accumulator;\n}\n\n/**\n * Field-aware three-way merge of one tracker item document. Commutative\n * collections (notes, tags, tests, ...) union by element identity so\n * concurrent appends never conflict; `updated_at` resolves to the latest\n * timestamp so disjoint-field edits never collide on the shared freshness\n * scalar; every other metadata field and the body use classic three-way\n * resolution. Unresolvable both-sides-changed conflicts are resolved toward\n * the preferred side but reported in `conflict_fields`, and the merged output\n * is always canonically serialized — count-prefixed TOON array headers are\n * recomputed, so the hand-resolution corruption class (stale `notes[N]`\n * headers) cannot be produced by this merge.\n */\nexport function mergeItemDocuments(\n baseRaw: string,\n oursRaw: string,\n theirsRaw: string,\n options: ItemDocumentFormatOptions & {\n /** Side that wins unresolvable conflicts (default \"ours\"). */\n preferred?: MergePreferredSide;\n } = {},\n): ItemDocumentMergeResult {\n const preferred: MergePreferredSide = options.preferred ?? \"ours\";\n // An empty base means both branches created the file independently\n // (add/add); three-way falls back to treating every differing field as an\n // ours/theirs decision, which the scalar resolver already models.\n const hasBase = baseRaw.trim().length > 0;\n const ours = parseItemMergeSide(oursRaw, \"ours\", options);\n const theirs = parseItemMergeSide(theirsRaw, \"theirs\", options);\n const base = hasBase ? parseItemMergeSide(baseRaw, \"base\", options) : ours;\n\n const baseRecord = hasBase\n ? toMetadataRecord(base)\n : ({} as Record<string, unknown>);\n const oursRecord = toMetadataRecord(ours);\n const theirsRecord = toMetadataRecord(theirs);\n const { merged, conflictFields, fieldsFromTheirs, unionFields } =\n mergeItemMetadataRecords(baseRecord, oursRecord, theirsRecord, preferred);\n\n const bodyOutcome = mergeScalarThreeWay(\n hasBase ? base.body : \"\",\n ours.body,\n theirs.body,\n preferred,\n );\n if (bodyOutcome.conflict) {\n conflictFields.push(\"body\");\n } else if (bodyOutcome.from_theirs) {\n fieldsFromTheirs.push(\"body\");\n }\n\n const mergedRaw = serializeItemDocument(\n {\n metadata: merged as unknown as ItemMetadata,\n body: bodyOutcome.value as string,\n },\n options,\n );\n return {\n merged: mergedRaw,\n conflict_fields: conflictFields,\n fields_from_theirs: fieldsFromTheirs,\n union_fields: unionFields,\n preferred,\n };\n}\n\n/** Documents the JSON document merge result payload exchanged by command, SDK, and package integrations. */\nexport interface JsonDocumentMergeResult {\n /** Serialized merged JSON document (two-space indent, trailing newline — the tracker's canonical config style). */\n merged: string;\n /** Dotted key paths where both sides changed to different values; resolved toward the preferred side. */\n conflict_paths: string[];\n /** Dotted key paths taken from the theirs side by clean three-way resolution. */\n paths_from_theirs: string[];\n /** Which side unresolvable conflicts were resolved toward. */\n preferred: MergePreferredSide;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n );\n}\n\nfunction parseJsonSide(raw: string, label: string): unknown {\n const conflictMarker = findFirstMergeConflictMarker(raw);\n if (conflictMarker) {\n throw new PmCliError(\n `JSON merge input (${label}) contains unresolved conflict markers at line ${conflictMarker.line}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n if (raw.trim().length === 0) {\n return undefined;\n }\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n throw new PmCliError(\n `JSON merge input (${label}) is not valid JSON.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n}\n\nfunction mergeJsonValue(\n base: unknown,\n ours: unknown,\n theirs: unknown,\n preferred: MergePreferredSide,\n pathPrefix: string,\n conflictPaths: string[],\n pathsFromTheirs: string[],\n): unknown {\n if (jsonEquals(ours, theirs)) {\n return ours;\n }\n if (isPlainObject(ours) && isPlainObject(theirs)) {\n const baseObject = isPlainObject(base) ? base : {};\n const merged: Record<string, unknown> = {};\n const keys = [\n ...new Set([...Object.keys(ours), ...Object.keys(theirs)]),\n ].sort((left, right) => left.localeCompare(right));\n for (const key of keys) {\n const childPath = pathPrefix.length > 0 ? `${pathPrefix}.${key}` : key;\n const child = mergeJsonKey(\n baseObject,\n ours,\n theirs,\n key,\n preferred,\n childPath,\n conflictPaths,\n pathsFromTheirs,\n );\n if (child !== undefined) {\n merged[key] = child;\n }\n }\n return merged;\n }\n const outcome = mergeScalarThreeWay(base, ours, theirs, preferred);\n if (outcome.conflict) {\n conflictPaths.push(pathPrefix);\n } else if (outcome.from_theirs) {\n pathsFromTheirs.push(pathPrefix);\n }\n return outcome.value;\n}\n\nfunction mergeJsonKey(\n base: Record<string, unknown>,\n ours: Record<string, unknown>,\n theirs: Record<string, unknown>,\n key: string,\n preferred: MergePreferredSide,\n childPath: string,\n conflictPaths: string[],\n pathsFromTheirs: string[],\n): unknown {\n const inOurs = Object.prototype.hasOwnProperty.call(ours, key);\n const inTheirs = Object.prototype.hasOwnProperty.call(theirs, key);\n const inBase = Object.prototype.hasOwnProperty.call(base, key);\n if (inOurs && inTheirs) {\n return mergeJsonValue(\n base[key],\n ours[key],\n theirs[key],\n preferred,\n childPath,\n conflictPaths,\n pathsFromTheirs,\n );\n }\n if (inOurs) {\n // Present only in ours: either ours added it (keep) or theirs deleted it\n // (honor the delete when ours left it untouched from base).\n if (inBase && jsonEquals(base[key], ours[key])) {\n pathsFromTheirs.push(childPath);\n return undefined;\n }\n if (inBase) {\n conflictPaths.push(childPath);\n return preferred === \"theirs\" ? undefined : ours[key];\n }\n return ours[key];\n }\n // Present only in theirs (mirror of the branch above).\n if (inBase && jsonEquals(base[key], theirs[key])) {\n return undefined;\n }\n if (inBase) {\n conflictPaths.push(childPath);\n return preferred === \"theirs\" ? theirs[key] : undefined;\n }\n pathsFromTheirs.push(childPath);\n return theirs[key];\n}\n\n/**\n * Key-level three-way merge for the tracker's single-file JSON configuration\n * artifacts (`settings.json`, `schema/*.json`). Nested objects merge\n * recursively per key so two branches editing disjoint settings never\n * conflict; both-sides-changed leaf values resolve toward the preferred side\n * and are reported in `conflict_paths`. The output is always valid JSON, so a\n * merged configuration can never regress into the silent-defaults fallback\n * that raw conflict markers cause.\n */\nexport function mergeJsonDocuments(\n baseRaw: string,\n oursRaw: string,\n theirsRaw: string,\n options: {\n /** Side that wins unresolvable conflicts (default \"ours\"). */\n preferred?: MergePreferredSide;\n } = {},\n): JsonDocumentMergeResult {\n const preferred: MergePreferredSide = options.preferred ?? \"ours\";\n const base = parseJsonSide(baseRaw, \"base\");\n const ours = parseJsonSide(oursRaw, \"ours\");\n const theirs = parseJsonSide(theirsRaw, \"theirs\");\n const conflictPaths: string[] = [];\n const pathsFromTheirs: string[] = [];\n const merged = mergeJsonValue(\n base,\n ours,\n theirs,\n preferred,\n \"\",\n conflictPaths,\n pathsFromTheirs,\n );\n return {\n merged: `${JSON.stringify(merged ?? null, null, 2)}\\n`,\n conflict_paths: conflictPaths,\n paths_from_theirs: pathsFromTheirs,\n preferred,\n };\n}\n","/**\n * @module sdk/merge/driver\n *\n * File-level git merge driver runner for tracker artifacts. Git invokes the\n * driver with the base (%O), ours (%A), and theirs (%B) temporary files; the\n * driver writes the merged content back to the ours path and reports whether\n * unresolvable conflicts remain. Conflicted artifacts are still written as\n * parseable documents (resolved toward the preferred side) so a conflicted\n * merge never corrupts tracker storage the way raw conflict markers do.\n */\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getActiveExtensionRegistrations } from \"../../core/extensions/index.js\";\nimport { collectRegisteredItemFieldNames } from \"../../core/extensions/item-fields.js\";\nimport { pathExists } from \"../../core/fs/fs-utils.js\";\nimport { EXIT_CODE } from \"../../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../../core/shared/command-types.js\";\nimport { PmCliError } from \"../../core/shared/errors.js\";\nimport { nowIso } from \"../../core/shared/time.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../../core/store/paths.js\";\nimport { readSettings } from \"../../core/store/settings.js\";\nimport type { ItemFormat, PmSettings } from \"../../types/index.js\";\nimport {\n mergeHistoryStreams,\n mergeItemDocuments,\n mergeJsonDocuments,\n mergeRelationshipEventStreams,\n type MergePreferredSide,\n} from \"./three-way.js\";\n\n/** Supported values accepted by the merge driver artifact contract across CLI, SDK, and MCP surfaces. */\nexport const MERGE_DRIVER_ARTIFACT_VALUES = [\n \"item\",\n \"history\",\n \"relationship\",\n \"json\",\n] as const;\n/** Restricts merge driver artifact values accepted by command, SDK, and storage contracts. */\nexport type MergeDriverArtifact = (typeof MERGE_DRIVER_ARTIFACT_VALUES)[number];\n\n/** Documents the merge driver options payload exchanged by command, SDK, and package integrations. */\nexport interface MergeDriverOptions {\n /** Artifact class being merged: item document, history JSONL stream, relationship event JSONL store, or key-level JSON config. */\n artifact: string;\n /** Path to the common-ancestor version (git %O). */\n basePath: string;\n /** Path to the current-branch version (git %A); also the default output path per the git merge-driver protocol. */\n oursPath: string;\n /** Path to the other-branch version (git %B). */\n theirsPath: string;\n /** Optional explicit output path overriding the git default of writing to the ours path. */\n outputPath?: string;\n /** Original repository-relative item path supplied by Git as `%P`, used to detect item format when temporary side paths lack extensions. */\n itemPath?: string;\n /** Side that wins unresolvable conflicts (default \"ours\"). */\n prefer?: string;\n}\n\n/** Documents the merge driver result payload exchanged by command, SDK, and package integrations. */\nexport interface MergeDriverResult {\n /** Whether the merge completed without unresolvable conflicts. */\n ok: boolean;\n /** Artifact class that was merged. */\n artifact: MergeDriverArtifact;\n /** Path the merged content was written to. */\n output_path: string;\n /** Side unresolvable conflicts were resolved toward. */\n preferred: MergePreferredSide;\n /** Unresolvable conflict labels: metadata field names (item), dotted key paths (json). Empty for history merges. */\n conflicts: string[];\n /** History-merge strategy and entry accounting; present only for the history artifact. */\n history?: {\n strategy: string;\n common_entries: number;\n entries_from_ours: number;\n entries_from_theirs: number;\n entries_total: number;\n reanchored: boolean;\n };\n /** Relationship-event-merge strategy and accounting; present only for the relationship artifact. */\n relationship?: {\n strategy: string;\n common_entries: number;\n entries_from_ours: number;\n entries_from_theirs: number;\n entries_total: number;\n reanchored: boolean;\n };\n /** Item-merge field accounting; present only for the item artifact. */\n item?: {\n fields_from_theirs: string[];\n union_fields: string[];\n };\n /** JSON-merge key accounting; present only for the json artifact. */\n json?: {\n paths_from_theirs: string[];\n };\n /** Guidance for resolving remaining conflicts or verifying the merged workspace. */\n guidance: string[];\n /** ISO 8601 timestamp recording when generated occurred. */\n generated_at: string;\n}\n\nfunction resolveArtifact(value: string): MergeDriverArtifact {\n const normalized = value.trim().toLowerCase();\n if (\n (MERGE_DRIVER_ARTIFACT_VALUES as readonly string[]).includes(normalized)\n ) {\n return normalized as MergeDriverArtifact;\n }\n throw new PmCliError(\n `Unknown merge artifact \"${value}\". Supported values: ${MERGE_DRIVER_ARTIFACT_VALUES.join(\", \")}.`,\n EXIT_CODE.USAGE,\n );\n}\n\nfunction resolvePreferredSide(value: string | undefined): MergePreferredSide {\n if (value === undefined) {\n return \"ours\";\n }\n const normalized = value.trim().toLowerCase();\n if (normalized === \"ours\" || normalized === \"theirs\") {\n return normalized;\n }\n throw new PmCliError(\n `Unknown --prefer value \"${value}\". Supported values: ours, theirs.`,\n EXIT_CODE.USAGE,\n );\n}\n\nasync function readSideFile(filePath: string, label: string): Promise<string> {\n try {\n return await readFile(filePath, \"utf8\");\n } catch {\n throw new PmCliError(\n `Cannot read merge ${label} file at ${filePath}.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n}\n\n/**\n * Load the workspace settings when a tracker is initialized at the resolved pm\n * root, or fall back to format defaults when the driver runs outside a tracker\n * (git can invoke merge drivers before `pm init`, e.g. while rebasing the\n * commit that introduces the tracker).\n */\nasync function loadOptionalSettings(\n global: GlobalOptions,\n): Promise<PmSettings | null> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n return null;\n }\n return readSettings(pmRoot);\n}\n\nfunction itemFormatForPath(\n filePath: string,\n settings: PmSettings | null,\n): ItemFormat {\n if (filePath.endsWith(\".md\")) {\n return \"json_markdown\";\n }\n if (filePath.endsWith(\".toon\")) {\n return \"toon\";\n }\n return settings?.item_format ?? \"toon\";\n}\n\n/**\n * Execute one git merge-driver invocation for a tracker artifact. Reads the\n * three per-side versions, applies the artifact's field-aware merge semantics,\n * writes the merged content (parseable even when conflicted) to the output\n * path, and reports remaining conflicts so the CLI can exit non-zero and let\n * git mark the path unmerged.\n */\nexport async function runMergeDriver(\n options: MergeDriverOptions,\n global: GlobalOptions,\n): Promise<MergeDriverResult> {\n const artifact = resolveArtifact(options.artifact);\n const preferred = resolvePreferredSide(options.prefer);\n const outputPath = path.resolve(options.outputPath ?? options.oursPath);\n const [baseRaw, oursRaw, theirsRaw] = await Promise.all([\n readSideFile(options.basePath, \"base\"),\n readSideFile(options.oursPath, \"ours\"),\n readSideFile(options.theirsPath, \"theirs\"),\n ]);\n\n let merged: string;\n const conflicts: string[] = [];\n const result: Partial<MergeDriverResult> = {};\n if (artifact === \"history\") {\n const historyMerge = mergeHistoryStreams(baseRaw, oursRaw, theirsRaw);\n merged = historyMerge.merged;\n result.history = {\n strategy: historyMerge.strategy,\n common_entries: historyMerge.common_entries,\n entries_from_ours: historyMerge.entries_from_ours,\n entries_from_theirs: historyMerge.entries_from_theirs,\n entries_total: historyMerge.entries_total,\n reanchored: historyMerge.reanchored,\n };\n } else if (artifact === \"relationship\") {\n const relationshipMerge = mergeRelationshipEventStreams(\n baseRaw,\n oursRaw,\n theirsRaw,\n );\n merged = relationshipMerge.merged;\n result.relationship = {\n strategy: relationshipMerge.strategy,\n common_entries: relationshipMerge.common_entries,\n entries_from_ours: relationshipMerge.entries_from_ours,\n entries_from_theirs: relationshipMerge.entries_from_theirs,\n entries_total: relationshipMerge.entries_total,\n reanchored: relationshipMerge.reanchored,\n };\n } else if (artifact === \"item\") {\n const settings = await loadOptionalSettings(global);\n const itemMerge = mergeItemDocuments(baseRaw, oursRaw, theirsRaw, {\n format: itemFormatForPath(options.itemPath ?? outputPath, settings),\n schema: settings?.schema,\n extensionFieldNames: collectRegisteredItemFieldNames(\n getActiveExtensionRegistrations(),\n ),\n preferred,\n });\n merged = itemMerge.merged;\n conflicts.push(...itemMerge.conflict_fields);\n result.item = {\n fields_from_theirs: itemMerge.fields_from_theirs,\n union_fields: itemMerge.union_fields,\n };\n } else {\n const jsonMerge = mergeJsonDocuments(baseRaw, oursRaw, theirsRaw, {\n preferred,\n });\n merged = jsonMerge.merged;\n conflicts.push(...jsonMerge.conflict_paths);\n result.json = {\n paths_from_theirs: jsonMerge.paths_from_theirs,\n };\n }\n\n await writeFile(outputPath, merged, \"utf8\");\n const guidance: string[] = [];\n if (conflicts.length > 0) {\n guidance.push(\n `Both branches changed ${conflicts.join(\", \")}; the ${preferred} value was kept. Review the merged file, re-apply the losing change if needed, then \"git add\" it.`,\n );\n }\n if (artifact === \"history\" && result.history?.reanchored) {\n guidance.push(\n 'The merged history chain was re-anchored. Run \"pm validate --check-history-drift\" and \"pm history-repair --all\" after the merge to reconcile item state with merged history.',\n );\n }\n return {\n ok: conflicts.length === 0,\n artifact,\n output_path: outputPath,\n preferred,\n conflicts,\n ...result,\n guidance,\n generated_at: nowIso(),\n };\n}\n"],"names":[],"mappings":"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","debugId":"ad0928de-27a9-5c52-9736-17eac79ff5da"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
!(function() {
|
|
3
3
|
try {
|
|
4
4
|
var e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack;
|
|
5
|
-
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "
|
|
5
|
+
n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "da5e9032-8e4f-5731-b861-ccab909a1495");
|
|
6
6
|
} catch (e2) {
|
|
7
7
|
}
|
|
8
8
|
})();
|
|
@@ -209,6 +209,14 @@ var NESTED_SETTING_DESCRIPTORS = [
|
|
|
209
209
|
min: 0,
|
|
210
210
|
summary: "Bounded jittered wait in milliseconds before a contended item mutation fails with lock_conflict; 0 fails fast. PM_LOCK_WAIT_MS overrides per invocation."
|
|
211
211
|
},
|
|
212
|
+
{
|
|
213
|
+
key: "ids_token_length",
|
|
214
|
+
path: "ids.token_length",
|
|
215
|
+
kind: "integer",
|
|
216
|
+
min: 4,
|
|
217
|
+
max: 12,
|
|
218
|
+
summary: "Random base36 token length for newly minted item ids (4-12, default 4). Raise it to shrink cross-branch id collision odds in concurrent multi-agent workflows (pm-pibw)."
|
|
219
|
+
},
|
|
212
220
|
{
|
|
213
221
|
key: "checkpoints_retention_days",
|
|
214
222
|
path: "checkpoints.retention_days",
|
|
@@ -332,6 +340,14 @@ function parseNestedIntegerValue(descriptor, rawValue, value) {
|
|
|
332
340
|
}
|
|
333
341
|
};
|
|
334
342
|
}
|
|
343
|
+
if (descriptor.max !== void 0 && value > descriptor.max) {
|
|
344
|
+
return {
|
|
345
|
+
ok: false,
|
|
346
|
+
error: {
|
|
347
|
+
message: `Config set ${descriptor.key} requires an integer <= ${descriptor.max}, got "${rawValue}"`
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
335
351
|
return { ok: true, parsed: { descriptor, value } };
|
|
336
352
|
}
|
|
337
353
|
function parseNestedRatioValue(descriptor, rawValue, value) {
|
|
@@ -428,4 +444,4 @@ export {
|
|
|
428
444
|
readNestedSettingValue,
|
|
429
445
|
writeNestedSettingValue
|
|
430
446
|
};
|
|
431
|
-
//# sourceMappingURL=chunk-
|
|
447
|
+
//# sourceMappingURL=chunk-SR3JOATZ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../../core/config/nested-settings.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Nested leaf settings exposed via `pm config <scope> set/get <key> <value>`.\n *\n * These are simple string/number leaves of {@link PmSettings} (provider URLs,\n * vector-store adapter, search tuning) that previously required hand-editing\n * `.agents/pm/settings.json`. They live here so the same dotted path is\n * documented in one place and surfaced both to the config dispatcher and to\n * `pm config list` (so `pm config list --json` is discoverable).\n *\n * Shape conventions:\n * - `path` is the dotted JSON path in {@link PmSettings} (e.g. `search.provider`).\n * - `kind` is the value shape: \"string\" | \"boolean\" | \"integer\" | \"number\" | \"ratio\"\n * - \"ratio\" must be a finite number in [0, 1].\n * - \"integer\" must be a finite non-negative integer. Set `min: 1` for keys\n * where the runtime silently falls back when 0 is supplied (e.g. batch\n * size, timeout, max-results limits).\n * - \"number\" must be a finite number — negatives ARE allowed (e.g. score\n * thresholds may legitimately be negative when a provider normalizes\n * scores into a signed range).\n *\n * Adding a key here makes it acceptable to `pm config <scope> set <key> <value>`\n * with no other code changes — the dispatcher walks the dotted path on the\n * already-validated PmSettings shape.\n */\n\n/** Supported coercion shapes for nested settings exposed through `pm config`. */\nexport type NestedSettingKind =\n | \"string\"\n | \"boolean\"\n | \"integer\"\n | \"number\"\n | \"ratio\";\n\n/** Documents the nested setting descriptor payload exchanged by command, SDK, and package integrations. */\nexport interface NestedSettingDescriptor {\n /** CLI key (snake_case). Kebab-case form is accepted by normalizing `-` → `_`. */\n key: string;\n /** Dotted JSON path in PmSettings. */\n path: string;\n /** Value shape. */\n kind: NestedSettingKind;\n /** Short human-facing summary for `pm config list`. */\n summary: string;\n /** Optional accepted values for string settings. */\n choices?: readonly string[];\n /** Require a non-empty trimmed string value for string settings. */\n non_empty?: boolean;\n /** Optional minimum value for `integer` / `number` kinds. When set, `parseNestedSettingValue` rejects values strictly below `min`. Useful for settings where 0 would be silently ignored by the runtime (batch sizes, timeouts, max-results limits). */\n min?: number;\n /** Optional maximum value for `integer` / `number` kinds. When set, `parseNestedSettingValue` rejects values strictly above `max` (bounded knobs like `ids.token_length`). */\n max?: number;\n}\n\n/** Search/provider/vector-store leaves. Order is the display order in `pm config list` and in error hints. */\nexport const NESTED_SETTING_DESCRIPTORS: readonly NestedSettingDescriptor[] = [\n {\n key: \"search_provider\",\n path: \"search.provider\",\n kind: \"string\",\n summary:\n \"Search embedding provider name (e.g. openai, ollama, or an extension provider).\",\n },\n {\n key: \"search_mutation_refresh_policy\",\n path: \"search.mutation_refresh_policy\",\n kind: \"string\",\n choices: [\"cache_only\", \"semantic_configured\", \"semantic_auto\"],\n summary:\n \"Mutation-time search refresh policy: cache_only, semantic_configured, or semantic_auto.\",\n },\n {\n key: \"search_query_expansion_enabled\",\n path: \"search.query_expansion.enabled\",\n kind: \"boolean\",\n summary: \"Enable or disable query expansion for semantic/hybrid search.\",\n },\n {\n key: \"search_query_expansion_provider\",\n path: \"search.query_expansion.provider\",\n kind: \"string\",\n summary:\n \"Query expansion provider name (built-in openai/ollama or extension provider).\",\n },\n {\n key: \"search_rerank_enabled\",\n path: \"search.rerank.enabled\",\n kind: \"boolean\",\n summary: \"Enable or disable post-retrieval reranking for hybrid search.\",\n },\n {\n key: \"search_rerank_model\",\n path: \"search.rerank.model\",\n kind: \"string\",\n summary: \"Rerank model name override used by built-in providers.\",\n },\n {\n key: \"search_rerank_top_k\",\n path: \"search.rerank.top_k\",\n kind: \"integer\",\n min: 1,\n summary:\n \"Number of top hybrid candidates to rerank when rerank is enabled.\",\n },\n {\n key: \"search_embedding_model\",\n path: \"search.embedding_model\",\n kind: \"string\",\n summary:\n \"Default embedding model name (overrides provider-specific model when set).\",\n },\n {\n key: \"search_embedding_corpus_max_characters\",\n path: \"search.embedding_corpus_max_characters\",\n kind: \"integer\",\n min: 1,\n summary: \"Maximum semantic corpus characters per item before truncation.\",\n },\n {\n key: \"search_embedding_batch_size\",\n path: \"search.embedding_batch_size\",\n kind: \"integer\",\n min: 1,\n summary: \"Number of items embedded per request batch.\",\n },\n {\n key: \"search_embedding_timeout_ms\",\n path: \"search.embedding_timeout_ms\",\n kind: \"integer\",\n min: 1,\n summary: \"Per-request embedding timeout in milliseconds.\",\n },\n {\n key: \"search_score_threshold\",\n path: \"search.score_threshold\",\n kind: \"number\",\n summary: \"Minimum score for a hit to be returned (0 keeps all matches).\",\n },\n {\n key: \"search_hybrid_semantic_weight\",\n path: \"search.hybrid_semantic_weight\",\n kind: \"ratio\",\n summary:\n \"Hybrid mode semantic weight in [0, 1] (1-weight goes to keyword).\",\n },\n {\n key: \"search_max_results\",\n path: \"search.max_results\",\n kind: \"integer\",\n min: 1,\n summary: \"Default upper bound on search hits when --limit is not supplied.\",\n },\n {\n key: \"search_bm25_k1\",\n path: \"search.bm25.k1\",\n kind: \"number\",\n min: 0,\n summary:\n \"Offline BM25 term-frequency saturation (k1); higher saturates repeated terms slower (default 1.2).\",\n },\n {\n key: \"search_bm25_b\",\n path: \"search.bm25.b\",\n kind: \"ratio\",\n summary:\n \"Offline BM25 document-length normalization (b) in [0, 1]; 0 disables, 1 fully normalizes (default 0.75).\",\n },\n {\n key: \"openai_base_url\",\n path: \"providers.openai.base_url\",\n kind: \"string\",\n summary: \"OpenAI-compatible API base URL (LM Studio/vLLM also use this).\",\n },\n {\n key: \"openai_api_key\",\n path: \"providers.openai.api_key\",\n kind: \"string\",\n summary: \"OpenAI-compatible API key.\",\n },\n {\n key: \"openai_model\",\n path: \"providers.openai.model\",\n kind: \"string\",\n summary: \"OpenAI-compatible embedding model name.\",\n },\n {\n key: \"ollama_base_url\",\n path: \"providers.ollama.base_url\",\n kind: \"string\",\n summary: \"Ollama API base URL (typically http://localhost:11434).\",\n },\n {\n key: \"ollama_model\",\n path: \"providers.ollama.model\",\n kind: \"string\",\n summary: \"Ollama embedding model name (e.g. nomic-embed-text).\",\n },\n {\n key: \"vector_store_adapter\",\n path: \"vector_store.adapter\",\n kind: \"string\",\n summary:\n \"Vector store adapter name (lancedb, qdrant, or an extension adapter).\",\n },\n {\n key: \"vector_store_collection_name\",\n path: \"vector_store.collection_name\",\n kind: \"string\",\n non_empty: true,\n summary:\n \"Vector collection/table name shared by Qdrant and LanceDB adapters.\",\n },\n {\n key: \"qdrant_url\",\n path: \"vector_store.qdrant.url\",\n kind: \"string\",\n summary: \"Qdrant HTTP API URL.\",\n },\n {\n key: \"qdrant_api_key\",\n path: \"vector_store.qdrant.api_key\",\n kind: \"string\",\n summary: \"Qdrant API key (empty if running unauthenticated).\",\n },\n {\n key: \"lancedb_path\",\n path: \"vector_store.lancedb.path\",\n kind: \"string\",\n summary: \"LanceDB storage path (relative to pm root or absolute).\",\n },\n // General workspace leaves (id/author/output/locks/schema governance). These\n // are documented user-facing settings in CONFIGURATION.md that previously\n // required hand-editing settings.json.\n {\n key: \"id_prefix\",\n path: \"id_prefix\",\n kind: \"string\",\n non_empty: true,\n summary: 'Prefix for generated item IDs (e.g. \"pm\" produces pm-xxxx).',\n },\n {\n key: \"author_default\",\n path: \"author_default\",\n kind: \"string\",\n non_empty: true,\n summary:\n \"Default author recorded on mutations when --author is not supplied.\",\n },\n {\n key: \"output_default_format\",\n path: \"output.default_format\",\n kind: \"string\",\n choices: [\"toon\", \"json\"],\n summary:\n \"Default output format for commands that support it: toon or json.\",\n },\n {\n key: \"locks_ttl_seconds\",\n path: \"locks.ttl_seconds\",\n kind: \"integer\",\n min: 1,\n summary:\n \"Claim/lock time-to-live in seconds before a stale lock can be reclaimed.\",\n },\n {\n key: \"locks_wait_ms\",\n path: \"locks.wait_ms\",\n kind: \"integer\",\n min: 0,\n summary:\n \"Bounded jittered wait in milliseconds before a contended item mutation fails with lock_conflict; 0 fails fast. PM_LOCK_WAIT_MS overrides per invocation.\",\n },\n {\n key: \"ids_token_length\",\n path: \"ids.token_length\",\n kind: \"integer\",\n min: 4,\n max: 12,\n summary:\n \"Random base36 token length for newly minted item ids (4-12, default 4). Raise it to shrink cross-branch id collision odds in concurrent multi-agent workflows (pm-pibw).\",\n },\n {\n key: \"checkpoints_retention_days\",\n path: \"checkpoints.retention_days\",\n kind: \"integer\",\n min: 1,\n summary:\n \"Age in days above which pm gc --scope checkpoints prunes bulk-mutation rollback checkpoints.\",\n },\n {\n key: \"schema_unknown_field_policy\",\n path: \"schema.unknown_field_policy\",\n kind: \"string\",\n choices: [\"allow\", \"warn\", \"reject\"],\n summary:\n \"How item I/O handles metadata keys not in the field registry: allow, warn, or reject.\",\n },\n // History compaction policy leaves (pm health advisory + pm history-compact\n // bulk-sweep default threshold). Disabled by default; enabling makes large\n // streams discoverable without a manual stats pass.\n {\n key: \"history_compact_policy_enabled\",\n path: \"history.compact_policy.enabled\",\n kind: \"boolean\",\n summary:\n \"Enable the history-compaction advisory: pm health warns on over-threshold streams.\",\n },\n {\n key: \"history_compact_policy_max_entries\",\n path: \"history.compact_policy.max_entries\",\n kind: \"integer\",\n min: 1,\n summary:\n \"Entry count above which a history stream is flagged (and the default pm history-compact --all-over threshold).\",\n },\n {\n key: \"history_compact_policy_trigger\",\n path: \"history.compact_policy.trigger\",\n kind: \"string\",\n choices: [\"health_warn\", \"auto\"],\n summary:\n \"History-compaction policy intent: health_warn (advisory only) or auto (scheduled sweeps expected).\",\n },\n];\n\nconst DESCRIPTOR_BY_KEY: ReadonlyMap<string, NestedSettingDescriptor> = new Map(\n NESTED_SETTING_DESCRIPTORS.flatMap((descriptor) => [\n [descriptor.key, descriptor],\n [descriptor.path.toLowerCase().replaceAll(\"-\", \"_\"), descriptor],\n ]),\n);\n\n/** Map a raw user-supplied key (kebab case, snake case, or the dotted settings path surfaced by `pm config list`) onto a known nested-leaf descriptor. Returns `undefined` when the key is not a nested leaf, letting callers fall back to the regular ConfigKey path. */\nexport function resolveNestedSettingDescriptor(\n raw: string | undefined,\n): NestedSettingDescriptor | undefined {\n if (typeof raw !== \"string\") {\n return undefined;\n }\n const normalized = raw.trim().toLowerCase().replaceAll(\"-\", \"_\");\n if (normalized.length === 0) {\n return undefined;\n }\n return DESCRIPTOR_BY_KEY.get(normalized);\n}\n\n/** Recoverable parsed value with the descriptor it satisfied. */\nexport interface NestedSettingParsedValue {\n /** Value that configures or reports descriptor for this contract. */\n descriptor: NestedSettingDescriptor;\n /** Value that configures or reports value for this contract. */\n value: string | number | boolean;\n}\n\n/** Throwable validation error returned as a structured result. */\nexport interface NestedSettingParseError {\n /** Human-readable explanation suitable for logs and agent-facing output. */\n message: string;\n}\n\n/** Restricts nested setting parse result values accepted by command, SDK, and storage contracts. */\nexport type NestedSettingParseResult =\n | { ok: true; parsed: NestedSettingParsedValue }\n | { ok: false; error: NestedSettingParseError };\n\nfunction parseNestedBooleanValue(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n): NestedSettingParseResult {\n const normalized = rawValue.trim().toLowerCase();\n if (\n normalized === \"true\" ||\n normalized === \"1\" ||\n normalized === \"yes\" ||\n normalized === \"on\"\n ) {\n return { ok: true, parsed: { descriptor, value: true } };\n }\n if (\n normalized === \"false\" ||\n normalized === \"0\" ||\n normalized === \"no\" ||\n normalized === \"off\"\n ) {\n return { ok: true, parsed: { descriptor, value: false } };\n }\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a boolean value (true|false), got \"${rawValue}\"`,\n },\n };\n}\n\nfunction parseNestedStringValue(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n trimmed: string,\n): NestedSettingParseResult {\n if (descriptor.non_empty === true && trimmed.length === 0) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a non-empty value`,\n },\n };\n }\n if (descriptor.choices && !descriptor.choices.includes(trimmed)) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} must be one of ${descriptor.choices.join(\"|\")}, got \"${rawValue}\"`,\n },\n };\n }\n return { ok: true, parsed: { descriptor, value: trimmed } };\n}\n\nfunction parseFiniteNestedNumber(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n trimmed: string,\n): { ok: true; value: number } | { ok: false; error: NestedSettingParseError } {\n if (trimmed.length === 0) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a non-empty value`,\n },\n };\n }\n const parsed = Number(trimmed);\n if (!Number.isFinite(parsed)) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a finite number, got \"${rawValue}\"`,\n },\n };\n }\n return { ok: true, value: parsed };\n}\n\nfunction parseNestedIntegerValue(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n value: number,\n): NestedSettingParseResult {\n if (!Number.isInteger(value) || value < 0) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a non-negative integer, got \"${rawValue}\"`,\n },\n };\n }\n if (descriptor.min !== undefined && value < descriptor.min) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires an integer >= ${descriptor.min}, got \"${rawValue}\" (the runtime silently ignores 0 here and falls back to the default)`,\n },\n };\n }\n if (descriptor.max !== undefined && value > descriptor.max) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires an integer <= ${descriptor.max}, got \"${rawValue}\"`,\n },\n };\n }\n return { ok: true, parsed: { descriptor, value } };\n}\n\nfunction parseNestedRatioValue(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n value: number,\n): NestedSettingParseResult {\n if (value < 0 || value > 1) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a number in [0, 1], got \"${rawValue}\"`,\n },\n };\n }\n return { ok: true, parsed: { descriptor, value } };\n}\n\nfunction parseNestedNumberValue(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n value: number,\n): NestedSettingParseResult {\n if (descriptor.min !== undefined && value < descriptor.min) {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a number >= ${descriptor.min}, got \"${rawValue}\"`,\n },\n };\n }\n return { ok: true, parsed: { descriptor, value } };\n}\n\n/**\n * Validate and coerce a raw string value for a nested-leaf setting. The\n * returned value is the typed leaf that should be written into PmSettings.\n *\n * Empty strings are allowed for \"string\" leaves unless `non_empty` is set.\n */\nexport function parseNestedSettingValue(\n descriptor: NestedSettingDescriptor,\n rawValue: string,\n): NestedSettingParseResult {\n if (typeof rawValue !== \"string\") {\n return {\n ok: false,\n error: {\n message: `Config set ${descriptor.key} requires a string value`,\n },\n };\n }\n const trimmed = rawValue.trim();\n if (descriptor.kind === \"boolean\") {\n return parseNestedBooleanValue(descriptor, rawValue);\n }\n if (descriptor.kind === \"string\") {\n return parseNestedStringValue(descriptor, rawValue, trimmed);\n }\n\n // Number(\"\") === 0, which would silently accept empty / whitespace-only input\n // as a valid zero. Reject explicitly so misconfigurations don't slip through.\n const parsed = parseFiniteNestedNumber(descriptor, rawValue, trimmed);\n if (!parsed.ok) {\n return { ok: false, error: parsed.error };\n }\n if (descriptor.kind === \"integer\") {\n return parseNestedIntegerValue(descriptor, rawValue, parsed.value);\n }\n if (descriptor.kind === \"ratio\") {\n return parseNestedRatioValue(descriptor, rawValue, parsed.value);\n }\n // kind === \"number\" — negatives are allowed; only apply an explicit `min`.\n return parseNestedNumberValue(descriptor, rawValue, parsed.value);\n}\n\n/** Walk a dotted path on an arbitrary record (best-effort, returns null on miss). */\nexport function readNestedSettingValue(\n settings: unknown,\n descriptor: NestedSettingDescriptor,\n): string | number | boolean | null {\n const segments = descriptor.path.split(\".\");\n let cursor: unknown = settings;\n for (const segment of segments) {\n if (typeof cursor !== \"object\" || cursor === null) {\n return null;\n }\n cursor = (cursor as Record<string, unknown>)[segment];\n }\n if (\n typeof cursor === \"string\" ||\n typeof cursor === \"number\" ||\n typeof cursor === \"boolean\"\n ) {\n return cursor;\n }\n return null;\n}\n\n/** Set a leaf value on a settings object by walking the descriptor's dotted path. Missing intermediate objects are created. Returns `true` when the value actually changed. */\nexport function writeNestedSettingValue(\n settings: Record<string, unknown>,\n descriptor: NestedSettingDescriptor,\n value: string | number | boolean,\n): boolean {\n const segments = descriptor.path.split(\".\");\n let cursor: Record<string, unknown> = settings;\n for (let index = 0; index < segments.length - 1; index += 1) {\n const segment = segments[index];\n const existing = cursor[segment];\n if (\n typeof existing !== \"object\" ||\n existing === null ||\n Array.isArray(existing)\n ) {\n const next: Record<string, unknown> = {};\n cursor[segment] = next;\n cursor = next;\n } else {\n cursor = existing as Record<string, unknown>;\n }\n }\n const leafKey = segments[segments.length - 1];\n const previous = cursor[leafKey];\n if (previous === value) {\n return false;\n }\n cursor[leafKey] = value;\n return true;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9a360c17-f01f-5885-b30d-30361c04ceac")}catch(e){}}();
|
|
3
3
|
import {
|
|
4
4
|
lifecycleClassifierFromStatusRegistry
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QWRVBJ4D.js";
|
|
6
6
|
import {
|
|
7
7
|
applyHistoryPatch,
|
|
8
|
-
cloneEmptyReplayDocument,
|
|
9
8
|
executeHistoryRewrite,
|
|
10
|
-
historyEntriesToRaw,
|
|
11
9
|
readHistoryEntries,
|
|
10
|
+
resolveHistorySubject,
|
|
11
|
+
writeHistoryRawWithRollback
|
|
12
|
+
} from "./chunk-2BO4CA46.js";
|
|
13
|
+
import {
|
|
14
|
+
cloneEmptyReplayDocument,
|
|
15
|
+
historyEntriesToRaw,
|
|
12
16
|
replayHash,
|
|
13
17
|
replayToItemDocument,
|
|
14
|
-
resolveHistorySubject,
|
|
15
18
|
toReplayDocument,
|
|
16
|
-
verifyHistoryChain
|
|
17
|
-
|
|
18
|
-
} from "./chunk-M4B4RK4J.js";
|
|
19
|
+
verifyHistoryChain
|
|
20
|
+
} from "./chunk-P7JTWYLH.js";
|
|
19
21
|
import {
|
|
20
22
|
resolveAuthor
|
|
21
23
|
} from "./chunk-CUFW7ITY.js";
|
|
@@ -28,7 +30,7 @@ import {
|
|
|
28
30
|
readSettings,
|
|
29
31
|
runActiveOnReadHooks,
|
|
30
32
|
runActiveOnWriteHooks
|
|
31
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-POG76WWZ.js";
|
|
32
34
|
import {
|
|
33
35
|
EXIT_CODE,
|
|
34
36
|
PmCliError,
|
|
@@ -38,7 +40,7 @@ import {
|
|
|
38
40
|
resolveItemTypeRegistry,
|
|
39
41
|
resolvePmRoot,
|
|
40
42
|
resolveRuntimeStatusRegistry
|
|
41
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-HYW67VJ5.js";
|
|
42
44
|
|
|
43
45
|
// dist/sdk/history-compact.js
|
|
44
46
|
import fs from "node:fs/promises";
|
|
@@ -584,6 +586,6 @@ export {
|
|
|
584
586
|
assertHistoryCompactTarget,
|
|
585
587
|
runHistoryCompactBulk
|
|
586
588
|
};
|
|
587
|
-
//# sourceMappingURL=chunk-
|
|
589
|
+
//# sourceMappingURL=chunk-SSKOQNMS.js.map
|
|
588
590
|
|
|
589
|
-
//# debugId=
|
|
591
|
+
//# debugId=9a360c17-f01f-5885-b30d-30361c04ceac
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../sdk/history-compact.ts","../../../../../../../../core/history/history-compact-bulk.ts"],"sourcesContent":["/**\n * @module sdk/history-compact\n *\n * Implements the pm history compact command surface and its agent-facing runtime behavior.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHistoryEntry } from \"../core/history/history.js\";\nimport {\n selectHistoryCompactBulkTargets,\n type HistoryCompactBulkCandidate,\n type HistoryCompactBulkSkipReason,\n type HistoryCompactScope,\n} from \"../core/history/history-compact-bulk.js\";\nimport {\n executeHistoryRewrite,\n writeHistoryRawWithRollback,\n} from \"../core/history/history-rewrite.js\";\nimport {\n cloneEmptyReplayDocument,\n historyEntriesToRaw,\n replayHash,\n replayToItemDocument,\n toReplayDocument,\n verifyHistoryChain,\n type ReplayDocument,\n} from \"../core/history/replay.js\";\nimport { applyHistoryPatch } from \"../core/history/projection.js\";\nimport { readHistoryEntries } from \"../core/history/read.js\";\nimport { resolveItemTypeRegistry } from \"../core/item/type-registry.js\";\nimport { lifecycleClassifierFromStatusRegistry } from \"../core/governance/metadata-coverage.js\";\nimport { resolveRuntimeStatusRegistry } from \"../core/schema/runtime-schema.js\";\nimport { listAllItemMetadataLight } from \"../core/store/item-store.js\";\nimport { pathExists, readFileIfExists } from \"../core/fs/fs-utils.js\";\nimport { EXIT_CODE } from \"../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../core/shared/command-types.js\";\nimport { PmCliError } from \"../core/shared/errors.js\";\nimport { nowIso } from \"../core/shared/time.js\";\nimport {\n getActiveExtensionRegistrations,\n runActiveOnReadHooks,\n runActiveOnWriteHooks,\n} from \"../core/extensions/index.js\";\nimport { readLocatedItem } from \"../core/store/item-store.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../core/store/paths.js\";\nimport { readSettings } from \"../core/store/settings.js\";\nimport { resolveAuthor } from \"../core/shared/author.js\";\nimport type { HistoryEntry } from \"../types/index.js\";\nimport { resolveHistorySubject } from \"./history-redact.js\";\n\n/** Documents the history compact command options payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactCommandOptions {\n /** Value that configures or reports before for this contract. */\n before?: string;\n /** Value that configures or reports dry run for this contract. */\n dryRun?: boolean;\n /** Value that configures or reports author for this contract. */\n author?: string;\n /** Human-readable explanation suitable for logs and agent-facing output. */\n message?: string;\n /** Value that configures or reports force for this contract. */\n force?: boolean;\n}\n\ntype HistoryCompactBoundaryKind = \"default\" | \"version\" | \"timestamp\";\n\ninterface HistoryCompactBoundary {\n kind: HistoryCompactBoundaryKind;\n raw: string | null;\n compactCount: number;\n retainedCount: number;\n}\n\ninterface HistoryCompactCurrentItem {\n loadedItem: Awaited<ReturnType<typeof readLocatedItem>> | null;\n currentItemRawBeforeLock: string | null;\n matchedChainBefore: boolean | null;\n}\n\n/** Documents the history compact result payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactResult {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports dry run for this contract. */\n dry_run: boolean;\n /** Value that configures or reports changed for this contract. */\n changed: boolean;\n /** Value that configures or reports compact boundary for this contract. */\n compact_boundary: {\n kind: HistoryCompactBoundaryKind;\n before: string | null;\n entries_compacted: number;\n entries_retained: number;\n first_retained_entry: number | null;\n };\n /** Value that configures or reports history for this contract. */\n history: {\n path: string;\n entries_scanned: number;\n entries_after: number;\n baseline_entry_added: boolean;\n audit_entry_added: boolean;\n verify_ok: boolean;\n verify_errors: string[];\n };\n /** Value that configures or reports item for this contract. */\n item: {\n exists: boolean;\n path: string | null;\n matched_chain_before: boolean | null;\n };\n /** Value that configures or reports warnings for this contract. */\n warnings: string[];\n /** ISO 8601 timestamp recording when generated occurred. */\n generated_at: string;\n}\n\nfunction parseBeforeBoundary(\n before: string | undefined,\n entries: HistoryEntry[],\n): HistoryCompactBoundary {\n if (before === undefined) {\n return {\n kind: \"default\",\n raw: null,\n compactCount: entries.length,\n retainedCount: 0,\n };\n }\n\n const raw = before.trim();\n if (raw.length === 0) {\n throw new PmCliError(\n \"history-compact --before requires a non-empty value.\",\n EXIT_CODE.USAGE,\n );\n }\n\n if (/^\\d+$/.test(raw)) {\n const version = Number.parseInt(raw, 10);\n if (\n !Number.isSafeInteger(version) ||\n version < 1 ||\n version > entries.length + 1\n ) {\n throw new PmCliError(\n `history-compact --before version must be between 1 and ${entries.length + 1}.`,\n EXIT_CODE.USAGE,\n );\n }\n const compactCount = Math.max(0, Math.min(entries.length, version - 1));\n return {\n kind: \"version\",\n raw,\n compactCount,\n retainedCount: entries.length - compactCount,\n };\n }\n\n const beforeTs = Date.parse(raw);\n if (!Number.isFinite(beforeTs)) {\n throw new PmCliError(\n `Invalid history-compact --before value \"${before}\". Use a version number or ISO timestamp.`,\n EXIT_CODE.USAGE,\n );\n }\n\n let compactCount = 0;\n for (const [index, entry] of entries.entries()) {\n const entryTs = Date.parse(entry.ts);\n if (!Number.isFinite(entryTs)) {\n throw new PmCliError(\n `History for this item contains invalid timestamp at entry ${index + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n if (entryTs >= beforeTs) {\n break;\n }\n compactCount += 1;\n }\n\n return {\n kind: \"timestamp\",\n raw,\n compactCount,\n retainedCount: entries.length - compactCount,\n };\n}\n\nfunction replayHistoryAndResolveCheckpoint(\n entries: HistoryEntry[],\n compactCount: number,\n): {\n checkpoint: ReplayDocument;\n finalReplay: ReplayDocument;\n} {\n let replay = cloneEmptyReplayDocument();\n let checkpoint = cloneEmptyReplayDocument();\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index];\n if (replayHash(replay) !== entry.before_hash) {\n throw new PmCliError(\n `history-compact detected before-hash drift at entry ${index + 1}; run pm history-repair first.`,\n EXIT_CODE.CONFLICT,\n );\n }\n replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);\n if (replayHash(replay) !== entry.after_hash) {\n throw new PmCliError(\n `history-compact detected after-hash drift at entry ${index + 1}; run pm history-repair first.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (index + 1 === compactCount) {\n checkpoint = structuredClone(replay);\n }\n }\n return {\n checkpoint,\n finalReplay: replay,\n };\n}\n\nfunction reanchorRetainedEntries(\n retainedEntries: HistoryEntry[],\n seed: ReplayDocument,\n retainedEntryOffset: number,\n): {\n entries: HistoryEntry[];\n finalReplay: ReplayDocument;\n} {\n let replay = structuredClone(seed);\n const rewritten: HistoryEntry[] = [];\n for (const [index, entry] of retainedEntries.entries()) {\n const beforeHash = replayHash(replay);\n replay = applyHistoryPatch(\n replay,\n entry.patch,\n retainedEntryOffset + index + 1,\n entry.op,\n );\n rewritten.push({\n ...entry,\n before_hash: beforeHash,\n after_hash: replayHash(replay),\n });\n }\n return {\n entries: rewritten,\n finalReplay: replay,\n };\n}\n\nasync function loadHistoryCompactCurrentItem(\n subject: Awaited<ReturnType<typeof resolveHistorySubject>>,\n settings: Awaited<ReturnType<typeof readSettings>>,\n historyEntries: HistoryEntry[],\n): Promise<HistoryCompactCurrentItem> {\n const loadedItem = subject.located\n ? await readLocatedItem(subject.located, { schema: settings.schema })\n : null;\n if (!loadedItem) {\n return {\n loadedItem: null,\n currentItemRawBeforeLock: null,\n matchedChainBefore: null,\n };\n }\n return {\n loadedItem,\n currentItemRawBeforeLock: loadedItem.raw,\n matchedChainBefore:\n replayHash(toReplayDocument(loadedItem.document)) ===\n historyEntries[historyEntries.length - 1]?.after_hash,\n };\n}\n\nfunction buildHistoryCompactMessage(\n options: HistoryCompactCommandOptions,\n boundary: HistoryCompactBoundary,\n): string {\n if (\n typeof options.message === \"string\" &&\n options.message.trim().length > 0\n ) {\n return options.message;\n }\n if (boundary.raw === null) {\n return `history-compact compacted full stream (${boundary.compactCount} entr${\n boundary.compactCount === 1 ? \"y\" : \"ies\"\n }).`;\n }\n return `history-compact compacted ${boundary.compactCount} entr${\n boundary.compactCount === 1 ? \"y\" : \"ies\"\n } before ${boundary.raw}.`;\n}\n\nfunction buildHistoryCompactBaselineMessage(\n boundary: HistoryCompactBoundary,\n): string {\n if (boundary.raw === null) {\n return `history-compact baseline snapshot after compacting ${boundary.compactCount} entr${\n boundary.compactCount === 1 ? \"y\" : \"ies\"\n }.`;\n }\n return `history-compact baseline snapshot before ${boundary.raw}.`;\n}\n\nfunction buildHistoryCompactEntries(params: {\n historyEntries: HistoryEntry[];\n boundary: HistoryCompactBoundary;\n changed: boolean;\n dryRun: boolean;\n author: string;\n options: HistoryCompactCommandOptions;\n}): {\n rewrittenEntries: HistoryEntry[];\n baselineEntryAdded: boolean;\n auditEntryAdded: boolean;\n} {\n if (!params.changed) {\n return {\n rewrittenEntries: params.historyEntries,\n baselineEntryAdded: false,\n auditEntryAdded: false,\n };\n }\n const { checkpoint, finalReplay } = replayHistoryAndResolveCheckpoint(\n params.historyEntries,\n params.boundary.compactCount,\n );\n const retained = params.historyEntries.slice(params.boundary.compactCount);\n const reanchored = reanchorRetainedEntries(\n retained,\n checkpoint,\n params.boundary.compactCount,\n );\n const baselineEntry = createHistoryEntry({\n nowIso: nowIso(),\n author: params.author,\n op: \"history_compact_baseline\",\n before: replayToItemDocument(cloneEmptyReplayDocument()),\n after: replayToItemDocument(checkpoint),\n message: buildHistoryCompactBaselineMessage(params.boundary),\n });\n const rewrittenEntries = [baselineEntry, ...reanchored.entries];\n if (!params.dryRun) {\n rewrittenEntries.push(\n createHistoryEntry({\n nowIso: nowIso(),\n author: params.author,\n op: \"history_compact\",\n before: replayToItemDocument(finalReplay),\n after: replayToItemDocument(finalReplay),\n message: buildHistoryCompactMessage(params.options, params.boundary),\n }),\n );\n }\n return {\n rewrittenEntries,\n baselineEntryAdded: true,\n auditEntryAdded: !params.dryRun,\n };\n}\n\nasync function applyHistoryCompactRewrite(params: {\n pmRoot: string;\n subject: Awaited<ReturnType<typeof resolveHistorySubject>>;\n settings: Awaited<ReturnType<typeof readSettings>>;\n typeRegistry: ReturnType<typeof resolveItemTypeRegistry>;\n historyRawBeforeLock: string;\n currentItemRawBeforeLock: string | null;\n author: string;\n force: boolean | undefined;\n loadedItem: Awaited<ReturnType<typeof readLocatedItem>> | null;\n historyPath: string;\n rewrittenEntries: HistoryEntry[];\n}): Promise<string[]> {\n return executeHistoryRewrite({\n pmRoot: params.pmRoot,\n subject: params.subject,\n settings: params.settings,\n typeRegistry: params.typeRegistry,\n historyRawBeforeLock: params.historyRawBeforeLock,\n currentItemRawBeforeLock: params.currentItemRawBeforeLock,\n operation: \"history-compact\",\n author: params.author,\n force: params.force,\n itemDocument: params.loadedItem?.document ?? null,\n applyRewrite: async ({ historyRawUnderLock }) =>\n writeHistoryRawWithRollback({\n historyPath: params.historyPath,\n nextHistoryRaw: historyEntriesToRaw(params.rewrittenEntries),\n historyRawUnderLock,\n }),\n applyPostRewrite: async () =>\n runActiveOnWriteHooks({\n path: params.historyPath,\n scope: \"project\",\n op: \"history_compact:history\",\n }),\n });\n}\n\n/** Implements run history compact for the public runtime surface of this module. */\nexport async function runHistoryCompact(\n id: string,\n options: HistoryCompactCommandOptions,\n global: GlobalOptions,\n): Promise<HistoryCompactResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n const subject = await resolveHistorySubject(\n pmRoot,\n id,\n settings,\n typeRegistry.type_to_folder,\n );\n const historyPath = subject.historyPath;\n const historyRawBeforeLock = await readFileIfExists(historyPath);\n if (historyRawBeforeLock === null) {\n throw new PmCliError(\n `No history stream exists for ${subject.id}.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n const historyEntries = await readHistoryEntries(historyPath, subject.id);\n if (historyEntries.length === 0) {\n throw new PmCliError(\n `No history entries exist for ${subject.id}; nothing to compact.`,\n EXIT_CODE.USAGE,\n );\n }\n\n const chainVerification = verifyHistoryChain(historyEntries);\n if (!chainVerification.ok) {\n throw new PmCliError(\n `history-compact requires a valid history chain (${chainVerification.errors.join(\", \")}). Run pm history-repair ${subject.id} first.`,\n EXIT_CODE.CONFLICT,\n );\n }\n\n const boundary = parseBeforeBoundary(options.before, historyEntries);\n const changed = boundary.compactCount > 0;\n const dryRun = Boolean(options.dryRun);\n const author = resolveAuthor(options.author, settings.author_default);\n const warnings: string[] = [];\n if (!changed) {\n warnings.push(\"history_compact_noop_before_boundary\");\n }\n\n const currentItem = await loadHistoryCompactCurrentItem(\n subject,\n settings,\n historyEntries,\n );\n if (currentItem.matchedChainBefore === false) {\n warnings.push(\"history_compact_item_chain_mismatch\");\n }\n\n const { rewrittenEntries, baselineEntryAdded, auditEntryAdded } =\n buildHistoryCompactEntries({\n historyEntries,\n boundary,\n changed,\n dryRun,\n author,\n options,\n });\n\n const rewrittenVerify = verifyHistoryChain(rewrittenEntries);\n if (!rewrittenVerify.ok) {\n throw new PmCliError(\n `history-compact produced an invalid rewritten chain (${rewrittenVerify.errors.join(\", \")}).`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n if (changed && !dryRun) {\n warnings.push(\n ...(await applyHistoryCompactRewrite({\n pmRoot,\n subject,\n settings,\n typeRegistry,\n historyRawBeforeLock,\n currentItemRawBeforeLock: currentItem.currentItemRawBeforeLock,\n author,\n force: options.force,\n loadedItem: currentItem.loadedItem,\n historyPath,\n rewrittenEntries,\n })),\n );\n }\n\n const firstRetainedEntry =\n boundary.retainedCount > 0 ? boundary.compactCount + 1 : null;\n return {\n id: subject.id,\n dry_run: dryRun,\n changed,\n compact_boundary: {\n kind: boundary.kind,\n before: boundary.raw,\n entries_compacted: boundary.compactCount,\n entries_retained: boundary.retainedCount,\n first_retained_entry: firstRetainedEntry,\n },\n history: {\n path: historyPath,\n entries_scanned: historyEntries.length,\n entries_after: rewrittenEntries.length,\n baseline_entry_added: baselineEntryAdded,\n audit_entry_added: auditEntryAdded,\n verify_ok: rewrittenVerify.ok,\n verify_errors: rewrittenVerify.errors,\n },\n item: {\n exists: subject.located !== null,\n path: subject.located?.itemPath ?? null,\n matched_chain_before: currentItem.matchedChainBefore,\n },\n warnings: [...new Set(warnings)].sort((left, right) =>\n left.localeCompare(right),\n ),\n generated_at: nowIso(),\n };\n}\n\n/** Default entry floor below which a stream is treated as already compact. */\nexport const HISTORY_COMPACT_BULK_DEFAULT_MIN_ENTRIES = 3;\n\n/** Documents the bulk history compact command options payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactBulkCommandOptions {\n /** Value that configures or reports ids for this contract. */\n ids?: string[];\n /** Value that configures or reports scope for this contract. */\n scope?: HistoryCompactScope;\n /** Value that configures or reports all over for this contract. */\n allOver?: number;\n /** Value that configures or reports min entries for this contract. */\n minEntries?: number;\n /** Value that configures or reports dry run for this contract. */\n dryRun?: boolean;\n /** Value that configures or reports author for this contract. */\n author?: string;\n /** Human-readable explanation suitable for logs and agent-facing output. */\n message?: string;\n /** Value that configures or reports force for this contract. */\n force?: boolean;\n}\n\n/** Per-item outcome row in a bulk compaction pass. */\nexport interface HistoryCompactBulkItemResult {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports outcome for this contract. */\n outcome: \"compacted\" | \"skipped\" | \"errored\";\n /** Value that configures or reports entries before for this contract. */\n entries_before: number;\n /** Value that configures or reports entries after for this contract. */\n entries_after: number | null;\n /** Value that configures or reports skip reason for this contract. */\n skip_reason: HistoryCompactBulkSkipReason | null;\n /** Value that configures or reports changed for this contract. */\n changed: boolean;\n /** Value that configures or reports error for this contract. */\n error: string | null;\n}\n\n/** Documents the bulk history compact result payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactBulkResult {\n /** Value that configures or reports bulk for this contract. */\n bulk: true;\n /** Value that configures or reports dry run for this contract. */\n dry_run: boolean;\n /** Value that configures or reports mode for this contract. */\n mode: \"ids\" | \"scan\";\n /** Value that configures or reports scope for this contract. */\n scope: HistoryCompactScope | null;\n /** Value that configures or reports criteria for this contract. */\n criteria: {\n min_entries: number;\n all_over: number | null;\n policy_threshold_applied: boolean;\n };\n /** Value that configures or reports totals for this contract. */\n totals: {\n streams_considered: number;\n selected: number;\n items_compacted: number;\n items_skipped: number;\n items_errored: number;\n };\n /** Value that configures or reports results for this contract. */\n results: HistoryCompactBulkItemResult[];\n /** ISO 8601 timestamp recording when generated occurred. */\n generated_at: string;\n}\n\n/** Enforce the `pm history-compact` target contract shared by the CLI and MCP surfaces: exactly one selection mode — a single item `<id>`, an explicit `--ids` list, or a scan selector (`--all-over` / `--closed` / `--all-streams`). */\nexport function assertHistoryCompactTarget(\n id: string | undefined,\n bulk: { ids?: string[]; allOver?: number; scope?: HistoryCompactScope },\n): void {\n const hasIds = bulk.ids !== undefined && bulk.ids.length > 0;\n const hasScan = bulk.allOver !== undefined || bulk.scope !== undefined;\n const selectorCount =\n (id !== undefined ? 1 : 0) + (hasIds ? 1 : 0) + (hasScan ? 1 : 0);\n if (selectorCount === 0) {\n throw new PmCliError(\n \"history-compact: provide an item <id>, or a bulk selector (--ids, --all-over <N>, --closed, or --all-streams).\",\n EXIT_CODE.USAGE,\n );\n }\n if (id !== undefined && (hasIds || hasScan)) {\n throw new PmCliError(\n \"history-compact: <id> and bulk selectors (--ids/--all-over/--closed/--all-streams) are mutually exclusive; pass one item id, or use bulk mode without a positional id.\",\n EXIT_CODE.USAGE,\n );\n }\n if (hasIds && hasScan) {\n throw new PmCliError(\n \"history-compact: --ids is mutually exclusive with --all-over/--closed/--all-streams; pass an explicit id list or a scan selector, not both.\",\n EXIT_CODE.USAGE,\n );\n }\n}\n\nfunction countHistoryStreamEntries(raw: string): number {\n let count = 0;\n for (const line of raw.split(/\\r?\\n/)) {\n if (line.trim().length > 0) {\n count += 1;\n }\n }\n return count;\n}\n\nasync function collectHistoryCompactBulkCandidates(params: {\n pmRoot: string;\n settings: Awaited<ReturnType<typeof readSettings>>;\n typeToFolder: Record<string, string>;\n}): Promise<{\n candidates: HistoryCompactBulkCandidate[];\n preselectionErrors: HistoryCompactBulkItemResult[];\n}> {\n const statusRegistry = resolveRuntimeStatusRegistry(params.settings.schema);\n const classifier = lifecycleClassifierFromStatusRegistry(statusRegistry);\n const items = await listAllItemMetadataLight(\n params.pmRoot,\n params.settings.item_format,\n params.typeToFolder,\n undefined,\n params.settings.schema,\n );\n const bucketById = new Map(\n items.map((item) => [item.id, classifier.classify(item.status)] as const),\n );\n const historyDir = path.join(params.pmRoot, \"history\");\n const candidates: HistoryCompactBulkCandidate[] = [];\n const preselectionErrors: HistoryCompactBulkItemResult[] = [];\n if (!(await pathExists(historyDir))) {\n return { candidates, preselectionErrors };\n }\n const historyFiles = (await fs.readdir(historyDir))\n .filter((entry) => entry.endsWith(\".jsonl\"))\n .sort((left, right) => left.localeCompare(right));\n for (const fileName of historyFiles) {\n const historyPath = path.join(historyDir, fileName);\n const id = fileName.slice(0, -\".jsonl\".length);\n try {\n const raw = await fs.readFile(historyPath, \"utf8\");\n await runActiveOnReadHooks({ path: historyPath, scope: \"project\" });\n candidates.push({\n id,\n entries: countHistoryStreamEntries(raw),\n bucket: bucketById.get(id) ?? null,\n });\n } catch (error) {\n preselectionErrors.push({\n id,\n outcome: \"errored\",\n entries_before: 0,\n entries_after: null,\n skip_reason: null,\n changed: false,\n /* c8 ignore next -- non-Error throws are normalized in defensive fallback. */\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return { candidates, preselectionErrors };\n}\n\nasync function runHistoryCompactBulkRow(params: {\n row: ReturnType<typeof selectHistoryCompactBulkTargets>[number];\n options: HistoryCompactBulkCommandOptions;\n dryRun: boolean;\n global: GlobalOptions;\n}): Promise<{\n result: HistoryCompactBulkItemResult;\n selected: boolean;\n compacted: boolean;\n errored: boolean;\n}> {\n if (!params.row.selected) {\n return {\n selected: false,\n compacted: false,\n errored: false,\n result: {\n id: params.row.id,\n outcome: \"skipped\",\n entries_before: params.row.entries,\n entries_after: null,\n skip_reason: params.row.skip_reason,\n changed: false,\n error: null,\n },\n };\n }\n try {\n const result = await runHistoryCompact(\n params.row.id,\n {\n dryRun: params.dryRun,\n author: params.options.author,\n message: params.options.message,\n force: params.options.force,\n },\n params.global,\n );\n return {\n selected: true,\n compacted: true,\n errored: false,\n result: {\n id: params.row.id,\n outcome: \"compacted\",\n entries_before: params.row.entries,\n entries_after: result.history.entries_after,\n skip_reason: null,\n changed: result.changed,\n error: null,\n },\n };\n } catch (error) {\n return {\n selected: true,\n compacted: false,\n errored: true,\n result: {\n id: params.row.id,\n outcome: \"errored\",\n entries_before: params.row.entries,\n entries_after: null,\n skip_reason: null,\n changed: false,\n /* c8 ignore next -- non-Error throws are normalized in defensive fallback. */\n error: error instanceof Error ? error.message : String(error),\n },\n };\n }\n}\n\n/**\n * Bulk history compaction: compact every history stream matching the requested\n * selection (explicit `--ids`, a `--scope` lifecycle filter, and/or an\n * `--all-over <N>` entry threshold) in one audited pass. Each selected stream is\n * compacted with the same single-item logic ({@link runHistoryCompact}); one\n * failing stream never aborts the rest, and the caller decides the exit code\n * from `totals.items_errored`.\n *\n * When `history.compact_policy` is enabled and no explicit `--all-over` is\n * given, the policy's `max_entries` is used as the scan threshold so the\n * configured policy drives the sweep.\n */\nexport async function runHistoryCompactBulk(\n options: HistoryCompactBulkCommandOptions,\n global: GlobalOptions,\n): Promise<HistoryCompactBulkResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n const { candidates, preselectionErrors } =\n await collectHistoryCompactBulkCandidates({\n pmRoot,\n settings,\n typeToFolder: typeRegistry.type_to_folder,\n });\n\n const mode: \"ids\" | \"scan\" =\n options.ids !== undefined && options.ids.length > 0 ? \"ids\" : \"scan\";\n const minEntries =\n options.minEntries ?? HISTORY_COMPACT_BULK_DEFAULT_MIN_ENTRIES;\n const policy = settings.history.compact_policy;\n const policyThresholdApplied =\n mode === \"scan\" && options.allOver === undefined && policy.enabled;\n const allOver =\n options.allOver ??\n (policyThresholdApplied ? policy.max_entries : undefined);\n\n const selection = selectHistoryCompactBulkTargets(candidates, {\n ids: options.ids,\n scope: options.scope,\n minEntries,\n allOver,\n });\n\n const dryRun = Boolean(options.dryRun);\n const results: HistoryCompactBulkItemResult[] = [...preselectionErrors];\n const totals = {\n streams_considered: candidates.length + preselectionErrors.length,\n selected: 0,\n items_compacted: 0,\n items_skipped: 0,\n items_errored: preselectionErrors.length,\n };\n for (const row of selection) {\n const outcome = await runHistoryCompactBulkRow({\n row,\n options,\n dryRun,\n global,\n });\n results.push(outcome.result);\n if (!outcome.selected) {\n totals.items_skipped += 1;\n continue;\n }\n totals.selected += 1;\n if (outcome.compacted) {\n totals.items_compacted += 1;\n }\n if (outcome.errored) {\n totals.items_errored += 1;\n }\n }\n\n return {\n bulk: true,\n dry_run: dryRun,\n mode,\n scope: options.scope ?? null,\n criteria: {\n min_entries: minEntries,\n all_over: allOver ?? null,\n policy_threshold_applied: policyThresholdApplied,\n },\n totals,\n results,\n generated_at: nowIso(),\n };\n}\n","/**\n * @module core/history/history-compact-bulk\n *\n * Pure selection logic for bulk history-stream compaction. Given a set of\n * history-stream candidates (id, entry count, and lifecycle bucket of the\n * owning item) plus the requested selection criteria, this module decides which\n * streams should be compacted and which are skipped (and why).\n *\n * The module performs no filesystem access and imports no heavy runtime\n * dependencies — the command layer reads streams and item statuses, hands the\n * resolved candidates here, then executes per-item compaction on the selection\n * this module returns. Keeping selection pure makes the matrix of scope /\n * threshold / explicit-id rules trivially testable without touching disk.\n */\n\nimport type { LifecycleBucket } from \"../governance/metadata-coverage.js\";\n\n/** Bulk-compaction scope: only closed items, or every history stream. */\nexport type HistoryCompactScope = \"closed\" | \"all-streams\";\n\n/** Why a candidate stream was not selected for compaction. */\nexport type HistoryCompactBulkSkipReason =\n | \"no_stream\"\n | \"already_compact\"\n | \"scope_mismatch\"\n | \"below_threshold\";\n\n/**\n * One history stream considered for bulk compaction.\n *\n * `bucket` is the lifecycle bucket of the owning item, or `null` when no item\n * matches the stream (an orphan history file). Orphan streams never satisfy a\n * `closed` scope filter but are eligible under `all-streams`.\n */\nexport interface HistoryCompactBulkCandidate {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports entries for this contract. */\n entries: number;\n /** Value that configures or reports bucket for this contract. */\n bucket: LifecycleBucket | null;\n}\n\n/** Selection criteria resolved from the command flags + policy defaults. */\nexport interface HistoryCompactBulkCriteria {\n /** Explicit, ordered list of item ids to compact. When non-empty the selection runs in \"ids\" mode: scope/allOver are ignored and only the `minEntries` floor applies. Duplicates are collapsed, preserving first-seen order. */\n ids?: string[];\n /** Lifecycle scope filter for scan mode (ignored in ids mode). */\n scope?: HistoryCompactScope;\n /** Streams with at most this many entries are skipped as `already_compact` (compaction collapses a stream to a 2-entry baseline+audit pair, so smaller streams gain nothing). Applies in both modes. */\n minEntries: number;\n /** Scan mode only: when set, only streams with strictly more entries than this are selected. Streams above `minEntries` but at/below `allOver` are skipped as `below_threshold`. */\n allOver?: number;\n}\n\n/** Per-candidate selection outcome. */\nexport interface HistoryCompactBulkSelectionRow {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports entries for this contract. */\n entries: number;\n /** Value that configures or reports selected for this contract. */\n selected: boolean;\n /** Value that configures or reports skip reason for this contract. */\n skip_reason: HistoryCompactBulkSkipReason | null;\n}\n\nfunction selectIdsMode(\n ids: string[],\n byId: ReadonlyMap<string, HistoryCompactBulkCandidate>,\n minEntries: number,\n): HistoryCompactBulkSelectionRow[] {\n const seen = new Set<string>();\n const rows: HistoryCompactBulkSelectionRow[] = [];\n for (const rawId of ids) {\n const id = rawId.trim();\n if (id.length === 0 || seen.has(id)) {\n continue;\n }\n seen.add(id);\n const candidate = byId.get(id);\n if (candidate === undefined) {\n rows.push({ id, entries: 0, selected: false, skip_reason: \"no_stream\" });\n continue;\n }\n if (candidate.entries <= minEntries) {\n rows.push({\n id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"already_compact\",\n });\n continue;\n }\n rows.push({\n id,\n entries: candidate.entries,\n selected: true,\n skip_reason: null,\n });\n }\n return rows;\n}\n\nfunction selectScanMode(\n candidates: HistoryCompactBulkCandidate[],\n criteria: HistoryCompactBulkCriteria,\n): HistoryCompactBulkSelectionRow[] {\n const ordered = [...candidates].sort(\n (a, b) => b.entries - a.entries || a.id.localeCompare(b.id),\n );\n const rows: HistoryCompactBulkSelectionRow[] = [];\n for (const candidate of ordered) {\n if (criteria.scope === \"closed\" && candidate.bucket !== \"closed\") {\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"scope_mismatch\",\n });\n continue;\n }\n if (candidate.entries <= criteria.minEntries) {\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"already_compact\",\n });\n continue;\n }\n if (\n criteria.allOver !== undefined &&\n candidate.entries <= criteria.allOver\n ) {\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"below_threshold\",\n });\n continue;\n }\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: true,\n skip_reason: null,\n });\n }\n return rows;\n}\n\n/**\n * Decide which history streams to compact.\n *\n * Runs in \"ids\" mode when `criteria.ids` is non-empty (exact, ordered set,\n * honouring only the `minEntries` floor) and \"scan\" mode otherwise (every\n * candidate, filtered by scope and entry thresholds, ordered deepest-first).\n */\nexport function selectHistoryCompactBulkTargets(\n candidates: HistoryCompactBulkCandidate[],\n criteria: HistoryCompactBulkCriteria,\n): HistoryCompactBulkSelectionRow[] {\n if (criteria.ids !== undefined && criteria.ids.length > 0) {\n const byId = new Map(\n candidates.map((candidate) => [candidate.id, candidate]),\n );\n return selectIdsMode(criteria.ids, byId, criteria.minEntries);\n }\n return selectScanMode(candidates, criteria);\n}\n"],"names":["compactCount"],"mappings":"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","debugId":"6697a54d-d56f-5a86-bbb2-7c12fef13cfe"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../sdk/history-compact.ts","../../../../../../../../core/history/history-compact-bulk.ts"],"sourcesContent":["/**\n * @module sdk/history-compact\n *\n * Implements the pm history compact command surface and its agent-facing runtime behavior.\n */\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { createHistoryEntry } from \"../core/history/history.js\";\nimport {\n selectHistoryCompactBulkTargets,\n type HistoryCompactBulkCandidate,\n type HistoryCompactBulkSkipReason,\n type HistoryCompactScope,\n} from \"../core/history/history-compact-bulk.js\";\nimport {\n executeHistoryRewrite,\n writeHistoryRawWithRollback,\n} from \"../core/history/history-rewrite.js\";\nimport {\n cloneEmptyReplayDocument,\n historyEntriesToRaw,\n replayHash,\n replayToItemDocument,\n toReplayDocument,\n verifyHistoryChain,\n type ReplayDocument,\n} from \"../core/history/replay.js\";\nimport { applyHistoryPatch } from \"../core/history/projection.js\";\nimport { readHistoryEntries } from \"../core/history/read.js\";\nimport { resolveItemTypeRegistry } from \"../core/item/type-registry.js\";\nimport { lifecycleClassifierFromStatusRegistry } from \"../core/governance/metadata-coverage.js\";\nimport { resolveRuntimeStatusRegistry } from \"../core/schema/runtime-schema.js\";\nimport { listAllItemMetadataLight } from \"../core/store/item-store.js\";\nimport { pathExists, readFileIfExists } from \"../core/fs/fs-utils.js\";\nimport { EXIT_CODE } from \"../core/shared/constants.js\";\nimport type { GlobalOptions } from \"../core/shared/command-types.js\";\nimport { PmCliError } from \"../core/shared/errors.js\";\nimport { nowIso } from \"../core/shared/time.js\";\nimport {\n getActiveExtensionRegistrations,\n runActiveOnReadHooks,\n runActiveOnWriteHooks,\n} from \"../core/extensions/index.js\";\nimport { readLocatedItem } from \"../core/store/item-store.js\";\nimport { getSettingsPath, resolvePmRoot } from \"../core/store/paths.js\";\nimport { readSettings } from \"../core/store/settings.js\";\nimport { resolveAuthor } from \"../core/shared/author.js\";\nimport type { HistoryEntry } from \"../types/index.js\";\nimport { resolveHistorySubject } from \"./history-redact.js\";\n\n/** Documents the history compact command options payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactCommandOptions {\n /** Value that configures or reports before for this contract. */\n before?: string;\n /** Value that configures or reports dry run for this contract. */\n dryRun?: boolean;\n /** Value that configures or reports author for this contract. */\n author?: string;\n /** Human-readable explanation suitable for logs and agent-facing output. */\n message?: string;\n /** Value that configures or reports force for this contract. */\n force?: boolean;\n}\n\ntype HistoryCompactBoundaryKind = \"default\" | \"version\" | \"timestamp\";\n\ninterface HistoryCompactBoundary {\n kind: HistoryCompactBoundaryKind;\n raw: string | null;\n compactCount: number;\n retainedCount: number;\n}\n\ninterface HistoryCompactCurrentItem {\n loadedItem: Awaited<ReturnType<typeof readLocatedItem>> | null;\n currentItemRawBeforeLock: string | null;\n matchedChainBefore: boolean | null;\n}\n\n/** Documents the history compact result payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactResult {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports dry run for this contract. */\n dry_run: boolean;\n /** Value that configures or reports changed for this contract. */\n changed: boolean;\n /** Value that configures or reports compact boundary for this contract. */\n compact_boundary: {\n kind: HistoryCompactBoundaryKind;\n before: string | null;\n entries_compacted: number;\n entries_retained: number;\n first_retained_entry: number | null;\n };\n /** Value that configures or reports history for this contract. */\n history: {\n path: string;\n entries_scanned: number;\n entries_after: number;\n baseline_entry_added: boolean;\n audit_entry_added: boolean;\n verify_ok: boolean;\n verify_errors: string[];\n };\n /** Value that configures or reports item for this contract. */\n item: {\n exists: boolean;\n path: string | null;\n matched_chain_before: boolean | null;\n };\n /** Value that configures or reports warnings for this contract. */\n warnings: string[];\n /** ISO 8601 timestamp recording when generated occurred. */\n generated_at: string;\n}\n\nfunction parseBeforeBoundary(\n before: string | undefined,\n entries: HistoryEntry[],\n): HistoryCompactBoundary {\n if (before === undefined) {\n return {\n kind: \"default\",\n raw: null,\n compactCount: entries.length,\n retainedCount: 0,\n };\n }\n\n const raw = before.trim();\n if (raw.length === 0) {\n throw new PmCliError(\n \"history-compact --before requires a non-empty value.\",\n EXIT_CODE.USAGE,\n );\n }\n\n if (/^\\d+$/.test(raw)) {\n const version = Number.parseInt(raw, 10);\n if (\n !Number.isSafeInteger(version) ||\n version < 1 ||\n version > entries.length + 1\n ) {\n throw new PmCliError(\n `history-compact --before version must be between 1 and ${entries.length + 1}.`,\n EXIT_CODE.USAGE,\n );\n }\n const compactCount = Math.max(0, Math.min(entries.length, version - 1));\n return {\n kind: \"version\",\n raw,\n compactCount,\n retainedCount: entries.length - compactCount,\n };\n }\n\n const beforeTs = Date.parse(raw);\n if (!Number.isFinite(beforeTs)) {\n throw new PmCliError(\n `Invalid history-compact --before value \"${before}\". Use a version number or ISO timestamp.`,\n EXIT_CODE.USAGE,\n );\n }\n\n let compactCount = 0;\n for (const [index, entry] of entries.entries()) {\n const entryTs = Date.parse(entry.ts);\n if (!Number.isFinite(entryTs)) {\n throw new PmCliError(\n `History for this item contains invalid timestamp at entry ${index + 1}.`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n if (entryTs >= beforeTs) {\n break;\n }\n compactCount += 1;\n }\n\n return {\n kind: \"timestamp\",\n raw,\n compactCount,\n retainedCount: entries.length - compactCount,\n };\n}\n\nfunction replayHistoryAndResolveCheckpoint(\n entries: HistoryEntry[],\n compactCount: number,\n): {\n checkpoint: ReplayDocument;\n finalReplay: ReplayDocument;\n} {\n let replay = cloneEmptyReplayDocument();\n let checkpoint = cloneEmptyReplayDocument();\n for (let index = 0; index < entries.length; index += 1) {\n const entry = entries[index];\n if (replayHash(replay) !== entry.before_hash) {\n throw new PmCliError(\n `history-compact detected before-hash drift at entry ${index + 1}; run pm history-repair first.`,\n EXIT_CODE.CONFLICT,\n );\n }\n replay = applyHistoryPatch(replay, entry.patch, index + 1, entry.op);\n if (replayHash(replay) !== entry.after_hash) {\n throw new PmCliError(\n `history-compact detected after-hash drift at entry ${index + 1}; run pm history-repair first.`,\n EXIT_CODE.CONFLICT,\n );\n }\n if (index + 1 === compactCount) {\n checkpoint = structuredClone(replay);\n }\n }\n return {\n checkpoint,\n finalReplay: replay,\n };\n}\n\nfunction reanchorRetainedEntries(\n retainedEntries: HistoryEntry[],\n seed: ReplayDocument,\n retainedEntryOffset: number,\n): {\n entries: HistoryEntry[];\n finalReplay: ReplayDocument;\n} {\n let replay = structuredClone(seed);\n const rewritten: HistoryEntry[] = [];\n for (const [index, entry] of retainedEntries.entries()) {\n const beforeHash = replayHash(replay);\n replay = applyHistoryPatch(\n replay,\n entry.patch,\n retainedEntryOffset + index + 1,\n entry.op,\n );\n rewritten.push({\n ...entry,\n before_hash: beforeHash,\n after_hash: replayHash(replay),\n });\n }\n return {\n entries: rewritten,\n finalReplay: replay,\n };\n}\n\nasync function loadHistoryCompactCurrentItem(\n subject: Awaited<ReturnType<typeof resolveHistorySubject>>,\n settings: Awaited<ReturnType<typeof readSettings>>,\n historyEntries: HistoryEntry[],\n): Promise<HistoryCompactCurrentItem> {\n const loadedItem = subject.located\n ? await readLocatedItem(subject.located, { schema: settings.schema })\n : null;\n if (!loadedItem) {\n return {\n loadedItem: null,\n currentItemRawBeforeLock: null,\n matchedChainBefore: null,\n };\n }\n return {\n loadedItem,\n currentItemRawBeforeLock: loadedItem.raw,\n matchedChainBefore:\n replayHash(toReplayDocument(loadedItem.document)) ===\n historyEntries[historyEntries.length - 1]?.after_hash,\n };\n}\n\nfunction buildHistoryCompactMessage(\n options: HistoryCompactCommandOptions,\n boundary: HistoryCompactBoundary,\n): string {\n if (\n typeof options.message === \"string\" &&\n options.message.trim().length > 0\n ) {\n return options.message;\n }\n if (boundary.raw === null) {\n return `history-compact compacted full stream (${boundary.compactCount} entr${\n boundary.compactCount === 1 ? \"y\" : \"ies\"\n }).`;\n }\n return `history-compact compacted ${boundary.compactCount} entr${\n boundary.compactCount === 1 ? \"y\" : \"ies\"\n } before ${boundary.raw}.`;\n}\n\nfunction buildHistoryCompactBaselineMessage(\n boundary: HistoryCompactBoundary,\n): string {\n if (boundary.raw === null) {\n return `history-compact baseline snapshot after compacting ${boundary.compactCount} entr${\n boundary.compactCount === 1 ? \"y\" : \"ies\"\n }.`;\n }\n return `history-compact baseline snapshot before ${boundary.raw}.`;\n}\n\nfunction buildHistoryCompactEntries(params: {\n historyEntries: HistoryEntry[];\n boundary: HistoryCompactBoundary;\n changed: boolean;\n dryRun: boolean;\n author: string;\n options: HistoryCompactCommandOptions;\n}): {\n rewrittenEntries: HistoryEntry[];\n baselineEntryAdded: boolean;\n auditEntryAdded: boolean;\n} {\n if (!params.changed) {\n return {\n rewrittenEntries: params.historyEntries,\n baselineEntryAdded: false,\n auditEntryAdded: false,\n };\n }\n const { checkpoint, finalReplay } = replayHistoryAndResolveCheckpoint(\n params.historyEntries,\n params.boundary.compactCount,\n );\n const retained = params.historyEntries.slice(params.boundary.compactCount);\n const reanchored = reanchorRetainedEntries(\n retained,\n checkpoint,\n params.boundary.compactCount,\n );\n const baselineEntry = createHistoryEntry({\n nowIso: nowIso(),\n author: params.author,\n op: \"history_compact_baseline\",\n before: replayToItemDocument(cloneEmptyReplayDocument()),\n after: replayToItemDocument(checkpoint),\n message: buildHistoryCompactBaselineMessage(params.boundary),\n });\n const rewrittenEntries = [baselineEntry, ...reanchored.entries];\n if (!params.dryRun) {\n rewrittenEntries.push(\n createHistoryEntry({\n nowIso: nowIso(),\n author: params.author,\n op: \"history_compact\",\n before: replayToItemDocument(finalReplay),\n after: replayToItemDocument(finalReplay),\n message: buildHistoryCompactMessage(params.options, params.boundary),\n }),\n );\n }\n return {\n rewrittenEntries,\n baselineEntryAdded: true,\n auditEntryAdded: !params.dryRun,\n };\n}\n\nasync function applyHistoryCompactRewrite(params: {\n pmRoot: string;\n subject: Awaited<ReturnType<typeof resolveHistorySubject>>;\n settings: Awaited<ReturnType<typeof readSettings>>;\n typeRegistry: ReturnType<typeof resolveItemTypeRegistry>;\n historyRawBeforeLock: string;\n currentItemRawBeforeLock: string | null;\n author: string;\n force: boolean | undefined;\n loadedItem: Awaited<ReturnType<typeof readLocatedItem>> | null;\n historyPath: string;\n rewrittenEntries: HistoryEntry[];\n}): Promise<string[]> {\n return executeHistoryRewrite({\n pmRoot: params.pmRoot,\n subject: params.subject,\n settings: params.settings,\n typeRegistry: params.typeRegistry,\n historyRawBeforeLock: params.historyRawBeforeLock,\n currentItemRawBeforeLock: params.currentItemRawBeforeLock,\n operation: \"history-compact\",\n author: params.author,\n force: params.force,\n itemDocument: params.loadedItem?.document ?? null,\n applyRewrite: async ({ historyRawUnderLock }) =>\n writeHistoryRawWithRollback({\n historyPath: params.historyPath,\n nextHistoryRaw: historyEntriesToRaw(params.rewrittenEntries),\n historyRawUnderLock,\n }),\n applyPostRewrite: async () =>\n runActiveOnWriteHooks({\n path: params.historyPath,\n scope: \"project\",\n op: \"history_compact:history\",\n }),\n });\n}\n\n/** Implements run history compact for the public runtime surface of this module. */\nexport async function runHistoryCompact(\n id: string,\n options: HistoryCompactCommandOptions,\n global: GlobalOptions,\n): Promise<HistoryCompactResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n const subject = await resolveHistorySubject(\n pmRoot,\n id,\n settings,\n typeRegistry.type_to_folder,\n );\n const historyPath = subject.historyPath;\n const historyRawBeforeLock = await readFileIfExists(historyPath);\n if (historyRawBeforeLock === null) {\n throw new PmCliError(\n `No history stream exists for ${subject.id}.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n const historyEntries = await readHistoryEntries(historyPath, subject.id);\n if (historyEntries.length === 0) {\n throw new PmCliError(\n `No history entries exist for ${subject.id}; nothing to compact.`,\n EXIT_CODE.USAGE,\n );\n }\n\n const chainVerification = verifyHistoryChain(historyEntries);\n if (!chainVerification.ok) {\n throw new PmCliError(\n `history-compact requires a valid history chain (${chainVerification.errors.join(\", \")}). Run pm history-repair ${subject.id} first.`,\n EXIT_CODE.CONFLICT,\n );\n }\n\n const boundary = parseBeforeBoundary(options.before, historyEntries);\n const changed = boundary.compactCount > 0;\n const dryRun = Boolean(options.dryRun);\n const author = resolveAuthor(options.author, settings.author_default);\n const warnings: string[] = [];\n if (!changed) {\n warnings.push(\"history_compact_noop_before_boundary\");\n }\n\n const currentItem = await loadHistoryCompactCurrentItem(\n subject,\n settings,\n historyEntries,\n );\n if (currentItem.matchedChainBefore === false) {\n warnings.push(\"history_compact_item_chain_mismatch\");\n }\n\n const { rewrittenEntries, baselineEntryAdded, auditEntryAdded } =\n buildHistoryCompactEntries({\n historyEntries,\n boundary,\n changed,\n dryRun,\n author,\n options,\n });\n\n const rewrittenVerify = verifyHistoryChain(rewrittenEntries);\n if (!rewrittenVerify.ok) {\n throw new PmCliError(\n `history-compact produced an invalid rewritten chain (${rewrittenVerify.errors.join(\", \")}).`,\n EXIT_CODE.GENERIC_FAILURE,\n );\n }\n\n if (changed && !dryRun) {\n warnings.push(\n ...(await applyHistoryCompactRewrite({\n pmRoot,\n subject,\n settings,\n typeRegistry,\n historyRawBeforeLock,\n currentItemRawBeforeLock: currentItem.currentItemRawBeforeLock,\n author,\n force: options.force,\n loadedItem: currentItem.loadedItem,\n historyPath,\n rewrittenEntries,\n })),\n );\n }\n\n const firstRetainedEntry =\n boundary.retainedCount > 0 ? boundary.compactCount + 1 : null;\n return {\n id: subject.id,\n dry_run: dryRun,\n changed,\n compact_boundary: {\n kind: boundary.kind,\n before: boundary.raw,\n entries_compacted: boundary.compactCount,\n entries_retained: boundary.retainedCount,\n first_retained_entry: firstRetainedEntry,\n },\n history: {\n path: historyPath,\n entries_scanned: historyEntries.length,\n entries_after: rewrittenEntries.length,\n baseline_entry_added: baselineEntryAdded,\n audit_entry_added: auditEntryAdded,\n verify_ok: rewrittenVerify.ok,\n verify_errors: rewrittenVerify.errors,\n },\n item: {\n exists: subject.located !== null,\n path: subject.located?.itemPath ?? null,\n matched_chain_before: currentItem.matchedChainBefore,\n },\n warnings: [...new Set(warnings)].sort((left, right) =>\n left.localeCompare(right),\n ),\n generated_at: nowIso(),\n };\n}\n\n/** Default entry floor below which a stream is treated as already compact. */\nexport const HISTORY_COMPACT_BULK_DEFAULT_MIN_ENTRIES = 3;\n\n/** Documents the bulk history compact command options payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactBulkCommandOptions {\n /** Value that configures or reports ids for this contract. */\n ids?: string[];\n /** Value that configures or reports scope for this contract. */\n scope?: HistoryCompactScope;\n /** Value that configures or reports all over for this contract. */\n allOver?: number;\n /** Value that configures or reports min entries for this contract. */\n minEntries?: number;\n /** Value that configures or reports dry run for this contract. */\n dryRun?: boolean;\n /** Value that configures or reports author for this contract. */\n author?: string;\n /** Human-readable explanation suitable for logs and agent-facing output. */\n message?: string;\n /** Value that configures or reports force for this contract. */\n force?: boolean;\n}\n\n/** Per-item outcome row in a bulk compaction pass. */\nexport interface HistoryCompactBulkItemResult {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports outcome for this contract. */\n outcome: \"compacted\" | \"skipped\" | \"errored\";\n /** Value that configures or reports entries before for this contract. */\n entries_before: number;\n /** Value that configures or reports entries after for this contract. */\n entries_after: number | null;\n /** Value that configures or reports skip reason for this contract. */\n skip_reason: HistoryCompactBulkSkipReason | null;\n /** Value that configures or reports changed for this contract. */\n changed: boolean;\n /** Value that configures or reports error for this contract. */\n error: string | null;\n}\n\n/** Documents the bulk history compact result payload exchanged by command, SDK, and package integrations. */\nexport interface HistoryCompactBulkResult {\n /** Value that configures or reports bulk for this contract. */\n bulk: true;\n /** Value that configures or reports dry run for this contract. */\n dry_run: boolean;\n /** Value that configures or reports mode for this contract. */\n mode: \"ids\" | \"scan\";\n /** Value that configures or reports scope for this contract. */\n scope: HistoryCompactScope | null;\n /** Value that configures or reports criteria for this contract. */\n criteria: {\n min_entries: number;\n all_over: number | null;\n policy_threshold_applied: boolean;\n };\n /** Value that configures or reports totals for this contract. */\n totals: {\n streams_considered: number;\n selected: number;\n items_compacted: number;\n items_skipped: number;\n items_errored: number;\n };\n /** Value that configures or reports results for this contract. */\n results: HistoryCompactBulkItemResult[];\n /** ISO 8601 timestamp recording when generated occurred. */\n generated_at: string;\n}\n\n/** Enforce the `pm history-compact` target contract shared by the CLI and MCP surfaces: exactly one selection mode — a single item `<id>`, an explicit `--ids` list, or a scan selector (`--all-over` / `--closed` / `--all-streams`). */\nexport function assertHistoryCompactTarget(\n id: string | undefined,\n bulk: { ids?: string[]; allOver?: number; scope?: HistoryCompactScope },\n): void {\n const hasIds = bulk.ids !== undefined && bulk.ids.length > 0;\n const hasScan = bulk.allOver !== undefined || bulk.scope !== undefined;\n const selectorCount =\n (id !== undefined ? 1 : 0) + (hasIds ? 1 : 0) + (hasScan ? 1 : 0);\n if (selectorCount === 0) {\n throw new PmCliError(\n \"history-compact: provide an item <id>, or a bulk selector (--ids, --all-over <N>, --closed, or --all-streams).\",\n EXIT_CODE.USAGE,\n );\n }\n if (id !== undefined && (hasIds || hasScan)) {\n throw new PmCliError(\n \"history-compact: <id> and bulk selectors (--ids/--all-over/--closed/--all-streams) are mutually exclusive; pass one item id, or use bulk mode without a positional id.\",\n EXIT_CODE.USAGE,\n );\n }\n if (hasIds && hasScan) {\n throw new PmCliError(\n \"history-compact: --ids is mutually exclusive with --all-over/--closed/--all-streams; pass an explicit id list or a scan selector, not both.\",\n EXIT_CODE.USAGE,\n );\n }\n}\n\nfunction countHistoryStreamEntries(raw: string): number {\n let count = 0;\n for (const line of raw.split(/\\r?\\n/)) {\n if (line.trim().length > 0) {\n count += 1;\n }\n }\n return count;\n}\n\nasync function collectHistoryCompactBulkCandidates(params: {\n pmRoot: string;\n settings: Awaited<ReturnType<typeof readSettings>>;\n typeToFolder: Record<string, string>;\n}): Promise<{\n candidates: HistoryCompactBulkCandidate[];\n preselectionErrors: HistoryCompactBulkItemResult[];\n}> {\n const statusRegistry = resolveRuntimeStatusRegistry(params.settings.schema);\n const classifier = lifecycleClassifierFromStatusRegistry(statusRegistry);\n const items = await listAllItemMetadataLight(\n params.pmRoot,\n params.settings.item_format,\n params.typeToFolder,\n undefined,\n params.settings.schema,\n );\n const bucketById = new Map(\n items.map((item) => [item.id, classifier.classify(item.status)] as const),\n );\n const historyDir = path.join(params.pmRoot, \"history\");\n const candidates: HistoryCompactBulkCandidate[] = [];\n const preselectionErrors: HistoryCompactBulkItemResult[] = [];\n if (!(await pathExists(historyDir))) {\n return { candidates, preselectionErrors };\n }\n const historyFiles = (await fs.readdir(historyDir))\n .filter((entry) => entry.endsWith(\".jsonl\"))\n .sort((left, right) => left.localeCompare(right));\n for (const fileName of historyFiles) {\n const historyPath = path.join(historyDir, fileName);\n const id = fileName.slice(0, -\".jsonl\".length);\n try {\n const raw = await fs.readFile(historyPath, \"utf8\");\n await runActiveOnReadHooks({ path: historyPath, scope: \"project\" });\n candidates.push({\n id,\n entries: countHistoryStreamEntries(raw),\n bucket: bucketById.get(id) ?? null,\n });\n } catch (error) {\n preselectionErrors.push({\n id,\n outcome: \"errored\",\n entries_before: 0,\n entries_after: null,\n skip_reason: null,\n changed: false,\n /* c8 ignore next -- non-Error throws are normalized in defensive fallback. */\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return { candidates, preselectionErrors };\n}\n\nasync function runHistoryCompactBulkRow(params: {\n row: ReturnType<typeof selectHistoryCompactBulkTargets>[number];\n options: HistoryCompactBulkCommandOptions;\n dryRun: boolean;\n global: GlobalOptions;\n}): Promise<{\n result: HistoryCompactBulkItemResult;\n selected: boolean;\n compacted: boolean;\n errored: boolean;\n}> {\n if (!params.row.selected) {\n return {\n selected: false,\n compacted: false,\n errored: false,\n result: {\n id: params.row.id,\n outcome: \"skipped\",\n entries_before: params.row.entries,\n entries_after: null,\n skip_reason: params.row.skip_reason,\n changed: false,\n error: null,\n },\n };\n }\n try {\n const result = await runHistoryCompact(\n params.row.id,\n {\n dryRun: params.dryRun,\n author: params.options.author,\n message: params.options.message,\n force: params.options.force,\n },\n params.global,\n );\n return {\n selected: true,\n compacted: true,\n errored: false,\n result: {\n id: params.row.id,\n outcome: \"compacted\",\n entries_before: params.row.entries,\n entries_after: result.history.entries_after,\n skip_reason: null,\n changed: result.changed,\n error: null,\n },\n };\n } catch (error) {\n return {\n selected: true,\n compacted: false,\n errored: true,\n result: {\n id: params.row.id,\n outcome: \"errored\",\n entries_before: params.row.entries,\n entries_after: null,\n skip_reason: null,\n changed: false,\n /* c8 ignore next -- non-Error throws are normalized in defensive fallback. */\n error: error instanceof Error ? error.message : String(error),\n },\n };\n }\n}\n\n/**\n * Bulk history compaction: compact every history stream matching the requested\n * selection (explicit `--ids`, a `--scope` lifecycle filter, and/or an\n * `--all-over <N>` entry threshold) in one audited pass. Each selected stream is\n * compacted with the same single-item logic ({@link runHistoryCompact}); one\n * failing stream never aborts the rest, and the caller decides the exit code\n * from `totals.items_errored`.\n *\n * When `history.compact_policy` is enabled and no explicit `--all-over` is\n * given, the policy's `max_entries` is used as the scan threshold so the\n * configured policy drives the sweep.\n */\nexport async function runHistoryCompactBulk(\n options: HistoryCompactBulkCommandOptions,\n global: GlobalOptions,\n): Promise<HistoryCompactBulkResult> {\n const pmRoot = resolvePmRoot(process.cwd(), global.path);\n if (!(await pathExists(getSettingsPath(pmRoot)))) {\n throw new PmCliError(\n `Tracker is not initialized at ${pmRoot}. Run pm init first.`,\n EXIT_CODE.NOT_FOUND,\n );\n }\n\n const settings = await readSettings(pmRoot);\n const typeRegistry = resolveItemTypeRegistry(\n settings,\n getActiveExtensionRegistrations(),\n );\n const { candidates, preselectionErrors } =\n await collectHistoryCompactBulkCandidates({\n pmRoot,\n settings,\n typeToFolder: typeRegistry.type_to_folder,\n });\n\n const mode: \"ids\" | \"scan\" =\n options.ids !== undefined && options.ids.length > 0 ? \"ids\" : \"scan\";\n const minEntries =\n options.minEntries ?? HISTORY_COMPACT_BULK_DEFAULT_MIN_ENTRIES;\n const policy = settings.history.compact_policy;\n const policyThresholdApplied =\n mode === \"scan\" && options.allOver === undefined && policy.enabled;\n const allOver =\n options.allOver ??\n (policyThresholdApplied ? policy.max_entries : undefined);\n\n const selection = selectHistoryCompactBulkTargets(candidates, {\n ids: options.ids,\n scope: options.scope,\n minEntries,\n allOver,\n });\n\n const dryRun = Boolean(options.dryRun);\n const results: HistoryCompactBulkItemResult[] = [...preselectionErrors];\n const totals = {\n streams_considered: candidates.length + preselectionErrors.length,\n selected: 0,\n items_compacted: 0,\n items_skipped: 0,\n items_errored: preselectionErrors.length,\n };\n for (const row of selection) {\n const outcome = await runHistoryCompactBulkRow({\n row,\n options,\n dryRun,\n global,\n });\n results.push(outcome.result);\n if (!outcome.selected) {\n totals.items_skipped += 1;\n continue;\n }\n totals.selected += 1;\n if (outcome.compacted) {\n totals.items_compacted += 1;\n }\n if (outcome.errored) {\n totals.items_errored += 1;\n }\n }\n\n return {\n bulk: true,\n dry_run: dryRun,\n mode,\n scope: options.scope ?? null,\n criteria: {\n min_entries: minEntries,\n all_over: allOver ?? null,\n policy_threshold_applied: policyThresholdApplied,\n },\n totals,\n results,\n generated_at: nowIso(),\n };\n}\n","/**\n * @module core/history/history-compact-bulk\n *\n * Pure selection logic for bulk history-stream compaction. Given a set of\n * history-stream candidates (id, entry count, and lifecycle bucket of the\n * owning item) plus the requested selection criteria, this module decides which\n * streams should be compacted and which are skipped (and why).\n *\n * The module performs no filesystem access and imports no heavy runtime\n * dependencies — the command layer reads streams and item statuses, hands the\n * resolved candidates here, then executes per-item compaction on the selection\n * this module returns. Keeping selection pure makes the matrix of scope /\n * threshold / explicit-id rules trivially testable without touching disk.\n */\n\nimport type { LifecycleBucket } from \"../governance/metadata-coverage.js\";\n\n/** Bulk-compaction scope: only closed items, or every history stream. */\nexport type HistoryCompactScope = \"closed\" | \"all-streams\";\n\n/** Why a candidate stream was not selected for compaction. */\nexport type HistoryCompactBulkSkipReason =\n | \"no_stream\"\n | \"already_compact\"\n | \"scope_mismatch\"\n | \"below_threshold\";\n\n/**\n * One history stream considered for bulk compaction.\n *\n * `bucket` is the lifecycle bucket of the owning item, or `null` when no item\n * matches the stream (an orphan history file). Orphan streams never satisfy a\n * `closed` scope filter but are eligible under `all-streams`.\n */\nexport interface HistoryCompactBulkCandidate {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports entries for this contract. */\n entries: number;\n /** Value that configures or reports bucket for this contract. */\n bucket: LifecycleBucket | null;\n}\n\n/** Selection criteria resolved from the command flags + policy defaults. */\nexport interface HistoryCompactBulkCriteria {\n /** Explicit, ordered list of item ids to compact. When non-empty the selection runs in \"ids\" mode: scope/allOver are ignored and only the `minEntries` floor applies. Duplicates are collapsed, preserving first-seen order. */\n ids?: string[];\n /** Lifecycle scope filter for scan mode (ignored in ids mode). */\n scope?: HistoryCompactScope;\n /** Streams with at most this many entries are skipped as `already_compact` (compaction collapses a stream to a 2-entry baseline+audit pair, so smaller streams gain nothing). Applies in both modes. */\n minEntries: number;\n /** Scan mode only: when set, only streams with strictly more entries than this are selected. Streams above `minEntries` but at/below `allOver` are skipped as `below_threshold`. */\n allOver?: number;\n}\n\n/** Per-candidate selection outcome. */\nexport interface HistoryCompactBulkSelectionRow {\n /** Stable identifier used to reference this record across commands and storage. */\n id: string;\n /** Value that configures or reports entries for this contract. */\n entries: number;\n /** Value that configures or reports selected for this contract. */\n selected: boolean;\n /** Value that configures or reports skip reason for this contract. */\n skip_reason: HistoryCompactBulkSkipReason | null;\n}\n\nfunction selectIdsMode(\n ids: string[],\n byId: ReadonlyMap<string, HistoryCompactBulkCandidate>,\n minEntries: number,\n): HistoryCompactBulkSelectionRow[] {\n const seen = new Set<string>();\n const rows: HistoryCompactBulkSelectionRow[] = [];\n for (const rawId of ids) {\n const id = rawId.trim();\n if (id.length === 0 || seen.has(id)) {\n continue;\n }\n seen.add(id);\n const candidate = byId.get(id);\n if (candidate === undefined) {\n rows.push({ id, entries: 0, selected: false, skip_reason: \"no_stream\" });\n continue;\n }\n if (candidate.entries <= minEntries) {\n rows.push({\n id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"already_compact\",\n });\n continue;\n }\n rows.push({\n id,\n entries: candidate.entries,\n selected: true,\n skip_reason: null,\n });\n }\n return rows;\n}\n\nfunction selectScanMode(\n candidates: HistoryCompactBulkCandidate[],\n criteria: HistoryCompactBulkCriteria,\n): HistoryCompactBulkSelectionRow[] {\n const ordered = [...candidates].sort(\n (a, b) => b.entries - a.entries || a.id.localeCompare(b.id),\n );\n const rows: HistoryCompactBulkSelectionRow[] = [];\n for (const candidate of ordered) {\n if (criteria.scope === \"closed\" && candidate.bucket !== \"closed\") {\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"scope_mismatch\",\n });\n continue;\n }\n if (candidate.entries <= criteria.minEntries) {\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"already_compact\",\n });\n continue;\n }\n if (\n criteria.allOver !== undefined &&\n candidate.entries <= criteria.allOver\n ) {\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: false,\n skip_reason: \"below_threshold\",\n });\n continue;\n }\n rows.push({\n id: candidate.id,\n entries: candidate.entries,\n selected: true,\n skip_reason: null,\n });\n }\n return rows;\n}\n\n/**\n * Decide which history streams to compact.\n *\n * Runs in \"ids\" mode when `criteria.ids` is non-empty (exact, ordered set,\n * honouring only the `minEntries` floor) and \"scan\" mode otherwise (every\n * candidate, filtered by scope and entry thresholds, ordered deepest-first).\n */\nexport function selectHistoryCompactBulkTargets(\n candidates: HistoryCompactBulkCandidate[],\n criteria: HistoryCompactBulkCriteria,\n): HistoryCompactBulkSelectionRow[] {\n if (criteria.ids !== undefined && criteria.ids.length > 0) {\n const byId = new Map(\n candidates.map((candidate) => [candidate.id, candidate]),\n );\n return selectIdsMode(criteria.ids, byId, criteria.minEntries);\n }\n return selectScanMode(candidates, criteria);\n}\n"],"names":["compactCount"],"mappings":"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","debugId":"9a360c17-f01f-5885-b30d-30361c04ceac"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="bd66882b-1bef-52df-b18f-5cb50c8e2ac3")}catch(e){}}();
|
|
3
3
|
import {
|
|
4
4
|
normalizeAddTypeInput
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TOBGV45Y.js";
|
|
6
6
|
import {
|
|
7
7
|
DEFAULT_RUNTIME_STATUS_DEFINITIONS,
|
|
8
8
|
ITEM_METADATA_KEY_ORDER,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
RUNTIME_FIELD_TYPE_VALUES,
|
|
11
11
|
RUNTIME_STATUS_ROLE_VALUES,
|
|
12
12
|
evictOldestMemoEntries
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-HYW67VJ5.js";
|
|
14
14
|
|
|
15
15
|
// dist/core/schema/status-defs-file.js
|
|
16
16
|
var RUNTIME_STATUS_ROLE_SET = new Set(RUNTIME_STATUS_ROLE_VALUES);
|
|
@@ -528,6 +528,6 @@ export {
|
|
|
528
528
|
normalizeTypePresetName,
|
|
529
529
|
resolveTypePresetDefinitions
|
|
530
530
|
};
|
|
531
|
-
//# sourceMappingURL=chunk-
|
|
531
|
+
//# sourceMappingURL=chunk-SZVB53Y3.js.map
|
|
532
532
|
|
|
533
533
|
//# debugId=bd66882b-1bef-52df-b18f-5cb50c8e2ac3
|