@juspay/shooter 1.1.0 → 1.2.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.DC5pAwP3.css → 0.BhZOCxO4.css} +1 -1
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css.br +0 -0
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css.gz +0 -0
- package/build/client/_app/immutable/assets/1.BYutk3aU.css +1 -0
- package/build/client/_app/immutable/assets/1.BYutk3aU.css.br +0 -0
- package/build/client/_app/immutable/assets/1.BYutk3aU.css.gz +0 -0
- package/build/client/_app/immutable/assets/{3.BoXp0JoS.css → 3.DGDHCVnW.css} +1 -1
- package/build/client/_app/immutable/assets/3.DGDHCVnW.css.br +0 -0
- package/build/client/_app/immutable/assets/3.DGDHCVnW.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.BFUut--w.css +1 -0
- package/build/client/_app/immutable/assets/4.BFUut--w.css.br +0 -0
- package/build/client/_app/immutable/assets/4.BFUut--w.css.gz +0 -0
- package/build/client/_app/immutable/assets/5.BTOx7yt7.css +1 -0
- package/build/client/_app/immutable/assets/5.BTOx7yt7.css.br +0 -0
- package/build/client/_app/immutable/assets/5.BTOx7yt7.css.gz +0 -0
- package/build/client/_app/immutable/assets/{7.PyEFVv_s.css → 7.DwS5ZHBh.css} +1 -1
- package/build/client/_app/immutable/assets/7.DwS5ZHBh.css.br +0 -0
- package/build/client/_app/immutable/assets/7.DwS5ZHBh.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChatView.CwWbzIL-.css +1 -0
- package/build/client/_app/immutable/assets/ChatView.CwWbzIL-.css.br +0 -0
- package/build/client/_app/immutable/assets/ChatView.CwWbzIL-.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B-K5Sh65.js +1 -0
- package/build/client/_app/immutable/chunks/B-K5Sh65.js.br +0 -0
- package/build/client/_app/immutable/chunks/B-K5Sh65.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B5NAKyil.js +20 -0
- package/build/client/_app/immutable/chunks/B5NAKyil.js.br +0 -0
- package/build/client/_app/immutable/chunks/B5NAKyil.js.gz +0 -0
- package/build/client/_app/immutable/chunks/B8XegpSE.js +1 -0
- package/build/client/_app/immutable/chunks/B8XegpSE.js.br +0 -0
- package/build/client/_app/immutable/chunks/B8XegpSE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{50RPd5u3.js → B8zoBsv3.js} +1 -1
- package/build/client/_app/immutable/chunks/B8zoBsv3.js.br +0 -0
- package/build/client/_app/immutable/chunks/B8zoBsv3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BLszSzTT.js +1 -0
- package/build/client/_app/immutable/chunks/BLszSzTT.js.br +0 -0
- package/build/client/_app/immutable/chunks/BLszSzTT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BOYo8yTr.js +1 -0
- package/build/client/_app/immutable/chunks/BOYo8yTr.js.br +0 -0
- package/build/client/_app/immutable/chunks/BOYo8yTr.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CdL99jkG.js → BYqGCrTe.js} +1 -1
- package/build/client/_app/immutable/chunks/BYqGCrTe.js.br +0 -0
- package/build/client/_app/immutable/chunks/BYqGCrTe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js +1 -0
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bu1aqm5j.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C4mLaWWx.js +1 -0
- package/build/client/_app/immutable/chunks/C4mLaWWx.js.br +0 -0
- package/build/client/_app/immutable/chunks/C4mLaWWx.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{ClK4wZbC.js → CQjSATpv.js} +16 -16
- package/build/client/_app/immutable/chunks/CQjSATpv.js.br +0 -0
- package/build/client/_app/immutable/chunks/CQjSATpv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CojFyTPp.js → CSoRdFvv.js} +1 -1
- package/build/client/_app/immutable/chunks/CSoRdFvv.js.br +0 -0
- package/build/client/_app/immutable/chunks/CSoRdFvv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{tjbnEgXP.js → CZHsSL_X.js} +1 -1
- package/build/client/_app/immutable/chunks/CZHsSL_X.js.br +0 -0
- package/build/client/_app/immutable/chunks/CZHsSL_X.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DVkn4r72.js +1 -0
- package/build/client/_app/immutable/chunks/DVkn4r72.js.br +0 -0
- package/build/client/_app/immutable/chunks/DVkn4r72.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DjsDGxCa.js +41 -0
- package/build/client/_app/immutable/chunks/DjsDGxCa.js.br +0 -0
- package/build/client/_app/immutable/chunks/DjsDGxCa.js.gz +0 -0
- package/build/client/_app/immutable/chunks/UJOiqIYE.js +1 -0
- package/build/client/_app/immutable/chunks/UJOiqIYE.js.br +0 -0
- package/build/client/_app/immutable/chunks/UJOiqIYE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/r0JawsZc.js +2 -0
- package/build/client/_app/immutable/chunks/r0JawsZc.js.br +0 -0
- package/build/client/_app/immutable/chunks/r0JawsZc.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.Z3zMnuSx.js +2 -0
- package/build/client/_app/immutable/entry/app.Z3zMnuSx.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Z3zMnuSx.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.Dd-gIP4y.js +1 -0
- package/build/client/_app/immutable/entry/start.Dd-gIP4y.js.br +2 -0
- package/build/client/_app/immutable/entry/start.Dd-gIP4y.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.D2YR8tTD.js +1 -0
- package/build/client/_app/immutable/nodes/0.D2YR8tTD.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.D2YR8tTD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.B3m6rO4C.js +1 -0
- package/build/client/_app/immutable/nodes/1.B3m6rO4C.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.B3m6rO4C.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CyRB2euU.js +1 -0
- package/build/client/_app/immutable/nodes/2.CyRB2euU.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CyRB2euU.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.3yohCM25.js +3 -0
- package/build/client/_app/immutable/nodes/3.3yohCM25.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.3yohCM25.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.DEAcwl7l.js +1 -0
- package/build/client/_app/immutable/nodes/4.DEAcwl7l.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.DEAcwl7l.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.C6bLGWQR.js +4 -0
- package/build/client/_app/immutable/nodes/5.C6bLGWQR.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.C6bLGWQR.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.ByTzlA2D.js +2 -0
- package/build/client/_app/immutable/nodes/6.ByTzlA2D.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.ByTzlA2D.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.BPMfwzd2.js +2 -0
- package/build/client/_app/immutable/nodes/7.BPMfwzd2.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.BPMfwzd2.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/client/manifest.json +13 -0
- package/build/client/manifest.json.br +0 -0
- package/build/client/manifest.json.gz +0 -0
- package/build/server/chunks/0-Vk38tI2J.js +9 -0
- package/build/server/chunks/0-Vk38tI2J.js.map +1 -0
- package/build/server/chunks/1-BvYQX5MR.js +9 -0
- package/build/server/chunks/1-BvYQX5MR.js.map +1 -0
- package/build/server/chunks/2-Cl7R4Qk2.js +9 -0
- package/build/server/chunks/2-Cl7R4Qk2.js.map +1 -0
- package/build/server/chunks/3-Ck7ewhOX.js +9 -0
- package/build/server/chunks/3-Ck7ewhOX.js.map +1 -0
- package/build/server/chunks/4-CnDeRm2Z.js +9 -0
- package/build/server/chunks/4-CnDeRm2Z.js.map +1 -0
- package/build/server/chunks/5-IxitzEvN.js +9 -0
- package/build/server/chunks/{5-D0wB7nfE.js.map → 5-IxitzEvN.js.map} +1 -1
- package/build/server/chunks/6-CyZ3r1iS.js +9 -0
- package/build/server/chunks/6-CyZ3r1iS.js.map +1 -0
- package/build/server/chunks/7-BmI7du46.js +9 -0
- package/build/server/chunks/7-BmI7du46.js.map +1 -0
- package/build/server/chunks/{Button-C7D5W6wV.js → Button-Cs1aE6ka.js} +2 -2
- package/build/server/chunks/{Button-C7D5W6wV.js.map → Button-Cs1aE6ka.js.map} +1 -1
- package/build/server/chunks/{EmptyState-Ci4pSpmY.js → EmptyState-DDFH1K8g.js} +10 -4
- package/build/server/chunks/EmptyState-DDFH1K8g.js.map +1 -0
- package/build/server/chunks/{Icon-DyrkHVnV.js → Icon-CEUrotA6.js} +3 -3
- package/build/server/chunks/{Icon-DyrkHVnV.js.map → Icon-CEUrotA6.js.map} +1 -1
- package/build/server/chunks/{Shimmer-BITK6wrm.js → Shimmer-DB8W1zt6.js} +2 -2
- package/build/server/chunks/{Shimmer-BITK6wrm.js.map → Shimmer-DB8W1zt6.js.map} +1 -1
- package/build/server/chunks/_error.svelte-uCOJNxvr.js +39 -0
- package/build/server/chunks/_error.svelte-uCOJNxvr.js.map +1 -0
- package/build/server/chunks/{_layout.svelte-CO4f8UD7.js → _layout.svelte-CtWmEJwe.js} +5 -25
- package/build/server/chunks/_layout.svelte-CtWmEJwe.js.map +1 -0
- package/build/server/chunks/{_page.svelte-C6bns9aQ.js → _page.svelte-BcZaKdX9.js} +13 -9
- package/build/server/chunks/_page.svelte-BcZaKdX9.js.map +1 -0
- package/build/server/chunks/{_page.svelte-3Cc3NMAP.js → _page.svelte-BdYynOck.js} +18 -14
- package/build/server/chunks/_page.svelte-BdYynOck.js.map +1 -0
- package/build/server/chunks/{_page.svelte-CFCONiDK.js → _page.svelte-BgevQjq1.js} +16 -12
- package/build/server/chunks/_page.svelte-BgevQjq1.js.map +1 -0
- package/build/server/chunks/{_page.svelte-DskND_G9.js → _page.svelte-CVq6tRb3.js} +8 -8
- package/build/server/chunks/_page.svelte-CVq6tRb3.js.map +1 -0
- package/build/server/chunks/{_page.svelte-rTrWmhOp.js → _page.svelte-CxWcQ0Am.js} +8 -8
- package/build/server/chunks/_page.svelte-CxWcQ0Am.js.map +1 -0
- package/build/server/chunks/{_page.svelte-C0p3HsIW.js → _page.svelte-DO4oa_LY.js} +11 -13
- package/build/server/chunks/_page.svelte-DO4oa_LY.js.map +1 -0
- package/build/server/chunks/{_server.ts-CS5H5klP.js → _server.ts-CAxsWKvS.js} +14 -10
- package/build/server/chunks/_server.ts-CAxsWKvS.js.map +1 -0
- package/build/server/chunks/{_server.ts-C8slOHB0.js → _server.ts-CTpcLUH8.js} +3 -2
- package/build/server/chunks/_server.ts-CTpcLUH8.js.map +1 -0
- package/build/server/chunks/_server.ts-CtH0dhUp.js +71 -0
- package/build/server/chunks/_server.ts-CtH0dhUp.js.map +1 -0
- package/build/server/chunks/{_server.ts-DhTrdlWH.js → _server.ts-DB_Kg97c.js} +14 -3
- package/build/server/chunks/_server.ts-DB_Kg97c.js.map +1 -0
- package/build/server/chunks/_server.ts-DYpJImqd.js +99 -0
- package/build/server/chunks/_server.ts-DYpJImqd.js.map +1 -0
- package/build/server/chunks/{_server.ts-DpEVfp8W.js → _server.ts-Deok2y88.js} +58 -40
- package/build/server/chunks/_server.ts-Deok2y88.js.map +1 -0
- package/build/server/chunks/{_server.ts-uHUi-4cd.js → _server.ts-vekTmWAx.js} +3 -2
- package/build/server/chunks/_server.ts-vekTmWAx.js.map +1 -0
- package/build/server/chunks/{client2-BjxIYuno.js → client-BdGHe_hY.js} +4 -4
- package/build/server/chunks/client-BdGHe_hY.js.map +1 -0
- package/build/server/chunks/client2-CCBGA-2V.js +7 -0
- package/build/server/chunks/client2-CCBGA-2V.js.map +1 -0
- package/build/server/chunks/{index-Cnl871UW.js → index-DwaY1cAm.js} +2 -2
- package/build/server/chunks/{index-Cnl871UW.js.map → index-DwaY1cAm.js.map} +1 -1
- package/build/server/chunks/{index-server-CUC9Jt7r.js → index-server-CrDaL06Y.js} +2 -2
- package/build/server/chunks/{index-server-CUC9Jt7r.js.map → index-server-CrDaL06Y.js.map} +1 -1
- package/build/server/chunks/{index2-HA3VTH7y.js → index2-CgclKpUj.js} +2 -2
- package/build/server/chunks/{index2-HA3VTH7y.js.map → index2-CgclKpUj.js.map} +1 -1
- package/build/server/chunks/opencode-db-path-DcfhJtJy.js +15 -0
- package/build/server/chunks/opencode-db-path-DcfhJtJy.js.map +1 -0
- package/build/server/chunks/{pty-manager-DR0Wt2Ac.js → pty-manager-BQVB7IVj.js} +17 -15
- package/build/server/chunks/pty-manager-BQVB7IVj.js.map +1 -0
- package/build/server/chunks/{root-DhswcH6o.js → root-DDSnEAZv.js} +2 -2
- package/build/server/chunks/{root-DhswcH6o.js.map → root-DDSnEAZv.js.map} +1 -1
- package/build/server/chunks/{state.svelte-2Lellg7t.js → state.svelte-hBbXlUak.js} +3 -3
- package/build/server/chunks/{state.svelte-2Lellg7t.js.map → state.svelte-hBbXlUak.js.map} +1 -1
- package/build/server/chunks/stores-DHNzYNpX.js +28 -0
- package/build/server/chunks/stores-DHNzYNpX.js.map +1 -0
- package/build/server/index.js +5 -5
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +30 -16
- package/build/server/manifest.js.map +1 -1
- package/package.json +1 -1
- package/scripts/setup.cjs +87 -13
- package/server.ts +3 -0
- package/src/app.html +3 -0
- package/src/lib/modules/client/common/cache.ts +10 -2
- package/src/lib/modules/client/common/index.ts +1 -1
- package/src/lib/modules/client/common/markdown.ts +22 -1
- package/src/lib/modules/client/common/time.ts +13 -11
- package/src/lib/modules/client/terminal/ChatView.svelte +324 -67
- package/src/lib/modules/client/terminal/ConnectionStatus.svelte +1 -0
- package/src/lib/modules/client/terminal/xterm-wrapper.ts +4 -1
- package/src/lib/modules/server/sessions/jsonl-reader.ts +43 -28
- package/src/lib/modules/server/sessions/opencode-db-path.ts +26 -0
- package/src/lib/modules/server/sessions/opencode-reader.ts +13 -15
- package/src/lib/modules/server/sessions/process-detector.ts +103 -0
- package/src/lib/modules/server/terminal/opencode-watcher.ts +3 -14
- package/src/lib/modules/server/terminal/pty-manager.ts +20 -8
- package/src/lib/modules/server/ws/session-handler.ts +282 -104
- package/src/lib/theme.css +30 -0
- package/src/routes/+error.svelte +94 -0
- package/src/routes/+page.svelte +18 -8
- package/src/routes/api/health/+server.ts +14 -2
- package/src/routes/api/sessions/+server.ts +12 -4
- package/src/routes/api/sessions/connect/+server.ts +125 -0
- package/src/routes/api/sessions/detect/+server.ts +27 -0
- package/src/routes/api/terminals/+server.ts +12 -9
- package/src/routes/config/+page.svelte +22 -1
- package/src/routes/project/+page.svelte +159 -8
- package/src/routes/session/[id]/+page.svelte +477 -299
- package/src/routes/terminals/+page.svelte +14 -3
- package/src/routes/terminals/[id]/+page.svelte +25 -0
- package/build/client/_app/immutable/assets/0.DC5pAwP3.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DC5pAwP3.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.BoXp0JoS.css.br +0 -0
- package/build/client/_app/immutable/assets/3.BoXp0JoS.css.gz +0 -0
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css +0 -1
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.br +0 -0
- package/build/client/_app/immutable/assets/4.cJuCkJKZ.css.gz +0 -0
- package/build/client/_app/immutable/assets/5.DRjApZQW.css +0 -1
- package/build/client/_app/immutable/assets/5.DRjApZQW.css.br +0 -0
- package/build/client/_app/immutable/assets/5.DRjApZQW.css.gz +0 -0
- package/build/client/_app/immutable/assets/7.PyEFVv_s.css.br +0 -0
- package/build/client/_app/immutable/assets/7.PyEFVv_s.css.gz +0 -0
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css +0 -1
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.br +0 -0
- package/build/client/_app/immutable/assets/ChatView.CsdBAOKx.css.gz +0 -0
- package/build/client/_app/immutable/chunks/50RPd5u3.js.br +0 -0
- package/build/client/_app/immutable/chunks/50RPd5u3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BDC7XD4o.js +0 -1
- package/build/client/_app/immutable/chunks/BDC7XD4o.js.br +0 -0
- package/build/client/_app/immutable/chunks/BDC7XD4o.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BeONA6_G.js +0 -2
- package/build/client/_app/immutable/chunks/BeONA6_G.js.br +0 -0
- package/build/client/_app/immutable/chunks/BeONA6_G.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BygiiMA0.js +0 -1
- package/build/client/_app/immutable/chunks/BygiiMA0.js.br +0 -0
- package/build/client/_app/immutable/chunks/BygiiMA0.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CGLrx-H5.js +0 -1
- package/build/client/_app/immutable/chunks/CGLrx-H5.js.br +0 -0
- package/build/client/_app/immutable/chunks/CGLrx-H5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CHvUpVYv.js +0 -1
- package/build/client/_app/immutable/chunks/CHvUpVYv.js.br +0 -0
- package/build/client/_app/immutable/chunks/CHvUpVYv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CbqC9BW7.js +0 -1
- package/build/client/_app/immutable/chunks/CbqC9BW7.js.br +0 -2
- package/build/client/_app/immutable/chunks/CbqC9BW7.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CdL99jkG.js.br +0 -0
- package/build/client/_app/immutable/chunks/CdL99jkG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ClK4wZbC.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClK4wZbC.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CojFyTPp.js.br +0 -0
- package/build/client/_app/immutable/chunks/CojFyTPp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DREFAyhX.js +0 -60
- package/build/client/_app/immutable/chunks/DREFAyhX.js.br +0 -0
- package/build/client/_app/immutable/chunks/DREFAyhX.js.gz +0 -0
- package/build/client/_app/immutable/chunks/K_aHH2KN.js +0 -1
- package/build/client/_app/immutable/chunks/K_aHH2KN.js.br +0 -0
- package/build/client/_app/immutable/chunks/K_aHH2KN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Ona8oofC.js +0 -1
- package/build/client/_app/immutable/chunks/Ona8oofC.js.br +0 -0
- package/build/client/_app/immutable/chunks/Ona8oofC.js.gz +0 -0
- package/build/client/_app/immutable/chunks/tjbnEgXP.js.br +0 -0
- package/build/client/_app/immutable/chunks/tjbnEgXP.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.anqwe7ZL.js +0 -2
- package/build/client/_app/immutable/entry/app.anqwe7ZL.js.br +0 -0
- package/build/client/_app/immutable/entry/app.anqwe7ZL.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BV2VRv6h.js +0 -1
- package/build/client/_app/immutable/entry/start.BV2VRv6h.js.br +0 -2
- package/build/client/_app/immutable/entry/start.BV2VRv6h.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.D0i5MqcI.js +0 -1
- package/build/client/_app/immutable/nodes/0.D0i5MqcI.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.D0i5MqcI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.DN5n5c6F.js +0 -1
- package/build/client/_app/immutable/nodes/1.DN5n5c6F.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.DN5n5c6F.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js +0 -1
- package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BTjkNKZJ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CEkigHDv.js +0 -3
- package/build/client/_app/immutable/nodes/3.CEkigHDv.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CEkigHDv.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js +0 -1
- package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.B-8Zsc9k.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.shitbtHc.js +0 -1
- package/build/client/_app/immutable/nodes/5.shitbtHc.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.shitbtHc.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js +0 -2
- package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.CB8Q6eH8.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.D0CrR6pl.js +0 -2
- package/build/client/_app/immutable/nodes/7.D0CrR6pl.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.D0CrR6pl.js.gz +0 -0
- package/build/server/chunks/0-Cs1dzfRz.js +0 -9
- package/build/server/chunks/0-Cs1dzfRz.js.map +0 -1
- package/build/server/chunks/1-BCSX7oED.js +0 -9
- package/build/server/chunks/1-BCSX7oED.js.map +0 -1
- package/build/server/chunks/2-6gkeO8b4.js +0 -9
- package/build/server/chunks/2-6gkeO8b4.js.map +0 -1
- package/build/server/chunks/3-DH9J9Vsc.js +0 -9
- package/build/server/chunks/3-DH9J9Vsc.js.map +0 -1
- package/build/server/chunks/4-Rzy5TYjl.js +0 -9
- package/build/server/chunks/4-Rzy5TYjl.js.map +0 -1
- package/build/server/chunks/5-D0wB7nfE.js +0 -9
- package/build/server/chunks/6-DR2ABDPq.js +0 -9
- package/build/server/chunks/6-DR2ABDPq.js.map +0 -1
- package/build/server/chunks/7-D-oQJsia.js +0 -9
- package/build/server/chunks/7-D-oQJsia.js.map +0 -1
- package/build/server/chunks/EmptyState-Ci4pSpmY.js.map +0 -1
- package/build/server/chunks/_layout.svelte-CO4f8UD7.js.map +0 -1
- package/build/server/chunks/_page.svelte-3Cc3NMAP.js.map +0 -1
- package/build/server/chunks/_page.svelte-C0p3HsIW.js.map +0 -1
- package/build/server/chunks/_page.svelte-C6bns9aQ.js.map +0 -1
- package/build/server/chunks/_page.svelte-CFCONiDK.js.map +0 -1
- package/build/server/chunks/_page.svelte-DskND_G9.js.map +0 -1
- package/build/server/chunks/_page.svelte-rTrWmhOp.js.map +0 -1
- package/build/server/chunks/_server.ts-C8slOHB0.js.map +0 -1
- package/build/server/chunks/_server.ts-CS5H5klP.js.map +0 -1
- package/build/server/chunks/_server.ts-DhTrdlWH.js.map +0 -1
- package/build/server/chunks/_server.ts-DpEVfp8W.js.map +0 -1
- package/build/server/chunks/_server.ts-uHUi-4cd.js.map +0 -1
- package/build/server/chunks/client-BYT9c0ig.js +0 -7
- package/build/server/chunks/client-BYT9c0ig.js.map +0 -1
- package/build/server/chunks/client2-BjxIYuno.js.map +0 -1
- package/build/server/chunks/error.svelte-BG_yE-Wt.js +0 -27
- package/build/server/chunks/error.svelte-BG_yE-Wt.js.map +0 -1
- package/build/server/chunks/pty-manager-DR0Wt2Ac.js.map +0 -1
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
ToolUsePart,
|
|
6
6
|
} from '$lib/modules/server/sessions/types';
|
|
7
7
|
|
|
8
|
+
import { browser } from '$app/environment';
|
|
8
9
|
import { getToolDescription, renderMarkdown } from '$lib/modules/client/common';
|
|
9
10
|
import { Accordion, Avatar, Button, Input, Pill } from '@juspay/svelte-ui-components';
|
|
10
11
|
import { tick } from 'svelte';
|
|
@@ -14,27 +15,110 @@
|
|
|
14
15
|
const {
|
|
15
16
|
connectionState = 'idle',
|
|
16
17
|
messages,
|
|
18
|
+
newestFirst = false,
|
|
17
19
|
onCancel,
|
|
18
20
|
onSendInput,
|
|
21
|
+
sendDisabled,
|
|
19
22
|
sessionEnded = false,
|
|
20
23
|
showHeader = false,
|
|
21
24
|
showInput = true,
|
|
22
25
|
}: {
|
|
23
26
|
connectionState?: 'connected' | 'connecting' | 'disconnected' | 'idle' | 'reconnecting';
|
|
24
27
|
messages: ConversationMessage[];
|
|
28
|
+
newestFirst?: boolean;
|
|
25
29
|
onCancel?: () => void;
|
|
26
30
|
onSendInput?: (text: string) => void;
|
|
31
|
+
sendDisabled?: boolean;
|
|
27
32
|
sessionEnded?: boolean;
|
|
28
33
|
showHeader?: boolean;
|
|
29
34
|
showInput?: boolean;
|
|
30
35
|
} = $props();
|
|
31
36
|
|
|
37
|
+
// When sendDisabled is explicitly provided, it overrides the connectionState check.
|
|
38
|
+
// Otherwise fall back to the existing behaviour (disabled when not connected).
|
|
39
|
+
const isInputDisabled = $derived(
|
|
40
|
+
sessionEnded ||
|
|
41
|
+
(sendDisabled !== undefined ? sendDisabled : connectionState !== 'connected')
|
|
42
|
+
);
|
|
43
|
+
|
|
32
44
|
// --- Local state ---
|
|
33
45
|
let inputText = $state('');
|
|
34
46
|
let chatContainerEl = $state<HTMLElement | null>(null);
|
|
35
47
|
let shouldAutoScroll = $state(true);
|
|
36
48
|
|
|
37
49
|
const expandedTools = new SvelteSet<string>();
|
|
50
|
+
const expandedGroups = new SvelteSet<string>();
|
|
51
|
+
|
|
52
|
+
// --- Show Details toggle (persisted in localStorage) ---
|
|
53
|
+
const SHOW_DETAILS_KEY = 'shooter:chatview:showDetails';
|
|
54
|
+
let showDetails = $state(
|
|
55
|
+
browser ? localStorage.getItem(SHOW_DETAILS_KEY) === 'true' : false,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
function toggleShowDetails(): void {
|
|
59
|
+
showDetails = !showDetails;
|
|
60
|
+
if (browser) {
|
|
61
|
+
localStorage.setItem(SHOW_DETAILS_KEY, String(showDetails));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// --- Tool grouping ---
|
|
66
|
+
interface ToolGroup {
|
|
67
|
+
groupId: string;
|
|
68
|
+
summary: string;
|
|
69
|
+
tools: ToolUsePart[];
|
|
70
|
+
type: 'tool_group';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
type GroupedPart = MessagePart | ToolGroup;
|
|
74
|
+
|
|
75
|
+
function groupMessageParts(parts: MessagePart[], messageId: string): GroupedPart[] {
|
|
76
|
+
const result: GroupedPart[] = [];
|
|
77
|
+
let currentToolGroup: ToolUsePart[] = [];
|
|
78
|
+
let groupIndex = 0;
|
|
79
|
+
|
|
80
|
+
function flushToolGroup(): void {
|
|
81
|
+
if (currentToolGroup.length === 0) {return;}
|
|
82
|
+
|
|
83
|
+
if (currentToolGroup.length === 1) {
|
|
84
|
+
// Single tool -- render as normal tool card, no group wrapper
|
|
85
|
+
result.push(currentToolGroup[0]);
|
|
86
|
+
} else {
|
|
87
|
+
const toolNames = currentToolGroup.map((t) => t.toolName);
|
|
88
|
+
// Deduplicate tool names while preserving order
|
|
89
|
+
const uniqueNames = [...new Set(toolNames)];
|
|
90
|
+
const summary = `Used ${currentToolGroup.length} tools: ${uniqueNames.join(', ')}`;
|
|
91
|
+
result.push({
|
|
92
|
+
groupId: `toolgroup-${messageId}-${groupIndex}`,
|
|
93
|
+
summary,
|
|
94
|
+
tools: currentToolGroup,
|
|
95
|
+
type: 'tool_group',
|
|
96
|
+
});
|
|
97
|
+
groupIndex++;
|
|
98
|
+
}
|
|
99
|
+
currentToolGroup = [];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const part of parts) {
|
|
103
|
+
if (part.type === 'tool_use') {
|
|
104
|
+
currentToolGroup.push(part);
|
|
105
|
+
} else {
|
|
106
|
+
flushToolGroup();
|
|
107
|
+
result.push(part);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
flushToolGroup();
|
|
111
|
+
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function isToolGroup(part: GroupedPart): part is ToolGroup {
|
|
116
|
+
return (part as ToolGroup).type === 'tool_group';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function hasOnlyToolResults(message: ConversationMessage): boolean {
|
|
120
|
+
return message.parts.every((p) => p.type === 'tool_result');
|
|
121
|
+
}
|
|
38
122
|
|
|
39
123
|
// --- Auto-scroll ---
|
|
40
124
|
// Re-scroll whenever the messages array identity changes
|
|
@@ -49,7 +133,11 @@
|
|
|
49
133
|
return;
|
|
50
134
|
}
|
|
51
135
|
await tick();
|
|
52
|
-
|
|
136
|
+
if (newestFirst) {
|
|
137
|
+
chatContainerEl.scrollTop = 0;
|
|
138
|
+
} else {
|
|
139
|
+
chatContainerEl.scrollTop = chatContainerEl.scrollHeight;
|
|
140
|
+
}
|
|
53
141
|
}
|
|
54
142
|
|
|
55
143
|
function handleScroll(): void {
|
|
@@ -57,7 +145,11 @@
|
|
|
57
145
|
return;
|
|
58
146
|
}
|
|
59
147
|
const { clientHeight, scrollHeight, scrollTop } = chatContainerEl;
|
|
60
|
-
|
|
148
|
+
if (newestFirst) {
|
|
149
|
+
shouldAutoScroll = scrollTop < 100;
|
|
150
|
+
} else {
|
|
151
|
+
shouldAutoScroll = scrollHeight - scrollTop - clientHeight < 100;
|
|
152
|
+
}
|
|
61
153
|
}
|
|
62
154
|
|
|
63
155
|
// --- Input handling ---
|
|
@@ -86,6 +178,14 @@
|
|
|
86
178
|
}
|
|
87
179
|
}
|
|
88
180
|
|
|
181
|
+
function toggleGroup(id: string): void {
|
|
182
|
+
if (expandedGroups.has(id)) {
|
|
183
|
+
expandedGroups.delete(id);
|
|
184
|
+
} else {
|
|
185
|
+
expandedGroups.add(id);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
89
189
|
function formatTime(ts: string): string {
|
|
90
190
|
return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
91
191
|
}
|
|
@@ -140,6 +240,19 @@
|
|
|
140
240
|
<p class="chatview-empty-text">Waiting for session messages...</p>
|
|
141
241
|
</div>
|
|
142
242
|
{:else}
|
|
243
|
+
<!-- Show details toggle -->
|
|
244
|
+
<div class="chatview-details-toggle">
|
|
245
|
+
<button
|
|
246
|
+
class="chatview-details-btn"
|
|
247
|
+
class:active={showDetails}
|
|
248
|
+
onclick={toggleShowDetails}
|
|
249
|
+
type="button"
|
|
250
|
+
>
|
|
251
|
+
<span class="chatview-details-icon">{showDetails ? '▼' : '▶'}</span>
|
|
252
|
+
{showDetails ? 'Hide details' : 'Show details'}
|
|
253
|
+
</button>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
143
256
|
{#each messages as message (message.id)}
|
|
144
257
|
{#if message.role === 'user'}
|
|
145
258
|
<div class="chat-message chat-message-user">
|
|
@@ -160,21 +273,71 @@
|
|
|
160
273
|
<div class="chat-message chat-message-assistant">
|
|
161
274
|
<Avatar alt="Claude" name="Claude" size="small" classes="avatar-assistant" />
|
|
162
275
|
<div>
|
|
163
|
-
{#each message.parts as
|
|
164
|
-
{#if
|
|
276
|
+
{#each groupMessageParts(message.parts, message.id) as gpart, partIdx (partIdx)}
|
|
277
|
+
{#if isToolGroup(gpart)}
|
|
278
|
+
<!-- Collapsed tool group summary -->
|
|
279
|
+
{@const groupExpanded = showDetails || expandedGroups.has(gpart.groupId)}
|
|
280
|
+
<div class="chat-tool-group">
|
|
281
|
+
<div
|
|
282
|
+
class="chat-tool-group-header"
|
|
283
|
+
onclick={() => { toggleGroup(gpart.groupId); }}
|
|
284
|
+
onkeydown={(e) => {
|
|
285
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
286
|
+
e.preventDefault();
|
|
287
|
+
toggleGroup(gpart.groupId);
|
|
288
|
+
}
|
|
289
|
+
}}
|
|
290
|
+
role="button"
|
|
291
|
+
tabindex="0"
|
|
292
|
+
>
|
|
293
|
+
<span class="chat-tool-group-chevron" class:expanded={groupExpanded}>▶</span>
|
|
294
|
+
<span class="chat-tool-group-summary">{gpart.summary}</span>
|
|
295
|
+
</div>
|
|
296
|
+
{#if groupExpanded}
|
|
297
|
+
<div class="chat-tool-group-body">
|
|
298
|
+
{#each gpart.tools as tool (tool.id)}
|
|
299
|
+
{@const toolId = tool.id}
|
|
300
|
+
{@const isExpanded = showDetails || expandedTools.has(toolId)}
|
|
301
|
+
<div class="chat-tool-card">
|
|
302
|
+
<div
|
|
303
|
+
class="chat-tool-header"
|
|
304
|
+
onclick={() => { toggleTool(toolId); }}
|
|
305
|
+
onkeydown={(e) => {
|
|
306
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
307
|
+
e.preventDefault();
|
|
308
|
+
toggleTool(toolId);
|
|
309
|
+
}
|
|
310
|
+
}}
|
|
311
|
+
role="button"
|
|
312
|
+
tabindex="0"
|
|
313
|
+
>
|
|
314
|
+
<span class="chat-tool-chevron" class:expanded={isExpanded}>▶</span>
|
|
315
|
+
<Pill text={tool.toolName} classes="pill-tool-name" />
|
|
316
|
+
<span class="chat-tool-description">{getToolDescriptionFromPart(tool)}</span>
|
|
317
|
+
</div>
|
|
318
|
+
<Accordion expand={isExpanded}>
|
|
319
|
+
{#if isExpanded}
|
|
320
|
+
<div class="chat-tool-body">{formatInput(tool.input)}</div>
|
|
321
|
+
{/if}
|
|
322
|
+
</Accordion>
|
|
323
|
+
</div>
|
|
324
|
+
{/each}
|
|
325
|
+
</div>
|
|
326
|
+
{/if}
|
|
327
|
+
</div>
|
|
328
|
+
{:else if gpart.type === 'text'}
|
|
165
329
|
<div class="chat-bubble chat-bubble-assistant">
|
|
166
330
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
|
|
167
|
-
{@html renderMarkdown(
|
|
331
|
+
{@html renderMarkdown(gpart.content)}
|
|
168
332
|
</div>
|
|
169
|
-
{:else if isToolUsePart(
|
|
170
|
-
|
|
171
|
-
{@const
|
|
333
|
+
{:else if isToolUsePart(gpart)}
|
|
334
|
+
<!-- Single tool (not grouped) -->
|
|
335
|
+
{@const toolId = gpart.id}
|
|
336
|
+
{@const isExpanded = showDetails || expandedTools.has(toolId)}
|
|
172
337
|
<div class="chat-tool-card">
|
|
173
338
|
<div
|
|
174
339
|
class="chat-tool-header"
|
|
175
|
-
onclick={() => {
|
|
176
|
-
toggleTool(toolId);
|
|
177
|
-
}}
|
|
340
|
+
onclick={() => { toggleTool(toolId); }}
|
|
178
341
|
onkeydown={(e) => {
|
|
179
342
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
180
343
|
e.preventDefault();
|
|
@@ -185,24 +348,22 @@
|
|
|
185
348
|
tabindex="0"
|
|
186
349
|
>
|
|
187
350
|
<span class="chat-tool-chevron" class:expanded={isExpanded}>▶</span>
|
|
188
|
-
<Pill text={
|
|
189
|
-
<span class="chat-tool-description">{getToolDescriptionFromPart(
|
|
351
|
+
<Pill text={gpart.toolName} classes="pill-tool-name" />
|
|
352
|
+
<span class="chat-tool-description">{getToolDescriptionFromPart(gpart)}</span>
|
|
190
353
|
</div>
|
|
191
354
|
<Accordion expand={isExpanded}>
|
|
192
355
|
{#if isExpanded}
|
|
193
|
-
<div class="chat-tool-body">{formatInput(
|
|
356
|
+
<div class="chat-tool-body">{formatInput(gpart.input)}</div>
|
|
194
357
|
{/if}
|
|
195
358
|
</Accordion>
|
|
196
359
|
</div>
|
|
197
|
-
{:else if
|
|
360
|
+
{:else if gpart.type === 'thinking'}
|
|
198
361
|
{@const thinkId = `thinking-${message.id}`}
|
|
199
|
-
{@const isThinkExpanded = expandedTools.has(thinkId)}
|
|
362
|
+
{@const isThinkExpanded = showDetails || expandedTools.has(thinkId)}
|
|
200
363
|
<div class="chat-thinking">
|
|
201
364
|
<div
|
|
202
365
|
class="chat-thinking-header"
|
|
203
|
-
onclick={() => {
|
|
204
|
-
toggleTool(thinkId);
|
|
205
|
-
}}
|
|
366
|
+
onclick={() => { toggleTool(thinkId); }}
|
|
206
367
|
onkeydown={(e) => {
|
|
207
368
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
208
369
|
e.preventDefault();
|
|
@@ -217,7 +378,7 @@
|
|
|
217
378
|
<Accordion expand={isThinkExpanded}>
|
|
218
379
|
{#if isThinkExpanded}
|
|
219
380
|
<!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
|
|
220
|
-
<div class="chat-thinking-body">{@html renderMarkdown(
|
|
381
|
+
<div class="chat-thinking-body">{@html renderMarkdown(gpart.content)}</div>
|
|
221
382
|
{/if}
|
|
222
383
|
</Accordion>
|
|
223
384
|
</div>
|
|
@@ -227,55 +388,58 @@
|
|
|
227
388
|
</div>
|
|
228
389
|
</div>
|
|
229
390
|
{:else if message.role === 'system'}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
{
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
toggleTool(resultId);
|
|
240
|
-
}}
|
|
241
|
-
onkeydown={(e) => {
|
|
242
|
-
if (e.key === 'Enter' || e.key === ' ') {
|
|
243
|
-
e.preventDefault();
|
|
244
|
-
toggleTool(resultId);
|
|
245
|
-
}
|
|
246
|
-
}}
|
|
247
|
-
role="button"
|
|
248
|
-
tabindex="0"
|
|
249
|
-
>
|
|
250
|
-
<span class="chat-tool-chevron" class:expanded={isResultExpanded}>▶</span>
|
|
251
|
-
<Pill
|
|
252
|
-
text={part.isError ? '\u274C Tool Error' : '\u2705 Tool Result'}
|
|
253
|
-
classes={part.isError ? 'pill-tool-error' : 'pill-tool-success'}
|
|
254
|
-
/>
|
|
255
|
-
</div>
|
|
256
|
-
<Accordion expand={isResultExpanded}>
|
|
257
|
-
{#if isResultExpanded}
|
|
391
|
+
<!-- Hide system messages with only tool_result when details are off -->
|
|
392
|
+
{#if showDetails || !hasOnlyToolResults(message)}
|
|
393
|
+
{#each message.parts as part, partIdx (partIdx)}
|
|
394
|
+
{#if part.type === 'tool_result'}
|
|
395
|
+
{#if showDetails}
|
|
396
|
+
{@const resultId = `result-${part.toolUseId}`}
|
|
397
|
+
{@const isResultExpanded = expandedTools.has(resultId)}
|
|
398
|
+
<div class="chat-message chat-message-system">
|
|
399
|
+
<div class="chat-tool-card">
|
|
258
400
|
<div
|
|
259
|
-
class="chat-tool-
|
|
260
|
-
|
|
261
|
-
|
|
401
|
+
class="chat-tool-header"
|
|
402
|
+
onclick={() => { toggleTool(resultId); }}
|
|
403
|
+
onkeydown={(e) => {
|
|
404
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
405
|
+
e.preventDefault();
|
|
406
|
+
toggleTool(resultId);
|
|
407
|
+
}
|
|
408
|
+
}}
|
|
409
|
+
role="button"
|
|
410
|
+
tabindex="0"
|
|
262
411
|
>
|
|
263
|
-
{
|
|
412
|
+
<span class="chat-tool-chevron" class:expanded={isResultExpanded}>▶</span>
|
|
413
|
+
<Pill
|
|
414
|
+
text={part.isError ? '\u274C Tool Error' : '\u2705 Tool Result'}
|
|
415
|
+
classes={part.isError ? 'pill-tool-error' : 'pill-tool-success'}
|
|
416
|
+
/>
|
|
264
417
|
</div>
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
418
|
+
<Accordion expand={isResultExpanded}>
|
|
419
|
+
{#if isResultExpanded}
|
|
420
|
+
<div
|
|
421
|
+
class="chat-tool-result"
|
|
422
|
+
class:chat-tool-result-success={!part.isError}
|
|
423
|
+
class:chat-tool-result-error={part.isError}
|
|
424
|
+
>
|
|
425
|
+
{part.output}
|
|
426
|
+
</div>
|
|
427
|
+
{/if}
|
|
428
|
+
</Accordion>
|
|
429
|
+
</div>
|
|
430
|
+
</div>
|
|
431
|
+
{/if}
|
|
432
|
+
{:else if part.type === 'text'}
|
|
433
|
+
<!-- System text messages (e.g. error messages displayed inline) -->
|
|
434
|
+
<div class="chat-message chat-message-system">
|
|
435
|
+
<div class="chat-bubble chat-bubble-system">
|
|
436
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -- sanitized markdown -->
|
|
437
|
+
{@html renderMarkdown(part.content)}
|
|
438
|
+
</div>
|
|
275
439
|
</div>
|
|
276
|
-
|
|
277
|
-
{/
|
|
278
|
-
{/
|
|
440
|
+
{/if}
|
|
441
|
+
{/each}
|
|
442
|
+
{/if}
|
|
279
443
|
{/if}
|
|
280
444
|
{/each}
|
|
281
445
|
|
|
@@ -297,13 +461,13 @@
|
|
|
297
461
|
dataType="text"
|
|
298
462
|
useTextArea={true}
|
|
299
463
|
placeholder={sessionEnded ? 'Session ended' : 'Send a message... (Shift+Enter for new line)'}
|
|
300
|
-
disable={
|
|
464
|
+
disable={isInputDisabled}
|
|
301
465
|
onKeyDown={handleKeydown}
|
|
302
466
|
classes="chat-input-field"
|
|
303
467
|
/>
|
|
304
468
|
<Button
|
|
305
469
|
classes="btn-primary btn-sm"
|
|
306
|
-
disabled={
|
|
470
|
+
disabled={isInputDisabled || !inputText.trim()}
|
|
307
471
|
onclick={handleSend}
|
|
308
472
|
text="Send"
|
|
309
473
|
/>
|
|
@@ -398,6 +562,99 @@
|
|
|
398
562
|
color: var(--text-tertiary, #7d7d7d);
|
|
399
563
|
}
|
|
400
564
|
|
|
565
|
+
/* Show details toggle */
|
|
566
|
+
.chatview-details-toggle {
|
|
567
|
+
display: flex;
|
|
568
|
+
justify-content: flex-end;
|
|
569
|
+
padding: 0 0 var(--space-2, 0.5rem) 0;
|
|
570
|
+
position: sticky;
|
|
571
|
+
top: 0;
|
|
572
|
+
z-index: 5;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.chatview-details-btn {
|
|
576
|
+
display: inline-flex;
|
|
577
|
+
align-items: center;
|
|
578
|
+
gap: var(--space-1, 0.25rem);
|
|
579
|
+
padding: 4px 10px;
|
|
580
|
+
border: 1px solid var(--border, #2a2a2a);
|
|
581
|
+
border-radius: var(--radius-sm, 4px);
|
|
582
|
+
background: var(--bg-secondary, #141414);
|
|
583
|
+
color: var(--text-tertiary, #7d7d7d);
|
|
584
|
+
font-size: 0.7rem;
|
|
585
|
+
cursor: pointer;
|
|
586
|
+
user-select: none;
|
|
587
|
+
transition:
|
|
588
|
+
color var(--transition-fast, 150ms),
|
|
589
|
+
border-color var(--transition-fast, 150ms);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.chatview-details-btn:hover {
|
|
593
|
+
color: var(--text-secondary, #a3a3a3);
|
|
594
|
+
border-color: var(--text-tertiary, #7d7d7d);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.chatview-details-btn.active {
|
|
598
|
+
color: var(--text-secondary, #a3a3a3);
|
|
599
|
+
border-color: var(--text-tertiary, #7d7d7d);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.chatview-details-icon {
|
|
603
|
+
font-size: 0.55rem;
|
|
604
|
+
line-height: 1;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/* Tool group (collapsed N tools) */
|
|
608
|
+
.chat-tool-group {
|
|
609
|
+
background: var(--bg-secondary, #141414);
|
|
610
|
+
border: 1px solid var(--border, #2a2a2a);
|
|
611
|
+
border-radius: var(--radius-md, 8px);
|
|
612
|
+
overflow: hidden;
|
|
613
|
+
margin: var(--space-2, 0.5rem) 0;
|
|
614
|
+
max-width: 90%;
|
|
615
|
+
align-self: flex-start;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.chat-tool-group-header {
|
|
619
|
+
display: flex;
|
|
620
|
+
align-items: center;
|
|
621
|
+
gap: var(--space-2, 0.5rem);
|
|
622
|
+
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
|
|
623
|
+
cursor: pointer;
|
|
624
|
+
user-select: none;
|
|
625
|
+
transition: background var(--transition-fast, 150ms);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
.chat-tool-group-header:hover {
|
|
629
|
+
background: rgba(255, 255, 255, 0.03);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.chat-tool-group-chevron {
|
|
633
|
+
font-size: 0.7rem;
|
|
634
|
+
color: var(--text-tertiary, #737373);
|
|
635
|
+
transition: transform 0.2s ease;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
.chat-tool-group-chevron.expanded {
|
|
639
|
+
transform: rotate(90deg);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
.chat-tool-group-summary {
|
|
643
|
+
font-size: 0.8rem;
|
|
644
|
+
color: var(--text-tertiary, #737373);
|
|
645
|
+
font-weight: 500;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.chat-tool-group-body {
|
|
649
|
+
border-top: 1px solid var(--border, #2a2a2a);
|
|
650
|
+
padding: var(--space-2, 0.5rem);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.chat-tool-group-body .chat-tool-card {
|
|
654
|
+
margin: var(--space-1, 0.25rem) 0;
|
|
655
|
+
max-width: 100%;
|
|
656
|
+
}
|
|
657
|
+
|
|
401
658
|
/* Mobile responsive */
|
|
402
659
|
@media (max-width: 768px) {
|
|
403
660
|
.chatview-header {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
class:reconnecting={status === 'reconnecting'}
|
|
23
23
|
class:disconnected={status === 'disconnected'}
|
|
24
24
|
class:connected={status === 'connected'}
|
|
25
|
+
aria-label="Connection: {status}"
|
|
25
26
|
>
|
|
26
27
|
<span class="status-dot {status}"></span>
|
|
27
28
|
<span class="status-label">{label}</span>
|
|
@@ -230,8 +230,11 @@ export async function createTerminal(options: TerminalOptions): Promise<Terminal
|
|
|
230
230
|
}
|
|
231
231
|
});
|
|
232
232
|
|
|
233
|
-
// Handle resize
|
|
233
|
+
// Handle resize — skip when container is hidden (display:none → size 0)
|
|
234
234
|
const resizeObserver = new ResizeObserver(() => {
|
|
235
|
+
if (!options.container.offsetWidth || !options.container.offsetHeight) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
235
238
|
fitAddon.fit();
|
|
236
239
|
if (ws?.readyState === WebSocket.OPEN) {
|
|
237
240
|
ws.send(JSON.stringify({ cols: term.cols, rows: term.rows, type: 'resize' }));
|
|
@@ -44,6 +44,15 @@ export function getSessionConversation(
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// If no explicit offset, return the LAST `limit` messages (most recent conversation)
|
|
48
|
+
if (offset === 0 && messages.length > limit) {
|
|
49
|
+
let startIdx = messages.length - limit;
|
|
50
|
+
// Adjust to start at a 'user' message boundary so we don't clip mid-turn
|
|
51
|
+
while (startIdx > 0 && startIdx < messages.length && messages[startIdx].role !== 'user') {
|
|
52
|
+
startIdx--;
|
|
53
|
+
}
|
|
54
|
+
return messages.slice(startIdx);
|
|
55
|
+
}
|
|
47
56
|
return messages.slice(offset, offset + limit);
|
|
48
57
|
} catch (error) {
|
|
49
58
|
console.error('[sessions] Failed to parse session JSONL:', error);
|
|
@@ -218,22 +227,20 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
|
|
|
218
227
|
let messageCount = 0;
|
|
219
228
|
try {
|
|
220
229
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
221
|
-
// Count user + assistant messages for the
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
} catch {
|
|
233
|
-
// skip malformed lines
|
|
234
|
-
}
|
|
230
|
+
// Count user + assistant messages by searching each line for the type field.
|
|
231
|
+
// The type field may appear anywhere on the line (after parentUuid, isSidechain, etc.)
|
|
232
|
+
// so a prefix-only check is not reliable with the current JSONL format.
|
|
233
|
+
let countPos = 0;
|
|
234
|
+
while (countPos < content.length) {
|
|
235
|
+
const nl = content.indexOf('\n', countPos);
|
|
236
|
+
const lineEnd = nl === -1 ? content.length : nl;
|
|
237
|
+
const line = content.substring(countPos, lineEnd);
|
|
238
|
+
if (line.includes('"type":"user"') || line.includes('"type":"assistant"')) {messageCount++;}
|
|
239
|
+
if (nl === -1) {break;}
|
|
240
|
+
countPos = nl + 1;
|
|
235
241
|
}
|
|
236
242
|
// Find the first real user message (skip system caveats, commands, tool results)
|
|
243
|
+
const lines = content.split('\n');
|
|
237
244
|
for (const line of lines) {
|
|
238
245
|
if (!line.trim()) {
|
|
239
246
|
continue;
|
|
@@ -320,23 +327,31 @@ function listSessionsForProject(projectDir: string): SessionInfo[] {
|
|
|
320
327
|
function readCwdFromProjectDir(projectDir: string, sessions: SessionInfo[]): string {
|
|
321
328
|
for (const session of sessions) {
|
|
322
329
|
try {
|
|
323
|
-
const
|
|
324
|
-
if (!fs.existsSync(
|
|
330
|
+
const filePath = path.join(projectDir, `${session.id}.jsonl`);
|
|
331
|
+
if (!fs.existsSync(filePath)) {
|
|
325
332
|
continue;
|
|
326
333
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
334
|
+
// Only read the first 4KB — cwd appears on line 1
|
|
335
|
+
const fd = fs.openSync(filePath, 'r');
|
|
336
|
+
let firstChunk: string;
|
|
337
|
+
try {
|
|
338
|
+
const buf = Buffer.alloc(4096);
|
|
339
|
+
const bytesRead = fs.readSync(fd, buf, 0, 4096, 0);
|
|
340
|
+
firstChunk = buf.toString('utf-8', 0, bytesRead);
|
|
341
|
+
} finally {
|
|
342
|
+
fs.closeSync(fd);
|
|
343
|
+
}
|
|
344
|
+
const firstLine = firstChunk.split('\n')[0];
|
|
345
|
+
if (!firstLine.trim()) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const entry = JSON.parse(firstLine) as Record<string, unknown>;
|
|
350
|
+
if (typeof entry.cwd === 'string' && entry.cwd) {
|
|
351
|
+
return entry.cwd;
|
|
339
352
|
}
|
|
353
|
+
} catch {
|
|
354
|
+
// skip malformed first line
|
|
340
355
|
}
|
|
341
356
|
} catch {
|
|
342
357
|
// skip unreadable files
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the path to the OpenCode SQLite database.
|
|
5
|
+
*
|
|
6
|
+
* Checks in this order:
|
|
7
|
+
* 1. XDG_DATA_HOME/opencode/opencode.db (honours XDG override)
|
|
8
|
+
* 2. ~/Library/Application Support/opencode/opencode.db (legacy macOS path)
|
|
9
|
+
* 3. ~/.local/share/opencode/opencode.db (XDG default)
|
|
10
|
+
*/
|
|
11
|
+
export function resolveOpenCodeDbPath(): string {
|
|
12
|
+
const home = process.env.HOME || '';
|
|
13
|
+
|
|
14
|
+
// 1. If XDG_DATA_HOME is explicitly set, use it
|
|
15
|
+
if (process.env.XDG_DATA_HOME) {
|
|
16
|
+
return path.join(process.env.XDG_DATA_HOME, 'opencode', 'opencode.db');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 2. Legacy macOS path (~/Library/Application Support/opencode/)
|
|
20
|
+
if (process.platform === 'darwin') {
|
|
21
|
+
return path.join(home, 'Library', 'Application Support', 'opencode', 'opencode.db');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 3. XDG default (~/.local/share/opencode/)
|
|
25
|
+
return path.join(home, '.local', 'share', 'opencode', 'opencode.db');
|
|
26
|
+
}
|