@juspay/shooter 1.17.0 → 1.19.0
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/build/client/_app/immutable/assets/{0.B0O0vCnX.css → 0.BwNtE8TX.css} +1 -1
- package/build/client/_app/immutable/assets/0.BwNtE8TX.css.br +0 -0
- package/build/client/_app/immutable/assets/{0.B0O0vCnX.css.gz → 0.BwNtE8TX.css.gz} +0 -0
- package/build/client/_app/immutable/assets/8.BYgAX7hR.css +1 -0
- package/build/client/_app/immutable/assets/8.BYgAX7hR.css.br +0 -0
- package/build/client/_app/immutable/assets/8.BYgAX7hR.css.gz +0 -0
- package/build/client/_app/immutable/assets/9.DV6pZunn.css +1 -0
- package/build/client/_app/immutable/assets/9.DV6pZunn.css.br +0 -0
- package/build/client/_app/immutable/assets/9.DV6pZunn.css.gz +0 -0
- package/build/client/_app/immutable/chunks/{DZQMsHM5.js → 2rBV5OkJ.js} +1 -1
- package/build/client/_app/immutable/chunks/2rBV5OkJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/2rBV5OkJ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BB2l8o4X.js +1 -0
- package/build/client/_app/immutable/chunks/BB2l8o4X.js.br +0 -0
- package/build/client/_app/immutable/chunks/BB2l8o4X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{Cg3dlX05.js → BPDiEZo0.js} +2 -2
- package/build/client/_app/immutable/chunks/BPDiEZo0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BPDiEZo0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{C_9BZILB.js → BcpydfqI.js} +1 -1
- package/build/client/_app/immutable/chunks/BcpydfqI.js.br +0 -0
- package/build/client/_app/immutable/chunks/BcpydfqI.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BcqA7eKM.js +3 -0
- package/build/client/_app/immutable/chunks/BcqA7eKM.js.br +0 -0
- package/build/client/_app/immutable/chunks/BcqA7eKM.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BdtLzPpO.js +1 -0
- package/build/client/_app/immutable/chunks/BdtLzPpO.js.br +0 -0
- package/build/client/_app/immutable/chunks/BdtLzPpO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BRqaaL5D.js → BvmdJful.js} +1 -1
- package/build/client/_app/immutable/chunks/BvmdJful.js.br +0 -0
- package/build/client/_app/immutable/chunks/BvmdJful.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{C5VOyQCG.js → ClIPTXf3.js} +1 -1
- package/build/client/_app/immutable/chunks/ClIPTXf3.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClIPTXf3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BctvtE4d.js → DA4Zt9Me.js} +1 -1
- package/build/client/_app/immutable/chunks/DA4Zt9Me.js.br +0 -0
- package/build/client/_app/immutable/chunks/{BctvtE4d.js.gz → DA4Zt9Me.js.gz} +0 -0
- package/build/client/_app/immutable/chunks/{CjfxuHdN.js → DCDL_9ys.js} +1 -1
- package/build/client/_app/immutable/chunks/DCDL_9ys.js.br +0 -0
- package/build/client/_app/immutable/chunks/DCDL_9ys.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DYuMZGL5.js → DWmC0QM7.js} +1 -1
- package/build/client/_app/immutable/chunks/DWmC0QM7.js.br +0 -0
- package/build/client/_app/immutable/chunks/DWmC0QM7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DZvnhU_8.js → ZS5XYDx_.js} +2 -2
- package/build/client/_app/immutable/chunks/ZS5XYDx_.js.br +0 -0
- package/build/client/_app/immutable/chunks/ZS5XYDx_.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.D4TXlu7A.js +2 -0
- package/build/client/_app/immutable/entry/app.D4TXlu7A.js.br +0 -0
- package/build/client/_app/immutable/entry/app.D4TXlu7A.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BBQhtURO.js +1 -0
- package/build/client/_app/immutable/entry/start.BBQhtURO.js.br +0 -0
- package/build/client/_app/immutable/entry/start.BBQhtURO.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.1zylwAPT.js +10 -0
- package/build/client/_app/immutable/nodes/0.1zylwAPT.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.1zylwAPT.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.Fqso94b3.js → 1.BVnLUSs-.js} +1 -1
- package/build/client/_app/immutable/nodes/1.BVnLUSs-.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BVnLUSs-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{8.BjKgvSie.js → 10.D1wl2wPX.js} +2 -2
- package/build/client/_app/immutable/nodes/10.D1wl2wPX.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.D1wl2wPX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{9.BRT6HOXB.js → 11.C18nMGmp.js} +1 -1
- package/build/client/_app/immutable/nodes/11.C18nMGmp.js.br +0 -0
- package/build/client/_app/immutable/nodes/11.C18nMGmp.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.BusCVJWk.js → 2.D1Mm0DUX.js} +2 -2
- package/build/client/_app/immutable/nodes/2.D1Mm0DUX.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.D1Mm0DUX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.DUlpocIc.js → 3.Wfz3TcJd.js} +3 -3
- package/build/client/_app/immutable/nodes/3.Wfz3TcJd.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.Wfz3TcJd.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{4.BSVqdrrD.js → 4.CBX9A3ka.js} +2 -2
- package/build/client/_app/immutable/nodes/4.CBX9A3ka.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.CBX9A3ka.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{5.Cfj35gpY.js → 5.DIVKuZc9.js} +1 -1
- package/build/client/_app/immutable/nodes/5.DIVKuZc9.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.DIVKuZc9.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.CG4eKRH0.js → 6.DtZAEPXb.js} +1 -1
- package/build/client/_app/immutable/nodes/6.DtZAEPXb.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.DtZAEPXb.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{7.DHilxD1o.js → 7.MfBRh32I.js} +1 -1
- package/build/client/_app/immutable/nodes/7.MfBRh32I.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.MfBRh32I.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.DVE6LnOC.js +1 -0
- package/build/client/_app/immutable/nodes/8.DVE6LnOC.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.DVE6LnOC.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.BCel5OqI.js +2 -0
- package/build/client/_app/immutable/nodes/9.BCel5OqI.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.BCel5OqI.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{0-BWFSL107.js → 0-DJqyZZTr.js} +4 -4
- package/build/server/chunks/{0-BWFSL107.js.map → 0-DJqyZZTr.js.map} +1 -1
- package/build/server/chunks/1-2YUVen1F.js +9 -0
- package/build/server/chunks/{1-Bw5KlAjL.js.map → 1-2YUVen1F.js.map} +1 -1
- package/build/server/chunks/10-D1X7LB3v.js +9 -0
- package/build/server/chunks/10-D1X7LB3v.js.map +1 -0
- package/build/server/chunks/11-qXSPdF5j.js +9 -0
- package/build/server/chunks/11-qXSPdF5j.js.map +1 -0
- package/build/server/chunks/{2-CQ3yYSVK.js → 2-BD7kj1mt.js} +3 -3
- package/build/server/chunks/{2-CQ3yYSVK.js.map → 2-BD7kj1mt.js.map} +1 -1
- package/build/server/chunks/{3-DZ4H9hPs.js → 3-oNjv-BhZ.js} +3 -3
- package/build/server/chunks/{3-DZ4H9hPs.js.map → 3-oNjv-BhZ.js.map} +1 -1
- package/build/server/chunks/{4-BtYdKCVW.js → 4-Bb5VFhsO.js} +3 -3
- package/build/server/chunks/{4-BtYdKCVW.js.map → 4-Bb5VFhsO.js.map} +1 -1
- package/build/server/chunks/{5-CvJK3PiH.js → 5-oNoWuIsn.js} +3 -3
- package/build/server/chunks/{5-CvJK3PiH.js.map → 5-oNoWuIsn.js.map} +1 -1
- package/build/server/chunks/6-DRJGUqHG.js +9 -0
- package/build/server/chunks/{6-BZ0enR6b.js.map → 6-DRJGUqHG.js.map} +1 -1
- package/build/server/chunks/7-_giJiu0L.js +9 -0
- package/build/server/chunks/{7-Lg8imTZn.js.map → 7-_giJiu0L.js.map} +1 -1
- package/build/server/chunks/8-zvWAVNT5.js +9 -0
- package/build/server/chunks/8-zvWAVNT5.js.map +1 -0
- package/build/server/chunks/9-DVyDL445.js +9 -0
- package/build/server/chunks/9-DVyDL445.js.map +1 -0
- package/build/server/chunks/Banner-BgaAs1rs.js +90 -0
- package/build/server/chunks/Banner-BgaAs1rs.js.map +1 -0
- package/build/server/chunks/{Button-B5dU-ntz.js → Button-D0hZ7JYt.js} +2 -2
- package/build/server/chunks/Button-D0hZ7JYt.js.map +1 -0
- package/build/server/chunks/{Icon-C7Ml3GX6.js → Icon-D0GBnDcs.js} +3 -3
- package/build/server/chunks/Icon-D0GBnDcs.js.map +1 -0
- package/build/server/chunks/{Input-CPGO0sbS.js → Input-OmIiydSx.js} +2 -2
- package/build/server/chunks/Input-OmIiydSx.js.map +1 -0
- package/build/server/chunks/{Pill-CcrtCejm.js → Pill-4xJ-VhAA.js} +3 -3
- package/build/server/chunks/Pill-4xJ-VhAA.js.map +1 -0
- package/build/server/chunks/{Shimmer-C5jkvGr1.js → Shimmer-Dw2uvTC1.js} +2 -2
- package/build/server/chunks/Shimmer-Dw2uvTC1.js.map +1 -0
- package/build/server/chunks/{_error.svelte-CSIxs-ab.js → _error.svelte-CZnkxeLr.js} +8 -8
- package/build/server/chunks/{_error.svelte-CSIxs-ab.js.map → _error.svelte-CZnkxeLr.js.map} +1 -1
- package/build/server/chunks/{_layout.svelte-noB4j-v2.js → _layout.svelte-DfgNGGiM.js} +16 -11
- package/build/server/chunks/_layout.svelte-DfgNGGiM.js.map +1 -0
- package/build/server/chunks/{_page.svelte-DnTpPnPR.js → _page.svelte-BLo2v_8E.js} +7 -88
- package/build/server/chunks/_page.svelte-BLo2v_8E.js.map +1 -0
- package/build/server/chunks/_page.svelte-BTlfUsBp.js +43 -0
- package/build/server/chunks/_page.svelte-BTlfUsBp.js.map +1 -0
- package/build/server/chunks/{_page.svelte-C60lAagP.js → _page.svelte-BUBLUSGo.js} +8 -8
- package/build/server/chunks/_page.svelte-BUBLUSGo.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BV0XyYJZ.js → _page.svelte-BX2FMgSg.js} +4 -4
- package/build/server/chunks/{_page.svelte-BV0XyYJZ.js.map → _page.svelte-BX2FMgSg.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-BUkm2304.js → _page.svelte-C7B0qdrC.js} +5 -5
- package/build/server/chunks/{_page.svelte-BUkm2304.js.map → _page.svelte-C7B0qdrC.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-Dmg-RFCg.js → _page.svelte-CE7COWnF.js} +7 -7
- package/build/server/chunks/{_page.svelte-Dmg-RFCg.js.map → _page.svelte-CE7COWnF.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-BfB8maoc.js → _page.svelte-CWsjjd4l.js} +9 -9
- package/build/server/chunks/{_page.svelte-BfB8maoc.js.map → _page.svelte-CWsjjd4l.js.map} +1 -1
- package/build/server/chunks/_page.svelte-D5S2hkBk.js +104 -0
- package/build/server/chunks/_page.svelte-D5S2hkBk.js.map +1 -0
- package/build/server/chunks/{_page.svelte-B6qyh-K-.js → _page.svelte-D_Ey8QRG.js} +11 -11
- package/build/server/chunks/{_page.svelte-B6qyh-K-.js.map → _page.svelte-D_Ey8QRG.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-DuzZr5dA.js → _page.svelte-tBuIq8Pg.js} +11 -11
- package/build/server/chunks/{_page.svelte-DuzZr5dA.js.map → _page.svelte-tBuIq8Pg.js.map} +1 -1
- package/build/server/chunks/_server.ts-BaaY7Z9D.js +77 -0
- package/build/server/chunks/_server.ts-BaaY7Z9D.js.map +1 -0
- package/build/server/chunks/{_server.ts-5wx4ZppI.js → _server.ts-Bi0Oe4PF.js} +7 -4
- package/build/server/chunks/_server.ts-Bi0Oe4PF.js.map +1 -0
- package/build/server/chunks/_server.ts-C0317RBD.js +57 -0
- package/build/server/chunks/_server.ts-C0317RBD.js.map +1 -0
- package/build/server/chunks/{_server.ts-CKXVBbwb.js → _server.ts-CRVNEOd2.js} +10 -8
- package/build/server/chunks/_server.ts-CRVNEOd2.js.map +1 -0
- package/build/server/chunks/_server.ts-CVPZOpiv.js +23 -0
- package/build/server/chunks/_server.ts-CVPZOpiv.js.map +1 -0
- package/build/server/chunks/{_server.ts-CyjDrcZN.js → _server.ts-C_OOUqsd.js} +9 -1
- package/build/server/chunks/_server.ts-C_OOUqsd.js.map +1 -0
- package/build/server/chunks/{_server.ts-BMMTS86y.js → _server.ts-D9ir7u24.js} +3 -4
- package/build/server/chunks/{_server.ts-BMMTS86y.js.map → _server.ts-D9ir7u24.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DZ5naqSL.js → _server.ts-DMm0hBP4.js} +5 -1
- package/build/server/chunks/_server.ts-DMm0hBP4.js.map +1 -0
- package/build/server/chunks/{_server.ts-CgHc1Zpx.js → _server.ts-DhJx0DLr.js} +7 -4
- package/build/server/chunks/_server.ts-DhJx0DLr.js.map +1 -0
- package/build/server/chunks/_server.ts-DkZX_O9a.js +39 -0
- package/build/server/chunks/_server.ts-DkZX_O9a.js.map +1 -0
- package/build/server/chunks/{_server.ts-B1z0q6qZ.js → _server.ts-DxT9IlZF.js} +6 -5
- package/build/server/chunks/_server.ts-DxT9IlZF.js.map +1 -0
- package/build/server/chunks/{_server.ts-Bt7EAfjo.js → _server.ts-MbnroWEF.js} +25 -48
- package/build/server/chunks/_server.ts-MbnroWEF.js.map +1 -0
- package/build/server/chunks/_server.ts-Mttr0-Sl.js +48 -0
- package/build/server/chunks/_server.ts-Mttr0-Sl.js.map +1 -0
- package/build/server/chunks/_server.ts-jtqWDWcf.js +45 -0
- package/build/server/chunks/_server.ts-jtqWDWcf.js.map +1 -0
- package/build/server/chunks/{cache-Me3zUAaD.js → cache-BlMaDsHi.js} +2 -2
- package/build/server/chunks/{cache-Me3zUAaD.js.map → cache-BlMaDsHi.js.map} +1 -1
- package/build/server/chunks/{client-CfNnl32g.js → client-Ds1brw-8.js} +4 -4
- package/build/server/chunks/{client-CfNnl32g.js.map → client-Ds1brw-8.js.map} +1 -1
- package/build/server/chunks/client2-DngLdcUc.js +7 -0
- package/build/server/chunks/{client2-DDP30_vY.js.map → client2-DngLdcUc.js.map} +1 -1
- package/build/server/chunks/coordinator-DMU_ADXf.js +530 -0
- package/build/server/chunks/coordinator-DMU_ADXf.js.map +1 -0
- package/build/server/chunks/{index-CJrGuxuM.js → index-CoYB03g7.js} +2 -2
- package/build/server/chunks/{index-CJrGuxuM.js.map → index-CoYB03g7.js.map} +1 -1
- package/build/server/chunks/{index-server--49oHtA0.js → index-server-Bq3cnK69.js} +2 -2
- package/build/server/chunks/{index-server--49oHtA0.js.map → index-server-Bq3cnK69.js.map} +1 -1
- package/build/server/chunks/{index2-MY7PXeAc.js → index2-dSGQ9Eaa.js} +2 -2
- package/build/server/chunks/{index2-MY7PXeAc.js.map → index2-dSGQ9Eaa.js.map} +1 -1
- package/build/server/chunks/{pty-manager-RmhVe2Ez.js → pty-manager-41h3IK8K.js} +100 -2
- package/build/server/chunks/pty-manager-41h3IK8K.js.map +1 -0
- package/build/server/chunks/qwen-reader-DGfUbKaJ.js +2112 -0
- package/build/server/chunks/qwen-reader-DGfUbKaJ.js.map +1 -0
- package/build/server/chunks/{registry-DzJj2E6I.js → registry-D4J_CuzW.js} +56 -24
- package/build/server/chunks/registry-D4J_CuzW.js.map +1 -0
- package/build/server/chunks/{root-xvQIR1Bt.js → root-D4IoFC8F.js} +2 -2
- package/build/server/chunks/root-D4IoFC8F.js.map +1 -0
- package/build/server/chunks/{state.svelte-RCtlkrNH.js → state.svelte-CmHqngc_.js} +3 -3
- package/build/server/chunks/{state.svelte-RCtlkrNH.js.map → state.svelte-CmHqngc_.js.map} +1 -1
- package/build/server/chunks/{stores-C-LqoonT.js → stores-CRYxfF0o.js} +4 -4
- package/build/server/chunks/stores-CRYxfF0o.js.map +1 -0
- package/build/server/chunks/super-session-handler-DPyxFgmz.js +22 -0
- package/build/server/chunks/super-session-handler-DPyxFgmz.js.map +1 -0
- package/build/server/index.js +4 -4
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +79 -21
- package/build/server/manifest.js.map +1 -1
- package/package.json +2 -2
- package/scripts/e2e-all-features.sh +204 -0
- package/scripts/e2e-cross-terminal.sh +168 -0
- package/server.ts +37 -0
- package/src/lib/modules/client/common/provider.ts +0 -2
- package/src/lib/modules/client/terminal/ChatView.svelte +9 -2
- package/src/lib/modules/client/terminal/LaunchSheet.svelte +3 -0
- package/src/lib/modules/server/sessions/amp-reader.ts +439 -0
- package/src/lib/modules/server/sessions/copilot-reader.ts +542 -0
- package/src/lib/modules/server/sessions/cursor-reader.ts +634 -0
- package/src/lib/modules/server/sessions/gemini-reader.ts +48 -25
- package/src/lib/modules/server/sessions/opencode-reader.ts +13 -12
- package/src/lib/modules/server/sessions/process-detector.ts +37 -60
- package/src/lib/modules/server/sessions/provider-paths.ts +173 -0
- package/src/lib/modules/server/sessions/qwen-reader.ts +41 -15
- package/src/lib/modules/server/sessions/registry.ts +55 -14
- package/src/lib/modules/server/sos/coordinator.ts +492 -0
- package/src/lib/modules/server/sos/policy-gate.ts +56 -0
- package/src/lib/modules/server/sos/relay-store.ts +159 -0
- package/src/lib/modules/server/terminal/generic-session-watcher.ts +163 -0
- package/src/lib/modules/server/terminal/pty-input.ts +37 -0
- package/src/lib/modules/server/terminal/pty-manager.ts +51 -0
- package/src/lib/modules/server/ws/server.ts +6 -1
- package/src/lib/modules/server/ws/session-handler.ts +17 -2
- package/src/lib/modules/server/ws/super-session-handler.ts +200 -0
- package/src/lib/theme.css +1 -2
- package/src/lib/types/generated/Sessions.ts +1 -4
- package/src/lib/types/index.ts +2 -1
- package/src/lib/types/server.ts +23 -6
- package/src/lib/types/sessions.ts +1 -10
- package/src/lib/types/sos.ts +134 -0
- package/src/routes/+layout.svelte +9 -2
- package/src/routes/api/sessions/connect/+server.ts +7 -3
- package/src/routes/api/sos/+server.ts +36 -0
- package/src/routes/api/sos/[id]/+server.ts +55 -0
- package/src/routes/api/sos/[id]/inject/+server.ts +44 -0
- package/src/routes/api/sos/[id]/members/+server.ts +47 -0
- package/src/routes/api/sos/[id]/members/[mid]/+server.ts +17 -0
- package/src/routes/api/sos/[id]/rules/+server.ts +85 -0
- package/src/routes/sos/+page.svelte +195 -0
- package/src/routes/sos/[id]/+page.svelte +677 -0
- package/build/client/_app/immutable/assets/0.B0O0vCnX.css.br +0 -0
- package/build/client/_app/immutable/chunks/BRqaaL5D.js.br +0 -0
- package/build/client/_app/immutable/chunks/BRqaaL5D.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BctvtE4d.js.br +0 -0
- package/build/client/_app/immutable/chunks/BxFShcQO.js +0 -1
- package/build/client/_app/immutable/chunks/BxFShcQO.js.br +0 -0
- package/build/client/_app/immutable/chunks/BxFShcQO.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ByzqAuXw.js +0 -3
- package/build/client/_app/immutable/chunks/ByzqAuXw.js.br +0 -0
- package/build/client/_app/immutable/chunks/ByzqAuXw.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C5VOyQCG.js.br +0 -0
- package/build/client/_app/immutable/chunks/C5VOyQCG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C_9BZILB.js.br +0 -0
- package/build/client/_app/immutable/chunks/C_9BZILB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cg3dlX05.js.br +0 -0
- package/build/client/_app/immutable/chunks/Cg3dlX05.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CjfxuHdN.js.br +0 -0
- package/build/client/_app/immutable/chunks/CjfxuHdN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DYuMZGL5.js.br +0 -0
- package/build/client/_app/immutable/chunks/DYuMZGL5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DZQMsHM5.js.br +0 -0
- package/build/client/_app/immutable/chunks/DZQMsHM5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DZvnhU_8.js.br +0 -0
- package/build/client/_app/immutable/chunks/DZvnhU_8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Pw0jDB7M.js +0 -1
- package/build/client/_app/immutable/chunks/Pw0jDB7M.js.br +0 -0
- package/build/client/_app/immutable/chunks/Pw0jDB7M.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CNaTe-zm.js +0 -2
- package/build/client/_app/immutable/entry/app.CNaTe-zm.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CNaTe-zm.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.hxYnjcDu.js +0 -1
- package/build/client/_app/immutable/entry/start.hxYnjcDu.js.br +0 -0
- package/build/client/_app/immutable/entry/start.hxYnjcDu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.C3ELOf4c.js +0 -7
- package/build/client/_app/immutable/nodes/0.C3ELOf4c.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.C3ELOf4c.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.Fqso94b3.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.Fqso94b3.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BusCVJWk.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BusCVJWk.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.DUlpocIc.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.DUlpocIc.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BSVqdrrD.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BSVqdrrD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.Cfj35gpY.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.Cfj35gpY.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.CG4eKRH0.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.CG4eKRH0.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.DHilxD1o.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.DHilxD1o.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.BjKgvSie.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.BjKgvSie.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.BRT6HOXB.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.BRT6HOXB.js.gz +0 -0
- package/build/server/chunks/1-Bw5KlAjL.js +0 -9
- package/build/server/chunks/6-BZ0enR6b.js +0 -9
- package/build/server/chunks/7-Lg8imTZn.js +0 -9
- package/build/server/chunks/8-DKs4yOL7.js +0 -9
- package/build/server/chunks/8-DKs4yOL7.js.map +0 -1
- package/build/server/chunks/9-UNmpUWDY.js +0 -9
- package/build/server/chunks/9-UNmpUWDY.js.map +0 -1
- package/build/server/chunks/Button-B5dU-ntz.js.map +0 -1
- package/build/server/chunks/Icon-C7Ml3GX6.js.map +0 -1
- package/build/server/chunks/Input-CPGO0sbS.js.map +0 -1
- package/build/server/chunks/Pill-CcrtCejm.js.map +0 -1
- package/build/server/chunks/Shimmer-C5jkvGr1.js.map +0 -1
- package/build/server/chunks/_layout.svelte-noB4j-v2.js.map +0 -1
- package/build/server/chunks/_page.svelte-C60lAagP.js.map +0 -1
- package/build/server/chunks/_page.svelte-DnTpPnPR.js.map +0 -1
- package/build/server/chunks/_server.ts-5wx4ZppI.js.map +0 -1
- package/build/server/chunks/_server.ts-B1z0q6qZ.js.map +0 -1
- package/build/server/chunks/_server.ts-Bt7EAfjo.js.map +0 -1
- package/build/server/chunks/_server.ts-CKXVBbwb.js.map +0 -1
- package/build/server/chunks/_server.ts-CgHc1Zpx.js.map +0 -1
- package/build/server/chunks/_server.ts-CyjDrcZN.js.map +0 -1
- package/build/server/chunks/_server.ts-DZ5naqSL.js.map +0 -1
- package/build/server/chunks/client2-DDP30_vY.js +0 -7
- package/build/server/chunks/opencode-db-path-BwaPufWf.js +0 -411
- package/build/server/chunks/opencode-db-path-BwaPufWf.js.map +0 -1
- package/build/server/chunks/pty-manager-RmhVe2Ez.js.map +0 -1
- package/build/server/chunks/qwen-reader-2fTFuC_D.js +0 -622
- package/build/server/chunks/qwen-reader-2fTFuC_D.js.map +0 -1
- package/build/server/chunks/registry-DzJj2E6I.js.map +0 -1
- package/build/server/chunks/root-xvQIR1Bt.js.map +0 -1
- package/build/server/chunks/stores-C-LqoonT.js.map +0 -1
- /package/build/client/_app/immutable/assets/{8.BhoBXADL.css → 10.BhoBXADL.css} +0 -0
- /package/build/client/_app/immutable/assets/{8.BhoBXADL.css.br → 10.BhoBXADL.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{8.BhoBXADL.css.gz → 10.BhoBXADL.css.gz} +0 -0
- /package/build/client/_app/immutable/assets/{9.v5KA95xm.css → 11.v5KA95xm.css} +0 -0
- /package/build/client/_app/immutable/assets/{9.v5KA95xm.css.br → 11.v5KA95xm.css.br} +0 -0
- /package/build/client/_app/immutable/assets/{9.v5KA95xm.css.gz → 11.v5KA95xm.css.gz} +0 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Amp session reader — listing + conversation retrieval.
|
|
3
|
+
*
|
|
4
|
+
* Amp stores one JSON document per thread at:
|
|
5
|
+
* ~/.local/share/amp/threads/T-<id>.json
|
|
6
|
+
*
|
|
7
|
+
* Document shape:
|
|
8
|
+
* { id, title, created, messages: [{role, content}],
|
|
9
|
+
* meta: { traces: [{endTime}] },
|
|
10
|
+
* env: { initial: { trees: [{displayName}] } } }
|
|
11
|
+
*
|
|
12
|
+
* `content` is either a plain string or an array of Anthropic-style blocks
|
|
13
|
+
* (text / thinking / tool_use / tool_result), so we handle both paths.
|
|
14
|
+
* The file is a single JSON document — skip files larger than 64 MB.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { ConversationMessage, MessagePart, ProjectGroup, SessionInfo } from '$lib/types';
|
|
18
|
+
|
|
19
|
+
import * as crypto from 'crypto';
|
|
20
|
+
import * as fs from 'fs';
|
|
21
|
+
import { homedir } from 'os';
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Constants
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
const AMP_THREADS = path.join(homedir(), '.local', 'share', 'amp', 'threads');
|
|
29
|
+
|
|
30
|
+
/** Single JSON document — skip (do not truncate) if larger than this. */
|
|
31
|
+
const MAX_FILE_BYTES = 64 * 1024 * 1024;
|
|
32
|
+
|
|
33
|
+
/** Pattern for valid thread file names: T-<id>.json */
|
|
34
|
+
const THREAD_FILE_RE = /^T-(.+)\.json$/;
|
|
35
|
+
|
|
36
|
+
/** Only allow these chars in a sessionId used to build a path. */
|
|
37
|
+
const SESSION_ID_RE = /^[A-Za-z0-9_.-]+$/;
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Public API
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Return sessions whose thread file mtime is within `thresholdMs` of now —
|
|
45
|
+
* i.e. sessions that are currently (or very recently) active.
|
|
46
|
+
*/
|
|
47
|
+
export function detectActiveAmpSessions(
|
|
48
|
+
thresholdMs: number
|
|
49
|
+
): { cwd: string; id: string; startedAt: number }[] {
|
|
50
|
+
const cutoff = Date.now() - thresholdMs;
|
|
51
|
+
const out: { cwd: string; id: string; startedAt: number }[] = [];
|
|
52
|
+
for (const filePath of collectThreadFiles()) {
|
|
53
|
+
try {
|
|
54
|
+
const stat = fs.statSync(filePath);
|
|
55
|
+
if (stat.mtimeMs < cutoff) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const doc = readThreadDoc(filePath);
|
|
59
|
+
if (!doc) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const id = threadId(filePath, doc);
|
|
63
|
+
const cwd = projectCwd(doc);
|
|
64
|
+
if (id && cwd) {
|
|
65
|
+
out.push({ cwd, id, startedAt: stat.birthtimeMs });
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
// skip unreadable files
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Return the conversation messages for a given Amp thread ID.
|
|
76
|
+
* Mirrors the pagination pattern from codex-reader / qwen-reader.
|
|
77
|
+
*/
|
|
78
|
+
export function getAmpConversation(
|
|
79
|
+
sessionId: string,
|
|
80
|
+
offset = 0,
|
|
81
|
+
limit = 200
|
|
82
|
+
): ConversationMessage[] {
|
|
83
|
+
if (!SESSION_ID_RE.test(sessionId)) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const filePath = path.join(AMP_THREADS, `T-${sessionId}.json`);
|
|
87
|
+
if (!fs.existsSync(filePath)) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const doc = readThreadDoc(filePath);
|
|
92
|
+
if (!doc) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
const rawMessages = Array.isArray(doc.messages) ? (doc.messages as unknown[]) : [];
|
|
96
|
+
const messages: ConversationMessage[] = [];
|
|
97
|
+
let idx = 0;
|
|
98
|
+
for (const raw of rawMessages) {
|
|
99
|
+
const msg = ampMessageToConversationMessage(raw, idx);
|
|
100
|
+
if (msg) {
|
|
101
|
+
messages.push(msg);
|
|
102
|
+
idx++;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (offset === 0 && messages.length > limit) {
|
|
106
|
+
let startIdx = messages.length - limit;
|
|
107
|
+
while (startIdx > 0 && messages[startIdx]?.role !== 'user') {
|
|
108
|
+
startIdx--;
|
|
109
|
+
}
|
|
110
|
+
return messages.slice(startIdx);
|
|
111
|
+
}
|
|
112
|
+
return messages.slice(offset, offset + limit);
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error('[amp] Failed to read conversation:', err);
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* List all Amp threads grouped by project (env.initial.trees[0].displayName),
|
|
121
|
+
* sorted by most-recently-modified first.
|
|
122
|
+
*/
|
|
123
|
+
export function listAmpProjects(): ProjectGroup[] {
|
|
124
|
+
const byCwd = new Map<string, SessionInfo[]>();
|
|
125
|
+
for (const filePath of collectThreadFiles()) {
|
|
126
|
+
let stat: fs.Stats;
|
|
127
|
+
try {
|
|
128
|
+
stat = fs.statSync(filePath);
|
|
129
|
+
} catch {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const doc = readThreadDoc(filePath);
|
|
133
|
+
if (!doc) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const id = threadId(filePath, doc);
|
|
137
|
+
if (!id) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const cwd = projectCwd(doc) || id;
|
|
141
|
+
const modified = lastModified(doc, stat);
|
|
142
|
+
const created =
|
|
143
|
+
typeof doc.created === 'string' && doc.created ? doc.created : stat.birthtime.toISOString();
|
|
144
|
+
const rawMessages = Array.isArray(doc.messages) ? (doc.messages as unknown[]) : [];
|
|
145
|
+
const session: SessionInfo = {
|
|
146
|
+
created,
|
|
147
|
+
gitBranch: '',
|
|
148
|
+
id,
|
|
149
|
+
messageCount: rawMessages.length,
|
|
150
|
+
modified,
|
|
151
|
+
projectPath: cwd,
|
|
152
|
+
source: 'amp' as const,
|
|
153
|
+
summary: '',
|
|
154
|
+
title: cleanTitle(typeof doc.title === 'string' ? doc.title : ''),
|
|
155
|
+
};
|
|
156
|
+
const bucket = byCwd.get(cwd);
|
|
157
|
+
if (bucket) {
|
|
158
|
+
bucket.push(session);
|
|
159
|
+
} else {
|
|
160
|
+
byCwd.set(cwd, [session]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const projects: ProjectGroup[] = [];
|
|
165
|
+
for (const [cwd, sessions] of byCwd) {
|
|
166
|
+
sessions.sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());
|
|
167
|
+
const segments = cwd.split('/').filter(Boolean);
|
|
168
|
+
projects.push({
|
|
169
|
+
fullPath: cwd,
|
|
170
|
+
id: shortHash(cwd),
|
|
171
|
+
lastModified: sessions[0]?.modified ?? '',
|
|
172
|
+
name: segments.slice(-2).join('/') || cwd,
|
|
173
|
+
sessionCount: sessions.length,
|
|
174
|
+
sessions,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return projects.sort(
|
|
178
|
+
(a, b) => new Date(b.lastModified).getTime() - new Date(a.lastModified).getTime()
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Parse the Amp thread JSON file at `filePath` and return the full list of
|
|
184
|
+
* ConversationMessage — no pagination or tail-limit applied.
|
|
185
|
+
* Returns `[]` on any error (missing file, malformed JSON, oversized file).
|
|
186
|
+
*/
|
|
187
|
+
export function parseAmpSessionFile(filePath: string): ConversationMessage[] {
|
|
188
|
+
try {
|
|
189
|
+
const doc = readThreadDoc(filePath);
|
|
190
|
+
if (!doc) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const rawMessages = Array.isArray(doc.messages) ? (doc.messages as unknown[]) : [];
|
|
194
|
+
const messages: ConversationMessage[] = [];
|
|
195
|
+
let idx = 0;
|
|
196
|
+
for (const raw of rawMessages) {
|
|
197
|
+
const msg = ampMessageToConversationMessage(raw, idx);
|
|
198
|
+
if (msg) {
|
|
199
|
+
messages.push(msg);
|
|
200
|
+
idx++;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return messages;
|
|
204
|
+
} catch {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Return the absolute path of the Amp thread file for `sessionId`, or `null`
|
|
211
|
+
* if the session ID is invalid or the file does not exist.
|
|
212
|
+
*/
|
|
213
|
+
export function resolveAmpSessionFile(sessionId: string): null | string {
|
|
214
|
+
if (!SESSION_ID_RE.test(sessionId)) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
const filePath = path.join(AMP_THREADS, `T-${sessionId}.json`);
|
|
218
|
+
return fs.existsSync(filePath) ? filePath : null;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Block → MessagePart mapping (Anthropic-style blocks)
|
|
223
|
+
// ---------------------------------------------------------------------------
|
|
224
|
+
|
|
225
|
+
/** Map one Anthropic-style content block to a MessagePart, or null to skip. */
|
|
226
|
+
function ampBlockToPart(block: Record<string, unknown>): MessagePart | null {
|
|
227
|
+
switch (block.type) {
|
|
228
|
+
case 'text':
|
|
229
|
+
return { content: typeof block.text === 'string' ? block.text : '', type: 'text' };
|
|
230
|
+
case 'thinking':
|
|
231
|
+
return {
|
|
232
|
+
content: typeof block.thinking === 'string' ? block.thinking : '',
|
|
233
|
+
type: 'thinking',
|
|
234
|
+
};
|
|
235
|
+
case 'tool_result': {
|
|
236
|
+
const output = extractToolResultText(block.content);
|
|
237
|
+
return {
|
|
238
|
+
isError: typeof block.is_error === 'boolean' ? block.is_error : false,
|
|
239
|
+
output: output.slice(0, 2000),
|
|
240
|
+
toolUseId: typeof block.tool_use_id === 'string' ? block.tool_use_id : '',
|
|
241
|
+
type: 'tool_result',
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
case 'tool_use':
|
|
245
|
+
return {
|
|
246
|
+
id: typeof block.id === 'string' ? block.id : '',
|
|
247
|
+
input: isRecord(block.input) ? block.input : {},
|
|
248
|
+
toolName: typeof block.name === 'string' ? block.name : 'tool',
|
|
249
|
+
type: 'tool_use',
|
|
250
|
+
};
|
|
251
|
+
default:
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Map one raw Amp message object to a ConversationMessage, or null to skip. */
|
|
257
|
+
function ampMessageToConversationMessage(raw: unknown, index: number): ConversationMessage | null {
|
|
258
|
+
if (!isRecord(raw)) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
const role = raw.role;
|
|
262
|
+
if (role !== 'user' && role !== 'assistant') {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
const parts = contentToParts(raw.content);
|
|
266
|
+
if (parts.length === 0) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
const msgRole: 'assistant' | 'user' = role === 'user' ? 'user' : 'assistant';
|
|
270
|
+
return {
|
|
271
|
+
id: `amp-${msgRole}-${index}`,
|
|
272
|
+
parts,
|
|
273
|
+
role: msgRole,
|
|
274
|
+
timestamp: '',
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ---------------------------------------------------------------------------
|
|
279
|
+
// File I/O helpers
|
|
280
|
+
// ---------------------------------------------------------------------------
|
|
281
|
+
|
|
282
|
+
function cleanTitle(raw: string): string {
|
|
283
|
+
const first = raw.replace(/\s+/g, ' ').trim().split('\n')[0]?.trim() ?? '';
|
|
284
|
+
if (!first) {
|
|
285
|
+
return 'Untitled Session';
|
|
286
|
+
}
|
|
287
|
+
return first.length > 80 ? `${first.slice(0, 77)}...` : first;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Collect all T-*.json files under the Amp threads directory, sorted by mtime desc. */
|
|
291
|
+
function collectThreadFiles(): string[] {
|
|
292
|
+
let entries: fs.Dirent[];
|
|
293
|
+
try {
|
|
294
|
+
entries = fs.readdirSync(AMP_THREADS, { withFileTypes: true });
|
|
295
|
+
} catch {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
const files: { mtime: number; path: string }[] = [];
|
|
299
|
+
for (const entry of entries) {
|
|
300
|
+
if (!entry.isFile() || !THREAD_FILE_RE.test(entry.name)) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
const full = path.join(AMP_THREADS, entry.name);
|
|
304
|
+
try {
|
|
305
|
+
const stat = fs.statSync(full);
|
|
306
|
+
files.push({ mtime: stat.mtimeMs, path: full });
|
|
307
|
+
} catch {
|
|
308
|
+
// skip
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
files.sort((a, b) => b.mtime - a.mtime);
|
|
312
|
+
return files.map((f) => f.path);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Map a `content` field (string or block array) to MessagePart[]. */
|
|
316
|
+
function contentToParts(content: unknown): MessagePart[] {
|
|
317
|
+
if (typeof content === 'string' && content) {
|
|
318
|
+
return [{ content, type: 'text' }];
|
|
319
|
+
}
|
|
320
|
+
if (!Array.isArray(content)) {
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
const parts: MessagePart[] = [];
|
|
324
|
+
for (const item of content as unknown[]) {
|
|
325
|
+
if (!isRecord(item)) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
const part = ampBlockToPart(item);
|
|
329
|
+
if (part) {
|
|
330
|
+
parts.push(part);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return parts;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// ---------------------------------------------------------------------------
|
|
337
|
+
// Metadata helpers
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
|
|
340
|
+
/** Extract plain text from a tool_result content field (string or text-block array). */
|
|
341
|
+
function extractToolResultText(content: unknown): string {
|
|
342
|
+
if (typeof content === 'string') {
|
|
343
|
+
return content;
|
|
344
|
+
}
|
|
345
|
+
if (!Array.isArray(content)) {
|
|
346
|
+
return '';
|
|
347
|
+
}
|
|
348
|
+
return (content as unknown[])
|
|
349
|
+
.filter((c): c is Record<string, unknown> => isRecord(c) && c.type === 'text')
|
|
350
|
+
.map((c) => (typeof c.text === 'string' ? c.text : ''))
|
|
351
|
+
.join('\n');
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Narrow an unknown value to a plain object with string keys. */
|
|
355
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
356
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Derive the modified timestamp: last trace endTime or file mtime.
|
|
361
|
+
* Amp records execution traces in meta.traces[].endTime (ISO string or ms number).
|
|
362
|
+
*/
|
|
363
|
+
function lastModified(doc: Record<string, unknown>, stat: fs.Stats): string {
|
|
364
|
+
if (isRecord(doc.meta)) {
|
|
365
|
+
const traces = doc.meta.traces;
|
|
366
|
+
if (Array.isArray(traces) && traces.length > 0) {
|
|
367
|
+
const last: unknown = traces[traces.length - 1];
|
|
368
|
+
if (isRecord(last)) {
|
|
369
|
+
const et = last.endTime;
|
|
370
|
+
if (typeof et === 'string' && et) {
|
|
371
|
+
return et;
|
|
372
|
+
}
|
|
373
|
+
if (typeof et === 'number' && et > 0) {
|
|
374
|
+
return new Date(et).toISOString();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return stat.mtime.toISOString();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Extract the project cwd/name from env.initial.trees[0].displayName.
|
|
384
|
+
* May be an absolute path or just a display name — surface it as-is.
|
|
385
|
+
*/
|
|
386
|
+
function projectCwd(doc: Record<string, unknown>): string {
|
|
387
|
+
if (isRecord(doc.env) && isRecord(doc.env.initial)) {
|
|
388
|
+
const trees = doc.env.initial.trees;
|
|
389
|
+
if (Array.isArray(trees) && trees.length > 0 && isRecord(trees[0])) {
|
|
390
|
+
const dn = trees[0].displayName;
|
|
391
|
+
if (typeof dn === 'string' && dn) {
|
|
392
|
+
return dn;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return '';
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Read and parse a thread JSON file.
|
|
401
|
+
* Returns null if the file is too large or malformed.
|
|
402
|
+
*/
|
|
403
|
+
function readThreadDoc(filePath: string): null | Record<string, unknown> {
|
|
404
|
+
try {
|
|
405
|
+
if (fs.statSync(filePath).size > MAX_FILE_BYTES) {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
const parsed: unknown = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
409
|
+
return isRecord(parsed) ? parsed : null;
|
|
410
|
+
} catch {
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function shortHash(input: string): string {
|
|
416
|
+
return crypto.createHash('sha256').update(input).digest('hex').slice(0, 8);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Derive the canonical session id from the filename stem (the part after
|
|
421
|
+
* "T-" in "T-<id>.json"). This must agree with what getAmpConversation
|
|
422
|
+
* expects: it reconstructs the file path as `T-${sessionId}.json`, so the
|
|
423
|
+
* id returned here must NOT include the leading "T-".
|
|
424
|
+
*
|
|
425
|
+
* The doc's `.id` field is accepted only as a last-resort fallback when the
|
|
426
|
+
* filename doesn't match the expected pattern — using doc.id first was the
|
|
427
|
+
* original bug (doc.id may contain or omit the "T-" prefix differently from
|
|
428
|
+
* the filename, causing a mismatch that produced zero messages on retrieval).
|
|
429
|
+
*/
|
|
430
|
+
function threadId(filePath: string, doc: Record<string, unknown>): string {
|
|
431
|
+
const m = THREAD_FILE_RE.exec(path.basename(filePath));
|
|
432
|
+
if (m?.[1]) {
|
|
433
|
+
return m[1];
|
|
434
|
+
}
|
|
435
|
+
if (typeof doc.id === 'string' && doc.id) {
|
|
436
|
+
return doc.id;
|
|
437
|
+
}
|
|
438
|
+
return '';
|
|
439
|
+
}
|