@unbrained/pm-cli 2026.6.5 → 2026.6.7
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/CHANGELOG.md +77 -0
- package/CONTRIBUTING.md +1 -0
- package/README.md +17 -5
- package/dist/cli/commander-usage.js +74 -4
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/aggregate.d.ts +8 -0
- package/dist/cli/commands/aggregate.js +84 -7
- package/dist/cli/commands/aggregate.js.map +1 -1
- package/dist/cli/commands/calendar.js +10 -3
- package/dist/cli/commands/calendar.js.map +1 -1
- package/dist/cli/commands/close-many.js +13 -10
- package/dist/cli/commands/close-many.js.map +1 -1
- package/dist/cli/commands/close.d.ts +1 -1
- package/dist/cli/commands/close.js +20 -10
- package/dist/cli/commands/close.js.map +1 -1
- package/dist/cli/commands/completion.js +87 -18
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/config.d.ts +5 -4
- package/dist/cli/commands/config.js +50 -2
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/contracts.js +6 -3
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/copy.d.ts +14 -0
- package/dist/cli/commands/copy.js +153 -0
- package/dist/cli/commands/copy.js.map +1 -0
- package/dist/cli/commands/extension/doctor.js +62 -2
- package/dist/cli/commands/extension/doctor.js.map +1 -1
- package/dist/cli/commands/extension/install-sources.d.ts +8 -0
- package/dist/cli/commands/extension/install-sources.js +82 -2
- package/dist/cli/commands/extension/install-sources.js.map +1 -1
- package/dist/cli/commands/extension.d.ts +29 -0
- package/dist/cli/commands/extension.js +61 -2
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/gc.d.ts +8 -1
- package/dist/cli/commands/gc.js +26 -3
- package/dist/cli/commands/gc.js.map +1 -1
- package/dist/cli/commands/get.d.ts +9 -0
- package/dist/cli/commands/get.js +23 -2
- package/dist/cli/commands/get.js.map +1 -1
- package/dist/cli/commands/health.js +15 -2
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/history-compact.d.ts +39 -0
- package/dist/cli/commands/history-compact.js +262 -0
- package/dist/cli/commands/history-compact.js.map +1 -0
- package/dist/cli/commands/history.d.ts +4 -1
- package/dist/cli/commands/history.js +12 -24
- package/dist/cli/commands/history.js.map +1 -1
- package/dist/cli/commands/index.d.ts +3 -0
- package/dist/cli/commands/index.js +5 -2
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/list.d.ts +2 -0
- package/dist/cli/commands/list.js +87 -9
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/reindex.js +8 -4
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.d.ts +1 -0
- package/dist/cli/commands/search.js +232 -35
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/stats.d.ts +8 -1
- package/dist/cli/commands/stats.js +18 -17
- package/dist/cli/commands/stats.js.map +1 -1
- package/dist/cli/commands/telemetry.d.ts +8 -0
- package/dist/cli/commands/telemetry.js +253 -0
- package/dist/cli/commands/telemetry.js.map +1 -0
- package/dist/cli/error-guidance.js +26 -2
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/extension-command-help.d.ts +1 -0
- package/dist/cli/extension-command-help.js +3 -2
- package/dist/cli/extension-command-help.js.map +1 -1
- package/dist/cli/help-content.js +19 -2
- package/dist/cli/help-content.js.map +1 -1
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +13 -21
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-list-query.js +24 -6
- package/dist/cli/register-list-query.js.map +1 -1
- package/dist/cli/register-mutation.js +52 -17
- package/dist/cli/register-mutation.js.map +1 -1
- package/dist/cli/register-operations.js +55 -8
- package/dist/cli/register-operations.js.map +1 -1
- package/dist/cli/register-setup.js +5 -5
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/registration-helpers.js +21 -3
- package/dist/cli/registration-helpers.js.map +1 -1
- package/dist/cli-bundle/chunks/activity-5UROHJ3D.js +16 -0
- package/dist/cli-bundle/chunks/{activity-3RWRRNOW.js → activity-YVB3QRTE.js} +11 -11
- package/dist/cli-bundle/chunks/{aggregate-OOAGKWRG.js → aggregate-LH66F75F.js} +87 -17
- package/dist/cli-bundle/chunks/aggregate-LH66F75F.js.map +7 -0
- package/dist/cli-bundle/chunks/{aggregate-J35K7WZB.js → aggregate-OHSWFQJM.js} +88 -18
- package/dist/cli-bundle/chunks/aggregate-OHSWFQJM.js.map +1 -0
- package/dist/cli-bundle/chunks/{append-PNN6UIBZ.js → append-2PPYFAG5.js} +8 -8
- package/dist/cli-bundle/chunks/{append-5JE3YGXU.js → append-AUGT5W6J.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-26KTVXJW.js → chunk-2IF7WLB7.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KA24HME7.js → chunk-2IXCHCLM.js} +5 -6
- package/dist/cli-bundle/chunks/chunk-2IXCHCLM.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-XX5LRINW.js → chunk-2OJHLWBZ.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ASQM3IF5.js → chunk-3A2CMEM7.js} +5 -4
- package/dist/cli-bundle/chunks/{chunk-S3CV7JGJ.js → chunk-3EOBJOF4.js} +5 -4
- package/dist/cli-bundle/chunks/{chunk-N5YF3VFN.js → chunk-42LOFGJS.js} +91 -16
- package/dist/cli-bundle/chunks/chunk-42LOFGJS.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-WIKR7KFL.js → chunk-4CHEG6UK.js} +108 -21
- package/dist/cli-bundle/chunks/chunk-4CHEG6UK.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-4QCR4QW3.js → chunk-4GHZR3BA.js} +56 -28
- package/dist/cli-bundle/chunks/chunk-4GHZR3BA.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-B3N4TKNL.js → chunk-5AXMRKN5.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-JQI2HE55.js → chunk-6J4K6JLA.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-V3JQ4IPL.js → chunk-6RZXO5M2.js} +102 -22
- package/dist/cli-bundle/chunks/chunk-6RZXO5M2.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-BNL6S7QH.js → chunk-AVJD6VTA.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-NQP3ECKF.js → chunk-B2KZGPM2.js} +39 -8
- package/dist/cli-bundle/chunks/chunk-B2KZGPM2.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-RQAWLSUU.js → chunk-B5RF3IP7.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-UFCG3SWR.js → chunk-C5W2UH56.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-3OH4DAEB.js → chunk-CKLBZHS7.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-GNHVV4SY.js → chunk-CLD3XNCH.js} +124 -20
- package/dist/cli-bundle/chunks/chunk-CLD3XNCH.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-RANZIID5.js → chunk-FHHBD7PN.js} +38 -7
- package/dist/cli-bundle/chunks/chunk-FHHBD7PN.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GFWHHMVV.js → chunk-FY6Z3FYY.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-CCUFLH4J.js → chunk-GNIUOLZ2.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-ZRVSMOMR.js → chunk-GPXQBR3H.js} +12 -12
- package/dist/cli-bundle/chunks/{chunk-SZQCER6S.js → chunk-GUZBNB3G.js} +27 -5
- package/dist/cli-bundle/chunks/chunk-GUZBNB3G.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-GPGAYASV.js → chunk-H7EO3QA3.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-MISYRLEP.js → chunk-HLC3KTLP.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-KK6YPGH3.js → chunk-HMMMWBK2.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-4PJQSECJ.js → chunk-HRMHZ4RV.js} +26 -4
- package/dist/cli-bundle/chunks/chunk-HRMHZ4RV.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-CJDQB2ED.js → chunk-HV5SSZXF.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-ATBVS6WW.js → chunk-IMCJBN2Q.js} +23 -14
- package/dist/cli-bundle/chunks/chunk-IMCJBN2Q.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-FVXM3GKS.js → chunk-KNGVP5WJ.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-OIQIXTNB.js → chunk-KR6R465K.js} +304 -215
- package/dist/cli-bundle/chunks/chunk-KR6R465K.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-UOVLWB47.js → chunk-LI65XLJR.js} +8 -8
- package/dist/cli-bundle/chunks/{chunk-AXXKLVTW.js → chunk-LIN2BPJ7.js} +2 -2
- package/dist/cli-bundle/chunks/chunk-LMTOY5HE.js +112 -0
- package/dist/cli-bundle/chunks/chunk-LMTOY5HE.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-Y2AKE2HS.js → chunk-LQHBENVW.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-D5X7N6FI.js → chunk-LXO6V66E.js} +14 -14
- package/dist/cli-bundle/chunks/{chunk-TK633IVD.js → chunk-M2PW7EZU.js} +26 -7
- package/dist/cli-bundle/chunks/chunk-M2PW7EZU.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-DFIZGAI5.js → chunk-MOYM2C3J.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-ZQ4F6EC4.js → chunk-MWRS7Z4P.js} +127 -23
- package/dist/cli-bundle/chunks/chunk-MWRS7Z4P.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-5PAOPUZX.js → chunk-NHR2QXXZ.js} +24 -15
- package/dist/cli-bundle/chunks/chunk-NHR2QXXZ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-OUF3ARDX.js → chunk-NQL32HQ5.js} +12 -12
- package/dist/cli-bundle/chunks/{chunk-TBQVUNVH.js → chunk-O7HSSFCC.js} +65 -16
- package/dist/cli-bundle/chunks/chunk-O7HSSFCC.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-GCAVRLGE.js → chunk-OKSKJKHX.js} +9 -9
- package/dist/cli-bundle/chunks/chunk-QQL5QSTZ.js +1572 -0
- package/dist/cli-bundle/chunks/chunk-QQL5QSTZ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-A6PEXMYN.js → chunk-R3V3YCMH.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-T2ORWB6D.js → chunk-RVPTZKBC.js} +9 -9
- package/dist/cli-bundle/chunks/{chunk-K47WAYQV.js → chunk-SFFVGNHC.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-DFUSXJDE.js → chunk-SQPKRA54.js} +14 -14
- package/dist/cli-bundle/chunks/chunk-THDEID2Z.js +115 -0
- package/dist/cli-bundle/chunks/chunk-THDEID2Z.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-G5BACLYH.js → chunk-TINUJMWN.js} +92 -17
- package/dist/cli-bundle/chunks/chunk-TINUJMWN.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-JB4RGL4V.js → chunk-TNPBPNII.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-XG7RJYHV.js → chunk-TP4DDY27.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-ORTLYVA4.js → chunk-TYJJOTUA.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-HZOS2UG5.js → chunk-UAQOQ7IE.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-D3WUNETC.js → chunk-UEWA73ZZ.js} +5 -5
- package/dist/cli-bundle/chunks/{chunk-O5IBJE6S.js → chunk-UIIQC5YO.js} +2 -2
- package/dist/cli-bundle/chunks/{chunk-SRVKTWPR.js → chunk-UJUT6AHZ.js} +314 -39
- package/dist/cli-bundle/chunks/chunk-UJUT6AHZ.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-SSFMJCPF.js → chunk-UT6WFXW2.js} +6 -7
- package/dist/cli-bundle/chunks/chunk-UT6WFXW2.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-KBG47ZOY.js → chunk-UYQ7HXH4.js} +10 -6
- package/dist/cli-bundle/chunks/chunk-UYQ7HXH4.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-LDJK7SHN.js → chunk-V6EYFTRL.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-5IRA6IYD.js → chunk-WAA7UI6M.js} +58 -30
- package/dist/cli-bundle/chunks/chunk-WAA7UI6M.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-HPH6X4ZZ.js → chunk-WCQZBDDH.js} +10 -6
- package/dist/cli-bundle/chunks/{chunk-HPH6X4ZZ.js.map → chunk-WCQZBDDH.js.map} +2 -2
- package/dist/cli-bundle/chunks/chunk-WR5567FH.js +1582 -0
- package/dist/cli-bundle/chunks/chunk-WR5567FH.js.map +7 -0
- package/dist/cli-bundle/chunks/{chunk-TQ3ZK6VD.js → chunk-WYEXLDDY.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-4LTBNUYT.js → chunk-X4IZKYHP.js} +307 -32
- package/dist/cli-bundle/chunks/chunk-X4IZKYHP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-KCMIYKTA.js → chunk-X7UHMKPE.js} +3 -3
- package/dist/cli-bundle/chunks/{chunk-7K24QB23.js → chunk-XS3O2TFJ.js} +27 -8
- package/dist/cli-bundle/chunks/chunk-XS3O2TFJ.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-EHXPIKKP.js → chunk-XYNT7UFP.js} +303 -207
- package/dist/cli-bundle/chunks/chunk-XYNT7UFP.js.map +1 -0
- package/dist/cli-bundle/chunks/{chunk-CWT53EYT.js → chunk-YBZW2QQ7.js} +6 -6
- package/dist/cli-bundle/chunks/{chunk-VGO2T3TY.js → chunk-YO3THIJF.js} +7 -7
- package/dist/cli-bundle/chunks/{chunk-5KB4X7YY.js → chunk-YPH4ESA2.js} +66 -17
- package/dist/cli-bundle/chunks/chunk-YPH4ESA2.js.map +1 -0
- package/dist/cli-bundle/chunks/{claim-ZFA7HKU4.js → claim-BJ4QMPJC.js} +10 -10
- package/dist/cli-bundle/chunks/{claim-AZLP7YFO.js → claim-KW743OSW.js} +10 -10
- package/dist/cli-bundle/chunks/close-P4ZBKODL.js +13 -0
- package/dist/cli-bundle/chunks/{close-65DFYAVS.js → close-SYHSRZDC.js} +8 -8
- package/dist/cli-bundle/chunks/{close-many-UKZSQGM7.js → close-many-DBLEYFOY.js} +29 -26
- package/dist/cli-bundle/chunks/close-many-DBLEYFOY.js.map +7 -0
- package/dist/cli-bundle/chunks/{close-many-AKPZNSGI.js → close-many-LAC5VR4G.js} +30 -27
- package/dist/cli-bundle/chunks/close-many-LAC5VR4G.js.map +1 -0
- package/dist/cli-bundle/chunks/{comments-AGBNSJJH.js → comments-JEO6HHVM.js} +10 -10
- package/dist/cli-bundle/chunks/{comments-CJWXQI7X.js → comments-YT2PQ5DD.js} +10 -10
- package/dist/cli-bundle/chunks/{config-DDPYIA6J.js → config-RZRVS3ZV.js} +127 -11
- package/dist/cli-bundle/chunks/config-RZRVS3ZV.js.map +1 -0
- package/dist/cli-bundle/chunks/{config-5ON3ADRH.js → config-YJSAAADD.js} +128 -12
- package/dist/cli-bundle/chunks/config-YJSAAADD.js.map +7 -0
- package/dist/cli-bundle/chunks/{context-E6U3DWVM.js → context-LGYEEKAW.js} +14 -14
- package/dist/cli-bundle/chunks/{context-E6U3DWVM.js.map → context-LGYEEKAW.js.map} +2 -2
- package/dist/cli-bundle/chunks/{context-ZOJEN5VT.js → context-ZUH5IOOI.js} +15 -15
- package/dist/cli-bundle/chunks/context-ZUH5IOOI.js.map +1 -0
- package/dist/cli-bundle/chunks/{contracts-CXSFM45B.js → contracts-YXJ6NXKH.js} +11 -5
- package/dist/cli-bundle/chunks/contracts-YXJ6NXKH.js.map +7 -0
- package/dist/cli-bundle/chunks/{contracts-LCSX5R53.js → contracts-ZIBXROPE.js} +12 -6
- package/dist/cli-bundle/chunks/contracts-ZIBXROPE.js.map +1 -0
- package/dist/cli-bundle/chunks/copy-BZALX5MQ.js +182 -0
- package/dist/cli-bundle/chunks/copy-BZALX5MQ.js.map +1 -0
- package/dist/cli-bundle/chunks/copy-YPWEIAPD.js +185 -0
- package/dist/cli-bundle/chunks/copy-YPWEIAPD.js.map +7 -0
- package/dist/cli-bundle/chunks/create-4DS2QWQC.js +27 -0
- package/dist/cli-bundle/chunks/{create-WYFKN2U4.js → create-CF7EVRX7.js} +13 -13
- package/dist/cli-bundle/chunks/{delete-ZXWC56WO.js → delete-KR4VBWVE.js} +7 -7
- package/dist/cli-bundle/chunks/{delete-RONNH4F4.js → delete-XLZRTRKR.js} +7 -7
- package/dist/cli-bundle/chunks/{deps-WII3O4HB.js → deps-2YTXD3VM.js} +7 -7
- package/dist/cli-bundle/chunks/{deps-EHXIFOZR.js → deps-GZMFMTGS.js} +7 -7
- package/dist/cli-bundle/chunks/{docs-PDREIMLS.js → docs-SLROFEQ4.js} +9 -9
- package/dist/cli-bundle/chunks/{docs-JMVCFNHH.js → docs-ZHISRR2D.js} +9 -9
- package/dist/cli-bundle/chunks/{extension-G6UXSM5S.js → extension-3C7OOI4F.js} +8 -6
- package/dist/cli-bundle/chunks/{extension-B4ROVWJD.js → extension-XYCUXICD.js} +8 -6
- package/dist/cli-bundle/chunks/{files-2PN7UM2D.js → files-FUWF2FYJ.js} +9 -9
- package/dist/cli-bundle/chunks/{files-MXYS5W4M.js → files-J4I5IU4O.js} +9 -9
- package/dist/cli-bundle/chunks/gc-34NXSNSN.js +362 -0
- package/dist/cli-bundle/chunks/gc-34NXSNSN.js.map +1 -0
- package/dist/cli-bundle/chunks/gc-SPIIZX3A.js +372 -0
- package/dist/cli-bundle/chunks/gc-SPIIZX3A.js.map +7 -0
- package/dist/cli-bundle/chunks/{get-WXMLRG7M.js → get-SZKNRHMA.js} +34 -12
- package/dist/cli-bundle/chunks/get-SZKNRHMA.js.map +1 -0
- package/dist/cli-bundle/chunks/{get-CINFEUIY.js → get-VITKYP6S.js} +33 -11
- package/dist/cli-bundle/chunks/get-VITKYP6S.js.map +7 -0
- package/dist/cli-bundle/chunks/{health-IT5DBPRJ.js → health-4SNTA2TF.js} +27 -13
- package/dist/cli-bundle/chunks/health-4SNTA2TF.js.map +7 -0
- package/dist/cli-bundle/chunks/{health-5VPOJQ53.js → health-7G3EPM57.js} +28 -14
- package/dist/cli-bundle/chunks/health-7G3EPM57.js.map +1 -0
- package/dist/cli-bundle/chunks/{history-FLZIP7PM.js → history-SDAWYZR3.js} +10 -10
- package/dist/cli-bundle/chunks/history-YDUEILKP.js +20 -0
- package/dist/cli-bundle/chunks/history-compact-DMW536VH.js +287 -0
- package/dist/cli-bundle/chunks/history-compact-DMW536VH.js.map +1 -0
- package/dist/cli-bundle/chunks/history-compact-POTZGG7K.js +290 -0
- package/dist/cli-bundle/chunks/history-compact-POTZGG7K.js.map +7 -0
- package/dist/cli-bundle/chunks/{history-redact-SSZBAD76.js → history-redact-EPJ7GENL.js} +11 -11
- package/dist/cli-bundle/chunks/history-redact-KASLLPE7.js +19 -0
- package/dist/cli-bundle/chunks/{history-repair-X7CO5JJZ.js → history-repair-IJ7LLBET.js} +11 -11
- package/dist/cli-bundle/chunks/{history-repair-KC5ZOJRZ.js → history-repair-YNESJRT6.js} +11 -11
- package/dist/cli-bundle/chunks/init-IGSS4GNH.js +17 -0
- package/dist/cli-bundle/chunks/{init-6MRFVOLH.js → init-YHVBTEET.js} +9 -8
- package/dist/cli-bundle/chunks/{learnings-DCX55BNX.js → learnings-4YBMIVCZ.js} +10 -10
- package/dist/cli-bundle/chunks/{learnings-A3CLB5CO.js → learnings-T4PF24YN.js} +10 -10
- package/dist/cli-bundle/chunks/{list-DBRECOG4.js → list-3KEVBOYW.js} +10 -10
- package/dist/cli-bundle/chunks/list-E44O2K64.js +20 -0
- package/dist/cli-bundle/chunks/{notes-42LIC3UE.js → notes-FLUCNJSH.js} +10 -10
- package/dist/cli-bundle/chunks/{notes-P5O3VMQ3.js → notes-GJKALVZM.js} +10 -10
- package/dist/cli-bundle/chunks/{plan-HDQXEUKD.js → plan-T5MMZLI3.js} +13 -13
- package/dist/cli-bundle/chunks/{plan-IGTE3WOJ.js → plan-YYMIL3HV.js} +13 -13
- package/dist/cli-bundle/chunks/{register-list-query-EMNSIUO4.js → register-list-query-I65EZ3HB.js} +33 -27
- package/dist/cli-bundle/chunks/register-list-query-I65EZ3HB.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-list-query-AG3XKXWL.js → register-list-query-OECMHO4G.js} +32 -26
- package/dist/cli-bundle/chunks/register-list-query-OECMHO4G.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-mutation-M3YS6XDO.js → register-mutation-2FLXORLR.js} +65 -47
- package/dist/cli-bundle/chunks/register-mutation-2FLXORLR.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-mutation-RSMT6DPK.js → register-mutation-5GPDEKHR.js} +64 -46
- package/dist/cli-bundle/chunks/register-mutation-5GPDEKHR.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-operations-KYUOOOOD.js → register-operations-BNGAUMGK.js} +71 -35
- package/dist/cli-bundle/chunks/register-operations-BNGAUMGK.js.map +1 -0
- package/dist/cli-bundle/chunks/{register-operations-Q54JQZUN.js → register-operations-GQKT35H5.js} +70 -34
- package/dist/cli-bundle/chunks/register-operations-GQKT35H5.js.map +7 -0
- package/dist/cli-bundle/chunks/{register-setup-DI6P7X75.js → register-setup-DNDCGZ4O.js} +18 -18
- package/dist/cli-bundle/chunks/{register-setup-DI6P7X75.js.map → register-setup-DNDCGZ4O.js.map} +1 -1
- package/dist/cli-bundle/chunks/{register-setup-YJKIQRKA.js → register-setup-EJY44FPH.js} +17 -17
- package/dist/cli-bundle/chunks/{register-setup-YJKIQRKA.js.map → register-setup-EJY44FPH.js.map} +2 -2
- package/dist/cli-bundle/chunks/{restore-2XVTBLKQ.js → restore-DDJGVZIN.js} +11 -11
- package/dist/cli-bundle/chunks/restore-SJSASGZP.js +17 -0
- package/dist/cli-bundle/chunks/{schema-V6BX65Q2.js → schema-B7NQ6XVP.js} +8 -8
- package/dist/cli-bundle/chunks/{schema-LVXZWFGY.js → schema-HEGYH6CE.js} +8 -8
- package/dist/cli-bundle/chunks/{search-C7NPB7G7.js → search-DVVQ4UO2.js} +421 -42
- package/dist/cli-bundle/chunks/search-DVVQ4UO2.js.map +1 -0
- package/dist/cli-bundle/chunks/{search-5A3BMFA7.js → search-JNEZJV7H.js} +427 -41
- package/dist/cli-bundle/chunks/search-JNEZJV7H.js.map +7 -0
- package/dist/cli-bundle/chunks/stats-7JDIJRDH.js +202 -0
- package/dist/cli-bundle/chunks/stats-7JDIJRDH.js.map +1 -0
- package/dist/cli-bundle/chunks/stats-SYTJRR4Z.js +212 -0
- package/dist/cli-bundle/chunks/stats-SYTJRR4Z.js.map +7 -0
- package/dist/cli-bundle/chunks/telemetry-4HHWD5Y7.js +251 -0
- package/dist/cli-bundle/chunks/telemetry-4HHWD5Y7.js.map +7 -0
- package/dist/cli-bundle/chunks/telemetry-EGWP7ZUX.js +248 -0
- package/dist/cli-bundle/chunks/telemetry-EGWP7ZUX.js.map +1 -0
- package/dist/cli-bundle/chunks/{test-OFYONO3C.js → test-IIELLSZX.js} +14 -13
- package/dist/cli-bundle/chunks/test-ML5RLWXE.js +32 -0
- package/dist/cli-bundle/chunks/{test-all-EEMKNTGU.js → test-all-7DNCMML7.js} +14 -13
- package/dist/cli-bundle/chunks/{test-all-EEMKNTGU.js.map → test-all-7DNCMML7.js.map} +1 -1
- package/dist/cli-bundle/chunks/{test-all-OJE6CIO7.js → test-all-IHTUJRRC.js} +16 -15
- package/dist/cli-bundle/chunks/{test-all-OJE6CIO7.js.map → test-all-IHTUJRRC.js.map} +1 -1
- package/dist/cli-bundle/chunks/{test-runs-IPOPFOAF.js → test-runs-5FEMBV3A.js} +5 -5
- package/dist/cli-bundle/chunks/{test-runs-L2M7WKH7.js → test-runs-RNKZ37PS.js} +5 -5
- package/dist/cli-bundle/chunks/update-6C67X4KS.js +21 -0
- package/dist/cli-bundle/chunks/update-VF26YPT3.js +25 -0
- package/dist/cli-bundle/chunks/{update-many-322CCH2L.js → update-many-BSZZZYXY.js} +22 -22
- package/dist/cli-bundle/chunks/{update-many-DYWGW57M.js → update-many-BWKJJEBF.js} +22 -22
- package/dist/cli-bundle/chunks/{upgrade-3W3RVSNM.js → upgrade-RSE5PC44.js} +7 -6
- package/dist/cli-bundle/chunks/{upgrade-3W3RVSNM.js.map → upgrade-RSE5PC44.js.map} +1 -1
- package/dist/cli-bundle/chunks/{upgrade-2U727SAM.js → upgrade-YWI5DJFA.js} +5 -4
- package/dist/cli-bundle/chunks/{upgrade-2U727SAM.js.map → upgrade-YWI5DJFA.js.map} +1 -1
- package/dist/cli-bundle/chunks/{validate-ZFVWPEEN.js → validate-NK3WKB7C.js} +18 -17
- package/dist/cli-bundle/chunks/{validate-ZFVWPEEN.js.map → validate-NK3WKB7C.js.map} +1 -1
- package/dist/cli-bundle/chunks/{validate-GZ24NYHO.js → validate-UCEOB7S6.js} +20 -19
- package/dist/cli-bundle/chunks/{validate-GZ24NYHO.js.map → validate-UCEOB7S6.js.map} +1 -1
- package/dist/cli-bundle/main.js +198 -1523
- package/dist/cli-bundle/main.js.map +4 -4
- package/dist/core/config/nested-settings.d.ts +8 -6
- package/dist/core/config/nested-settings.js +71 -5
- package/dist/core/config/nested-settings.js.map +1 -1
- package/dist/core/config/positional-value.js +4 -2
- package/dist/core/config/positional-value.js.map +1 -1
- package/dist/core/extensions/extension-types.d.ts +36 -0
- package/dist/core/extensions/extension-types.js +2 -2
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/loader.js +46 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/history/drift-scan.d.ts +3 -4
- package/dist/core/history/drift-scan.js +71 -18
- package/dist/core/history/drift-scan.js.map +1 -1
- package/dist/core/history/history-diff.d.ts +47 -0
- package/dist/core/history/history-diff.js +152 -0
- package/dist/core/history/history-diff.js.map +1 -0
- package/dist/core/history/history-storage-stats.d.ts +31 -0
- package/dist/core/history/history-storage-stats.js +101 -0
- package/dist/core/history/history-storage-stats.js.map +1 -0
- package/dist/core/item/id.js +4 -5
- package/dist/core/item/id.js.map +1 -1
- package/dist/core/item/item-format.js +7 -3
- package/dist/core/item/item-format.js.map +1 -1
- package/dist/core/item/toon-decode.d.ts +7 -0
- package/dist/core/item/toon-decode.js +11 -2
- package/dist/core/item/toon-decode.js.map +1 -1
- package/dist/core/item/type-registry.js +25 -7
- package/dist/core/item/type-registry.js.map +1 -1
- package/dist/core/lock/lock-gc.d.ts +46 -0
- package/dist/core/lock/lock-gc.js +194 -0
- package/dist/core/lock/lock-gc.js.map +1 -0
- package/dist/core/search/cache.js +5 -3
- package/dist/core/search/cache.js.map +1 -1
- package/dist/core/search/corpus.d.ts +6 -0
- package/dist/core/search/corpus.js +22 -9
- package/dist/core/search/corpus.js.map +1 -1
- package/dist/core/search/embedding-batches.js +10 -7
- package/dist/core/search/embedding-batches.js.map +1 -1
- package/dist/core/search/relevance.d.ts +29 -0
- package/dist/core/search/relevance.js +226 -0
- package/dist/core/search/relevance.js.map +1 -0
- package/dist/core/search/vector-stores.d.ts +3 -0
- package/dist/core/search/vector-stores.js +23 -10
- package/dist/core/search/vector-stores.js.map +1 -1
- package/dist/core/shared/constants.js +15 -2
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/errors.d.ts +6 -0
- package/dist/core/shared/errors.js +2 -2
- package/dist/core/shared/errors.js.map +1 -1
- package/dist/core/shared/primitives.d.ts +8 -0
- package/dist/core/shared/primitives.js +29 -2
- package/dist/core/shared/primitives.js.map +1 -1
- package/dist/core/shared/serial-queue.d.ts +12 -0
- package/dist/core/shared/serial-queue.js +43 -0
- package/dist/core/shared/serial-queue.js.map +1 -0
- package/dist/core/shared/time.js +42 -6
- package/dist/core/shared/time.js.map +1 -1
- package/dist/core/store/paths.js +25 -7
- package/dist/core/store/paths.js.map +1 -1
- package/dist/core/store/settings-validator.d.ts +11 -0
- package/dist/core/store/settings-validator.js +14 -2
- package/dist/core/store/settings-validator.js.map +1 -1
- package/dist/core/store/settings.d.ts +19 -1
- package/dist/core/store/settings.js +199 -17
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/observability.js +3 -3
- package/dist/core/telemetry/observability.js.map +1 -1
- package/dist/core/telemetry/runtime.js +99 -6
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +187 -42
- package/dist/mcp/server.js.map +1 -1
- package/dist/sdk/cli-contracts/commander-types.d.ts +1 -0
- package/dist/sdk/cli-contracts/commander-types.js +13 -2
- package/dist/sdk/cli-contracts/commander-types.js.map +1 -1
- package/dist/sdk/cli-contracts/enum-contracts.d.ts +2 -2
- package/dist/sdk/cli-contracts/enum-contracts.js +8 -2
- package/dist/sdk/cli-contracts/enum-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-option-contracts.js +7 -2
- package/dist/sdk/cli-contracts/tool-option-contracts.js.map +1 -1
- package/dist/sdk/cli-contracts/tool-parameter-tables.js +39 -7
- package/dist/sdk/cli-contracts/tool-parameter-tables.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +26 -1
- package/dist/sdk/cli-contracts.js +75 -11
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/index.d.ts +2 -2
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/testing.d.ts +51 -1
- package/dist/sdk/testing.js +93 -2
- package/dist/sdk/testing.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -1
- package/docs/ARCHITECTURE.md +11 -1
- package/docs/CLAUDE_CODE_PLUGIN.md +4 -4
- package/docs/CODEX_PLUGIN.md +1 -1
- package/docs/COMMANDS.md +42 -4
- package/docs/CONFIGURATION.md +31 -2
- package/docs/EXTENSIONS.md +28 -8
- package/docs/EXTENSION_AUTHOR_CONTRACTS.md +73 -0
- package/docs/ONBOARDING.md +165 -0
- package/docs/QUICKSTART.md +2 -2
- package/docs/README.md +12 -4
- package/docs/RELEASING.md +36 -1
- package/docs/SDK.md +66 -0
- package/docs/TESTING.md +33 -1
- package/package.json +6 -2
- package/packages/pm-governance-audit/README.md +14 -0
- package/packages/pm-governance-audit/extensions/governance-audit/index.js +39 -1
- package/packages/pm-governance-audit/extensions/governance-audit/index.ts +40 -2
- package/packages/pm-governance-audit/extensions/governance-audit/manifest.json +1 -1
- package/packages/pm-governance-audit/package.json +4 -2
- package/packages/pm-lifecycle-hooks/README.md +21 -0
- package/packages/pm-search-advanced/README.md +38 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.js +17 -0
- package/packages/pm-search-advanced/extensions/search-advanced/index.ts +17 -0
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.js +216 -1
- package/packages/pm-search-advanced/extensions/search-advanced/runtime.ts +271 -2
- package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
- package/plugins/pm-claude/README.md +11 -8
- package/plugins/pm-claude/agents/pm-coordinator.md +1 -1
- package/plugins/pm-claude/commands/pm-init.md +1 -1
- package/plugins/pm-codex/README.md +1 -1
- package/dist/cli-bundle/chunks/activity-P5BUMWP3.js +0 -16
- package/dist/cli-bundle/chunks/aggregate-J35K7WZB.js.map +0 -1
- package/dist/cli-bundle/chunks/aggregate-OOAGKWRG.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-4LTBNUYT.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-4PJQSECJ.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-4QCR4QW3.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-5IRA6IYD.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-5KB4X7YY.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-5PAOPUZX.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-7K24QB23.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-ATBVS6WW.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-EHXPIKKP.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-G5BACLYH.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-GNHVV4SY.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-KA24HME7.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-KBG47ZOY.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-N5YF3VFN.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-NQP3ECKF.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-OIQIXTNB.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-RANZIID5.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SRVKTWPR.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-SSFMJCPF.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-SZQCER6S.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-TBQVUNVH.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-TK633IVD.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-V3JQ4IPL.js.map +0 -1
- package/dist/cli-bundle/chunks/chunk-WIKR7KFL.js.map +0 -7
- package/dist/cli-bundle/chunks/chunk-ZQ4F6EC4.js.map +0 -7
- package/dist/cli-bundle/chunks/close-RMHQ3KWH.js +0 -13
- package/dist/cli-bundle/chunks/close-many-AKPZNSGI.js.map +0 -1
- package/dist/cli-bundle/chunks/close-many-UKZSQGM7.js.map +0 -7
- package/dist/cli-bundle/chunks/config-5ON3ADRH.js.map +0 -7
- package/dist/cli-bundle/chunks/config-DDPYIA6J.js.map +0 -1
- package/dist/cli-bundle/chunks/context-ZOJEN5VT.js.map +0 -1
- package/dist/cli-bundle/chunks/contracts-CXSFM45B.js.map +0 -7
- package/dist/cli-bundle/chunks/contracts-LCSX5R53.js.map +0 -1
- package/dist/cli-bundle/chunks/create-ATONSAZW.js +0 -27
- package/dist/cli-bundle/chunks/gc-GT552UJH.js +0 -178
- package/dist/cli-bundle/chunks/gc-GT552UJH.js.map +0 -1
- package/dist/cli-bundle/chunks/gc-QNBRJG6H.js +0 -181
- package/dist/cli-bundle/chunks/gc-QNBRJG6H.js.map +0 -7
- package/dist/cli-bundle/chunks/get-CINFEUIY.js.map +0 -7
- package/dist/cli-bundle/chunks/get-WXMLRG7M.js.map +0 -1
- package/dist/cli-bundle/chunks/health-5VPOJQ53.js.map +0 -1
- package/dist/cli-bundle/chunks/health-IT5DBPRJ.js.map +0 -7
- package/dist/cli-bundle/chunks/history-6FC4H6HI.js +0 -20
- package/dist/cli-bundle/chunks/history-redact-XKYEZDBL.js +0 -19
- package/dist/cli-bundle/chunks/init-KHX3FEEM.js +0 -16
- package/dist/cli-bundle/chunks/list-53LZ2AEO.js +0 -20
- package/dist/cli-bundle/chunks/register-list-query-AG3XKXWL.js.map +0 -7
- package/dist/cli-bundle/chunks/register-list-query-EMNSIUO4.js.map +0 -1
- package/dist/cli-bundle/chunks/register-mutation-M3YS6XDO.js.map +0 -1
- package/dist/cli-bundle/chunks/register-mutation-RSMT6DPK.js.map +0 -7
- package/dist/cli-bundle/chunks/register-operations-KYUOOOOD.js.map +0 -1
- package/dist/cli-bundle/chunks/register-operations-Q54JQZUN.js.map +0 -7
- package/dist/cli-bundle/chunks/restore-JL5QIH7H.js +0 -17
- package/dist/cli-bundle/chunks/search-5A3BMFA7.js.map +0 -7
- package/dist/cli-bundle/chunks/search-C7NPB7G7.js.map +0 -1
- package/dist/cli-bundle/chunks/stats-FNLYVXTB.js +0 -120
- package/dist/cli-bundle/chunks/stats-FNLYVXTB.js.map +0 -1
- package/dist/cli-bundle/chunks/stats-Y2CBTZSL.js +0 -123
- package/dist/cli-bundle/chunks/stats-Y2CBTZSL.js.map +0 -7
- package/dist/cli-bundle/chunks/test-RJ4ZF35X.js +0 -31
- package/dist/cli-bundle/chunks/update-6YEHPVXH.js +0 -25
- package/dist/cli-bundle/chunks/update-PYLVHMRD.js +0 -21
- /package/dist/cli-bundle/chunks/{activity-P5BUMWP3.js.map → activity-5UROHJ3D.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{activity-3RWRRNOW.js.map → activity-YVB3QRTE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-PNN6UIBZ.js.map → append-2PPYFAG5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{append-5JE3YGXU.js.map → append-AUGT5W6J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-26KTVXJW.js.map → chunk-2IF7WLB7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XX5LRINW.js.map → chunk-2OJHLWBZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ASQM3IF5.js.map → chunk-3A2CMEM7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-S3CV7JGJ.js.map → chunk-3EOBJOF4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-B3N4TKNL.js.map → chunk-5AXMRKN5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JQI2HE55.js.map → chunk-6J4K6JLA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-BNL6S7QH.js.map → chunk-AVJD6VTA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-RQAWLSUU.js.map → chunk-B5RF3IP7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UFCG3SWR.js.map → chunk-C5W2UH56.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-3OH4DAEB.js.map → chunk-CKLBZHS7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GFWHHMVV.js.map → chunk-FY6Z3FYY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CCUFLH4J.js.map → chunk-GNIUOLZ2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ZRVSMOMR.js.map → chunk-GPXQBR3H.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GPGAYASV.js.map → chunk-H7EO3QA3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-MISYRLEP.js.map → chunk-HLC3KTLP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KK6YPGH3.js.map → chunk-HMMMWBK2.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CJDQB2ED.js.map → chunk-HV5SSZXF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-FVXM3GKS.js.map → chunk-KNGVP5WJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-UOVLWB47.js.map → chunk-LI65XLJR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-AXXKLVTW.js.map → chunk-LIN2BPJ7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-Y2AKE2HS.js.map → chunk-LQHBENVW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-D5X7N6FI.js.map → chunk-LXO6V66E.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DFIZGAI5.js.map → chunk-MOYM2C3J.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-OUF3ARDX.js.map → chunk-NQL32HQ5.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-GCAVRLGE.js.map → chunk-OKSKJKHX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-A6PEXMYN.js.map → chunk-R3V3YCMH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-T2ORWB6D.js.map → chunk-RVPTZKBC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-K47WAYQV.js.map → chunk-SFFVGNHC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-DFUSXJDE.js.map → chunk-SQPKRA54.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-JB4RGL4V.js.map → chunk-TNPBPNII.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-XG7RJYHV.js.map → chunk-TP4DDY27.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-ORTLYVA4.js.map → chunk-TYJJOTUA.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-HZOS2UG5.js.map → chunk-UAQOQ7IE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-D3WUNETC.js.map → chunk-UEWA73ZZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-O5IBJE6S.js.map → chunk-UIIQC5YO.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-LDJK7SHN.js.map → chunk-V6EYFTRL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-TQ3ZK6VD.js.map → chunk-WYEXLDDY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-KCMIYKTA.js.map → chunk-X7UHMKPE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-CWT53EYT.js.map → chunk-YBZW2QQ7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{chunk-VGO2T3TY.js.map → chunk-YO3THIJF.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{claim-ZFA7HKU4.js.map → claim-BJ4QMPJC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{claim-AZLP7YFO.js.map → claim-KW743OSW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-RMHQ3KWH.js.map → close-P4ZBKODL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{close-65DFYAVS.js.map → close-SYHSRZDC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-AGBNSJJH.js.map → comments-JEO6HHVM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{comments-CJWXQI7X.js.map → comments-YT2PQ5DD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-ATONSAZW.js.map → create-4DS2QWQC.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{create-WYFKN2U4.js.map → create-CF7EVRX7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-ZXWC56WO.js.map → delete-KR4VBWVE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{delete-RONNH4F4.js.map → delete-XLZRTRKR.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-WII3O4HB.js.map → deps-2YTXD3VM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{deps-EHXIFOZR.js.map → deps-GZMFMTGS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-PDREIMLS.js.map → docs-SLROFEQ4.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{docs-JMVCFNHH.js.map → docs-ZHISRR2D.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{extension-G6UXSM5S.js.map → extension-3C7OOI4F.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{extension-B4ROVWJD.js.map → extension-XYCUXICD.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-2PN7UM2D.js.map → files-FUWF2FYJ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{files-MXYS5W4M.js.map → files-J4I5IU4O.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-FLZIP7PM.js.map → history-SDAWYZR3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-6FC4H6HI.js.map → history-YDUEILKP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-SSZBAD76.js.map → history-redact-EPJ7GENL.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-redact-XKYEZDBL.js.map → history-redact-KASLLPE7.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-X7CO5JJZ.js.map → history-repair-IJ7LLBET.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{history-repair-KC5ZOJRZ.js.map → history-repair-YNESJRT6.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{init-KHX3FEEM.js.map → init-IGSS4GNH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{init-6MRFVOLH.js.map → init-YHVBTEET.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-DCX55BNX.js.map → learnings-4YBMIVCZ.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{learnings-A3CLB5CO.js.map → learnings-T4PF24YN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{list-DBRECOG4.js.map → list-3KEVBOYW.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{list-53LZ2AEO.js.map → list-E44O2K64.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-42LIC3UE.js.map → notes-FLUCNJSH.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{notes-P5O3VMQ3.js.map → notes-GJKALVZM.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-HDQXEUKD.js.map → plan-T5MMZLI3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{plan-IGTE3WOJ.js.map → plan-YYMIL3HV.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-2XVTBLKQ.js.map → restore-DDJGVZIN.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{restore-JL5QIH7H.js.map → restore-SJSASGZP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-V6BX65Q2.js.map → schema-B7NQ6XVP.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{schema-LVXZWFGY.js.map → schema-HEGYH6CE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{test-OFYONO3C.js.map → test-IIELLSZX.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{test-RJ4ZF35X.js.map → test-ML5RLWXE.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{test-runs-IPOPFOAF.js.map → test-runs-5FEMBV3A.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{test-runs-L2M7WKH7.js.map → test-runs-RNKZ37PS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-PYLVHMRD.js.map → update-6C67X4KS.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-6YEHPVXH.js.map → update-VF26YPT3.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-322CCH2L.js.map → update-many-BSZZZYXY.js.map} +0 -0
- /package/dist/cli-bundle/chunks/{update-many-DYWGW57M.js.map → update-many-BWKJJEBF.js.map} +0 -0
|
@@ -12,10 +12,9 @@ export interface DriftScanResult {
|
|
|
12
12
|
*
|
|
13
13
|
* Full chain re-verification of a 17MB+ history tree is the dominant cost of
|
|
14
14
|
* `pm health`. We cache the per-stream verification keyed by the history file's
|
|
15
|
-
* mtime/size
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `latest_after_hash`.
|
|
15
|
+
* mtime/ctime/size + content hash: metadata-stable replacements (same stat tuple)
|
|
16
|
+
* can still happen, so each metadata hit recomputes a content hash guard before
|
|
17
|
+
* trusting the cached chain/hash verification.
|
|
19
18
|
*/
|
|
20
19
|
export declare function scanHistoryDrift(pmRoot: string, items: Array<ItemMetadata & {
|
|
21
20
|
body: string;
|
|
@@ -1,12 +1,13 @@
|
|
|
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]="0dd4c4e6-9086-5afb-814b-38d0b36d4283")}catch(e){}}();
|
|
3
3
|
import fs from "fs/promises";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { getHistoryPath } from "../store/paths.js";
|
|
6
7
|
import { writeFileAtomic } from "../fs/fs-utils.js";
|
|
7
8
|
import { hashDocument } from "./history.js";
|
|
8
9
|
import { verifyHistoryChain } from "./replay.js";
|
|
9
|
-
const DRIFT_CACHE_VERSION =
|
|
10
|
+
const DRIFT_CACHE_VERSION = 2;
|
|
10
11
|
const DRIFT_CACHE_FILENAME = "history-drift-cache.json";
|
|
11
12
|
function getDriftCachePath(pmRoot) {
|
|
12
13
|
return path.join(pmRoot, "runtime", DRIFT_CACHE_FILENAME);
|
|
@@ -27,12 +28,20 @@ async function loadDriftCache(pmRoot) {
|
|
|
27
28
|
function isErrno(error, code) {
|
|
28
29
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
29
30
|
}
|
|
31
|
+
function hashContent(raw) {
|
|
32
|
+
return createHash("sha256").update(raw).digest("hex");
|
|
33
|
+
}
|
|
34
|
+
async function readHistoryContentHash(historyPath) {
|
|
35
|
+
const raw = await fs.readFile(historyPath, "utf8");
|
|
36
|
+
return hashContent(raw);
|
|
37
|
+
}
|
|
30
38
|
/**
|
|
31
39
|
* Read and fully verify one history stream's hash chain. Returns null for an
|
|
32
40
|
* empty/missing stream (caller records it as a missing stream).
|
|
33
41
|
*/
|
|
34
42
|
async function verifyHistoryStream(historyPath) {
|
|
35
43
|
const raw = await fs.readFile(historyPath, "utf8");
|
|
44
|
+
const contentHash = hashContent(raw);
|
|
36
45
|
if (raw.trim().length === 0) {
|
|
37
46
|
return null;
|
|
38
47
|
}
|
|
@@ -55,7 +64,11 @@ async function verifyHistoryStream(historyPath) {
|
|
|
55
64
|
return null;
|
|
56
65
|
}
|
|
57
66
|
/* c8 ignore stop */
|
|
58
|
-
return {
|
|
67
|
+
return {
|
|
68
|
+
latestAfterHash,
|
|
69
|
+
chainOk: verifyHistoryChain(entries).ok,
|
|
70
|
+
contentHash,
|
|
71
|
+
};
|
|
59
72
|
}
|
|
60
73
|
/**
|
|
61
74
|
* Scan every item's history stream for drift (missing/unreadable streams, broken
|
|
@@ -63,10 +76,9 @@ async function verifyHistoryStream(historyPath) {
|
|
|
63
76
|
*
|
|
64
77
|
* Full chain re-verification of a 17MB+ history tree is the dominant cost of
|
|
65
78
|
* `pm health`. We cache the per-stream verification keyed by the history file's
|
|
66
|
-
* mtime/size
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `latest_after_hash`.
|
|
79
|
+
* mtime/ctime/size + content hash: metadata-stable replacements (same stat tuple)
|
|
80
|
+
* can still happen, so each metadata hit recomputes a content hash guard before
|
|
81
|
+
* trusting the cached chain/hash verification.
|
|
70
82
|
*/
|
|
71
83
|
export async function scanHistoryDrift(pmRoot, items) {
|
|
72
84
|
const missingStreams = [];
|
|
@@ -92,26 +104,66 @@ export async function scanHistoryDrift(pmRoot, items) {
|
|
|
92
104
|
}
|
|
93
105
|
continue;
|
|
94
106
|
}
|
|
107
|
+
const loadStreamVerification = async () => {
|
|
108
|
+
try {
|
|
109
|
+
return await verifyHistoryStream(historyPath);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return "unreadable";
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const loadFreshVerification = async () => {
|
|
116
|
+
const loaded = await loadStreamVerification();
|
|
117
|
+
if (loaded === "unreadable") {
|
|
118
|
+
unreadableStreams.push(item.id);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (!loaded) {
|
|
122
|
+
missingStreams.push(item.id);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
return loaded;
|
|
126
|
+
};
|
|
95
127
|
const cached = previousEntries[item.id];
|
|
96
128
|
let verification;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
129
|
+
const metadataMatchesCache = cached !== undefined &&
|
|
130
|
+
cached.mtime_ms === stat.mtimeMs &&
|
|
131
|
+
cached.ctime_ms === stat.ctimeMs &&
|
|
132
|
+
cached.size === stat.size;
|
|
133
|
+
const cachedContentHash = typeof cached?.content_hash === "string" && cached.content_hash.length > 0 ? cached.content_hash : undefined;
|
|
134
|
+
const canUseCache = metadataMatchesCache && cachedContentHash !== undefined;
|
|
135
|
+
if (canUseCache && cached) {
|
|
136
|
+
let currentContentHash;
|
|
103
137
|
try {
|
|
104
|
-
|
|
138
|
+
currentContentHash = await readHistoryContentHash(historyPath);
|
|
105
139
|
}
|
|
106
140
|
catch {
|
|
107
141
|
unreadableStreams.push(item.id);
|
|
108
142
|
continue;
|
|
109
143
|
}
|
|
110
|
-
if (
|
|
111
|
-
|
|
144
|
+
if (currentContentHash === cachedContentHash) {
|
|
145
|
+
verification = {
|
|
146
|
+
latestAfterHash: cached.latest_after_hash,
|
|
147
|
+
chainOk: cached.chain_ok,
|
|
148
|
+
contentHash: currentContentHash,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
cacheDirty = true;
|
|
153
|
+
const refreshed = await loadFreshVerification();
|
|
154
|
+
if (!refreshed) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
verification = refreshed;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
cacheDirty = true;
|
|
162
|
+
const refreshed = await loadFreshVerification();
|
|
163
|
+
if (!refreshed) {
|
|
112
164
|
continue;
|
|
113
165
|
}
|
|
114
|
-
verification =
|
|
166
|
+
verification = refreshed;
|
|
115
167
|
}
|
|
116
168
|
if (!verification.chainOk) {
|
|
117
169
|
chainMismatches.push(item.id);
|
|
@@ -120,6 +172,7 @@ export async function scanHistoryDrift(pmRoot, items) {
|
|
|
120
172
|
mtime_ms: stat.mtimeMs,
|
|
121
173
|
ctime_ms: stat.ctimeMs,
|
|
122
174
|
size: stat.size,
|
|
175
|
+
content_hash: verification.contentHash,
|
|
123
176
|
latest_after_hash: verification.latestAfterHash,
|
|
124
177
|
chain_ok: verification.chainOk,
|
|
125
178
|
};
|
|
@@ -146,4 +199,4 @@ export async function scanHistoryDrift(pmRoot, items) {
|
|
|
146
199
|
return { missingStreams, unreadableStreams, hashMismatches, chainMismatches, driftedItems };
|
|
147
200
|
}
|
|
148
201
|
//# sourceMappingURL=drift-scan.js.map
|
|
149
|
-
//# debugId=
|
|
202
|
+
//# debugId=0dd4c4e6-9086-5afb-814b-38d0b36d4283
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drift-scan.js","sources":["core/history/drift-scan.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"fs/promises\";\nimport path from \"node:path\";\nimport { getHistoryPath } from \"../store/paths.js\";\nimport { writeFileAtomic } from \"../fs/fs-utils.js\";\nimport { hashDocument } from \"./history.js\";\nimport { verifyHistoryChain } from \"./replay.js\";\nimport type { HistoryEntry, ItemMetadata } from \"../../types/index.js\";\n\nexport interface DriftScanResult {\n missingStreams: string[];\n unreadableStreams: string[];\n hashMismatches: string[];\n chainMismatches: string[];\n driftedItems: string[];\n}\n\nconst DRIFT_CACHE_VERSION = 1;\nconst DRIFT_CACHE_FILENAME = \"history-drift-cache.json\";\n\ninterface DriftCacheEntry {\n mtime_ms: number;\n ctime_ms: number;\n size: number;\n latest_after_hash: string;\n chain_ok: boolean;\n}\n\ninterface DriftCacheEnvelope {\n version: number;\n entries: Record<string, DriftCacheEntry>;\n}\n\nfunction getDriftCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", DRIFT_CACHE_FILENAME);\n}\n\nasync function loadDriftCache(pmRoot: string): Promise<DriftCacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getDriftCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as DriftCacheEnvelope;\n if (parsed.version !== DRIFT_CACHE_VERSION || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: string }).code === code;\n}\n\ninterface StreamVerification {\n latestAfterHash: string;\n chainOk: boolean;\n}\n\n/**\n * Read and fully verify one history stream's hash chain. Returns null for an\n * empty/missing stream (caller records it as a missing stream).\n */\nasync function verifyHistoryStream(historyPath: string): Promise<StreamVerification | null> {\n const raw = await fs.readFile(historyPath, \"utf8\");\n if (raw.trim().length === 0) {\n return null;\n }\n const entries: HistoryEntry[] = [];\n let latestAfterHash: string | null = null;\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed.length === 0) {\n continue;\n }\n const parsed = JSON.parse(trimmed) as HistoryEntry;\n if (typeof parsed.after_hash !== \"string\" || parsed.after_hash.trim().length === 0) {\n throw new Error(\"missing after_hash\");\n }\n entries.push(parsed);\n latestAfterHash = parsed.after_hash;\n }\n /* c8 ignore start -- defensive guard for future history schema changes. */\n if (!latestAfterHash) {\n return null;\n }\n /* c8 ignore stop */\n return { latestAfterHash, chainOk: verifyHistoryChain(entries).ok };\n}\n\n/**\n * Scan every item's history stream for drift (missing/unreadable streams, broken\n * hash chains, and item/history hash mismatches).\n *\n * Full chain re-verification of a 17MB+ history tree is the dominant cost of\n * `pm health`. We cache the per-stream verification keyed by the history file's\n * mtime/size: an unchanged file has an identical chain and latest stored hash, so\n * we skip re-reading and re-hashing it. Item-side changes are still caught every\n * run because the current document hash is recomputed and compared to the cached\n * `latest_after_hash`.\n */\nexport async function scanHistoryDrift(\n pmRoot: string,\n items: Array<ItemMetadata & { body: string }>,\n): Promise<DriftScanResult> {\n const missingStreams: string[] = [];\n const unreadableStreams: string[] = [];\n const hashMismatches: string[] = [];\n const chainMismatches: string[] = [];\n\n const cache = await loadDriftCache(pmRoot);\n const previousEntries: Record<string, DriftCacheEntry> = cache?.entries ?? {};\n const nextEntries: Record<string, DriftCacheEntry> = {};\n let cacheDirty = false;\n\n for (const item of items) {\n const historyPath = getHistoryPath(pmRoot, item.id);\n\n let stat: Awaited<ReturnType<typeof fs.stat>>;\n try {\n stat = await fs.stat(historyPath);\n } catch (error: unknown) {\n if (isErrno(error, \"ENOENT\")) {\n missingStreams.push(item.id);\n } else {\n unreadableStreams.push(item.id);\n }\n continue;\n }\n\n const cached = previousEntries[item.id];\n let verification: StreamVerification;\n if (cached && cached.mtime_ms === stat.mtimeMs && cached.ctime_ms === stat.ctimeMs && cached.size === stat.size) {\n verification = { latestAfterHash: cached.latest_after_hash, chainOk: cached.chain_ok };\n } else {\n cacheDirty = true;\n let result: StreamVerification | null;\n try {\n result = await verifyHistoryStream(historyPath);\n } catch {\n unreadableStreams.push(item.id);\n continue;\n }\n if (!result) {\n missingStreams.push(item.id);\n continue;\n }\n verification = result;\n }\n\n if (!verification.chainOk) {\n chainMismatches.push(item.id);\n }\n nextEntries[item.id] = {\n mtime_ms: stat.mtimeMs,\n ctime_ms: stat.ctimeMs,\n size: stat.size,\n latest_after_hash: verification.latestAfterHash,\n chain_ok: verification.chainOk,\n };\n\n const { body, ...frontMatter } = item;\n const currentHash = hashDocument({\n metadata: frontMatter as ItemMetadata,\n body,\n });\n if (currentHash !== verification.latestAfterHash) {\n hashMismatches.push(item.id);\n }\n }\n\n if (cacheDirty || Object.keys(previousEntries).length !== Object.keys(nextEntries).length) {\n const cachePath = getDriftCachePath(pmRoot);\n try {\n await fs.mkdir(path.dirname(cachePath), { recursive: true });\n await writeFileAtomic(cachePath, JSON.stringify({ version: DRIFT_CACHE_VERSION, entries: nextEntries }));\n } catch {\n // Best-effort cache write: a failed persist must never fail a health scan.\n }\n }\n\n const driftedItems = [...new Set([...missingStreams, ...unreadableStreams, ...hashMismatches, ...chainMismatches])].sort((a, b) =>\n a.localeCompare(b),\n );\n return { missingStreams, unreadableStreams, hashMismatches, chainMismatches, driftedItems };\n}\n"],"names":[],"mappings":"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","debugId":"e8559b46-0199-506f-bf98-8f92a4474215"}
|
|
1
|
+
{"version":3,"file":"drift-scan.js","sources":["core/history/drift-scan.ts"],"sourceRoot":"/","sourcesContent":["import fs from \"fs/promises\";\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { getHistoryPath } from \"../store/paths.js\";\nimport { writeFileAtomic } from \"../fs/fs-utils.js\";\nimport { hashDocument } from \"./history.js\";\nimport { verifyHistoryChain } from \"./replay.js\";\nimport type { HistoryEntry, ItemMetadata } from \"../../types/index.js\";\n\nexport interface DriftScanResult {\n missingStreams: string[];\n unreadableStreams: string[];\n hashMismatches: string[];\n chainMismatches: string[];\n driftedItems: string[];\n}\n\nconst DRIFT_CACHE_VERSION = 2;\nconst DRIFT_CACHE_FILENAME = \"history-drift-cache.json\";\n\ninterface DriftCacheEntry {\n mtime_ms: number;\n ctime_ms: number;\n size: number;\n content_hash: string;\n latest_after_hash: string;\n chain_ok: boolean;\n}\n\ninterface DriftCacheEnvelope {\n version: number;\n entries: Record<string, DriftCacheEntry>;\n}\n\nfunction getDriftCachePath(pmRoot: string): string {\n return path.join(pmRoot, \"runtime\", DRIFT_CACHE_FILENAME);\n}\n\nasync function loadDriftCache(pmRoot: string): Promise<DriftCacheEnvelope | null> {\n try {\n const raw = await fs.readFile(getDriftCachePath(pmRoot), \"utf8\");\n const parsed = JSON.parse(raw) as DriftCacheEnvelope;\n if (parsed.version !== DRIFT_CACHE_VERSION || typeof parsed.entries !== \"object\" || parsed.entries === null) {\n return null;\n }\n return parsed;\n } catch {\n return null;\n }\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && (error as { code?: string }).code === code;\n}\n\ninterface StreamVerification {\n latestAfterHash: string;\n chainOk: boolean;\n contentHash: string;\n}\n\nfunction hashContent(raw: string): string {\n return createHash(\"sha256\").update(raw).digest(\"hex\");\n}\n\nasync function readHistoryContentHash(historyPath: string): Promise<string> {\n const raw = await fs.readFile(historyPath, \"utf8\");\n return hashContent(raw);\n}\n\n/**\n * Read and fully verify one history stream's hash chain. Returns null for an\n * empty/missing stream (caller records it as a missing stream).\n */\nasync function verifyHistoryStream(historyPath: string): Promise<StreamVerification | null> {\n const raw = await fs.readFile(historyPath, \"utf8\");\n const contentHash = hashContent(raw);\n if (raw.trim().length === 0) {\n return null;\n }\n const entries: HistoryEntry[] = [];\n let latestAfterHash: string | null = null;\n for (const line of raw.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed.length === 0) {\n continue;\n }\n const parsed = JSON.parse(trimmed) as HistoryEntry;\n if (typeof parsed.after_hash !== \"string\" || parsed.after_hash.trim().length === 0) {\n throw new Error(\"missing after_hash\");\n }\n entries.push(parsed);\n latestAfterHash = parsed.after_hash;\n }\n /* c8 ignore start -- defensive guard for future history schema changes. */\n if (!latestAfterHash) {\n return null;\n }\n /* c8 ignore stop */\n return {\n latestAfterHash,\n chainOk: verifyHistoryChain(entries).ok,\n contentHash,\n };\n}\n\n/**\n * Scan every item's history stream for drift (missing/unreadable streams, broken\n * hash chains, and item/history hash mismatches).\n *\n * Full chain re-verification of a 17MB+ history tree is the dominant cost of\n * `pm health`. We cache the per-stream verification keyed by the history file's\n * mtime/ctime/size + content hash: metadata-stable replacements (same stat tuple)\n * can still happen, so each metadata hit recomputes a content hash guard before\n * trusting the cached chain/hash verification.\n */\nexport async function scanHistoryDrift(\n pmRoot: string,\n items: Array<ItemMetadata & { body: string }>,\n): Promise<DriftScanResult> {\n const missingStreams: string[] = [];\n const unreadableStreams: string[] = [];\n const hashMismatches: string[] = [];\n const chainMismatches: string[] = [];\n\n const cache = await loadDriftCache(pmRoot);\n const previousEntries: Record<string, DriftCacheEntry> = cache?.entries ?? {};\n const nextEntries: Record<string, DriftCacheEntry> = {};\n let cacheDirty = false;\n\n for (const item of items) {\n const historyPath = getHistoryPath(pmRoot, item.id);\n\n let stat: Awaited<ReturnType<typeof fs.stat>>;\n try {\n stat = await fs.stat(historyPath);\n } catch (error: unknown) {\n if (isErrno(error, \"ENOENT\")) {\n missingStreams.push(item.id);\n } else {\n unreadableStreams.push(item.id);\n }\n continue;\n }\n\n const loadStreamVerification = async (): Promise<StreamVerification | null | \"unreadable\"> => {\n try {\n return await verifyHistoryStream(historyPath);\n } catch {\n return \"unreadable\";\n }\n };\n\n const loadFreshVerification = async (): Promise<StreamVerification | null> => {\n const loaded = await loadStreamVerification();\n if (loaded === \"unreadable\") {\n unreadableStreams.push(item.id);\n return null;\n }\n if (!loaded) {\n missingStreams.push(item.id);\n return null;\n }\n return loaded;\n };\n\n const cached = previousEntries[item.id];\n let verification: StreamVerification;\n const metadataMatchesCache =\n cached !== undefined &&\n cached.mtime_ms === stat.mtimeMs &&\n cached.ctime_ms === stat.ctimeMs &&\n cached.size === stat.size;\n const cachedContentHash =\n typeof cached?.content_hash === \"string\" && cached.content_hash.length > 0 ? cached.content_hash : undefined;\n const canUseCache = metadataMatchesCache && cachedContentHash !== undefined;\n if (canUseCache && cached) {\n let currentContentHash: string;\n try {\n currentContentHash = await readHistoryContentHash(historyPath);\n } catch {\n unreadableStreams.push(item.id);\n continue;\n }\n if (currentContentHash === cachedContentHash) {\n verification = {\n latestAfterHash: cached.latest_after_hash,\n chainOk: cached.chain_ok,\n contentHash: currentContentHash,\n };\n } else {\n cacheDirty = true;\n const refreshed = await loadFreshVerification();\n if (!refreshed) {\n continue;\n }\n verification = refreshed;\n }\n } else {\n cacheDirty = true;\n const refreshed = await loadFreshVerification();\n if (!refreshed) {\n continue;\n }\n verification = refreshed;\n }\n\n if (!verification.chainOk) {\n chainMismatches.push(item.id);\n }\n nextEntries[item.id] = {\n mtime_ms: stat.mtimeMs,\n ctime_ms: stat.ctimeMs,\n size: stat.size,\n content_hash: verification.contentHash,\n latest_after_hash: verification.latestAfterHash,\n chain_ok: verification.chainOk,\n };\n\n const { body, ...frontMatter } = item;\n const currentHash = hashDocument({\n metadata: frontMatter as ItemMetadata,\n body,\n });\n if (currentHash !== verification.latestAfterHash) {\n hashMismatches.push(item.id);\n }\n }\n\n if (cacheDirty || Object.keys(previousEntries).length !== Object.keys(nextEntries).length) {\n const cachePath = getDriftCachePath(pmRoot);\n try {\n await fs.mkdir(path.dirname(cachePath), { recursive: true });\n await writeFileAtomic(cachePath, JSON.stringify({ version: DRIFT_CACHE_VERSION, entries: nextEntries }));\n } catch {\n // Best-effort cache write: a failed persist must never fail a health scan.\n }\n }\n\n const driftedItems = [...new Set([...missingStreams, ...unreadableStreams, ...hashMismatches, ...chainMismatches])].sort((a, b) =>\n a.localeCompare(b),\n );\n return { missingStreams, unreadableStreams, hashMismatches, chainMismatches, driftedItems };\n}\n"],"names":[],"mappings":"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","debugId":"0dd4c4e6-9086-5afb-814b-38d0b36d4283"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { HistoryEntry } from "../../types/index.js";
|
|
2
|
+
export interface HistoryFieldChange {
|
|
3
|
+
field: string;
|
|
4
|
+
before: unknown;
|
|
5
|
+
after: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface HistoryDiffValueEntry {
|
|
8
|
+
/** 1-based position in the FULL stream (fullEntries index + 1). */
|
|
9
|
+
index: number;
|
|
10
|
+
ts: string;
|
|
11
|
+
op: string;
|
|
12
|
+
author: string;
|
|
13
|
+
/** Number of JSON-patch operations in this entry (entry.patch.length). */
|
|
14
|
+
patch_ops: number;
|
|
15
|
+
/** Unique field names touched by this entry, sorted by localeCompare. */
|
|
16
|
+
changed_fields: string[];
|
|
17
|
+
/** Per-field before/after values, sorted by field name (localeCompare). */
|
|
18
|
+
changes: HistoryFieldChange[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Map a JSON-Patch path string to a human-readable changed-field name.
|
|
22
|
+
*
|
|
23
|
+
* Rules (in priority order):
|
|
24
|
+
* - "/body" or "/body/…" → "body"
|
|
25
|
+
* - "/metadata/…" or "/front_matter/…"
|
|
26
|
+
* with a first segment → that decoded segment (e.g. "status")
|
|
27
|
+
* without a first segment (bare prefix) → "metadata"
|
|
28
|
+
* - "/" (root pointer, empty segment after strip) → "root"
|
|
29
|
+
* - anything else → decoded first path segment
|
|
30
|
+
*/
|
|
31
|
+
export declare function patchPathToChangedField(path: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Replay a full history entry stream and produce enriched diff entries with
|
|
34
|
+
* per-field before/after values.
|
|
35
|
+
*
|
|
36
|
+
* @param fullEntries The complete ordered history chain to replay.
|
|
37
|
+
* @param options.windowStartIndex 0-based index into fullEntries at which the
|
|
38
|
+
* DISPLAYED window begins. Entries before this index are still replayed (so
|
|
39
|
+
* state is accurate) but are not emitted. Defaults to 0.
|
|
40
|
+
* @param options.field When supplied, only entries that changed this field are
|
|
41
|
+
* emitted, and each emitted entry's `changes` and `changed_fields` are
|
|
42
|
+
* restricted to that single field.
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeHistoryDiff(fullEntries: HistoryEntry[], options?: {
|
|
45
|
+
windowStartIndex?: number;
|
|
46
|
+
field?: string;
|
|
47
|
+
}): HistoryDiffValueEntry[];
|
|
@@ -0,0 +1,152 @@
|
|
|
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]="2b77be38-f27c-5a56-86de-9625777f7211")}catch(e){}}();
|
|
3
|
+
import { cloneEmptyReplayDocument, tryApplyReplayPatch } from "./replay.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// JSON-Pointer helpers (ported from src/cli/commands/history.ts so the
|
|
6
|
+
// orchestrator can replace the private copy there with an import from here).
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
function decodeJsonPointerSegment(segment) {
|
|
9
|
+
return segment.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Map a JSON-Patch path string to a human-readable changed-field name.
|
|
13
|
+
*
|
|
14
|
+
* Rules (in priority order):
|
|
15
|
+
* - "/body" or "/body/…" → "body"
|
|
16
|
+
* - "/metadata/…" or "/front_matter/…"
|
|
17
|
+
* with a first segment → that decoded segment (e.g. "status")
|
|
18
|
+
* without a first segment (bare prefix) → "metadata"
|
|
19
|
+
* - "/" (root pointer, empty segment after strip) → "root"
|
|
20
|
+
* - anything else → decoded first path segment
|
|
21
|
+
*/
|
|
22
|
+
export function patchPathToChangedField(path) {
|
|
23
|
+
if (path === "/body" || path.startsWith("/body/"))
|
|
24
|
+
return "body";
|
|
25
|
+
if (path === "/metadata" ||
|
|
26
|
+
path.startsWith("/metadata/") ||
|
|
27
|
+
path === "/front_matter" ||
|
|
28
|
+
path.startsWith("/front_matter/")) {
|
|
29
|
+
const segment = path.replace(/^\/(?:metadata|front_matter)\/?/, "").split("/")[0];
|
|
30
|
+
if (!segment)
|
|
31
|
+
return "metadata";
|
|
32
|
+
return decodeJsonPointerSegment(segment);
|
|
33
|
+
}
|
|
34
|
+
const segment = path.replace(/^\//, "").split("/")[0];
|
|
35
|
+
return segment ? decodeJsonPointerSegment(segment) : "root";
|
|
36
|
+
}
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Field-value reader
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
/**
|
|
41
|
+
* Extract the before/after value for a logical field from a replay document.
|
|
42
|
+
*
|
|
43
|
+
* - "body" → doc.body
|
|
44
|
+
* - "metadata" → doc.metadata (the whole object, for a bare /metadata replace)
|
|
45
|
+
* - "root" → the whole document (for a bare "/" patch op)
|
|
46
|
+
* - other → doc.metadata[field] (may be undefined when the field was absent)
|
|
47
|
+
*/
|
|
48
|
+
function readFieldValue(doc, field) {
|
|
49
|
+
if (field === "body")
|
|
50
|
+
return doc.body;
|
|
51
|
+
if (field === "metadata")
|
|
52
|
+
return doc.metadata;
|
|
53
|
+
if (field === "root")
|
|
54
|
+
return doc;
|
|
55
|
+
return doc.metadata[field];
|
|
56
|
+
}
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Main export
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
/**
|
|
61
|
+
* Replay a full history entry stream and produce enriched diff entries with
|
|
62
|
+
* per-field before/after values.
|
|
63
|
+
*
|
|
64
|
+
* @param fullEntries The complete ordered history chain to replay.
|
|
65
|
+
* @param options.windowStartIndex 0-based index into fullEntries at which the
|
|
66
|
+
* DISPLAYED window begins. Entries before this index are still replayed (so
|
|
67
|
+
* state is accurate) but are not emitted. Defaults to 0.
|
|
68
|
+
* @param options.field When supplied, only entries that changed this field are
|
|
69
|
+
* emitted, and each emitted entry's `changes` and `changed_fields` are
|
|
70
|
+
* restricted to that single field.
|
|
71
|
+
*/
|
|
72
|
+
export function computeHistoryDiff(fullEntries, options) {
|
|
73
|
+
const windowStartIndex = options?.windowStartIndex ?? 0;
|
|
74
|
+
const fieldFilter = options?.field;
|
|
75
|
+
if (fullEntries.length === 0 || windowStartIndex >= fullEntries.length) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
let current = cloneEmptyReplayDocument();
|
|
79
|
+
const result = [];
|
|
80
|
+
for (let p = 0; p < fullEntries.length; p += 1) {
|
|
81
|
+
const entry = fullEntries[p];
|
|
82
|
+
// Capture before state.
|
|
83
|
+
const beforeDoc = current;
|
|
84
|
+
// Attempt to apply patch.
|
|
85
|
+
const applied = tryApplyReplayPatch(current, entry.patch);
|
|
86
|
+
let afterDoc;
|
|
87
|
+
if (applied.ok) {
|
|
88
|
+
afterDoc = applied.document;
|
|
89
|
+
current = afterDoc;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Patch failed — use before state as after (cannot trust partial result).
|
|
93
|
+
// Do NOT advance current; keep prior replay state.
|
|
94
|
+
afterDoc = beforeDoc;
|
|
95
|
+
}
|
|
96
|
+
// Collect changed field names from patch paths (and from: paths for move/copy).
|
|
97
|
+
const changedFieldSet = new Set();
|
|
98
|
+
for (const patchOp of entry.patch) {
|
|
99
|
+
changedFieldSet.add(patchPathToChangedField(patchOp.path));
|
|
100
|
+
if (patchOp.from !== undefined) {
|
|
101
|
+
changedFieldSet.add(patchPathToChangedField(patchOp.from));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const sortedFields = [...changedFieldSet].sort((a, b) => a.localeCompare(b));
|
|
105
|
+
// Only emit entries in the display window.
|
|
106
|
+
if (p >= windowStartIndex) {
|
|
107
|
+
// Apply field filter: skip this entry entirely if it doesn't touch the
|
|
108
|
+
// requested field; otherwise narrow down to only that field.
|
|
109
|
+
if (fieldFilter !== undefined) {
|
|
110
|
+
if (!changedFieldSet.has(fieldFilter)) {
|
|
111
|
+
// This entry does not touch the requested field — skip it.
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
// Emit only the filtered field.
|
|
115
|
+
const change = {
|
|
116
|
+
field: fieldFilter,
|
|
117
|
+
before: readFieldValue(beforeDoc, fieldFilter),
|
|
118
|
+
after: readFieldValue(afterDoc, fieldFilter),
|
|
119
|
+
};
|
|
120
|
+
result.push({
|
|
121
|
+
index: p + 1,
|
|
122
|
+
ts: entry.ts,
|
|
123
|
+
op: entry.op,
|
|
124
|
+
author: entry.author,
|
|
125
|
+
patch_ops: entry.patch.length,
|
|
126
|
+
changed_fields: [fieldFilter],
|
|
127
|
+
changes: [change],
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// Emit all changed fields.
|
|
132
|
+
const changes = sortedFields.map((field) => ({
|
|
133
|
+
field,
|
|
134
|
+
before: readFieldValue(beforeDoc, field),
|
|
135
|
+
after: readFieldValue(afterDoc, field),
|
|
136
|
+
}));
|
|
137
|
+
result.push({
|
|
138
|
+
index: p + 1,
|
|
139
|
+
ts: entry.ts,
|
|
140
|
+
op: entry.op,
|
|
141
|
+
author: entry.author,
|
|
142
|
+
patch_ops: entry.patch.length,
|
|
143
|
+
changed_fields: sortedFields,
|
|
144
|
+
changes,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=history-diff.js.map
|
|
152
|
+
//# debugId=2b77be38-f27c-5a56-86de-9625777f7211
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-diff.js","sources":["core/history/history-diff.ts"],"sourceRoot":"/","sourcesContent":["import { cloneEmptyReplayDocument, tryApplyReplayPatch, type ReplayDocument } from \"./replay.js\";\nimport type { HistoryEntry } from \"../../types/index.js\";\n\nexport interface HistoryFieldChange {\n field: string;\n // before and after are the raw field values captured by replaying the history chain.\n // `undefined` is intentional: it signals that the field was absent in the document at\n // that point (e.g. after a JSON-Patch `remove` op). JSON serialization will omit\n // undefined values, which correctly communicates \"field did not exist\".\n before: unknown;\n after: unknown;\n}\n\nexport interface HistoryDiffValueEntry {\n /** 1-based position in the FULL stream (fullEntries index + 1). */\n index: number;\n ts: string;\n op: string;\n author: string;\n /** Number of JSON-patch operations in this entry (entry.patch.length). */\n patch_ops: number;\n /** Unique field names touched by this entry, sorted by localeCompare. */\n changed_fields: string[];\n /** Per-field before/after values, sorted by field name (localeCompare). */\n changes: HistoryFieldChange[];\n}\n\n// ---------------------------------------------------------------------------\n// JSON-Pointer helpers (ported from src/cli/commands/history.ts so the\n// orchestrator can replace the private copy there with an import from here).\n// ---------------------------------------------------------------------------\n\nfunction decodeJsonPointerSegment(segment: string): string {\n return segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n}\n\n/**\n * Map a JSON-Patch path string to a human-readable changed-field name.\n *\n * Rules (in priority order):\n * - \"/body\" or \"/body/…\" → \"body\"\n * - \"/metadata/…\" or \"/front_matter/…\"\n * with a first segment → that decoded segment (e.g. \"status\")\n * without a first segment (bare prefix) → \"metadata\"\n * - \"/\" (root pointer, empty segment after strip) → \"root\"\n * - anything else → decoded first path segment\n */\nexport function patchPathToChangedField(path: string): string {\n if (path === \"/body\" || path.startsWith(\"/body/\")) return \"body\";\n if (\n path === \"/metadata\" ||\n path.startsWith(\"/metadata/\") ||\n path === \"/front_matter\" ||\n path.startsWith(\"/front_matter/\")\n ) {\n const segment = path.replace(/^\\/(?:metadata|front_matter)\\/?/, \"\").split(\"/\")[0];\n if (!segment) return \"metadata\";\n return decodeJsonPointerSegment(segment);\n }\n const segment = path.replace(/^\\//, \"\").split(\"/\")[0];\n return segment ? decodeJsonPointerSegment(segment) : \"root\";\n}\n\n// ---------------------------------------------------------------------------\n// Field-value reader\n// ---------------------------------------------------------------------------\n\n/**\n * Extract the before/after value for a logical field from a replay document.\n *\n * - \"body\" → doc.body\n * - \"metadata\" → doc.metadata (the whole object, for a bare /metadata replace)\n * - \"root\" → the whole document (for a bare \"/\" patch op)\n * - other → doc.metadata[field] (may be undefined when the field was absent)\n */\nfunction readFieldValue(doc: ReplayDocument, field: string): unknown {\n if (field === \"body\") return doc.body;\n if (field === \"metadata\") return doc.metadata;\n if (field === \"root\") return doc;\n return doc.metadata[field];\n}\n\n// ---------------------------------------------------------------------------\n// Main export\n// ---------------------------------------------------------------------------\n\n/**\n * Replay a full history entry stream and produce enriched diff entries with\n * per-field before/after values.\n *\n * @param fullEntries The complete ordered history chain to replay.\n * @param options.windowStartIndex 0-based index into fullEntries at which the\n * DISPLAYED window begins. Entries before this index are still replayed (so\n * state is accurate) but are not emitted. Defaults to 0.\n * @param options.field When supplied, only entries that changed this field are\n * emitted, and each emitted entry's `changes` and `changed_fields` are\n * restricted to that single field.\n */\nexport function computeHistoryDiff(\n fullEntries: HistoryEntry[],\n options?: { windowStartIndex?: number; field?: string },\n): HistoryDiffValueEntry[] {\n const windowStartIndex = options?.windowStartIndex ?? 0;\n const fieldFilter = options?.field;\n\n if (fullEntries.length === 0 || windowStartIndex >= fullEntries.length) {\n return [];\n }\n\n let current = cloneEmptyReplayDocument();\n const result: HistoryDiffValueEntry[] = [];\n\n for (let p = 0; p < fullEntries.length; p += 1) {\n const entry = fullEntries[p];\n\n // Capture before state.\n const beforeDoc = current;\n\n // Attempt to apply patch.\n const applied = tryApplyReplayPatch(current, entry.patch);\n let afterDoc: ReplayDocument;\n if (applied.ok) {\n afterDoc = applied.document;\n current = afterDoc;\n } else {\n // Patch failed — use before state as after (cannot trust partial result).\n // Do NOT advance current; keep prior replay state.\n afterDoc = beforeDoc;\n }\n\n // Collect changed field names from patch paths (and from: paths for move/copy).\n const changedFieldSet = new Set<string>();\n for (const patchOp of entry.patch) {\n changedFieldSet.add(patchPathToChangedField(patchOp.path));\n if (patchOp.from !== undefined) {\n changedFieldSet.add(patchPathToChangedField(patchOp.from));\n }\n }\n const sortedFields = [...changedFieldSet].sort((a, b) => a.localeCompare(b));\n\n // Only emit entries in the display window.\n if (p >= windowStartIndex) {\n // Apply field filter: skip this entry entirely if it doesn't touch the\n // requested field; otherwise narrow down to only that field.\n if (fieldFilter !== undefined) {\n if (!changedFieldSet.has(fieldFilter)) {\n // This entry does not touch the requested field — skip it.\n continue;\n }\n // Emit only the filtered field.\n const change: HistoryFieldChange = {\n field: fieldFilter,\n before: readFieldValue(beforeDoc, fieldFilter),\n after: readFieldValue(afterDoc, fieldFilter),\n };\n result.push({\n index: p + 1,\n ts: entry.ts,\n op: entry.op,\n author: entry.author,\n patch_ops: entry.patch.length,\n changed_fields: [fieldFilter],\n changes: [change],\n });\n } else {\n // Emit all changed fields.\n const changes: HistoryFieldChange[] = sortedFields.map((field) => ({\n field,\n before: readFieldValue(beforeDoc, field),\n after: readFieldValue(afterDoc, field),\n }));\n result.push({\n index: p + 1,\n ts: entry.ts,\n op: entry.op,\n author: entry.author,\n patch_ops: entry.patch.length,\n changed_fields: sortedFields,\n changes,\n });\n }\n }\n }\n\n return result;\n}\n"],"names":[],"mappings":"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","debugId":"2b77be38-f27c-5a56-86de-9625777f7211"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure aggregate metrics for history streams (JSONL files).
|
|
3
|
+
* No filesystem access — callers read raw stream contents and pass them in.
|
|
4
|
+
* This module has no Node imports; Buffer is available as a global.
|
|
5
|
+
*/
|
|
6
|
+
export interface HistoryStreamStat {
|
|
7
|
+
id: string;
|
|
8
|
+
bytes: number;
|
|
9
|
+
lines: number;
|
|
10
|
+
oldest_ts: string | null;
|
|
11
|
+
newest_ts: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface HistoryStorageEntryRef {
|
|
14
|
+
id: string;
|
|
15
|
+
ts: string;
|
|
16
|
+
}
|
|
17
|
+
export interface HistoryStorageStats {
|
|
18
|
+
total_streams: number;
|
|
19
|
+
total_lines: number;
|
|
20
|
+
total_bytes: number;
|
|
21
|
+
largest_by_bytes: HistoryStreamStat[];
|
|
22
|
+
deepest_by_lines: HistoryStreamStat[];
|
|
23
|
+
oldest_entry: HistoryStorageEntryRef | null;
|
|
24
|
+
newest_entry: HistoryStorageEntryRef | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function computeHistoryStorageStats(streams: Array<{
|
|
27
|
+
id: string;
|
|
28
|
+
raw: string;
|
|
29
|
+
}>, options?: {
|
|
30
|
+
topN?: number;
|
|
31
|
+
}): HistoryStorageStats;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure aggregate metrics for history streams (JSONL files).
|
|
3
|
+
* No filesystem access — callers read raw stream contents and pass them in.
|
|
4
|
+
* This module has no Node imports; Buffer is available as a global.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
!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]="006b5d42-0ff6-57af-a598-4ca069ec316e")}catch(e){}}();
|
|
8
|
+
function parseStreamStat(id, raw) {
|
|
9
|
+
const bytes = Buffer.byteLength(raw, "utf8");
|
|
10
|
+
let lines = 0;
|
|
11
|
+
let oldestTs = null;
|
|
12
|
+
let newestTs = null;
|
|
13
|
+
let oldestMs = Number.POSITIVE_INFINITY;
|
|
14
|
+
let newestMs = Number.NEGATIVE_INFINITY;
|
|
15
|
+
for (const rawLine of raw.split(/\r?\n/)) {
|
|
16
|
+
const trimmed = rawLine.trim();
|
|
17
|
+
if (trimmed === "") {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
lines += 1;
|
|
21
|
+
let parsed;
|
|
22
|
+
try {
|
|
23
|
+
parsed = JSON.parse(trimmed);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (parsed === null ||
|
|
29
|
+
typeof parsed !== "object" ||
|
|
30
|
+
!("ts" in parsed) ||
|
|
31
|
+
typeof parsed["ts"] !== "string") {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const ts = parsed["ts"];
|
|
35
|
+
const ms = Date.parse(ts);
|
|
36
|
+
if (Number.isNaN(ms)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (ms < oldestMs || (ms === oldestMs && oldestTs !== null && ts < oldestTs)) {
|
|
40
|
+
oldestMs = ms;
|
|
41
|
+
oldestTs = ts;
|
|
42
|
+
}
|
|
43
|
+
if (ms > newestMs || (ms === newestMs && newestTs !== null && ts > newestTs)) {
|
|
44
|
+
newestMs = ms;
|
|
45
|
+
newestTs = ts;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { id, bytes, lines, oldest_ts: oldestTs, newest_ts: newestTs };
|
|
49
|
+
}
|
|
50
|
+
export function computeHistoryStorageStats(streams, options) {
|
|
51
|
+
const rawTopN = options?.topN ?? 5;
|
|
52
|
+
const topN = Math.max(0, Math.floor(rawTopN));
|
|
53
|
+
const stats = streams.map(({ id, raw }) => parseStreamStat(id, raw));
|
|
54
|
+
let totalLines = 0;
|
|
55
|
+
let totalBytes = 0;
|
|
56
|
+
let oldestEntry = null;
|
|
57
|
+
let newestEntry = null;
|
|
58
|
+
let globalOldestMs = Number.POSITIVE_INFINITY;
|
|
59
|
+
let globalNewestMs = Number.NEGATIVE_INFINITY;
|
|
60
|
+
for (const stat of stats) {
|
|
61
|
+
totalLines += stat.lines;
|
|
62
|
+
totalBytes += stat.bytes;
|
|
63
|
+
if (stat.oldest_ts !== null) {
|
|
64
|
+
const ms = Date.parse(stat.oldest_ts);
|
|
65
|
+
if (ms < globalOldestMs ||
|
|
66
|
+
(ms === globalOldestMs && oldestEntry !== null && stat.id < oldestEntry.id)) {
|
|
67
|
+
globalOldestMs = ms;
|
|
68
|
+
oldestEntry = { id: stat.id, ts: stat.oldest_ts };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (stat.newest_ts !== null) {
|
|
72
|
+
const ms = Date.parse(stat.newest_ts);
|
|
73
|
+
if (ms > globalNewestMs ||
|
|
74
|
+
(ms === globalNewestMs && newestEntry !== null && stat.id < newestEntry.id)) {
|
|
75
|
+
globalNewestMs = ms;
|
|
76
|
+
newestEntry = { id: stat.id, ts: stat.newest_ts };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const largestByBytes = topN === 0
|
|
81
|
+
? []
|
|
82
|
+
: [...stats]
|
|
83
|
+
.sort((a, b) => b.bytes - a.bytes || a.id.localeCompare(b.id))
|
|
84
|
+
.slice(0, topN);
|
|
85
|
+
const deepestByLines = topN === 0
|
|
86
|
+
? []
|
|
87
|
+
: [...stats]
|
|
88
|
+
.sort((a, b) => b.lines - a.lines || a.id.localeCompare(b.id))
|
|
89
|
+
.slice(0, topN);
|
|
90
|
+
return {
|
|
91
|
+
total_streams: streams.length,
|
|
92
|
+
total_lines: totalLines,
|
|
93
|
+
total_bytes: totalBytes,
|
|
94
|
+
largest_by_bytes: largestByBytes,
|
|
95
|
+
deepest_by_lines: deepestByLines,
|
|
96
|
+
oldest_entry: oldestEntry,
|
|
97
|
+
newest_entry: newestEntry,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=history-storage-stats.js.map
|
|
101
|
+
//# debugId=006b5d42-0ff6-57af-a598-4ca069ec316e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-storage-stats.js","sources":["core/history/history-storage-stats.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Pure aggregate metrics for history streams (JSONL files).\n * No filesystem access — callers read raw stream contents and pass them in.\n * This module has no Node imports; Buffer is available as a global.\n */\n\nexport interface HistoryStreamStat {\n id: string;\n bytes: number;\n lines: number; // non-empty JSONL entry count\n oldest_ts: string | null; // min parseable ts in this stream, else null\n newest_ts: string | null; // max parseable ts in this stream, else null\n}\n\nexport interface HistoryStorageEntryRef {\n id: string;\n ts: string;\n}\n\nexport interface HistoryStorageStats {\n total_streams: number;\n total_lines: number;\n total_bytes: number;\n largest_by_bytes: HistoryStreamStat[]; // top-N desc by bytes, tie-break id asc\n deepest_by_lines: HistoryStreamStat[]; // top-N desc by lines, tie-break id asc\n oldest_entry: HistoryStorageEntryRef | null; // global min ts across all streams\n newest_entry: HistoryStorageEntryRef | null; // global max ts across all streams\n}\n\nfunction parseStreamStat(id: string, raw: string): HistoryStreamStat {\n const bytes = Buffer.byteLength(raw, \"utf8\");\n\n let lines = 0;\n let oldestTs: string | null = null;\n let newestTs: string | null = null;\n let oldestMs = Number.POSITIVE_INFINITY;\n let newestMs = Number.NEGATIVE_INFINITY;\n\n for (const rawLine of raw.split(/\\r?\\n/)) {\n const trimmed = rawLine.trim();\n if (trimmed === \"\") {\n continue;\n }\n lines += 1;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n continue;\n }\n\n if (\n parsed === null ||\n typeof parsed !== \"object\" ||\n !(\"ts\" in (parsed as object)) ||\n typeof (parsed as Record<string, unknown>)[\"ts\"] !== \"string\"\n ) {\n continue;\n }\n\n const ts = (parsed as Record<string, unknown>)[\"ts\"] as string;\n const ms = Date.parse(ts);\n if (Number.isNaN(ms)) {\n continue;\n }\n\n if (ms < oldestMs || (ms === oldestMs && oldestTs !== null && ts < oldestTs)) {\n oldestMs = ms;\n oldestTs = ts;\n }\n if (ms > newestMs || (ms === newestMs && newestTs !== null && ts > newestTs)) {\n newestMs = ms;\n newestTs = ts;\n }\n }\n\n return { id, bytes, lines, oldest_ts: oldestTs, newest_ts: newestTs };\n}\n\nexport function computeHistoryStorageStats(\n streams: Array<{ id: string; raw: string }>,\n options?: { topN?: number },\n): HistoryStorageStats {\n const rawTopN = options?.topN ?? 5;\n const topN = Math.max(0, Math.floor(rawTopN));\n\n const stats: HistoryStreamStat[] = streams.map(({ id, raw }) => parseStreamStat(id, raw));\n\n let totalLines = 0;\n let totalBytes = 0;\n let oldestEntry: HistoryStorageEntryRef | null = null;\n let newestEntry: HistoryStorageEntryRef | null = null;\n let globalOldestMs = Number.POSITIVE_INFINITY;\n let globalNewestMs = Number.NEGATIVE_INFINITY;\n\n for (const stat of stats) {\n totalLines += stat.lines;\n totalBytes += stat.bytes;\n\n if (stat.oldest_ts !== null) {\n const ms = Date.parse(stat.oldest_ts);\n if (\n ms < globalOldestMs ||\n (ms === globalOldestMs && oldestEntry !== null && stat.id < oldestEntry.id)\n ) {\n globalOldestMs = ms;\n oldestEntry = { id: stat.id, ts: stat.oldest_ts };\n }\n }\n\n if (stat.newest_ts !== null) {\n const ms = Date.parse(stat.newest_ts);\n if (\n ms > globalNewestMs ||\n (ms === globalNewestMs && newestEntry !== null && stat.id < newestEntry.id)\n ) {\n globalNewestMs = ms;\n newestEntry = { id: stat.id, ts: stat.newest_ts };\n }\n }\n }\n\n const largestByBytes =\n topN === 0\n ? []\n : [...stats]\n .sort((a, b) => b.bytes - a.bytes || a.id.localeCompare(b.id))\n .slice(0, topN);\n\n const deepestByLines =\n topN === 0\n ? []\n : [...stats]\n .sort((a, b) => b.lines - a.lines || a.id.localeCompare(b.id))\n .slice(0, topN);\n\n return {\n total_streams: streams.length,\n total_lines: totalLines,\n total_bytes: totalBytes,\n largest_by_bytes: largestByBytes,\n deepest_by_lines: deepestByLines,\n oldest_entry: oldestEntry,\n newest_entry: newestEntry,\n };\n}\n"],"names":[],"mappings":"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","debugId":"006b5d42-0ff6-57af-a598-4ca069ec316e"}
|
package/dist/core/item/id.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="681913fe-dcec-59f2-a0dc-0f3578f11e37")}catch(e){}}();
|
|
3
3
|
import crypto from "node:crypto";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { TYPE_TO_FOLDER } from "../shared/constants.js";
|
|
@@ -26,10 +26,9 @@ export function normalizeItemId(input, prefix) {
|
|
|
26
26
|
return `${canonicalPrefix}${normalized}`;
|
|
27
27
|
}
|
|
28
28
|
function randomToken(length) {
|
|
29
|
-
const bytes = crypto.randomBytes(length);
|
|
30
29
|
let token = "";
|
|
31
|
-
for (
|
|
32
|
-
token += (
|
|
30
|
+
for (let index = 0; index < length; index += 1) {
|
|
31
|
+
token += crypto.randomInt(0, 36).toString(36);
|
|
33
32
|
}
|
|
34
33
|
return token;
|
|
35
34
|
}
|
|
@@ -61,4 +60,4 @@ export async function generateItemId(pmRoot, prefix) {
|
|
|
61
60
|
throw new Error(`Unable to generate unique id after ${attempts} attempts`);
|
|
62
61
|
}
|
|
63
62
|
//# sourceMappingURL=id.js.map
|
|
64
|
-
//# debugId=
|
|
63
|
+
//# debugId=681913fe-dcec-59f2-a0dc-0f3578f11e37
|