@deepseek-insight/dsi 0.8.5 → 0.9.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/.agents/skills/{dsi-gb-verifier → glass-dsi}/SKILL.md +57 -5
- package/.agents/skills/glass-dsi/references/cdp-verification.md +132 -0
- package/.agents/skills/glass-dsi/scripts/_connect.mjs +81 -0
- package/.agents/skills/glass-dsi/scripts/glass-url.mjs +48 -0
- package/.agents/skills/glass-dsi/scripts/glass.mjs +84 -0
- package/.agents/skills/glass-url/SKILL.md +117 -0
- package/.agents/skills/glass-url/scripts/_args.mjs +49 -0
- package/.agents/skills/glass-url/scripts/_connect.mjs +99 -0
- package/.agents/skills/glass-url/scripts/glass-url.mjs +114 -0
- package/bin/dsi.mjs +23 -74
- package/bin/lib/zai-patch.mjs +115 -0
- package/build/client/_app/immutable/assets/0.Ch5VtsKp.css +2 -0
- package/build/client/_app/immutable/assets/2.D0QOh44D.css +1 -0
- package/build/client/_app/immutable/chunks/{DwcY-69G.js → 02Wfo2G3.js} +1 -1
- package/build/client/_app/immutable/chunks/0Tfhif1V.js +3 -0
- package/build/client/_app/immutable/chunks/0ruuBBbh.js +2 -0
- package/build/client/_app/immutable/chunks/{DUCaFYlx.js → 4bHE1npv.js} +1 -1
- package/build/client/_app/immutable/chunks/{4cwyag_I.js → B4hDUAJl.js} +1 -1
- package/build/client/_app/immutable/chunks/{Cr2ck_ss.js → BIPXB-2I.js} +1 -1
- package/build/client/_app/immutable/chunks/{CeLBjOd9.js → BIgv-kQR.js} +1 -1
- package/build/client/_app/immutable/chunks/BK6k1nBs.js +1 -0
- package/build/client/_app/immutable/chunks/{SN3Efo-Q.js → BKwmKcDY.js} +1 -1
- package/build/client/_app/immutable/chunks/{CRFuOqJI.js → BORjuqef.js} +1 -1
- package/build/client/_app/immutable/chunks/{CH_bR_0j.js → BPmZB0-N.js} +1 -1
- package/build/client/_app/immutable/chunks/BROtno1Y.js +1 -0
- package/build/client/_app/immutable/chunks/{DEVxi5CK.js → BT5Iel00.js} +1 -1
- package/build/client/_app/immutable/chunks/{DdI16loP.js → BX3y_1Hh.js} +1 -1
- package/build/client/_app/immutable/chunks/{DuiFyTVb.js → Bea1gxLq.js} +1 -1
- package/build/client/_app/immutable/chunks/{D0uxHECr.js → BpkpgvVw.js} +1 -1
- package/build/client/_app/immutable/chunks/{CB55Rp7-.js → BreZS7EW.js} +1 -1
- package/build/client/_app/immutable/chunks/{BmDADyfH.js → BsS_byzk.js} +1 -1
- package/build/client/_app/immutable/chunks/{BWRXzjmQ.js → Bslg-dr5.js} +1 -1
- package/build/client/_app/immutable/chunks/{BkYT72a1.js → C-YczRN1.js} +1 -1
- package/build/client/_app/immutable/chunks/{DBKMIEwD.js → C2aW4lzo.js} +1 -1
- package/build/client/_app/immutable/chunks/{C4gs6zoI.js → C2qFXaz5.js} +1 -1
- package/build/client/_app/immutable/chunks/{BBd0nTHG.js → C5RyRpOh.js} +1 -1
- package/build/client/_app/immutable/chunks/{DJQr4efH.js → C5iHDVU_.js} +1 -1
- package/build/client/_app/immutable/chunks/{B4F5liKq.js → C7opVlLF.js} +1 -1
- package/build/client/_app/immutable/chunks/{DIxy2USu.js → CAuEkmZ4.js} +1 -1
- package/build/client/_app/immutable/chunks/{BO99LSSA.js → CIkiqgtA.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bpd0I3U7.js → CJesWaZn.js} +1 -1
- package/build/client/_app/immutable/chunks/{at6PQqQ4.js → CRsoS5Y9.js} +1 -1
- package/build/client/_app/immutable/chunks/CTWtsoJD.js +6 -0
- package/build/client/_app/immutable/chunks/CWk5gmU2.js +1 -0
- package/build/client/_app/immutable/chunks/{lF8CNVOA.js → CXkrluSK.js} +1 -1
- package/build/client/_app/immutable/chunks/{DmRY6FWm.js → C_8kFZ_X.js} +4 -4
- package/build/client/_app/immutable/chunks/{D6KenyiF.js → Ch7hUoAH.js} +1 -1
- package/build/client/_app/immutable/chunks/{b4-Ro8NH.js → ChmmHPdM.js} +1 -1
- package/build/client/_app/immutable/chunks/{DfUgh5E_.js → CjajmcJs.js} +1 -1
- package/build/client/_app/immutable/chunks/{q5PRaRZk.js → Ck6GS6Vb.js} +1 -1
- package/build/client/_app/immutable/chunks/{eFcFJ9Ld.js → ClGoDr_f.js} +1 -1
- package/build/client/_app/immutable/chunks/{BQC6O_RV.js → ClqGHlec.js} +1 -1
- package/build/client/_app/immutable/chunks/{zypfUZYM.js → CnW6hje6.js} +1 -1
- package/build/client/_app/immutable/chunks/{OW5Q7tGb.js → CpI6VYCH.js} +1 -1
- package/build/client/_app/immutable/chunks/{BXKc4uuX.js → CygwwaiE.js} +1 -1
- package/build/client/_app/immutable/chunks/{Bqwvv7Vf.js → CyhZtsZO.js} +35 -35
- package/build/client/_app/immutable/chunks/{BenkQ_4r.js → D-E2Noqq.js} +1 -1
- package/build/client/_app/immutable/chunks/{DuRZnRVw.js → D4Btzp_A.js} +1 -1
- package/build/client/_app/immutable/chunks/{CdaJvl_A.js → D4C3Jijv.js} +1 -1
- package/build/client/_app/immutable/chunks/D9jhmf3I.js +1 -0
- package/build/client/_app/immutable/chunks/{Cf0aMC4n.js → DCw0gAtv.js} +1 -1
- package/build/client/_app/immutable/chunks/{B6bTO8_7.js → DEW3KpiC.js} +1 -1
- package/build/client/_app/immutable/chunks/{O6xxeEm8.js → DYLFbKJe.js} +1 -1
- package/build/client/_app/immutable/chunks/{BsBBq-Qk.js → DYu7kgVa.js} +1 -1
- package/build/client/_app/immutable/chunks/Dfexc5qV.js +1 -0
- package/build/client/_app/immutable/chunks/{kzciT-3i.js → DhmUE8Ri.js} +1 -1
- package/build/client/_app/immutable/chunks/{DdJNsJBH.js → DjwX3rAC.js} +1 -1
- package/build/client/_app/immutable/chunks/{CajOZJDl.js → DlOfy8Sx.js} +1 -1
- package/build/client/_app/immutable/chunks/{CK5vhXvt.js → Do7Y1_MQ.js} +1 -1
- package/build/client/_app/immutable/chunks/{ap4GAVq-.js → Dq2XIb1m.js} +1 -1
- package/build/client/_app/immutable/chunks/{Czey8tDK.js → DuT_Qr5k.js} +1 -1
- package/build/client/_app/immutable/chunks/{4B6J_kM2.js → DyGggFea.js} +1 -1
- package/build/client/_app/immutable/chunks/{D0ChUnpi.js → Dym4i64U.js} +1 -1
- package/build/client/_app/immutable/chunks/FPsIAiN_.js +1 -0
- package/build/client/_app/immutable/chunks/{CevKuuic.js → GIczpP_D.js} +1 -1
- package/build/client/_app/immutable/chunks/{B2jrDnt8.js → LjOLSmU7.js} +1 -1
- package/build/client/_app/immutable/chunks/VtK73aN-.js +8 -0
- package/build/client/_app/immutable/chunks/{AcmOeh2U.js → ZqoQH_jm.js} +1 -1
- package/build/client/_app/immutable/chunks/{BlwWx85l.js → aXn6rE_7.js} +1 -1
- package/build/client/_app/immutable/chunks/{Czc4_W7v.js → dUOeoGwg.js} +1 -1
- package/build/client/_app/immutable/chunks/f50lp1rr.js +1 -0
- package/build/client/_app/immutable/chunks/{7FnrqGK9.js → lvLrv1cG.js} +1 -1
- package/build/client/_app/immutable/chunks/{CZoElI5B.js → pt3_jHwh.js} +1 -1
- package/build/client/_app/immutable/chunks/{Byu_teLA.js → q8irUX-p.js} +1 -1
- package/build/client/_app/immutable/chunks/{CnxoqrkQ.js → qmOgUo3c.js} +1 -1
- package/build/client/_app/immutable/chunks/vpNeypNM.js +1 -0
- package/build/client/_app/immutable/chunks/{DU8C5thd.js → xvTPLhcB.js} +1 -1
- package/build/client/_app/immutable/chunks/{DFBKiA2Z.js → zp7hrpsC.js} +1 -1
- package/build/client/_app/immutable/entry/app.D4oc_iez.js +2 -0
- package/build/client/_app/immutable/entry/start.Xkr2MCWg.js +1 -0
- package/build/client/_app/immutable/nodes/0.fsrqKU9i.js +1 -0
- package/build/client/_app/immutable/nodes/1.3F37GwcO.js +1 -0
- package/build/client/_app/immutable/nodes/2.DsWNNw0K.js +340 -0
- package/build/client/_app/version.json +1 -1
- package/build/handler.js +6 -6
- package/build/index.js +6 -6
- package/build/server/chunks/chunks/{app-config.svelte.js-DCc9d7A4.js → app-config.svelte.js-BXjvTmJu.js} +4 -3
- package/build/server/chunks/chunks/{config.js-s6iKwHD7.js → config.js-r_jw_bQQ.js} +53 -2
- package/build/server/chunks/chunks/{db.js-CxxWK5sn.js → db.js-f2PmBjyD.js} +2 -2
- package/build/server/chunks/chunks/{db2.js-DwJ9lySe.js → db2.js-DkwY64WO.js} +2 -2
- package/build/server/chunks/chunks/{dsh-connection.js-Chtudg1p.js → dsh-connection.js-BW07Aicl.js} +18 -10
- package/build/server/chunks/chunks/{dsh-events.js-BUdvZQmd.js → dsh-events.js-BHf0lLZ5.js} +11 -1
- package/build/server/chunks/chunks/{git-probe.js-BX9FPnet.js → git-probe.js-CQqTV7XX.js} +3 -3
- package/build/server/chunks/chunks/{index-server.js-DmIEbDVz.js → index-server.js-CPkVoRxB.js} +2 -2
- package/build/server/chunks/chunks/{insight-config.js-Db5fe5Df.js → insight-config.js-C5-Rhh5A.js} +13 -4
- package/build/server/chunks/chunks/{internal2.js-CaZaz-a9.js → internal2.js-DbC8VGqD.js} +4 -4
- package/build/server/chunks/chunks/{registry.js-syaTZ_-A.js → registry.js-CWnRQ4vx.js} +430 -52
- package/build/server/chunks/chunks/{registry2.js-D3Pr1Rv9.js → registry2.js-CFzpvj9c.js} +17 -1
- package/build/server/chunks/chunks/{server.js-B1bDXhHu.js → server.js-Dijo7DtV.js} +2 -2
- package/build/server/chunks/chunks/{settings-document.js-BHESJ7im.js → settings-document.js-DxKURfc_.js} +2 -2
- package/build/server/chunks/chunks/{state.js-oYjf745s.js → state.js-DR4xiIVw.js} +5 -5
- package/build/server/chunks/chunks/{watcher.js-Ci9jsM5l.js → watcher.js-DvlNn8X0.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-CHaYhzjy.js → _server.ts.js-DItDXV23.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-CdyqA85c.js → _server.ts.js-Hor8QZb1.js} +8 -8
- package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-DO_FS5b4.js → _server.ts.js-CEvvsa8B.js} +8 -8
- package/build/server/chunks/entries/endpoints/api/browser/_id_/activate/{_server.ts.js-D7Be4JUf.js → _server.ts.js-sXqf-okw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/close/{_server.ts.js-CGkm2H-U.js → _server.ts.js-Byj9ApJh.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/closetab/{_server.ts.js-D7SLUfOo.js → _server.ts.js-DOIsrzvg.js} +16 -9
- package/build/server/chunks/entries/endpoints/api/browser/_id_/element/{_server.ts.js-C3d_JV-q.js → _server.ts.js-Cq3gmRfE.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/history/_server.ts.js-BGSLIV0t.js +61 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/input/{_server.ts.js-DW0hyVML.js → _server.ts.js-8slca75-.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/mcp/{_server.ts.js-Ev-hdBlf.js → _server.ts.js-CpbdTYds.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/navigate/{_server.ts.js-DZ8-wocV.js → _server.ts.js-Bls9LtLY.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/opentab/{_server.ts.js-aapPrIQK.js → _server.ts.js-DqNi_iW_.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/page/{_server.ts.js-DANA_hMd.js → _server.ts.js-DuXWwo7i.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/stream/{_server.ts.js-BqfseXFy.js → _server.ts.js-DXfqBDEw.js} +17 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/tabs/{_server.ts.js-DFFF9qe-.js → _server.ts.js-Bgnl8lYs.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/viewport/{_server.ts.js-ek6-D4Zm.js → _server.ts.js-FHmQVbrv.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/zoom/_server.ts.js-BV4cBtSA.js +62 -0
- package/build/server/chunks/entries/endpoints/api/browser/{_server.ts.js-CPjKy3ma.js → _server.ts.js-4vgkwh7v.js} +9 -6
- package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-CWE9NP6g.js → _server.ts.js-C_9kwANR.js} +9 -6
- package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-D-raYQon.js → _server.ts.js-h1OTHcL4.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/{_server.ts.js-CI4dEHFY.js → _server.ts.js-B6nih9Sd.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/follow/{_server.ts.js-cnjoSLtY.js → _server.ts.js-Cf17SVmD.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-0UUtapX5.js → _server.ts.js-DjNwMbdS.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-MK5ezU8u.js → _server.ts.js-Cz5aaEhC.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-BFBy5O9Y.js +78 -0
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-wGEl1fuF.js → _server.ts.js-CgEdCo3T.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-Bz7u2BlD.js → _server.ts.js-Bo_aEnHh.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/changes/{_server.ts.js-yue5aEjr.js → _server.ts.js-Bd2G_GaH.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-BFSs5T2m.js → _server.ts.js-DL64FyRw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-C2i85wQy.js → _server.ts.js-MhOGB66D.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-_toO4f4W.js → _server.ts.js-MjPgXgGO.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-BGJnDV85.js → _server.ts.js-BUjDae5H.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-CQCJg8U8.js → _server.ts.js-dTKd7Hsv.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-0ADvdE79.js → _server.ts.js-B82rvKoI.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-DyO4T1Ro.js → _server.ts.js-Cqijsi-c.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-CIY7oimw.js → _server.ts.js-CL_vVv2p.js} +29 -6
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-B-9faNHX.js → _server.ts.js-WS4W9Ly4.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-E7-0zfiH.js → _server.ts.js-B72KGRGh.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-CODtLQ3Q.js → _server.ts.js-DK5xb2b5.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-BiSxsU-j.js → _server.ts.js-lhT87EQu.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-C0WJnv2b.js → _server.ts.js-CMhfhbkN.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/subagents/{_server.ts.js-D5bc4xg4.js → _server.ts.js-BLvcFsg6.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-23ycAyUg.js → _server.ts.js-D_rw2Uq6.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-B4w5Jh7f.js → _server.ts.js-DfXpMMpw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-VQLxDbFE.js → _server.ts.js-2mJCJVxk.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-vs5N5Cya.js → _server.ts.js-BCx0Lzjf.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-BOWhoBHV.js → _server.ts.js-DECaSjwp.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-aDEAGfJe.js → _server.ts.js-i_ciJzlb.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-BZ-nRrTp.js → _server.ts.js-BO1pScn7.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/use/{_server.ts.js-CkDY1PQ7.js → _server.ts.js-Buhpf7WE.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-CHvgF47Y.js → _server.ts.js-DngUQzcT.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/output/{_server.ts.js-BNBxebgG.js → _server.ts.js-DLETP4yQ.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/reattach/{_server.ts.js-DDRJBGIr.js → _server.ts.js-uWl6oxPS.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/send/{_server.ts.js-CA0vc_Cm.js → _server.ts.js-DYNmXaAd.js} +9 -2
- package/build/server/chunks/entries/endpoints/api/terminal/_id_/stream/{_server.ts.js-D6L8Gd_f.js → _server.ts.js-C5m3Ktho.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/{_server.ts.js-CbRT4vBo.js → _server.ts.js-DoTNvcOa.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-BwD0KaXy.js → _server.ts.js-BzYOJSkI.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-DgbMRh3d.js → _server.ts.js-xcNesei9.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-DRqZawic.js → _server.ts.js-DsJWYdxt.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-CTXwwwB1.js → _server.ts.js-CNCku9BR.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-B4aJBY2w.js → _server.ts.js-nLsNjOxj.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/write-gate/{_server.ts.js-CDJJA18L.js → _server.ts.js-urQk2-ds.js} +7 -7
- package/build/server/chunks/entries/{hooks.server.js-Iel6oE7w.js → hooks.server.js-CU2RE5vs.js} +3 -3
- package/build/server/chunks/entries/pages/{_error.svelte.js-B-wdFjVG.js → _error.svelte.js-e018KpwE.js} +6 -6
- package/build/server/chunks/entries/pages/{_page.server.ts.js-CaoeQzem.js → _page.server.ts.js-BK3Y6eff.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.svelte.js-CY7zcWr4.js → _page.svelte.js-DQWBiRk1.js} +2681 -648
- package/build/server/chunks/{handler-DYk4NJto.js → handler-DsD7I1_u.js} +3 -3
- package/build/server/chunks/{index.js-kL9MZ99b.js → index.js-C_WAkwJs.js} +4 -4
- package/build/server/chunks/{manifest.js-BrMLQqec.js → manifest.js-DUy52VaP.js} +79 -65
- package/build/server/chunks/nodes/{0.js-BembYTTr.js → 0.js-CuV3dXVD.js} +3 -3
- package/build/server/chunks/nodes/1.js-Dc5QC-NJ.js +9 -0
- package/build/server/chunks/nodes/{2.js-BezA2RPm.js → 2.js-PwcF4_kT.js} +10 -10
- package/package.json +2 -2
- package/template/.dsi/prompts.sqlite +0 -0
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/template/.dsi/settings.yaml +7 -2
- package/build/client/_app/immutable/assets/0.C6AGVUc8.css +0 -2
- package/build/client/_app/immutable/assets/2.gXzZuuwh.css +0 -1
- package/build/client/_app/immutable/chunks/BFOY8uwF.js +0 -1
- package/build/client/_app/immutable/chunks/BHDqH9nE.js +0 -1
- package/build/client/_app/immutable/chunks/CAneZX4t.js +0 -8
- package/build/client/_app/immutable/chunks/CrTRqozz.js +0 -1
- package/build/client/_app/immutable/chunks/DQXo7qdJ.js +0 -1
- package/build/client/_app/immutable/chunks/DxGYLnDH.js +0 -1
- package/build/client/_app/immutable/chunks/HD-mJtOS.js +0 -6
- package/build/client/_app/immutable/chunks/K3xyLTzZ.js +0 -1
- package/build/client/_app/immutable/chunks/cHj8EuyS.js +0 -3
- package/build/client/_app/immutable/chunks/hC0DBYN6.js +0 -2
- package/build/client/_app/immutable/chunks/o7DVZODA.js +0 -1
- package/build/client/_app/immutable/chunks/pdYhlwhf.js +0 -1
- package/build/client/_app/immutable/entry/app.DHewwbUQ.js +0 -2
- package/build/client/_app/immutable/entry/start.C0PcwkeZ.js +0 -1
- package/build/client/_app/immutable/nodes/0.CP10wY64.js +0 -1
- package/build/client/_app/immutable/nodes/1.qWvE0DiU.js +0 -1
- package/build/client/_app/immutable/nodes/2.Nw7iFtoh.js +0 -341
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/_server.ts.js-CEiMgzjC.js +0 -46
- package/build/server/chunks/nodes/1.js-CKJjyWGZ.js +0 -9
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { a as __exportAll, o as onDestroy } from '../../chunks/index-server.js-
|
|
1
|
+
import { a as __exportAll, o as onDestroy } from '../../chunks/index-server.js-CPkVoRxB.js';
|
|
2
2
|
import '../../chunks/exports.js-DH_tjtdv.js';
|
|
3
|
-
import { M as derived, V as head, T as writable,
|
|
4
|
-
import { U as UI_LOCALES } from '../../chunks/config.js-
|
|
3
|
+
import { M as derived, V as head, T as writable, X as attr, W as escape_html, Y as ensure_array_like, Z as attr_class, _ as attr_style, $ as stringify, a0 as bind_props, a as setContext, a1 as store_get, a2 as spread_props, a3 as attributes, a4 as clsx, a5 as element, g as getContext, a6 as unsubscribe_stores, a7 as html, r as run, a8 as props_id } from '../../chunks/server.js-Dijo7DtV.js';
|
|
4
|
+
import { U as UI_LOCALES } from '../../chunks/config.js-r_jw_bQQ.js';
|
|
5
5
|
import { m as mergeEntries, c as collapseSystemPromptEntries, t as truncate } from '../../chunks/merge.js-yMwW440S.js';
|
|
6
6
|
import { p as parseA2aSignature, m as mintA2aId, b as buildDeliveredText } from '../../chunks/a2a-protocol.js-C77mVg2Q.js';
|
|
7
7
|
import { b as applyKnobEvent, E as EMPTY_KNOBS, r as resolvePermission, l as localPermission, c as presetLabel, d as presetDescription, C as CUSTOM_PRESET, F as FULL_ACCESS_PRESET } from '../../chunks/permission-state.js-B7UpAHBv.js';
|
|
8
8
|
import { D as DEFAULT_IMAGE_LIMITS } from '../../chunks/image-limits.js-CUdJ0f7r.js';
|
|
9
9
|
import { s as sanitizeWorkspaceProfile, d as dsiKey, t as themePrefs } from '../../chunks/theme-prefs.svelte.js-8CaWz46g.js';
|
|
10
|
-
import { a as appConfig, p as previewSegments, b as parseTagWords, i as isValidTagWord, s as shouldRecordPrompt, g as getTrigger, t as triggerMode, c as searchKey, d as textPreviewOf } from '../../chunks/app-config.svelte.js-
|
|
10
|
+
import { a as appConfig, p as previewSegments, b as parseTagWords, i as isValidTagWord, s as shouldRecordPrompt, g as getTrigger, t as triggerMode, c as searchKey, d as textPreviewOf } from '../../chunks/app-config.svelte.js-BXjvTmJu.js';
|
|
11
11
|
import { c as getLocale } from '../../chunks/runtime.js-CCJi3XaY.js';
|
|
12
|
-
import { p as page, a as afterNavigate, t, c as currentLocale, e as replaceState, u as unexpectederror1, s as sessionnotfound2, r as reapednote1, d as dshunreachable1, b as backtoworkspace2 } from '../../chunks/state.js-
|
|
12
|
+
import { p as page, a as afterNavigate, t, c as currentLocale, e as replaceState, u as unexpectederror1, s as sessionnotfound2, r as reapednote1, d as dshunreachable1, b as backtoworkspace2 } from '../../chunks/state.js-DR4xiIVw.js';
|
|
13
13
|
import 'yaml';
|
|
14
14
|
import 'html-to-image';
|
|
15
15
|
import hljs from 'highlight.js/lib/core';
|
|
@@ -21,7 +21,7 @@ import xml from 'highlight.js/lib/languages/xml';
|
|
|
21
21
|
import css from 'highlight.js/lib/languages/css';
|
|
22
22
|
import '../../chunks/uneval.js-BJ9Qq2SF.js';
|
|
23
23
|
import '../../chunks/shared.js-HQ0rfhm4.js';
|
|
24
|
-
import '../../chunks/internal2.js-
|
|
24
|
+
import '../../chunks/internal2.js-DbC8VGqD.js';
|
|
25
25
|
import '../../chunks/utils.js-CAdNO8Tu.js';
|
|
26
26
|
|
|
27
27
|
//#region src/lib/paraglide/messages/abort.js
|
|
@@ -1336,6 +1336,38 @@ var browserreload1 = ((inputs = {}, options = {}) => {
|
|
|
1336
1336
|
return en_browserreload1();
|
|
1337
1337
|
});
|
|
1338
1338
|
//#endregion
|
|
1339
|
+
//#region src/lib/paraglide/messages/browsersessiondead2.js
|
|
1340
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1341
|
+
/** @typedef {{}} Browsersessiondead2Inputs */
|
|
1342
|
+
var en_browsersessiondead2 = () => {
|
|
1343
|
+
return `glass session closed — the browser behind this panel is gone`;
|
|
1344
|
+
};
|
|
1345
|
+
var zh_browsersessiondead2 = () => {
|
|
1346
|
+
return `glass 会话已关闭 — 该面板背后的浏览器已不存在`;
|
|
1347
|
+
};
|
|
1348
|
+
var id_browsersessiondead2 = () => {
|
|
1349
|
+
return `sesi glass ditutup — peramban di balik panel ini sudah tiada`;
|
|
1350
|
+
};
|
|
1351
|
+
var es_browsersessiondead2 = () => {
|
|
1352
|
+
return `sesión de glass cerrada — el navegador detrás de este panel ya no existe`;
|
|
1353
|
+
};
|
|
1354
|
+
/**
|
|
1355
|
+
* | output |
|
|
1356
|
+
* | --- |
|
|
1357
|
+
* | "glass session closed — the browser behind this panel is gone" |
|
|
1358
|
+
*
|
|
1359
|
+
* @param {Browsersessiondead2Inputs} inputs
|
|
1360
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1361
|
+
* @returns {LocalizedString}
|
|
1362
|
+
*/
|
|
1363
|
+
var browsersessiondead2 = ((inputs = {}, options = {}) => {
|
|
1364
|
+
const locale = options.locale ?? getLocale();
|
|
1365
|
+
if (locale === "zh") return zh_browsersessiondead2();
|
|
1366
|
+
if (locale === "id") return id_browsersessiondead2();
|
|
1367
|
+
if (locale === "es") return es_browsersessiondead2();
|
|
1368
|
+
return en_browsersessiondead2();
|
|
1369
|
+
});
|
|
1370
|
+
//#endregion
|
|
1339
1371
|
//#region src/lib/paraglide/messages/browsersessionfailed2.js
|
|
1340
1372
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1341
1373
|
/** @typedef {{ reason: NonNullable<unknown> }} Browsersessionfailed2Inputs */
|
|
@@ -1464,6 +1496,38 @@ var browserwaitingframes2 = ((inputs = {}, options = {}) => {
|
|
|
1464
1496
|
return en_browserwaitingframes2();
|
|
1465
1497
|
});
|
|
1466
1498
|
//#endregion
|
|
1499
|
+
//#region src/lib/paraglide/messages/browserzoom1.js
|
|
1500
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1501
|
+
/** @typedef {{}} Browserzoom1Inputs */
|
|
1502
|
+
var en_browserzoom1 = () => {
|
|
1503
|
+
return `Content zoom`;
|
|
1504
|
+
};
|
|
1505
|
+
var zh_browserzoom1 = () => {
|
|
1506
|
+
return `内容缩放`;
|
|
1507
|
+
};
|
|
1508
|
+
var id_browserzoom1 = () => {
|
|
1509
|
+
return `Zoom konten`;
|
|
1510
|
+
};
|
|
1511
|
+
var es_browserzoom1 = () => {
|
|
1512
|
+
return `Zoom de contenido`;
|
|
1513
|
+
};
|
|
1514
|
+
/**
|
|
1515
|
+
* | output |
|
|
1516
|
+
* | --- |
|
|
1517
|
+
* | "Content zoom" |
|
|
1518
|
+
*
|
|
1519
|
+
* @param {Browserzoom1Inputs} inputs
|
|
1520
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1521
|
+
* @returns {LocalizedString}
|
|
1522
|
+
*/
|
|
1523
|
+
var browserzoom1 = ((inputs = {}, options = {}) => {
|
|
1524
|
+
const locale = options.locale ?? getLocale();
|
|
1525
|
+
if (locale === "zh") return zh_browserzoom1();
|
|
1526
|
+
if (locale === "id") return id_browserzoom1();
|
|
1527
|
+
if (locale === "es") return es_browserzoom1();
|
|
1528
|
+
return en_browserzoom1();
|
|
1529
|
+
});
|
|
1530
|
+
//#endregion
|
|
1467
1531
|
//#region src/lib/paraglide/messages/cachehit1.js
|
|
1468
1532
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1469
1533
|
/** @typedef {{}} Cachehit1Inputs */
|
|
@@ -1688,6 +1752,70 @@ var choosefolder1 = ((inputs = {}, options = {}) => {
|
|
|
1688
1752
|
return en_choosefolder1();
|
|
1689
1753
|
});
|
|
1690
1754
|
//#endregion
|
|
1755
|
+
//#region src/lib/paraglide/messages/chordarmedlabel2.js
|
|
1756
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1757
|
+
/** @typedef {{}} Chordarmedlabel2Inputs */
|
|
1758
|
+
var en_chordarmedlabel2 = () => {
|
|
1759
|
+
return `Alt+S chord armed — next key`;
|
|
1760
|
+
};
|
|
1761
|
+
var zh_chordarmedlabel2 = () => {
|
|
1762
|
+
return `Alt+S 组合键已就绪 — 下一个按键`;
|
|
1763
|
+
};
|
|
1764
|
+
var id_chordarmedlabel2 = () => {
|
|
1765
|
+
return `Kord Alt+S armed — tombol berikutnya`;
|
|
1766
|
+
};
|
|
1767
|
+
var es_chordarmedlabel2 = () => {
|
|
1768
|
+
return `Acordo Alt+S armado — siguiente tecla`;
|
|
1769
|
+
};
|
|
1770
|
+
/**
|
|
1771
|
+
* | output |
|
|
1772
|
+
* | --- |
|
|
1773
|
+
* | "Alt+S chord armed — next key" |
|
|
1774
|
+
*
|
|
1775
|
+
* @param {Chordarmedlabel2Inputs} inputs
|
|
1776
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1777
|
+
* @returns {LocalizedString}
|
|
1778
|
+
*/
|
|
1779
|
+
var chordarmedlabel2 = ((inputs = {}, options = {}) => {
|
|
1780
|
+
const locale = options.locale ?? getLocale();
|
|
1781
|
+
if (locale === "zh") return zh_chordarmedlabel2();
|
|
1782
|
+
if (locale === "id") return id_chordarmedlabel2();
|
|
1783
|
+
if (locale === "es") return es_chordarmedlabel2();
|
|
1784
|
+
return en_chordarmedlabel2();
|
|
1785
|
+
});
|
|
1786
|
+
//#endregion
|
|
1787
|
+
//#region src/lib/paraglide/messages/chordarmedtitle2.js
|
|
1788
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1789
|
+
/** @typedef {{}} Chordarmedtitle2Inputs */
|
|
1790
|
+
var en_chordarmedtitle2 = () => {
|
|
1791
|
+
return `Alt+S armed`;
|
|
1792
|
+
};
|
|
1793
|
+
var zh_chordarmedtitle2 = () => {
|
|
1794
|
+
return `Alt+S 已就绪`;
|
|
1795
|
+
};
|
|
1796
|
+
var id_chordarmedtitle2 = () => {
|
|
1797
|
+
return `Alt+S diarmed`;
|
|
1798
|
+
};
|
|
1799
|
+
var es_chordarmedtitle2 = () => {
|
|
1800
|
+
return `Alt+S armado`;
|
|
1801
|
+
};
|
|
1802
|
+
/**
|
|
1803
|
+
* | output |
|
|
1804
|
+
* | --- |
|
|
1805
|
+
* | "Alt+S armed" |
|
|
1806
|
+
*
|
|
1807
|
+
* @param {Chordarmedtitle2Inputs} inputs
|
|
1808
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1809
|
+
* @returns {LocalizedString}
|
|
1810
|
+
*/
|
|
1811
|
+
var chordarmedtitle2 = ((inputs = {}, options = {}) => {
|
|
1812
|
+
const locale = options.locale ?? getLocale();
|
|
1813
|
+
if (locale === "zh") return zh_chordarmedtitle2();
|
|
1814
|
+
if (locale === "id") return id_chordarmedtitle2();
|
|
1815
|
+
if (locale === "es") return es_chordarmedtitle2();
|
|
1816
|
+
return en_chordarmedtitle2();
|
|
1817
|
+
});
|
|
1818
|
+
//#endregion
|
|
1691
1819
|
//#region src/lib/paraglide/messages/clearbtn1.js
|
|
1692
1820
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1693
1821
|
/** @typedef {{}} Clearbtn1Inputs */
|
|
@@ -3288,6 +3416,38 @@ var ctxchipcontext2 = ((inputs = {}, options = {}) => {
|
|
|
3288
3416
|
return en_ctxchipcontext2();
|
|
3289
3417
|
});
|
|
3290
3418
|
//#endregion
|
|
3419
|
+
//#region src/lib/paraglide/messages/ctxchipgoal2.js
|
|
3420
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
3421
|
+
/** @typedef {{}} Ctxchipgoal2Inputs */
|
|
3422
|
+
var en_ctxchipgoal2 = () => {
|
|
3423
|
+
return `goal`;
|
|
3424
|
+
};
|
|
3425
|
+
var zh_ctxchipgoal2 = () => {
|
|
3426
|
+
return `目标`;
|
|
3427
|
+
};
|
|
3428
|
+
var id_ctxchipgoal2 = () => {
|
|
3429
|
+
return `tujuan`;
|
|
3430
|
+
};
|
|
3431
|
+
var es_ctxchipgoal2 = () => {
|
|
3432
|
+
return `meta`;
|
|
3433
|
+
};
|
|
3434
|
+
/**
|
|
3435
|
+
* | output |
|
|
3436
|
+
* | --- |
|
|
3437
|
+
* | "goal" |
|
|
3438
|
+
*
|
|
3439
|
+
* @param {Ctxchipgoal2Inputs} inputs
|
|
3440
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
3441
|
+
* @returns {LocalizedString}
|
|
3442
|
+
*/
|
|
3443
|
+
var ctxchipgoal2 = ((inputs = {}, options = {}) => {
|
|
3444
|
+
const locale = options.locale ?? getLocale();
|
|
3445
|
+
if (locale === "zh") return zh_ctxchipgoal2();
|
|
3446
|
+
if (locale === "id") return id_ctxchipgoal2();
|
|
3447
|
+
if (locale === "es") return es_ctxchipgoal2();
|
|
3448
|
+
return en_ctxchipgoal2();
|
|
3449
|
+
});
|
|
3450
|
+
//#endregion
|
|
3291
3451
|
//#region src/lib/paraglide/messages/ctxchipinjected2.js
|
|
3292
3452
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
3293
3453
|
/** @typedef {{}} Ctxchipinjected2Inputs */
|
|
@@ -3480,6 +3640,70 @@ var ctxchipskills2 = ((inputs = {}, options = {}) => {
|
|
|
3480
3640
|
return en_ctxchipskills2();
|
|
3481
3641
|
});
|
|
3482
3642
|
//#endregion
|
|
3643
|
+
//#region src/lib/paraglide/messages/ctxchiptimecontext3.js
|
|
3644
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
3645
|
+
/** @typedef {{}} Ctxchiptimecontext3Inputs */
|
|
3646
|
+
var en_ctxchiptimecontext3 = () => {
|
|
3647
|
+
return `time context`;
|
|
3648
|
+
};
|
|
3649
|
+
var zh_ctxchiptimecontext3 = () => {
|
|
3650
|
+
return `时间上下文`;
|
|
3651
|
+
};
|
|
3652
|
+
var id_ctxchiptimecontext3 = () => {
|
|
3653
|
+
return `konteks waktu`;
|
|
3654
|
+
};
|
|
3655
|
+
var es_ctxchiptimecontext3 = () => {
|
|
3656
|
+
return `contexto temporal`;
|
|
3657
|
+
};
|
|
3658
|
+
/**
|
|
3659
|
+
* | output |
|
|
3660
|
+
* | --- |
|
|
3661
|
+
* | "time context" |
|
|
3662
|
+
*
|
|
3663
|
+
* @param {Ctxchiptimecontext3Inputs} inputs
|
|
3664
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
3665
|
+
* @returns {LocalizedString}
|
|
3666
|
+
*/
|
|
3667
|
+
var ctxchiptimecontext3 = ((inputs = {}, options = {}) => {
|
|
3668
|
+
const locale = options.locale ?? getLocale();
|
|
3669
|
+
if (locale === "zh") return zh_ctxchiptimecontext3();
|
|
3670
|
+
if (locale === "id") return id_ctxchiptimecontext3();
|
|
3671
|
+
if (locale === "es") return es_ctxchiptimecontext3();
|
|
3672
|
+
return en_ctxchiptimecontext3();
|
|
3673
|
+
});
|
|
3674
|
+
//#endregion
|
|
3675
|
+
//#region src/lib/paraglide/messages/ctxchiptoolgoal3.js
|
|
3676
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
3677
|
+
/** @typedef {{}} Ctxchiptoolgoal3Inputs */
|
|
3678
|
+
var en_ctxchiptoolgoal3 = () => {
|
|
3679
|
+
return `tool goal`;
|
|
3680
|
+
};
|
|
3681
|
+
var zh_ctxchiptoolgoal3 = () => {
|
|
3682
|
+
return `工具目标`;
|
|
3683
|
+
};
|
|
3684
|
+
var id_ctxchiptoolgoal3 = () => {
|
|
3685
|
+
return `tujuan alat`;
|
|
3686
|
+
};
|
|
3687
|
+
var es_ctxchiptoolgoal3 = () => {
|
|
3688
|
+
return `meta de herramienta`;
|
|
3689
|
+
};
|
|
3690
|
+
/**
|
|
3691
|
+
* | output |
|
|
3692
|
+
* | --- |
|
|
3693
|
+
* | "tool goal" |
|
|
3694
|
+
*
|
|
3695
|
+
* @param {Ctxchiptoolgoal3Inputs} inputs
|
|
3696
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
3697
|
+
* @returns {LocalizedString}
|
|
3698
|
+
*/
|
|
3699
|
+
var ctxchiptoolgoal3 = ((inputs = {}, options = {}) => {
|
|
3700
|
+
const locale = options.locale ?? getLocale();
|
|
3701
|
+
if (locale === "zh") return zh_ctxchiptoolgoal3();
|
|
3702
|
+
if (locale === "id") return id_ctxchiptoolgoal3();
|
|
3703
|
+
if (locale === "es") return es_ctxchiptoolgoal3();
|
|
3704
|
+
return en_ctxchiptoolgoal3();
|
|
3705
|
+
});
|
|
3706
|
+
//#endregion
|
|
3483
3707
|
//#region src/lib/paraglide/messages/ctxchipuserapproval3.js
|
|
3484
3708
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
3485
3709
|
/** @typedef {{}} Ctxchipuserapproval3Inputs */
|
|
@@ -4952,38 +5176,6 @@ var fileeyediff2 = ((inputs = {}, options = {}) => {
|
|
|
4952
5176
|
return en_fileeyediff2();
|
|
4953
5177
|
});
|
|
4954
5178
|
//#endregion
|
|
4955
|
-
//#region src/lib/paraglide/messages/fileeyeedit2.js
|
|
4956
|
-
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
4957
|
-
/** @typedef {{}} Fileeyeedit2Inputs */
|
|
4958
|
-
var en_fileeyeedit2 = () => {
|
|
4959
|
-
return `Edit`;
|
|
4960
|
-
};
|
|
4961
|
-
var zh_fileeyeedit2 = () => {
|
|
4962
|
-
return `编辑`;
|
|
4963
|
-
};
|
|
4964
|
-
var id_fileeyeedit2 = () => {
|
|
4965
|
-
return `Edit`;
|
|
4966
|
-
};
|
|
4967
|
-
var es_fileeyeedit2 = () => {
|
|
4968
|
-
return `Editar`;
|
|
4969
|
-
};
|
|
4970
|
-
/**
|
|
4971
|
-
* | output |
|
|
4972
|
-
* | --- |
|
|
4973
|
-
* | "Edit" |
|
|
4974
|
-
*
|
|
4975
|
-
* @param {Fileeyeedit2Inputs} inputs
|
|
4976
|
-
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
4977
|
-
* @returns {LocalizedString}
|
|
4978
|
-
*/
|
|
4979
|
-
var fileeyeedit2 = ((inputs = {}, options = {}) => {
|
|
4980
|
-
const locale = options.locale ?? getLocale();
|
|
4981
|
-
if (locale === "zh") return zh_fileeyeedit2();
|
|
4982
|
-
if (locale === "id") return id_fileeyeedit2();
|
|
4983
|
-
if (locale === "es") return es_fileeyeedit2();
|
|
4984
|
-
return en_fileeyeedit2();
|
|
4985
|
-
});
|
|
4986
|
-
//#endregion
|
|
4987
5179
|
//#region src/lib/paraglide/messages/fileeyeexternalchange3.js
|
|
4988
5180
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
4989
5181
|
/** @typedef {{}} Fileeyeexternalchange3Inputs */
|
|
@@ -5048,6 +5240,38 @@ var fileeyenewfile3 = ((inputs = {}, options = {}) => {
|
|
|
5048
5240
|
return en_fileeyenewfile3();
|
|
5049
5241
|
});
|
|
5050
5242
|
//#endregion
|
|
5243
|
+
//#region src/lib/paraglide/messages/fileeyepreview2.js
|
|
5244
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
5245
|
+
/** @typedef {{}} Fileeyepreview2Inputs */
|
|
5246
|
+
var en_fileeyepreview2 = () => {
|
|
5247
|
+
return `Preview`;
|
|
5248
|
+
};
|
|
5249
|
+
var zh_fileeyepreview2 = () => {
|
|
5250
|
+
return `预览`;
|
|
5251
|
+
};
|
|
5252
|
+
var id_fileeyepreview2 = () => {
|
|
5253
|
+
return `Pratinjau`;
|
|
5254
|
+
};
|
|
5255
|
+
var es_fileeyepreview2 = () => {
|
|
5256
|
+
return `Vista previa`;
|
|
5257
|
+
};
|
|
5258
|
+
/**
|
|
5259
|
+
* | output |
|
|
5260
|
+
* | --- |
|
|
5261
|
+
* | "Preview" |
|
|
5262
|
+
*
|
|
5263
|
+
* @param {Fileeyepreview2Inputs} inputs
|
|
5264
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
5265
|
+
* @returns {LocalizedString}
|
|
5266
|
+
*/
|
|
5267
|
+
var fileeyepreview2 = ((inputs = {}, options = {}) => {
|
|
5268
|
+
const locale = options.locale ?? getLocale();
|
|
5269
|
+
if (locale === "zh") return zh_fileeyepreview2();
|
|
5270
|
+
if (locale === "id") return id_fileeyepreview2();
|
|
5271
|
+
if (locale === "es") return es_fileeyepreview2();
|
|
5272
|
+
return en_fileeyepreview2();
|
|
5273
|
+
});
|
|
5274
|
+
//#endregion
|
|
5051
5275
|
//#region src/lib/paraglide/messages/fileeyereadonly3.js
|
|
5052
5276
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
5053
5277
|
/** @typedef {{}} Fileeyereadonly3Inputs */
|
|
@@ -6264,6 +6488,38 @@ var injectedtitle1 = ((inputs = {}, options = {}) => {
|
|
|
6264
6488
|
return en_injectedtitle1();
|
|
6265
6489
|
});
|
|
6266
6490
|
//#endregion
|
|
6491
|
+
//#region src/lib/paraglide/messages/jobtailempty2.js
|
|
6492
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
6493
|
+
/** @typedef {{}} Jobtailempty2Inputs */
|
|
6494
|
+
var en_jobtailempty2 = () => {
|
|
6495
|
+
return `no output — the command wrote nothing to the job's log`;
|
|
6496
|
+
};
|
|
6497
|
+
var zh_jobtailempty2 = () => {
|
|
6498
|
+
return `无输出 — 命令未向作业日志写入任何内容`;
|
|
6499
|
+
};
|
|
6500
|
+
var id_jobtailempty2 = () => {
|
|
6501
|
+
return `tidak ada output — perintah tidak menulis apa pun ke log pekerjaan`;
|
|
6502
|
+
};
|
|
6503
|
+
var es_jobtailempty2 = () => {
|
|
6504
|
+
return `sin salida — el comando no escribió nada en el registro del trabajo`;
|
|
6505
|
+
};
|
|
6506
|
+
/**
|
|
6507
|
+
* | output |
|
|
6508
|
+
* | --- |
|
|
6509
|
+
* | "no output — the command wrote nothing to the job's log" |
|
|
6510
|
+
*
|
|
6511
|
+
* @param {Jobtailempty2Inputs} inputs
|
|
6512
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
6513
|
+
* @returns {LocalizedString}
|
|
6514
|
+
*/
|
|
6515
|
+
var jobtailempty2 = ((inputs = {}, options = {}) => {
|
|
6516
|
+
const locale = options.locale ?? getLocale();
|
|
6517
|
+
if (locale === "zh") return zh_jobtailempty2();
|
|
6518
|
+
if (locale === "id") return id_jobtailempty2();
|
|
6519
|
+
if (locale === "es") return es_jobtailempty2();
|
|
6520
|
+
return en_jobtailempty2();
|
|
6521
|
+
});
|
|
6522
|
+
//#endregion
|
|
6267
6523
|
//#region src/lib/paraglide/messages/jobtailwaiting2.js
|
|
6268
6524
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
6269
6525
|
/** @typedef {{}} Jobtailwaiting2Inputs */
|
|
@@ -8632,6 +8888,38 @@ var planmode1 = ((inputs = {}, options = {}) => {
|
|
|
8632
8888
|
return en_planmode1();
|
|
8633
8889
|
});
|
|
8634
8890
|
//#endregion
|
|
8891
|
+
//#region src/lib/paraglide/messages/pluginrackapplynote3.js
|
|
8892
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
8893
|
+
/** @typedef {{}} Pluginrackapplynote3Inputs */
|
|
8894
|
+
var en_pluginrackapplynote3 = () => {
|
|
8895
|
+
return `The apply finished while the floor was down — the list below is already refreshed.`;
|
|
8896
|
+
};
|
|
8897
|
+
var zh_pluginrackapplynote3 = () => {
|
|
8898
|
+
return `应用已在页面下线期间完成 — 下面的列表已是最新。`;
|
|
8899
|
+
};
|
|
8900
|
+
var id_pluginrackapplynote3 = () => {
|
|
8901
|
+
return `Penerapan selesai saat lantai mati — daftar di bawah sudah diperbarui.`;
|
|
8902
|
+
};
|
|
8903
|
+
var es_pluginrackapplynote3 = () => {
|
|
8904
|
+
return `La aplicación terminó mientras el piso estaba caído — la lista de abajo ya está actualizada.`;
|
|
8905
|
+
};
|
|
8906
|
+
/**
|
|
8907
|
+
* | output |
|
|
8908
|
+
* | --- |
|
|
8909
|
+
* | "The apply finished while the floor was down — the list below is already refreshed." |
|
|
8910
|
+
*
|
|
8911
|
+
* @param {Pluginrackapplynote3Inputs} inputs
|
|
8912
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
8913
|
+
* @returns {LocalizedString}
|
|
8914
|
+
*/
|
|
8915
|
+
var pluginrackapplynote3 = ((inputs = {}, options = {}) => {
|
|
8916
|
+
const locale = options.locale ?? getLocale();
|
|
8917
|
+
if (locale === "zh") return zh_pluginrackapplynote3();
|
|
8918
|
+
if (locale === "id") return id_pluginrackapplynote3();
|
|
8919
|
+
if (locale === "es") return es_pluginrackapplynote3();
|
|
8920
|
+
return en_pluginrackapplynote3();
|
|
8921
|
+
});
|
|
8922
|
+
//#endregion
|
|
8635
8923
|
//#region src/lib/paraglide/messages/pluginrackapplying2.js
|
|
8636
8924
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
8637
8925
|
/** @typedef {{}} Pluginrackapplying2Inputs */
|
|
@@ -13176,6 +13464,134 @@ var terminaltabclose2 = ((inputs = {}, options = {}) => {
|
|
|
13176
13464
|
return en_terminaltabclose2();
|
|
13177
13465
|
});
|
|
13178
13466
|
//#endregion
|
|
13467
|
+
//#region src/lib/paraglide/messages/terminaltabsclear2.js
|
|
13468
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13469
|
+
/** @typedef {{}} Terminaltabsclear2Inputs */
|
|
13470
|
+
var en_terminaltabsclear2 = () => {
|
|
13471
|
+
return `Clear tabs`;
|
|
13472
|
+
};
|
|
13473
|
+
var zh_terminaltabsclear2 = () => {
|
|
13474
|
+
return `清除标签`;
|
|
13475
|
+
};
|
|
13476
|
+
var id_terminaltabsclear2 = () => {
|
|
13477
|
+
return `Bersihkan tab`;
|
|
13478
|
+
};
|
|
13479
|
+
var es_terminaltabsclear2 = () => {
|
|
13480
|
+
return `Limpiar pestañas`;
|
|
13481
|
+
};
|
|
13482
|
+
/**
|
|
13483
|
+
* | output |
|
|
13484
|
+
* | --- |
|
|
13485
|
+
* | "Clear tabs" |
|
|
13486
|
+
*
|
|
13487
|
+
* @param {Terminaltabsclear2Inputs} inputs
|
|
13488
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
13489
|
+
* @returns {LocalizedString}
|
|
13490
|
+
*/
|
|
13491
|
+
var terminaltabsclear2 = ((inputs = {}, options = {}) => {
|
|
13492
|
+
const locale = options.locale ?? getLocale();
|
|
13493
|
+
if (locale === "zh") return zh_terminaltabsclear2();
|
|
13494
|
+
if (locale === "id") return id_terminaltabsclear2();
|
|
13495
|
+
if (locale === "es") return es_terminaltabsclear2();
|
|
13496
|
+
return en_terminaltabsclear2();
|
|
13497
|
+
});
|
|
13498
|
+
//#endregion
|
|
13499
|
+
//#region src/lib/paraglide/messages/terminaltabsclearall3.js
|
|
13500
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13501
|
+
/** @typedef {{}} Terminaltabsclearall3Inputs */
|
|
13502
|
+
var en_terminaltabsclearall3 = () => {
|
|
13503
|
+
return `Clear all`;
|
|
13504
|
+
};
|
|
13505
|
+
var zh_terminaltabsclearall3 = () => {
|
|
13506
|
+
return `全部清除`;
|
|
13507
|
+
};
|
|
13508
|
+
var id_terminaltabsclearall3 = () => {
|
|
13509
|
+
return `Bersihkan semua`;
|
|
13510
|
+
};
|
|
13511
|
+
var es_terminaltabsclearall3 = () => {
|
|
13512
|
+
return `Limpiar todo`;
|
|
13513
|
+
};
|
|
13514
|
+
/**
|
|
13515
|
+
* | output |
|
|
13516
|
+
* | --- |
|
|
13517
|
+
* | "Clear all" |
|
|
13518
|
+
*
|
|
13519
|
+
* @param {Terminaltabsclearall3Inputs} inputs
|
|
13520
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
13521
|
+
* @returns {LocalizedString}
|
|
13522
|
+
*/
|
|
13523
|
+
var terminaltabsclearall3 = ((inputs = {}, options = {}) => {
|
|
13524
|
+
const locale = options.locale ?? getLocale();
|
|
13525
|
+
if (locale === "zh") return zh_terminaltabsclearall3();
|
|
13526
|
+
if (locale === "id") return id_terminaltabsclearall3();
|
|
13527
|
+
if (locale === "es") return es_terminaltabsclearall3();
|
|
13528
|
+
return en_terminaltabsclearall3();
|
|
13529
|
+
});
|
|
13530
|
+
//#endregion
|
|
13531
|
+
//#region src/lib/paraglide/messages/terminaltabsclearjobs3.js
|
|
13532
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13533
|
+
/** @typedef {{}} Terminaltabsclearjobs3Inputs */
|
|
13534
|
+
var en_terminaltabsclearjobs3 = () => {
|
|
13535
|
+
return `Clear jobs`;
|
|
13536
|
+
};
|
|
13537
|
+
var zh_terminaltabsclearjobs3 = () => {
|
|
13538
|
+
return `清除任务`;
|
|
13539
|
+
};
|
|
13540
|
+
var id_terminaltabsclearjobs3 = () => {
|
|
13541
|
+
return `Bersihkan job`;
|
|
13542
|
+
};
|
|
13543
|
+
var es_terminaltabsclearjobs3 = () => {
|
|
13544
|
+
return `Limpiar jobs`;
|
|
13545
|
+
};
|
|
13546
|
+
/**
|
|
13547
|
+
* | output |
|
|
13548
|
+
* | --- |
|
|
13549
|
+
* | "Clear jobs" |
|
|
13550
|
+
*
|
|
13551
|
+
* @param {Terminaltabsclearjobs3Inputs} inputs
|
|
13552
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
13553
|
+
* @returns {LocalizedString}
|
|
13554
|
+
*/
|
|
13555
|
+
var terminaltabsclearjobs3 = ((inputs = {}, options = {}) => {
|
|
13556
|
+
const locale = options.locale ?? getLocale();
|
|
13557
|
+
if (locale === "zh") return zh_terminaltabsclearjobs3();
|
|
13558
|
+
if (locale === "id") return id_terminaltabsclearjobs3();
|
|
13559
|
+
if (locale === "es") return es_terminaltabsclearjobs3();
|
|
13560
|
+
return en_terminaltabsclearjobs3();
|
|
13561
|
+
});
|
|
13562
|
+
//#endregion
|
|
13563
|
+
//#region src/lib/paraglide/messages/terminaltabsclearterminals3.js
|
|
13564
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13565
|
+
/** @typedef {{}} Terminaltabsclearterminals3Inputs */
|
|
13566
|
+
var en_terminaltabsclearterminals3 = () => {
|
|
13567
|
+
return `Clear terminals`;
|
|
13568
|
+
};
|
|
13569
|
+
var zh_terminaltabsclearterminals3 = () => {
|
|
13570
|
+
return `清除终端`;
|
|
13571
|
+
};
|
|
13572
|
+
var id_terminaltabsclearterminals3 = () => {
|
|
13573
|
+
return `Bersihkan terminal`;
|
|
13574
|
+
};
|
|
13575
|
+
var es_terminaltabsclearterminals3 = () => {
|
|
13576
|
+
return `Limpiar terminales`;
|
|
13577
|
+
};
|
|
13578
|
+
/**
|
|
13579
|
+
* | output |
|
|
13580
|
+
* | --- |
|
|
13581
|
+
* | "Clear terminals" |
|
|
13582
|
+
*
|
|
13583
|
+
* @param {Terminaltabsclearterminals3Inputs} inputs
|
|
13584
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
13585
|
+
* @returns {LocalizedString}
|
|
13586
|
+
*/
|
|
13587
|
+
var terminaltabsclearterminals3 = ((inputs = {}, options = {}) => {
|
|
13588
|
+
const locale = options.locale ?? getLocale();
|
|
13589
|
+
if (locale === "zh") return zh_terminaltabsclearterminals3();
|
|
13590
|
+
if (locale === "id") return id_terminaltabsclearterminals3();
|
|
13591
|
+
if (locale === "es") return es_terminaltabsclearterminals3();
|
|
13592
|
+
return en_terminaltabsclearterminals3();
|
|
13593
|
+
});
|
|
13594
|
+
//#endregion
|
|
13179
13595
|
//#region src/lib/paraglide/messages/text.js
|
|
13180
13596
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13181
13597
|
/** @typedef {{}} TextInputs */
|
|
@@ -14584,6 +15000,38 @@ var workspaceexplorerempty2 = ((inputs = {}, options = {}) => {
|
|
|
14584
15000
|
return en_workspaceexplorerempty2();
|
|
14585
15001
|
});
|
|
14586
15002
|
//#endregion
|
|
15003
|
+
//#region src/lib/paraglide/messages/workspaceexplorerhide2.js
|
|
15004
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15005
|
+
/** @typedef {{}} Workspaceexplorerhide2Inputs */
|
|
15006
|
+
var en_workspaceexplorerhide2 = () => {
|
|
15007
|
+
return `Hide explorer`;
|
|
15008
|
+
};
|
|
15009
|
+
var zh_workspaceexplorerhide2 = () => {
|
|
15010
|
+
return `隐藏资源管理器`;
|
|
15011
|
+
};
|
|
15012
|
+
var id_workspaceexplorerhide2 = () => {
|
|
15013
|
+
return `Sembunyikan explorer`;
|
|
15014
|
+
};
|
|
15015
|
+
var es_workspaceexplorerhide2 = () => {
|
|
15016
|
+
return `Ocultar explorador`;
|
|
15017
|
+
};
|
|
15018
|
+
/**
|
|
15019
|
+
* | output |
|
|
15020
|
+
* | --- |
|
|
15021
|
+
* | "Hide explorer" |
|
|
15022
|
+
*
|
|
15023
|
+
* @param {Workspaceexplorerhide2Inputs} inputs
|
|
15024
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15025
|
+
* @returns {LocalizedString}
|
|
15026
|
+
*/
|
|
15027
|
+
var workspaceexplorerhide2 = ((inputs = {}, options = {}) => {
|
|
15028
|
+
const locale = options.locale ?? getLocale();
|
|
15029
|
+
if (locale === "zh") return zh_workspaceexplorerhide2();
|
|
15030
|
+
if (locale === "id") return id_workspaceexplorerhide2();
|
|
15031
|
+
if (locale === "es") return es_workspaceexplorerhide2();
|
|
15032
|
+
return en_workspaceexplorerhide2();
|
|
15033
|
+
});
|
|
15034
|
+
//#endregion
|
|
14587
15035
|
//#region src/lib/paraglide/messages/workspaceexplorerloadfailed3.js
|
|
14588
15036
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
14589
15037
|
/** @typedef {{}} Workspaceexplorerloadfailed3Inputs */
|
|
@@ -14648,6 +15096,38 @@ var workspaceexplorerloading2 = ((inputs = {}, options = {}) => {
|
|
|
14648
15096
|
return en_workspaceexplorerloading2();
|
|
14649
15097
|
});
|
|
14650
15098
|
//#endregion
|
|
15099
|
+
//#region src/lib/paraglide/messages/workspaceexplorershow2.js
|
|
15100
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15101
|
+
/** @typedef {{}} Workspaceexplorershow2Inputs */
|
|
15102
|
+
var en_workspaceexplorershow2 = () => {
|
|
15103
|
+
return `Show explorer`;
|
|
15104
|
+
};
|
|
15105
|
+
var zh_workspaceexplorershow2 = () => {
|
|
15106
|
+
return `显示资源管理器`;
|
|
15107
|
+
};
|
|
15108
|
+
var id_workspaceexplorershow2 = () => {
|
|
15109
|
+
return `Tampilkan explorer`;
|
|
15110
|
+
};
|
|
15111
|
+
var es_workspaceexplorershow2 = () => {
|
|
15112
|
+
return `Mostrar explorador`;
|
|
15113
|
+
};
|
|
15114
|
+
/**
|
|
15115
|
+
* | output |
|
|
15116
|
+
* | --- |
|
|
15117
|
+
* | "Show explorer" |
|
|
15118
|
+
*
|
|
15119
|
+
* @param {Workspaceexplorershow2Inputs} inputs
|
|
15120
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15121
|
+
* @returns {LocalizedString}
|
|
15122
|
+
*/
|
|
15123
|
+
var workspaceexplorershow2 = ((inputs = {}, options = {}) => {
|
|
15124
|
+
const locale = options.locale ?? getLocale();
|
|
15125
|
+
if (locale === "zh") return zh_workspaceexplorershow2();
|
|
15126
|
+
if (locale === "id") return id_workspaceexplorershow2();
|
|
15127
|
+
if (locale === "es") return es_workspaceexplorershow2();
|
|
15128
|
+
return en_workspaceexplorershow2();
|
|
15129
|
+
});
|
|
15130
|
+
//#endregion
|
|
14651
15131
|
//#region src/lib/paraglide/messages/workspaceexplorertitle2.js
|
|
14652
15132
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
14653
15133
|
/** @typedef {{}} Workspaceexplorertitle2Inputs */
|
|
@@ -14712,6 +15192,38 @@ var workspaceexplorertruncated2 = ((inputs = {}, options = {}) => {
|
|
|
14712
15192
|
return en_workspaceexplorertruncated2();
|
|
14713
15193
|
});
|
|
14714
15194
|
//#endregion
|
|
15195
|
+
//#region src/lib/paraglide/messages/workspacefilecancel2.js
|
|
15196
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15197
|
+
/** @typedef {{}} Workspacefilecancel2Inputs */
|
|
15198
|
+
var en_workspacefilecancel2 = () => {
|
|
15199
|
+
return `Cancel`;
|
|
15200
|
+
};
|
|
15201
|
+
var zh_workspacefilecancel2 = () => {
|
|
15202
|
+
return `取消`;
|
|
15203
|
+
};
|
|
15204
|
+
var id_workspacefilecancel2 = () => {
|
|
15205
|
+
return `Batal`;
|
|
15206
|
+
};
|
|
15207
|
+
var es_workspacefilecancel2 = () => {
|
|
15208
|
+
return `Cancelar`;
|
|
15209
|
+
};
|
|
15210
|
+
/**
|
|
15211
|
+
* | output |
|
|
15212
|
+
* | --- |
|
|
15213
|
+
* | "Cancel" |
|
|
15214
|
+
*
|
|
15215
|
+
* @param {Workspacefilecancel2Inputs} inputs
|
|
15216
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15217
|
+
* @returns {LocalizedString}
|
|
15218
|
+
*/
|
|
15219
|
+
var workspacefilecancel2 = ((inputs = {}, options = {}) => {
|
|
15220
|
+
const locale = options.locale ?? getLocale();
|
|
15221
|
+
if (locale === "zh") return zh_workspacefilecancel2();
|
|
15222
|
+
if (locale === "id") return id_workspacefilecancel2();
|
|
15223
|
+
if (locale === "es") return es_workspacefilecancel2();
|
|
15224
|
+
return en_workspacefilecancel2();
|
|
15225
|
+
});
|
|
15226
|
+
//#endregion
|
|
14715
15227
|
//#region src/lib/paraglide/messages/workspacefilecopyfilename3.js
|
|
14716
15228
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
14717
15229
|
/** @typedef {{}} Workspacefilecopyfilename3Inputs */
|
|
@@ -14968,6 +15480,38 @@ var workspacefilesaving2 = ((inputs = {}, options = {}) => {
|
|
|
14968
15480
|
return en_workspacefilesaving2();
|
|
14969
15481
|
});
|
|
14970
15482
|
//#endregion
|
|
15483
|
+
//#region src/lib/paraglide/messages/workspacefilesource2.js
|
|
15484
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15485
|
+
/** @typedef {{}} Workspacefilesource2Inputs */
|
|
15486
|
+
var en_workspacefilesource2 = () => {
|
|
15487
|
+
return `Source`;
|
|
15488
|
+
};
|
|
15489
|
+
var zh_workspacefilesource2 = () => {
|
|
15490
|
+
return `源码`;
|
|
15491
|
+
};
|
|
15492
|
+
var id_workspacefilesource2 = () => {
|
|
15493
|
+
return `Kode`;
|
|
15494
|
+
};
|
|
15495
|
+
var es_workspacefilesource2 = () => {
|
|
15496
|
+
return `Código`;
|
|
15497
|
+
};
|
|
15498
|
+
/**
|
|
15499
|
+
* | output |
|
|
15500
|
+
* | --- |
|
|
15501
|
+
* | "Source" |
|
|
15502
|
+
*
|
|
15503
|
+
* @param {Workspacefilesource2Inputs} inputs
|
|
15504
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15505
|
+
* @returns {LocalizedString}
|
|
15506
|
+
*/
|
|
15507
|
+
var workspacefilesource2 = ((inputs = {}, options = {}) => {
|
|
15508
|
+
const locale = options.locale ?? getLocale();
|
|
15509
|
+
if (locale === "zh") return zh_workspacefilesource2();
|
|
15510
|
+
if (locale === "id") return id_workspacefilesource2();
|
|
15511
|
+
if (locale === "es") return es_workspacefilesource2();
|
|
15512
|
+
return en_workspacefilesource2();
|
|
15513
|
+
});
|
|
15514
|
+
//#endregion
|
|
14971
15515
|
//#region src/lib/paraglide/messages/workspacefilestale2.js
|
|
14972
15516
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
14973
15517
|
/** @typedef {{}} Workspacefilestale2Inputs */
|
|
@@ -15000,6 +15544,102 @@ var workspacefilestale2 = ((inputs = {}, options = {}) => {
|
|
|
15000
15544
|
return en_workspacefilestale2();
|
|
15001
15545
|
});
|
|
15002
15546
|
//#endregion
|
|
15547
|
+
//#region src/lib/paraglide/messages/workspacefiletabsclear3.js
|
|
15548
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15549
|
+
/** @typedef {{}} Workspacefiletabsclear3Inputs */
|
|
15550
|
+
var en_workspacefiletabsclear3 = () => {
|
|
15551
|
+
return `Clear tabs`;
|
|
15552
|
+
};
|
|
15553
|
+
var zh_workspacefiletabsclear3 = () => {
|
|
15554
|
+
return `清除标签`;
|
|
15555
|
+
};
|
|
15556
|
+
var id_workspacefiletabsclear3 = () => {
|
|
15557
|
+
return `Bersihkan tab`;
|
|
15558
|
+
};
|
|
15559
|
+
var es_workspacefiletabsclear3 = () => {
|
|
15560
|
+
return `Limpiar pestañas`;
|
|
15561
|
+
};
|
|
15562
|
+
/**
|
|
15563
|
+
* | output |
|
|
15564
|
+
* | --- |
|
|
15565
|
+
* | "Clear tabs" |
|
|
15566
|
+
*
|
|
15567
|
+
* @param {Workspacefiletabsclear3Inputs} inputs
|
|
15568
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15569
|
+
* @returns {LocalizedString}
|
|
15570
|
+
*/
|
|
15571
|
+
var workspacefiletabsclear3 = ((inputs = {}, options = {}) => {
|
|
15572
|
+
const locale = options.locale ?? getLocale();
|
|
15573
|
+
if (locale === "zh") return zh_workspacefiletabsclear3();
|
|
15574
|
+
if (locale === "id") return id_workspacefiletabsclear3();
|
|
15575
|
+
if (locale === "es") return es_workspacefiletabsclear3();
|
|
15576
|
+
return en_workspacefiletabsclear3();
|
|
15577
|
+
});
|
|
15578
|
+
//#endregion
|
|
15579
|
+
//#region src/lib/paraglide/messages/workspacefiletabsclearall4.js
|
|
15580
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15581
|
+
/** @typedef {{}} Workspacefiletabsclearall4Inputs */
|
|
15582
|
+
var en_workspacefiletabsclearall4 = () => {
|
|
15583
|
+
return `Clear all`;
|
|
15584
|
+
};
|
|
15585
|
+
var zh_workspacefiletabsclearall4 = () => {
|
|
15586
|
+
return `全部清除`;
|
|
15587
|
+
};
|
|
15588
|
+
var id_workspacefiletabsclearall4 = () => {
|
|
15589
|
+
return `Bersihkan semua`;
|
|
15590
|
+
};
|
|
15591
|
+
var es_workspacefiletabsclearall4 = () => {
|
|
15592
|
+
return `Limpiar todo`;
|
|
15593
|
+
};
|
|
15594
|
+
/**
|
|
15595
|
+
* | output |
|
|
15596
|
+
* | --- |
|
|
15597
|
+
* | "Clear all" |
|
|
15598
|
+
*
|
|
15599
|
+
* @param {Workspacefiletabsclearall4Inputs} inputs
|
|
15600
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15601
|
+
* @returns {LocalizedString}
|
|
15602
|
+
*/
|
|
15603
|
+
var workspacefiletabsclearall4 = ((inputs = {}, options = {}) => {
|
|
15604
|
+
const locale = options.locale ?? getLocale();
|
|
15605
|
+
if (locale === "zh") return zh_workspacefiletabsclearall4();
|
|
15606
|
+
if (locale === "id") return id_workspacefiletabsclearall4();
|
|
15607
|
+
if (locale === "es") return es_workspacefiletabsclearall4();
|
|
15608
|
+
return en_workspacefiletabsclearall4();
|
|
15609
|
+
});
|
|
15610
|
+
//#endregion
|
|
15611
|
+
//#region src/lib/paraglide/messages/workspacefiletabsclearnondirty5.js
|
|
15612
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15613
|
+
/** @typedef {{}} Workspacefiletabsclearnondirty5Inputs */
|
|
15614
|
+
var en_workspacefiletabsclearnondirty5 = () => {
|
|
15615
|
+
return `Clear non-dirty`;
|
|
15616
|
+
};
|
|
15617
|
+
var zh_workspacefiletabsclearnondirty5 = () => {
|
|
15618
|
+
return `清除未修改`;
|
|
15619
|
+
};
|
|
15620
|
+
var id_workspacefiletabsclearnondirty5 = () => {
|
|
15621
|
+
return `Bersihkan yang tidak berubah`;
|
|
15622
|
+
};
|
|
15623
|
+
var es_workspacefiletabsclearnondirty5 = () => {
|
|
15624
|
+
return `Limpiar sin cambios`;
|
|
15625
|
+
};
|
|
15626
|
+
/**
|
|
15627
|
+
* | output |
|
|
15628
|
+
* | --- |
|
|
15629
|
+
* | "Clear non-dirty" |
|
|
15630
|
+
*
|
|
15631
|
+
* @param {Workspacefiletabsclearnondirty5Inputs} inputs
|
|
15632
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
15633
|
+
* @returns {LocalizedString}
|
|
15634
|
+
*/
|
|
15635
|
+
var workspacefiletabsclearnondirty5 = ((inputs = {}, options = {}) => {
|
|
15636
|
+
const locale = options.locale ?? getLocale();
|
|
15637
|
+
if (locale === "zh") return zh_workspacefiletabsclearnondirty5();
|
|
15638
|
+
if (locale === "id") return id_workspacefiletabsclearnondirty5();
|
|
15639
|
+
if (locale === "es") return es_workspacefiletabsclearnondirty5();
|
|
15640
|
+
return en_workspacefiletabsclearnondirty5();
|
|
15641
|
+
});
|
|
15642
|
+
//#endregion
|
|
15003
15643
|
//#region src/lib/paraglide/messages/workspacefiletruncated2.js
|
|
15004
15644
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
15005
15645
|
/** @typedef {{}} Workspacefiletruncated2Inputs */
|
|
@@ -15204,10 +15844,12 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15204
15844
|
browserOpenTitle: () => browseropentitle2,
|
|
15205
15845
|
browserPanelTitle: () => browserpaneltitle2,
|
|
15206
15846
|
browserReload: () => browserreload1,
|
|
15847
|
+
browserSessionDead: () => browsersessiondead2,
|
|
15207
15848
|
browserSessionFailed: () => browsersessionfailed2,
|
|
15208
15849
|
browserTabCloseTitle: () => browsertabclosetitle3,
|
|
15209
15850
|
browserUrlPlaceholder: () => browserurlplaceholder2,
|
|
15210
15851
|
browserWaitingFrames: () => browserwaitingframes2,
|
|
15852
|
+
browserZoom: () => browserzoom1,
|
|
15211
15853
|
cacheHit: () => cachehit1,
|
|
15212
15854
|
cachedInput: () => cachedinput1,
|
|
15213
15855
|
cancel: () => cancel,
|
|
@@ -15215,6 +15857,8 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15215
15857
|
catalogUnavailable: () => catalogunavailable1,
|
|
15216
15858
|
chatButtonMode: () => chatbuttonmode2,
|
|
15217
15859
|
chooseFolder: () => choosefolder1,
|
|
15860
|
+
chordArmedLabel: () => chordarmedlabel2,
|
|
15861
|
+
chordArmedTitle: () => chordarmedtitle2,
|
|
15218
15862
|
clearBtn: () => clearbtn1,
|
|
15219
15863
|
clearDateFilter: () => cleardatefilter2,
|
|
15220
15864
|
clearFilter: () => clearfilter1,
|
|
@@ -15265,12 +15909,15 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15265
15909
|
creating: () => creating,
|
|
15266
15910
|
ctxChipCompact: () => ctxchipcompact2,
|
|
15267
15911
|
ctxChipContext: () => ctxchipcontext2,
|
|
15912
|
+
ctxChipGoal: () => ctxchipgoal2,
|
|
15268
15913
|
ctxChipInjected: () => ctxchipinjected2,
|
|
15269
15914
|
ctxChipInstructions: () => ctxchipinstructions2,
|
|
15270
15915
|
ctxChipPlugin: () => ctxchipplugin2,
|
|
15271
15916
|
ctxChipRecall: () => ctxchiprecall2,
|
|
15272
15917
|
ctxChipSkill: () => ctxchipskill2,
|
|
15273
15918
|
ctxChipSkills: () => ctxchipskills2,
|
|
15919
|
+
ctxChipTimeContext: () => ctxchiptimecontext3,
|
|
15920
|
+
ctxChipToolGoal: () => ctxchiptoolgoal3,
|
|
15274
15921
|
ctxChipUserApproval: () => ctxchipuserapproval3,
|
|
15275
15922
|
ctxSnapshotSupersedes: () => ctxsnapshotsupersedes2,
|
|
15276
15923
|
ctxWindowTitle: () => ctxwindowtitle2,
|
|
@@ -15318,9 +15965,9 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15318
15965
|
failedToLoad: () => failedtoload2,
|
|
15319
15966
|
feedNext: () => feednext1,
|
|
15320
15967
|
fileEyeDiff: () => fileeyediff2,
|
|
15321
|
-
fileEyeEdit: () => fileeyeedit2,
|
|
15322
15968
|
fileEyeExternalChange: () => fileeyeexternalchange3,
|
|
15323
15969
|
fileEyeNewFile: () => fileeyenewfile3,
|
|
15970
|
+
fileEyePreview: () => fileeyepreview2,
|
|
15324
15971
|
fileEyeReadOnly: () => fileeyereadonly3,
|
|
15325
15972
|
fileEyeToggleLabel: () => fileeyetogglelabel3,
|
|
15326
15973
|
filterBy: () => filterby1,
|
|
@@ -15359,6 +16006,7 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15359
16006
|
impliedNote: () => impliednote1,
|
|
15360
16007
|
injectedFiles: () => injectedfiles1,
|
|
15361
16008
|
injectedTitle: () => injectedtitle1,
|
|
16009
|
+
jobTailEmpty: () => jobtailempty2,
|
|
15362
16010
|
jobTailWaiting: () => jobtailwaiting2,
|
|
15363
16011
|
jobs: () => jobs,
|
|
15364
16012
|
jobsLiveTitle_one: () => jobslivetitle_one2,
|
|
@@ -15433,6 +16081,7 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15433
16081
|
pendingAttachments: () => pendingattachments1,
|
|
15434
16082
|
pickSession: () => picksession1,
|
|
15435
16083
|
planMode: () => planmode1,
|
|
16084
|
+
pluginRackApplyNote: () => pluginrackapplynote3,
|
|
15436
16085
|
pluginRackApplying: () => pluginrackapplying2,
|
|
15437
16086
|
pluginRackBy: () => pluginrackby2,
|
|
15438
16087
|
pluginRackCollapseAll: () => pluginrackcollapseall3,
|
|
@@ -15577,6 +16226,10 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15577
16226
|
terminalSettleStdinRead: () => terminalsettlestdinread3,
|
|
15578
16227
|
terminalSettleTimeout: () => terminalsettletimeout2,
|
|
15579
16228
|
terminalTabClose: () => terminaltabclose2,
|
|
16229
|
+
terminalTabsClear: () => terminaltabsclear2,
|
|
16230
|
+
terminalTabsClearAll: () => terminaltabsclearall3,
|
|
16231
|
+
terminalTabsClearJobs: () => terminaltabsclearjobs3,
|
|
16232
|
+
terminalTabsClearTerminals: () => terminaltabsclearterminals3,
|
|
15580
16233
|
text: () => text,
|
|
15581
16234
|
themeChoice_dark: () => themechoice_dark1,
|
|
15582
16235
|
themeChoice_light: () => themechoice_light1,
|
|
@@ -15622,10 +16275,13 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15622
16275
|
workspaceDeleteCost: () => workspacedeletecost2,
|
|
15623
16276
|
workspaceExplorerCopyWorkspace: () => workspaceexplorercopyworkspace3,
|
|
15624
16277
|
workspaceExplorerEmpty: () => workspaceexplorerempty2,
|
|
16278
|
+
workspaceExplorerHide: () => workspaceexplorerhide2,
|
|
15625
16279
|
workspaceExplorerLoadFailed: () => workspaceexplorerloadfailed3,
|
|
15626
16280
|
workspaceExplorerLoading: () => workspaceexplorerloading2,
|
|
16281
|
+
workspaceExplorerShow: () => workspaceexplorershow2,
|
|
15627
16282
|
workspaceExplorerTitle: () => workspaceexplorertitle2,
|
|
15628
16283
|
workspaceExplorerTruncated: () => workspaceexplorertruncated2,
|
|
16284
|
+
workspaceFileCancel: () => workspacefilecancel2,
|
|
15629
16285
|
workspaceFileCopyFilename: () => workspacefilecopyfilename3,
|
|
15630
16286
|
workspaceFileDirty: () => workspacefiledirty2,
|
|
15631
16287
|
workspaceFileEdit: () => workspacefileedit2,
|
|
@@ -15634,7 +16290,11 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15634
16290
|
workspaceFileSave: () => workspacefilesave2,
|
|
15635
16291
|
workspaceFileSaveFailed: () => workspacefilesavefailed3,
|
|
15636
16292
|
workspaceFileSaving: () => workspacefilesaving2,
|
|
16293
|
+
workspaceFileSource: () => workspacefilesource2,
|
|
15637
16294
|
workspaceFileStale: () => workspacefilestale2,
|
|
16295
|
+
workspaceFileTabsClear: () => workspacefiletabsclear3,
|
|
16296
|
+
workspaceFileTabsClearAll: () => workspacefiletabsclearall4,
|
|
16297
|
+
workspaceFileTabsClearNonDirty: () => workspacefiletabsclearnondirty5,
|
|
15638
16298
|
workspaceFileTruncated: () => workspacefiletruncated2,
|
|
15639
16299
|
workspacePanelCommonCopyColumn: () => workspacepanelcommoncopycolumn4,
|
|
15640
16300
|
workspacePlusAgent: () => workspaceplusagent2,
|
|
@@ -15686,10 +16346,12 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15686
16346
|
browserOpenTitle: () => browseropentitle2,
|
|
15687
16347
|
browserPanelTitle: () => browserpaneltitle2,
|
|
15688
16348
|
browserReload: () => browserreload1,
|
|
16349
|
+
browserSessionDead: () => browsersessiondead2,
|
|
15689
16350
|
browserSessionFailed: () => browsersessionfailed2,
|
|
15690
16351
|
browserTabCloseTitle: () => browsertabclosetitle3,
|
|
15691
16352
|
browserUrlPlaceholder: () => browserurlplaceholder2,
|
|
15692
16353
|
browserWaitingFrames: () => browserwaitingframes2,
|
|
16354
|
+
browserZoom: () => browserzoom1,
|
|
15693
16355
|
cacheHit: () => cachehit1,
|
|
15694
16356
|
cachedInput: () => cachedinput1,
|
|
15695
16357
|
cancel: () => cancel,
|
|
@@ -15697,6 +16359,8 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15697
16359
|
catalogUnavailable: () => catalogunavailable1,
|
|
15698
16360
|
chatButtonMode: () => chatbuttonmode2,
|
|
15699
16361
|
chooseFolder: () => choosefolder1,
|
|
16362
|
+
chordArmedLabel: () => chordarmedlabel2,
|
|
16363
|
+
chordArmedTitle: () => chordarmedtitle2,
|
|
15700
16364
|
clearBtn: () => clearbtn1,
|
|
15701
16365
|
clearDateFilter: () => cleardatefilter2,
|
|
15702
16366
|
clearFilter: () => clearfilter1,
|
|
@@ -15747,12 +16411,15 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15747
16411
|
creating: () => creating,
|
|
15748
16412
|
ctxChipCompact: () => ctxchipcompact2,
|
|
15749
16413
|
ctxChipContext: () => ctxchipcontext2,
|
|
16414
|
+
ctxChipGoal: () => ctxchipgoal2,
|
|
15750
16415
|
ctxChipInjected: () => ctxchipinjected2,
|
|
15751
16416
|
ctxChipInstructions: () => ctxchipinstructions2,
|
|
15752
16417
|
ctxChipPlugin: () => ctxchipplugin2,
|
|
15753
16418
|
ctxChipRecall: () => ctxchiprecall2,
|
|
15754
16419
|
ctxChipSkill: () => ctxchipskill2,
|
|
15755
16420
|
ctxChipSkills: () => ctxchipskills2,
|
|
16421
|
+
ctxChipTimeContext: () => ctxchiptimecontext3,
|
|
16422
|
+
ctxChipToolGoal: () => ctxchiptoolgoal3,
|
|
15756
16423
|
ctxChipUserApproval: () => ctxchipuserapproval3,
|
|
15757
16424
|
ctxSnapshotSupersedes: () => ctxsnapshotsupersedes2,
|
|
15758
16425
|
ctxWindowTitle: () => ctxwindowtitle2,
|
|
@@ -15800,9 +16467,9 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15800
16467
|
failedToLoad: () => failedtoload2,
|
|
15801
16468
|
feedNext: () => feednext1,
|
|
15802
16469
|
fileEyeDiff: () => fileeyediff2,
|
|
15803
|
-
fileEyeEdit: () => fileeyeedit2,
|
|
15804
16470
|
fileEyeExternalChange: () => fileeyeexternalchange3,
|
|
15805
16471
|
fileEyeNewFile: () => fileeyenewfile3,
|
|
16472
|
+
fileEyePreview: () => fileeyepreview2,
|
|
15806
16473
|
fileEyeReadOnly: () => fileeyereadonly3,
|
|
15807
16474
|
fileEyeToggleLabel: () => fileeyetogglelabel3,
|
|
15808
16475
|
filterBy: () => filterby1,
|
|
@@ -15841,6 +16508,7 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15841
16508
|
impliedNote: () => impliednote1,
|
|
15842
16509
|
injectedFiles: () => injectedfiles1,
|
|
15843
16510
|
injectedTitle: () => injectedtitle1,
|
|
16511
|
+
jobTailEmpty: () => jobtailempty2,
|
|
15844
16512
|
jobTailWaiting: () => jobtailwaiting2,
|
|
15845
16513
|
jobs: () => jobs,
|
|
15846
16514
|
jobsLiveTitle_one: () => jobslivetitle_one2,
|
|
@@ -15916,6 +16584,7 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15916
16584
|
pendingAttachments: () => pendingattachments1,
|
|
15917
16585
|
pickSession: () => picksession1,
|
|
15918
16586
|
planMode: () => planmode1,
|
|
16587
|
+
pluginRackApplyNote: () => pluginrackapplynote3,
|
|
15919
16588
|
pluginRackApplying: () => pluginrackapplying2,
|
|
15920
16589
|
pluginRackBy: () => pluginrackby2,
|
|
15921
16590
|
pluginRackCollapseAll: () => pluginrackcollapseall3,
|
|
@@ -16060,6 +16729,10 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
16060
16729
|
terminalSettleStdinRead: () => terminalsettlestdinread3,
|
|
16061
16730
|
terminalSettleTimeout: () => terminalsettletimeout2,
|
|
16062
16731
|
terminalTabClose: () => terminaltabclose2,
|
|
16732
|
+
terminalTabsClear: () => terminaltabsclear2,
|
|
16733
|
+
terminalTabsClearAll: () => terminaltabsclearall3,
|
|
16734
|
+
terminalTabsClearJobs: () => terminaltabsclearjobs3,
|
|
16735
|
+
terminalTabsClearTerminals: () => terminaltabsclearterminals3,
|
|
16063
16736
|
text: () => text,
|
|
16064
16737
|
themeChoice_dark: () => themechoice_dark1,
|
|
16065
16738
|
themeChoice_light: () => themechoice_light1,
|
|
@@ -16105,10 +16778,13 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
16105
16778
|
workspaceDeleteCost: () => workspacedeletecost2,
|
|
16106
16779
|
workspaceExplorerCopyWorkspace: () => workspaceexplorercopyworkspace3,
|
|
16107
16780
|
workspaceExplorerEmpty: () => workspaceexplorerempty2,
|
|
16781
|
+
workspaceExplorerHide: () => workspaceexplorerhide2,
|
|
16108
16782
|
workspaceExplorerLoadFailed: () => workspaceexplorerloadfailed3,
|
|
16109
16783
|
workspaceExplorerLoading: () => workspaceexplorerloading2,
|
|
16784
|
+
workspaceExplorerShow: () => workspaceexplorershow2,
|
|
16110
16785
|
workspaceExplorerTitle: () => workspaceexplorertitle2,
|
|
16111
16786
|
workspaceExplorerTruncated: () => workspaceexplorertruncated2,
|
|
16787
|
+
workspaceFileCancel: () => workspacefilecancel2,
|
|
16112
16788
|
workspaceFileCopyFilename: () => workspacefilecopyfilename3,
|
|
16113
16789
|
workspaceFileDirty: () => workspacefiledirty2,
|
|
16114
16790
|
workspaceFileEdit: () => workspacefileedit2,
|
|
@@ -16117,7 +16793,11 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
16117
16793
|
workspaceFileSave: () => workspacefilesave2,
|
|
16118
16794
|
workspaceFileSaveFailed: () => workspacefilesavefailed3,
|
|
16119
16795
|
workspaceFileSaving: () => workspacefilesaving2,
|
|
16796
|
+
workspaceFileSource: () => workspacefilesource2,
|
|
16120
16797
|
workspaceFileStale: () => workspacefilestale2,
|
|
16798
|
+
workspaceFileTabsClear: () => workspacefiletabsclear3,
|
|
16799
|
+
workspaceFileTabsClearAll: () => workspacefiletabsclearall4,
|
|
16800
|
+
workspaceFileTabsClearNonDirty: () => workspacefiletabsclearnondirty5,
|
|
16121
16801
|
workspaceFileTruncated: () => workspacefiletruncated2,
|
|
16122
16802
|
workspacePanelCommonCopyColumn: () => workspacepanelcommoncopycolumn4,
|
|
16123
16803
|
workspacePlusAgent: () => workspaceplusagent2,
|
|
@@ -16435,6 +17115,24 @@ function Circle_dashed($$renderer, $$props) {
|
|
|
16435
17115
|
]));
|
|
16436
17116
|
}
|
|
16437
17117
|
//#endregion
|
|
17118
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/circle-plus.svelte
|
|
17119
|
+
function Circle_plus($$renderer, $$props) {
|
|
17120
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
17121
|
+
Icon($$renderer, spread_props([
|
|
17122
|
+
{ name: "circle-plus" },
|
|
17123
|
+
props,
|
|
17124
|
+
{ iconNode: [
|
|
17125
|
+
["circle", {
|
|
17126
|
+
"cx": "12",
|
|
17127
|
+
"cy": "12",
|
|
17128
|
+
"r": "10"
|
|
17129
|
+
}],
|
|
17130
|
+
["path", { "d": "M8 12h8" }],
|
|
17131
|
+
["path", { "d": "M12 8v8" }]
|
|
17132
|
+
] }
|
|
17133
|
+
]));
|
|
17134
|
+
}
|
|
17135
|
+
//#endregion
|
|
16438
17136
|
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/circle-x.svelte
|
|
16439
17137
|
function Circle_x($$renderer, $$props) {
|
|
16440
17138
|
let { $$slots, $$events, ...props } = $$props;
|
|
@@ -16727,6 +17425,26 @@ function Panel_left_close($$renderer, $$props) {
|
|
|
16727
17425
|
]));
|
|
16728
17426
|
}
|
|
16729
17427
|
//#endregion
|
|
17428
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/panel-left-open.svelte
|
|
17429
|
+
function Panel_left_open($$renderer, $$props) {
|
|
17430
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
17431
|
+
Icon($$renderer, spread_props([
|
|
17432
|
+
{ name: "panel-left-open" },
|
|
17433
|
+
props,
|
|
17434
|
+
{ iconNode: [
|
|
17435
|
+
["rect", {
|
|
17436
|
+
"width": "18",
|
|
17437
|
+
"height": "18",
|
|
17438
|
+
"x": "3",
|
|
17439
|
+
"y": "3",
|
|
17440
|
+
"rx": "2"
|
|
17441
|
+
}],
|
|
17442
|
+
["path", { "d": "M9 3v18" }],
|
|
17443
|
+
["path", { "d": "m14 9 3 3-3 3" }]
|
|
17444
|
+
] }
|
|
17445
|
+
]));
|
|
17446
|
+
}
|
|
17447
|
+
//#endregion
|
|
16730
17448
|
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/paperclip.svelte
|
|
16731
17449
|
function Paperclip($$renderer, $$props) {
|
|
16732
17450
|
let { $$slots, $$events, ...props } = $$props;
|
|
@@ -16737,6 +17455,16 @@ function Paperclip($$renderer, $$props) {
|
|
|
16737
17455
|
]));
|
|
16738
17456
|
}
|
|
16739
17457
|
//#endregion
|
|
17458
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/pencil.svelte
|
|
17459
|
+
function Pencil($$renderer, $$props) {
|
|
17460
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
17461
|
+
Icon($$renderer, spread_props([
|
|
17462
|
+
{ name: "pencil" },
|
|
17463
|
+
props,
|
|
17464
|
+
{ iconNode: [["path", { "d": "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }], ["path", { "d": "m15 5 4 4" }]] }
|
|
17465
|
+
]));
|
|
17466
|
+
}
|
|
17467
|
+
//#endregion
|
|
16740
17468
|
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/plus.svelte
|
|
16741
17469
|
function Plus($$renderer, $$props) {
|
|
16742
17470
|
let { $$slots, $$events, ...props } = $$props;
|
|
@@ -16747,17 +17475,16 @@ function Plus($$renderer, $$props) {
|
|
|
16747
17475
|
]));
|
|
16748
17476
|
}
|
|
16749
17477
|
//#endregion
|
|
16750
|
-
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/
|
|
16751
|
-
function
|
|
17478
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/presentation.svelte
|
|
17479
|
+
function Presentation($$renderer, $$props) {
|
|
16752
17480
|
let { $$slots, $$events, ...props } = $$props;
|
|
16753
17481
|
Icon($$renderer, spread_props([
|
|
16754
|
-
{ name: "
|
|
17482
|
+
{ name: "presentation" },
|
|
16755
17483
|
props,
|
|
16756
17484
|
{ iconNode: [
|
|
16757
|
-
["path", { "d": "
|
|
16758
|
-
["path", { "d": "M21
|
|
16759
|
-
["path", { "d": "
|
|
16760
|
-
["path", { "d": "M8 16H3v5" }]
|
|
17485
|
+
["path", { "d": "M2 3h20" }],
|
|
17486
|
+
["path", { "d": "M21 3v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V3" }],
|
|
17487
|
+
["path", { "d": "m7 21 5-5 5 5" }]
|
|
16761
17488
|
] }
|
|
16762
17489
|
]));
|
|
16763
17490
|
}
|
|
@@ -16796,6 +17523,20 @@ function Rotate_cw($$renderer, $$props) {
|
|
|
16796
17523
|
]));
|
|
16797
17524
|
}
|
|
16798
17525
|
//#endregion
|
|
17526
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/save.svelte
|
|
17527
|
+
function Save($$renderer, $$props) {
|
|
17528
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
17529
|
+
Icon($$renderer, spread_props([
|
|
17530
|
+
{ name: "save" },
|
|
17531
|
+
props,
|
|
17532
|
+
{ iconNode: [
|
|
17533
|
+
["path", { "d": "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }],
|
|
17534
|
+
["path", { "d": "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7" }],
|
|
17535
|
+
["path", { "d": "M7 3v4a1 1 0 0 0 1 1h7" }]
|
|
17536
|
+
] }
|
|
17537
|
+
]));
|
|
17538
|
+
}
|
|
17539
|
+
//#endregion
|
|
16799
17540
|
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/settings.svelte
|
|
16800
17541
|
function Settings($$renderer, $$props) {
|
|
16801
17542
|
let { $$slots, $$events, ...props } = $$props;
|
|
@@ -16908,6 +17649,24 @@ function Trash_2($$renderer, $$props) {
|
|
|
16908
17649
|
]));
|
|
16909
17650
|
}
|
|
16910
17651
|
//#endregion
|
|
17652
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/undo-dot.svelte
|
|
17653
|
+
function Undo_dot($$renderer, $$props) {
|
|
17654
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
17655
|
+
Icon($$renderer, spread_props([
|
|
17656
|
+
{ name: "undo-dot" },
|
|
17657
|
+
props,
|
|
17658
|
+
{ iconNode: [
|
|
17659
|
+
["path", { "d": "M21 17a9 9 0 0 0-15-6.7L3 13" }],
|
|
17660
|
+
["path", { "d": "M3 7v6h6" }],
|
|
17661
|
+
["circle", {
|
|
17662
|
+
"cx": "12",
|
|
17663
|
+
"cy": "17",
|
|
17664
|
+
"r": "1"
|
|
17665
|
+
}]
|
|
17666
|
+
] }
|
|
17667
|
+
]));
|
|
17668
|
+
}
|
|
17669
|
+
//#endregion
|
|
16911
17670
|
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/wrench.svelte
|
|
16912
17671
|
function Wrench($$renderer, $$props) {
|
|
16913
17672
|
let { $$slots, $$events, ...props } = $$props;
|
|
@@ -17975,8 +18734,8 @@ function ThemeToggle($$renderer, $$props) {
|
|
|
17975
18734
|
}
|
|
17976
18735
|
//#endregion
|
|
17977
18736
|
//#region package.json
|
|
17978
|
-
var version = "0.
|
|
17979
|
-
var dsh = { "webVersion": "0.2.
|
|
18737
|
+
var version = "0.9.0";
|
|
18738
|
+
var dsh = { "webVersion": "0.2.2-alpha.2" };
|
|
17980
18739
|
//#endregion
|
|
17981
18740
|
//#region src/lib/version.ts
|
|
17982
18741
|
/**
|
|
@@ -18115,13 +18874,34 @@ function voicedSkillRow(row) {
|
|
|
18115
18874
|
};
|
|
18116
18875
|
}
|
|
18117
18876
|
//#endregion
|
|
18118
|
-
//#region src/lib/components/composer/menu/
|
|
18877
|
+
//#region src/lib/components/composer/menu/slash-menu-shared.ts
|
|
18878
|
+
/**
|
|
18879
|
+
* SlashMenu's exported pure helpers, in a plain .ts module so BOTH
|
|
18880
|
+
* svelte-check (svelte2tsx) AND raw tsc see the named exports — the
|
|
18881
|
+
* wildcard `declare module '*.svelte'` ambient has no named members,
|
|
18882
|
+
* so module-script exports of a .svelte file are invisible to tsc.
|
|
18883
|
+
* SlashMenu.svelte re-exports these from its <script module> (ONE
|
|
18884
|
+
* source of truth; existing importers keep their import paths).
|
|
18885
|
+
*/
|
|
18886
|
+
/**
|
|
18887
|
+
* slashMenuMatches — the menu's And-filter, exported so the HOST
|
|
18888
|
+
* counts matched rows for its keyboard guard with the SAME matcher
|
|
18889
|
+
* (ONE source of truth; the menu and the ladder-guard never drift).
|
|
18890
|
+
*
|
|
18891
|
+
* Strip parity: split the query on `;` and whitespace, lowercase,
|
|
18892
|
+
* drop empties; EVERY term must hit the row's display text
|
|
18893
|
+
* (`name + description`), case-insensitive. A bare `/` (query with
|
|
18894
|
+
* no terms) matches everything — the open menu lists the whole
|
|
18895
|
+
* vocabulary before the operator narrows it.
|
|
18896
|
+
*/
|
|
18119
18897
|
function slashMenuMatches(row, query) {
|
|
18120
18898
|
const terms = query.slice(1).toLowerCase().split(/[;\s]+/).filter(Boolean);
|
|
18121
18899
|
if (terms.length === 0) return true;
|
|
18122
18900
|
const hay = `${row.name} ${row.display ?? ""} ${row.description}`.toLowerCase();
|
|
18123
18901
|
return terms.every((t) => hay.includes(t));
|
|
18124
18902
|
}
|
|
18903
|
+
//#endregion
|
|
18904
|
+
//#region src/lib/components/composer/menu/SlashMenu.svelte
|
|
18125
18905
|
function SlashMenu($$renderer, $$props) {
|
|
18126
18906
|
$$renderer.component(($$renderer) => {
|
|
18127
18907
|
/**
|
|
@@ -18304,335 +19084,10 @@ function saveTagFilter(base, words, profile) {
|
|
|
18304
19084
|
} catch {}
|
|
18305
19085
|
}
|
|
18306
19086
|
//#endregion
|
|
18307
|
-
//#region src/lib/utils/markdown.ts
|
|
18308
|
-
/**
|
|
18309
|
-
* markdown — render markdown to sanitized HTML (Wave 2, task 2.1;
|
|
18310
|
-
* PRD §3.3 shared layer; BC-12).
|
|
18311
|
-
*
|
|
18312
|
-
* Pure function, no I/O, no Svelte, no DOM: runs server-side (SSR cold load)
|
|
18313
|
-
* and client-side alike. Two-stage pipeline with an allow-list escape hatch —
|
|
18314
|
-
* raw HTML never reaches the output:
|
|
18315
|
-
*
|
|
18316
|
-
* 1. ESCAPE every <, >, &, ", ' in the source text. Any markup-like
|
|
18317
|
-
* construct in the transcript is now inert character data; the markdown
|
|
18318
|
-
* tokenizer can no longer emit an HTML node from user/wire content.
|
|
18319
|
-
* 2. Convert the escaped text with a small CommonMark-subset tokenizer
|
|
18320
|
-
* whose emitter can ONLY produce the allow-listed tags below (p, strong,
|
|
18321
|
-
* em, del, code, pre, h1-h4, ul/ol/li, blockquote, hr, a, table/
|
|
18322
|
-
* thead/tbody/tr/th/td) — plus ONE structured exception: a ```mermaid
|
|
18323
|
-
* fence emits a bare placeholder <div class="mermaid-diagram"> whose
|
|
18324
|
-
* only attribute is the base64 diagram source; the SVG itself is
|
|
18325
|
-
* produced client-side by the mermaid runtime, never by this emitter.
|
|
18326
|
-
* Inline
|
|
18327
|
-
* code and code fences re-inject their (already-escaped) bodies verbatim
|
|
18328
|
-
* — code renders as characters, never markup (tool-payload rule).
|
|
18329
|
-
* Paragraph soft line breaks stay as raw \n (the bubble renders with
|
|
18330
|
-
* whitespace-pre-wrap — no <br> node needed).
|
|
18331
|
-
* 3. Links: only http(s) schemes survive; every other scheme (javascript:,
|
|
18332
|
-
* data:, vbscript:, file:, mailto:…) is reduced to plain text. Emitted
|
|
18333
|
-
* <a> tags carry rel="noopener noreferrer" target="_blank".
|
|
18334
|
-
*
|
|
18335
|
-
* Why not a dependency: the project has zero render deps today; the subset
|
|
18336
|
-
* below is what the harness transcripts actually use (bold, inline code,
|
|
18337
|
-
* fenced blocks, lists, headings) — pinned by markdown.test.ts. The escape-
|
|
18338
|
-
* first order makes sanitization structural rather than a block-list chase.
|
|
18339
|
-
*/
|
|
18340
|
-
/** Escape HTML-significant characters — stage 1 of the pipeline. */
|
|
18341
|
-
function escapeHtml(text) {
|
|
18342
|
-
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
18343
|
-
}
|
|
18344
|
-
/**
|
|
18345
|
-
* GFM table row: two or more pipe-delimited cells. Cells may ALL be empty —
|
|
18346
|
-
* a header-less table (`| | | |\n|---|---|---|\n…`, GitHub renders these)
|
|
18347
|
-
* must still start a table; requiring content here swallowed the header,
|
|
18348
|
-
* the delimiter row, and every body row into one raw pipe paragraph
|
|
18349
|
-
* (2026-08-26 fix, found via a header-less lineage table rendering as text).
|
|
18350
|
-
* Over-triggering is structurally impossible: a row only becomes a table
|
|
18351
|
-
* when the NEXT line is a strict delimiter row; and `| just a pipe line`
|
|
18352
|
-
* stays one cell.
|
|
18353
|
-
*/
|
|
18354
|
-
function isTableRow(line) {
|
|
18355
|
-
if (!line.includes("|")) return false;
|
|
18356
|
-
return splitRow(line).length >= 2;
|
|
18357
|
-
}
|
|
18358
|
-
/** GFM delimiter row: cells of only -, :, optional spaces (e.g. |---|:--:|). */
|
|
18359
|
-
function isDelimiterRow(line) {
|
|
18360
|
-
if (!line.includes("|") && !/^[-:\s]+$/.test(line)) return false;
|
|
18361
|
-
const stripped = line.replace(/\|/g, "").trim();
|
|
18362
|
-
if (stripped === "" || !/^[-:\s]+$/.test(stripped)) return false;
|
|
18363
|
-
return splitRow(line).length >= 2 && splitRow(line).every((c) => /^:?-+:?$/.test(c.trim()));
|
|
18364
|
-
}
|
|
18365
|
-
/** Split one pipe row into cells: trim outer pipes, split on inner ones. */
|
|
18366
|
-
function splitRow(line) {
|
|
18367
|
-
let s = line.trim();
|
|
18368
|
-
if (s.startsWith("|")) s = s.slice(1);
|
|
18369
|
-
if (s.endsWith("|")) s = s.slice(0, -1);
|
|
18370
|
-
const literals = [];
|
|
18371
|
-
s = s.replace(/\\\|/g, () => {
|
|
18372
|
-
literals.push("|");
|
|
18373
|
-
return `\u0001${literals.length - 1}\u0001`;
|
|
18374
|
-
});
|
|
18375
|
-
return s.split("|").map((c) => c.replace(/\u0001(\d+)\u0001/g, (_m, idx) => literals[Number(idx)] ?? "").trim());
|
|
18376
|
-
}
|
|
18377
|
-
/** List item line: indent, bullet (- * +) or ordered (N. / N)) marker, body. */
|
|
18378
|
-
var LIST_ITEM_RE = /^(\s*)([-*+]|\d+[.)])\s+(.*)$/;
|
|
18379
|
-
/** Indent width in spaces — a tab advances to the next multiple of 4. */
|
|
18380
|
-
function indentWidth(s) {
|
|
18381
|
-
let w = 0;
|
|
18382
|
-
for (const ch of s) if (ch === " ") w += 4 - w % 4;
|
|
18383
|
-
else w += 1;
|
|
18384
|
-
return w;
|
|
18385
|
-
}
|
|
18386
|
-
/**
|
|
18387
|
-
* Parse one list run from lines[start] (a list item): consecutive item
|
|
18388
|
-
* lines at ANY indent plus lazy plain-text continuations.
|
|
18389
|
-
*
|
|
18390
|
-
* deeper indent than the innermost open item → nests INSIDE it;
|
|
18391
|
-
* same indent → sibling;
|
|
18392
|
-
* kind change (bullet ⇄ ordered) at an EXISTING depth → ends the run
|
|
18393
|
-
* (the outer scan then emits the next list as its own block — the
|
|
18394
|
-
* pre-nesting behavior of two sibling lists is kept);
|
|
18395
|
-
* blank line / fence / heading / quote → run over.
|
|
18396
|
-
*
|
|
18397
|
-
* Mixed kinds still nest when the indent is deeper — a numbered plan
|
|
18398
|
-
* under a bullet is legal CommonMark and common in transcripts.
|
|
18399
|
-
*/
|
|
18400
|
-
function parseListRun(lines, start) {
|
|
18401
|
-
const items = [];
|
|
18402
|
-
const stack = [];
|
|
18403
|
-
let i = start;
|
|
18404
|
-
while (i < lines.length) {
|
|
18405
|
-
const l = lines[i];
|
|
18406
|
-
const m = LIST_ITEM_RE.exec(l);
|
|
18407
|
-
if (m) {
|
|
18408
|
-
const indent = indentWidth(m[1]);
|
|
18409
|
-
const ordered = /^\d/.test(m[2]);
|
|
18410
|
-
while (stack.length > 0 && stack[stack.length - 1].indent > indent) stack.pop();
|
|
18411
|
-
if (stack.length === 0) {
|
|
18412
|
-
if (items.length > 0 && ordered !== items[0].ordered) break;
|
|
18413
|
-
const it = {
|
|
18414
|
-
indent,
|
|
18415
|
-
ordered,
|
|
18416
|
-
text: m[3],
|
|
18417
|
-
children: []
|
|
18418
|
-
};
|
|
18419
|
-
items.push(it);
|
|
18420
|
-
stack.push(it);
|
|
18421
|
-
} else {
|
|
18422
|
-
const top = stack[stack.length - 1];
|
|
18423
|
-
if (indent === top.indent && ordered !== top.ordered) break;
|
|
18424
|
-
const it = {
|
|
18425
|
-
indent,
|
|
18426
|
-
ordered,
|
|
18427
|
-
text: m[3],
|
|
18428
|
-
children: []
|
|
18429
|
-
};
|
|
18430
|
-
if (indent > top.indent) top.children.push(it);
|
|
18431
|
-
else {
|
|
18432
|
-
const parent = stack.length >= 2 ? stack[stack.length - 2] : null;
|
|
18433
|
-
if (parent) parent.children.push(it);
|
|
18434
|
-
else items.push(it);
|
|
18435
|
-
stack.pop();
|
|
18436
|
-
}
|
|
18437
|
-
stack.push(it);
|
|
18438
|
-
}
|
|
18439
|
-
i += 1;
|
|
18440
|
-
continue;
|
|
18441
|
-
}
|
|
18442
|
-
if (stack.length > 0 && l.trim() !== "" && !/^(#{1,6})\s|^```|^>/.test(l)) {
|
|
18443
|
-
stack[stack.length - 1].text += ` ${l.trim()}`;
|
|
18444
|
-
i += 1;
|
|
18445
|
-
continue;
|
|
18446
|
-
}
|
|
18447
|
-
break;
|
|
18448
|
-
}
|
|
18449
|
-
return {
|
|
18450
|
-
items,
|
|
18451
|
-
next: i
|
|
18452
|
-
};
|
|
18453
|
-
}
|
|
18454
|
-
/** Emit an item tree — one inline pass per item, children inside the <li>. */
|
|
18455
|
-
function emitList(items) {
|
|
18456
|
-
const tag = items[0].ordered ? "ol" : "ul";
|
|
18457
|
-
return `<${tag}>${items.map((it) => `<li>${renderInline(it.text)}${it.children.length > 0 ? emitList(it.children) : ""}</li>`).join("")}</${tag}>`;
|
|
18458
|
-
}
|
|
18459
|
-
/** Reverse stage-1 escaping — mermaid parses the ORIGINAL syntax, not entities. */
|
|
18460
|
-
function unescapeEntities(text) {
|
|
18461
|
-
return text.replaceAll("<", "<").replaceAll(">", ">").replaceAll(""", "\"").replaceAll("'", "'").replaceAll("&", "&");
|
|
18462
|
-
}
|
|
18463
|
-
/** Base64 that survives non-ASCII (diagram labels are arbitrary text). */
|
|
18464
|
-
function btoaUnicode(text) {
|
|
18465
|
-
return btoa(String.fromCharCode(...new TextEncoder().encode(text)));
|
|
18466
|
-
}
|
|
18467
|
-
var ESCAPED_CODE_FENCE = /^```/;
|
|
18468
|
-
/**
|
|
18469
|
-
* Render markdown to sanitized HTML (single entry point, BC-12).
|
|
18470
|
-
* Output uses ONLY the allow-listed tags; empty input renders ''.
|
|
18471
|
-
*/
|
|
18472
|
-
function renderMarkdown(text) {
|
|
18473
|
-
if (text === "") return "";
|
|
18474
|
-
const escaped = escapeHtml(text);
|
|
18475
|
-
const out = [];
|
|
18476
|
-
const lines = escaped.split("\n");
|
|
18477
|
-
let i = 0;
|
|
18478
|
-
while (i < lines.length) {
|
|
18479
|
-
const line = lines[i];
|
|
18480
|
-
if (ESCAPED_CODE_FENCE.test(line.trimStart())) {
|
|
18481
|
-
const opener = line.trimStart().slice(3).trim().toLowerCase();
|
|
18482
|
-
const body = [];
|
|
18483
|
-
i += 1;
|
|
18484
|
-
while (i < lines.length && !ESCAPED_CODE_FENCE.test(lines[i].trimStart())) {
|
|
18485
|
-
body.push(lines[i]);
|
|
18486
|
-
i += 1;
|
|
18487
|
-
}
|
|
18488
|
-
i += 1;
|
|
18489
|
-
if (opener === "mermaid") {
|
|
18490
|
-
const encoded = btoaUnicode(unescapeEntities(body.join("\n")));
|
|
18491
|
-
out.push(`<div class="mermaid-diagram" data-source="${encoded}" data-processed="false"></div>`);
|
|
18492
|
-
continue;
|
|
18493
|
-
}
|
|
18494
|
-
out.push(`<pre><code>${body.join("\n")}</code></pre>`);
|
|
18495
|
-
continue;
|
|
18496
|
-
}
|
|
18497
|
-
if (line.trim() === "") {
|
|
18498
|
-
i += 1;
|
|
18499
|
-
continue;
|
|
18500
|
-
}
|
|
18501
|
-
const heading = /^(#{1,6})\s+(.*)$/.exec(line);
|
|
18502
|
-
if (heading) {
|
|
18503
|
-
const level = Math.min(4, heading[1].length);
|
|
18504
|
-
out.push(`<h${level}>${renderInline(heading[2])}</h${level}>`);
|
|
18505
|
-
i += 1;
|
|
18506
|
-
continue;
|
|
18507
|
-
}
|
|
18508
|
-
if (/^([-*_])(\s*\1){2,}\s*$/.test(line)) {
|
|
18509
|
-
out.push("<hr />");
|
|
18510
|
-
i += 1;
|
|
18511
|
-
continue;
|
|
18512
|
-
}
|
|
18513
|
-
if (isTableRow(line) && i + 1 < lines.length && isDelimiterRow(lines[i + 1])) {
|
|
18514
|
-
const header = splitRow(line);
|
|
18515
|
-
i += 2;
|
|
18516
|
-
const body = [];
|
|
18517
|
-
while (i < lines.length && isTableRow(lines[i]) && !isDelimiterRow(lines[i])) {
|
|
18518
|
-
body.push(splitRow(lines[i]));
|
|
18519
|
-
i += 1;
|
|
18520
|
-
}
|
|
18521
|
-
const thead = `<thead><tr>${header.map((c) => `<th>${renderInline(c)}</th>`).join("")}</tr></thead>`;
|
|
18522
|
-
const tbody = `<tbody>${body.map((row) => `<tr>${row.map((c) => `<td>${renderInline(c)}</td>`).join("")}</tr>`).join("")}</tbody>`;
|
|
18523
|
-
out.push(`<table>${thead}${tbody}</table>`);
|
|
18524
|
-
continue;
|
|
18525
|
-
}
|
|
18526
|
-
if (/^>\s?/.test(line)) {
|
|
18527
|
-
const body = [];
|
|
18528
|
-
while (i < lines.length && /^>\s?/.test(lines[i])) {
|
|
18529
|
-
body.push(lines[i].replace(/^>\s?/, ""));
|
|
18530
|
-
i += 1;
|
|
18531
|
-
}
|
|
18532
|
-
out.push(`<blockquote><p>${renderInline(body.join(" "))}</p></blockquote>`);
|
|
18533
|
-
continue;
|
|
18534
|
-
}
|
|
18535
|
-
if (LIST_ITEM_RE.test(line)) {
|
|
18536
|
-
const run = parseListRun(lines, i);
|
|
18537
|
-
out.push(emitList(run.items));
|
|
18538
|
-
i = run.next;
|
|
18539
|
-
continue;
|
|
18540
|
-
}
|
|
18541
|
-
const para = [];
|
|
18542
|
-
while (i < lines.length && lines[i].trim() !== "" && !ESCAPED_CODE_FENCE.test(lines[i].trimStart()) && !/^#{1,6}\s/.test(lines[i]) && !/^>\s?/.test(lines[i]) && !/^(\s*)([-*+]|\d+[.)])\s+/.test(lines[i]) && !/^([-*_])(\s*\1){2,}\s*$/.test(lines[i]) && !(isTableRow(lines[i]) && i + 1 < lines.length && isDelimiterRow(lines[i + 1]))) {
|
|
18543
|
-
para.push(lines[i]);
|
|
18544
|
-
i += 1;
|
|
18545
|
-
}
|
|
18546
|
-
if (para.length > 0) out.push(`<p>${renderInline(para.join("\n"))}</p>`);
|
|
18547
|
-
}
|
|
18548
|
-
return out.join("\n");
|
|
18549
|
-
}
|
|
18550
|
-
/**
|
|
18551
|
-
* Inline pass: code spans first (their bodies stay verbatim), then emphasis,
|
|
18552
|
-
* then links. Escaped text in, allow-listed tags out.
|
|
18553
|
-
*/
|
|
18554
|
-
function renderInline(text) {
|
|
18555
|
-
const codeSpans = [];
|
|
18556
|
-
let rest = text.replace(/`([^`\n]+)`/g, (_m, body) => {
|
|
18557
|
-
const raw = unescapeEntities(body);
|
|
18558
|
-
if (/^https?:\/\/\S+$/i.test(raw)) codeSpans.push(externalAnchor(raw));
|
|
18559
|
-
else codeSpans.push(`<code>${body}</code>`);
|
|
18560
|
-
return `\u0000${codeSpans.length - 1}\u0000`;
|
|
18561
|
-
});
|
|
18562
|
-
rest = emphasis(rest);
|
|
18563
|
-
rest = links(rest);
|
|
18564
|
-
rest = autolinkBareUrls(rest);
|
|
18565
|
-
return rest.replace(/\u0000(\d+)\u0000/g, (_m, idx) => codeSpans[Number(idx)] ?? "");
|
|
18566
|
-
}
|
|
18567
|
-
/** One hardened external anchor from a RAW url — display is origin+path
|
|
18568
|
-
* (query/fragment stripped), href keeps everything (BC-12 attributes). */
|
|
18569
|
-
function externalAnchor(rawUrl) {
|
|
18570
|
-
let cut = rawUrl.length;
|
|
18571
|
-
for (const c of ["?", "#"]) {
|
|
18572
|
-
const i = rawUrl.indexOf(c);
|
|
18573
|
-
if (i !== -1 && i < cut) cut = i;
|
|
18574
|
-
}
|
|
18575
|
-
return `<a href="${rawUrl.replaceAll("\"", """)}" rel="noopener noreferrer" target="_blank">${rawUrl.slice(0, cut)}</a>`;
|
|
18576
|
-
}
|
|
18577
|
-
/**
|
|
18578
|
-
* Bare-URL autolink (2026-09-27): an http(s) URL in plain text becomes an
|
|
18579
|
-
* anchor whose DISPLAY TEXT is the origin+path with the query/hash stripped
|
|
18580
|
-
* (transcript URLs like …new?merge_request[source_branch]=… render short)
|
|
18581
|
-
* while the HREF keeps the FULL URL. Runs after [label](href) parsing and
|
|
18582
|
-
* skips text inside existing anchors/code placeholders (\u0000N\u0000 markers).
|
|
18583
|
-
* Trailing punctuation ),.,;:!?'"] and matching surrounding parens stay
|
|
18584
|
-
* outside the link (CommonMark's autolink tail rule).
|
|
18585
|
-
*/
|
|
18586
|
-
function autolinkBareUrls(text) {
|
|
18587
|
-
return text.replace(/https?:\/\/[^\s<>"'\u0000]+/gi, (whole, offset, full) => {
|
|
18588
|
-
const before = full.slice(Math.max(0, offset - 2e3), offset);
|
|
18589
|
-
if (/<a\s[^>]*$/i.test(before) || /<code>[^<]*$/i.test(before)) return whole;
|
|
18590
|
-
let url = whole;
|
|
18591
|
-
while (url.endsWith(")") && (url.match(/\(/g)?.length ?? 0) < (url.match(/\)/g)?.length ?? 0)) url = url.slice(0, -1);
|
|
18592
|
-
url = url.replace(/[.,;:!?]+$/, "");
|
|
18593
|
-
const tail = whole.slice(url.length);
|
|
18594
|
-
return `${externalAnchor(url)}${tail}`;
|
|
18595
|
-
});
|
|
18596
|
-
}
|
|
18597
|
-
/** ***bold-italic***, **bold**, *italic*, _italic_, ~~strike~~. */
|
|
18598
|
-
function emphasis(text) {
|
|
18599
|
-
return text.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>").replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/(?<![\w])_(.+?)_(?![\w])/g, "<em>$1</em>").replace(/~~(.+?)~~/g, "<del>$1</del>");
|
|
18600
|
-
}
|
|
18601
|
-
/**
|
|
18602
|
-
* [label](href) — http(s) hrefs become hardened external anchors; SCHEME-FREE
|
|
18603
|
-
* relative hrefs (assistant file links like [card](src/lib/…)) become same-
|
|
18604
|
-
* origin anchors; anything carrying a scheme (javascript:, data:, mailto:,
|
|
18605
|
-
* //evil.com protocol-relative, …) stays inert text (BC-12).
|
|
18606
|
-
*/
|
|
18607
|
-
function links(text) {
|
|
18608
|
-
return text.replace(/\[([^\]]+)\]\((?:<([^>]*?)>|([^)\s]+))\)/g, (whole, labelA, angleHref, bareHref) => {
|
|
18609
|
-
const label = labelA;
|
|
18610
|
-
const bare = (angleHref !== void 0 ? angleHref : bareHref).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll(""", "\"").replaceAll("'", "'").replace(/^<(.+)>$/, "$1");
|
|
18611
|
-
if (/^https?:\/\//i.test(bare)) return `<a href="${bare.replaceAll("\"", """)}" rel="noopener noreferrer" target="_blank">${label}</a>`;
|
|
18612
|
-
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(bare) || bare.startsWith("//")) return whole;
|
|
18613
|
-
return `<a href="${bare.replaceAll("\"", """)}">${label}</a>`;
|
|
18614
|
-
});
|
|
18615
|
-
}
|
|
18616
|
-
//#endregion
|
|
18617
19087
|
//#region src/lib/components/composer/menu/suggest-strip/StripTip.svelte
|
|
18618
19088
|
function StripTip($$renderer, $$props) {
|
|
18619
19089
|
$$renderer.component(($$renderer) => {
|
|
18620
|
-
|
|
18621
|
-
* StripTip — the multiline full-text preview tooltip of one suggestion
|
|
18622
|
-
* row (OCI's StripMultiline lineage, its own component again).
|
|
18623
|
-
*
|
|
18624
|
-
* Presentational: chip anchor + live flags + raw text in, one portaled
|
|
18625
|
-
* tooltip out. Visible only while its chip is the active (keyboard-
|
|
18626
|
-
* highlighted) row, the row text is multiline, and no ⋯ menu is open
|
|
18627
|
-
* anywhere on the strip (the host threads menuOpen/anyMenuOpen).
|
|
18628
|
-
*/
|
|
18629
|
-
let { active = false, menuOpen = false, anyMenuOpen = false, text } = $$props;
|
|
18630
|
-
/** Tooltip box; null = hidden. Mirrors the STRIP's horizontal geometry
|
|
18631
|
-
* — same left edge, same width — regardless of which chip is active;
|
|
18632
|
-
* y anchors above the whole strip. Hides whenever any ⋯ menu is open. */
|
|
18633
|
-
let tipPos = null;
|
|
18634
|
-
if (active && text.includes("\n") && !menuOpen && !anyMenuOpen && tipPos);
|
|
18635
|
-
else $$renderer.push("<!--[-1-->");
|
|
19090
|
+
$$renderer.push("<!--[-1-->");
|
|
18636
19091
|
$$renderer.push(`<!--]-->`);
|
|
18637
19092
|
});
|
|
18638
19093
|
}
|
|
@@ -18656,7 +19111,7 @@ function StripChip($$renderer, $$props) {
|
|
|
18656
19111
|
* tooltip renders through StripTip (same body-portal escape); this
|
|
18657
19112
|
* chip only hands it the anchor and the live flags.
|
|
18658
19113
|
*/
|
|
18659
|
-
let { row, active = false, query = "", mode = "find", menuOpen = false,
|
|
19114
|
+
let { row, active = false, query = "", mode = "find", menuOpen = false, onstep = void 0, onrename = void 0, ondelete = void 0} = $$props;
|
|
18660
19115
|
/** The ⋯ menu exists only when both of its handlers do. */
|
|
18661
19116
|
const hasMenu = derived(() => onrename !== void 0 && ondelete !== void 0);
|
|
18662
19117
|
/** Segments for the current query — recomputed per render (pure service). */
|
|
@@ -18698,9 +19153,6 @@ function StripChip($$renderer, $$props) {
|
|
|
18698
19153
|
} else $$renderer.push("<!--[-1-->");
|
|
18699
19154
|
$$renderer.push(`<!--]--> `);
|
|
18700
19155
|
StripTip($$renderer, {
|
|
18701
|
-
active,
|
|
18702
|
-
menuOpen,
|
|
18703
|
-
anyMenuOpen,
|
|
18704
19156
|
text: row.text});
|
|
18705
19157
|
$$renderer.push(`<!----> `);
|
|
18706
19158
|
if (menuOpen && onrename !== void 0 && ondelete !== void 0) {
|
|
@@ -18824,7 +19276,6 @@ function SuggestStrip($$renderer, $$props) {
|
|
|
18824
19276
|
row,
|
|
18825
19277
|
active: index === activeIndex,
|
|
18826
19278
|
menuOpen: menuForId === row.id,
|
|
18827
|
-
anyMenuOpen: menuForId !== null,
|
|
18828
19279
|
query,
|
|
18829
19280
|
mode,
|
|
18830
19281
|
onstep: onstep === void 0 ? void 0 : () => onstep(index),
|
|
@@ -19759,7 +20210,8 @@ function defaultPanelPrefs() {
|
|
|
19759
20210
|
selectedPanelId: null,
|
|
19760
20211
|
panelWidth: defaultPanelWidth(),
|
|
19761
20212
|
zoom: 1,
|
|
19762
|
-
treePct: 30
|
|
20213
|
+
treePct: 30,
|
|
20214
|
+
explorerHidden: false
|
|
19763
20215
|
};
|
|
19764
20216
|
}
|
|
19765
20217
|
/**
|
|
@@ -19930,12 +20382,14 @@ function loadPanelPrefs(profile) {
|
|
|
19930
20382
|
const panelWidth = typeof parsed.panelWidth === "number" && Number.isFinite(parsed.panelWidth) ? clampPanelWidth(parsed.panelWidth) : defaultPanelWidth();
|
|
19931
20383
|
const zoom = typeof parsed.zoom === "number" && Number.isFinite(parsed.zoom) ? clampPanelZoom(parsed.zoom) : 1;
|
|
19932
20384
|
const treePct = typeof parsed.treePct === "number" && Number.isFinite(parsed.treePct) ? clampTreePct(parsed.treePct) : 30;
|
|
20385
|
+
const explorerHidden = parsed.explorerHidden === true;
|
|
19933
20386
|
return {
|
|
19934
20387
|
panels,
|
|
19935
20388
|
selectedPanelId: typeof parsed.selectedPanelId === "string" && panels.some((panel) => panel.id === parsed.selectedPanelId) ? parsed.selectedPanelId : panels[0]?.id ?? null,
|
|
19936
20389
|
panelWidth,
|
|
19937
20390
|
zoom,
|
|
19938
|
-
treePct
|
|
20391
|
+
treePct,
|
|
20392
|
+
explorerHidden
|
|
19939
20393
|
};
|
|
19940
20394
|
} catch {
|
|
19941
20395
|
return defaultPanelPrefs();
|
|
@@ -20165,6 +20619,148 @@ function AppSidebarHeader($$renderer, $$props) {
|
|
|
20165
20619
|
});
|
|
20166
20620
|
}
|
|
20167
20621
|
//#endregion
|
|
20622
|
+
//#region src/lib/components/common/WidthBadge.svelte
|
|
20623
|
+
function WidthBadge($$renderer, $$props) {
|
|
20624
|
+
/**
|
|
20625
|
+
* WidthBadge — the resize chip (Movable Rail ADR, amendment 2026-10-30
|
|
20626
|
+
* D1): one home for the live px readout that used to live inline in
|
|
20627
|
+
* PanelColumn (2026-08-28). Presentational ONLY — the owner's drag
|
|
20628
|
+
* machine writes the phase; this renders it and intercepts no pointer
|
|
20629
|
+
* (the drag owns the pointer; the afterglow must not block clicks).
|
|
20630
|
+
* The floor badge (PanelColumn) and the sidebar rail badge
|
|
20631
|
+
* (AppSidebar standalone) share this grammar; the embedded rail gets
|
|
20632
|
+
* no badge at all (zoom-scaled px would misreport — ADR D3).
|
|
20633
|
+
*/
|
|
20634
|
+
let { phase, width, testid = "panel-width-badge" } = $$props;
|
|
20635
|
+
$$renderer.push(`<span data-svelte="WidthBadge"${attr_class("width-badge svelte-1mjaqxx", void 0, { "fading": phase === "fading" })}${attr("data-testid", testid)}${attr("data-badge-phase", phase)} aria-hidden="true">${escape_html(Math.round(width))}px</span>`);
|
|
20636
|
+
}
|
|
20637
|
+
//#endregion
|
|
20638
|
+
//#region src/lib/utils/sidebar-prefs.ts
|
|
20639
|
+
/**
|
|
20640
|
+
* Sidebar preferences — persisted layout state for the conversation page's
|
|
20641
|
+
* app sidebar (OCI ControlRail pattern, 2026-08-23).
|
|
20642
|
+
*
|
|
20643
|
+
* Pure localStorage round-trip: SSR-safe (no localStorage → defaults), junk
|
|
20644
|
+
* payloads and out-of-range widths fall back instead of throwing into the
|
|
20645
|
+
* page, and writes are best-effort (a full or blocked store must not break
|
|
20646
|
+
* the layout — it only loses persistence for that session).
|
|
20647
|
+
*
|
|
20648
|
+
* Workspace profiles (storage-profile.ts): `?profile=widi` moves the key
|
|
20649
|
+
* to `dsi-sidebar_widi` — each desk remembers its own rail layout.
|
|
20650
|
+
*/
|
|
20651
|
+
/** localStorage base key — one JSON blob `{ collapsed, width }`. */
|
|
20652
|
+
var STORAGE_KEY = "dsi-sidebar";
|
|
20653
|
+
/** The single width bound site — load-side sanitizing and drag clamping
|
|
20654
|
+
* both route through here so the bounds exist in exactly one place.
|
|
20655
|
+
* Bounds read the config store (layout load has landed them before any
|
|
20656
|
+
* mount; constants are the fallback defaults). */
|
|
20657
|
+
function clampSidebarWidth(width) {
|
|
20658
|
+
const { minWidth, maxWidth } = appConfig().sidebar;
|
|
20659
|
+
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
20660
|
+
}
|
|
20661
|
+
/** Config-driven default width (clamped through the single bound site). */
|
|
20662
|
+
function defaultSidebarWidth() {
|
|
20663
|
+
return clampSidebarWidth(appConfig().sidebar.defaultWidth);
|
|
20664
|
+
}
|
|
20665
|
+
/** Persisted defaults when nothing (usable) is stored. */
|
|
20666
|
+
function defaultSidebarPrefs() {
|
|
20667
|
+
return {
|
|
20668
|
+
collapsed: false,
|
|
20669
|
+
width: defaultSidebarWidth()
|
|
20670
|
+
};
|
|
20671
|
+
}
|
|
20672
|
+
/**
|
|
20673
|
+
* Read prefs from localStorage.
|
|
20674
|
+
* @param profile sanitized workspace profile (null/omitted = default desk).
|
|
20675
|
+
* @returns stored prefs when parseable, defaults when absent, junk, or SSR.
|
|
20676
|
+
*/
|
|
20677
|
+
function loadSidebarPrefs(profile) {
|
|
20678
|
+
if (typeof localStorage === "undefined") return defaultSidebarPrefs();
|
|
20679
|
+
try {
|
|
20680
|
+
const raw = localStorage.getItem(dsiKey(STORAGE_KEY, profile));
|
|
20681
|
+
if (!raw) return defaultSidebarPrefs();
|
|
20682
|
+
const parsed = JSON.parse(raw);
|
|
20683
|
+
if (parsed === null || typeof parsed !== "object") return defaultSidebarPrefs();
|
|
20684
|
+
return {
|
|
20685
|
+
collapsed: parsed.collapsed === true,
|
|
20686
|
+
width: clampSidebarWidth(typeof parsed.width === "number" && Number.isFinite(parsed.width) ? parsed.width : defaultSidebarWidth())
|
|
20687
|
+
};
|
|
20688
|
+
} catch {
|
|
20689
|
+
return defaultSidebarPrefs();
|
|
20690
|
+
}
|
|
20691
|
+
}
|
|
20692
|
+
//#endregion
|
|
20693
|
+
//#region src/lib/services/workspace/page-prefs.svelte.ts
|
|
20694
|
+
var PagePrefs = class {
|
|
20695
|
+
/** Width preset for the next conversation panel (clamped). */
|
|
20696
|
+
panelWidth = 0;
|
|
20697
|
+
/** Floor zoom (clamped). */
|
|
20698
|
+
zoom = 1;
|
|
20699
|
+
/** Explorer Layout split (clamped). */
|
|
20700
|
+
treePct = 0;
|
|
20701
|
+
/** Explorer hide/show (2026-10-31 toggle RCA): $state is REQUIRED —
|
|
20702
|
+
* a plain field swallowed the toggle click silently (no re-render). */
|
|
20703
|
+
explorerHidden = false;
|
|
20704
|
+
/** Sidebar rail state (OCI ControlRail port). */
|
|
20705
|
+
sidebarCollapsed = false;
|
|
20706
|
+
sidebarWidth = 0;
|
|
20707
|
+
/** Sidebar width-badge phase (Movable Rail ADR amendment 2026-10-30):
|
|
20708
|
+
* 'live' while the gutter drag moves, 'fading' through the 10s
|
|
20709
|
+
* afterglow, null otherwise. GESTURE state, never persisted — the
|
|
20710
|
+
* save whitelist below carries only collapsed + width. */
|
|
20711
|
+
sidebarBadge = null;
|
|
20712
|
+
#profile = null;
|
|
20713
|
+
#initialised = false;
|
|
20714
|
+
/** Non-reactive: the afterglow timer id (drag.svelte.ts dragRefs
|
|
20715
|
+
* pattern — timers never belong in reactive state). */
|
|
20716
|
+
#afterglowTimer = null;
|
|
20717
|
+
/** Seed every field from the persisted blobs — exactly once, BEFORE
|
|
20718
|
+
* the route reads any field (makePanel reads panelWidth during the
|
|
20719
|
+
* seed reset). Intentional initial capture per the route's old
|
|
20720
|
+
* "svelte-ignore state_referenced_locally" comments: prefs seed the
|
|
20721
|
+
* layout once; later writes go through the save effects. */
|
|
20722
|
+
init(profile) {
|
|
20723
|
+
this.#initialised = true;
|
|
20724
|
+
this.#profile = profile;
|
|
20725
|
+
const floor = loadPanelPrefs(profile);
|
|
20726
|
+
this.panelWidth = clampPanelWidth(floor.panelWidth);
|
|
20727
|
+
this.zoom = clampPanelZoom(floor.zoom);
|
|
20728
|
+
this.treePct = clampTreePct(floor.treePct);
|
|
20729
|
+
this.explorerHidden = floor.explorerHidden === true;
|
|
20730
|
+
const sidebar = loadSidebarPrefs(profile);
|
|
20731
|
+
this.sidebarCollapsed = sidebar.collapsed;
|
|
20732
|
+
this.sidebarWidth = sidebar.width;
|
|
20733
|
+
}
|
|
20734
|
+
get profile() {
|
|
20735
|
+
return this.#profile;
|
|
20736
|
+
}
|
|
20737
|
+
/** Sidebar persistence (the route's old sidebar save effect). Call
|
|
20738
|
+
* during component initialisation — $effect needs an owner. */
|
|
20739
|
+
installSidebarAutoSave() {}
|
|
20740
|
+
/** The badge afterglow (10s linear fade, mirroring the floor's
|
|
20741
|
+
* drag.svelte.ts:118-128): called at gutter mouseup — freezes the
|
|
20742
|
+
* phase into 'fading', then null. A drag that starts before the
|
|
20743
|
+
* timer fires cancels it (the chip goes back to live instantly,
|
|
20744
|
+
* never a 10s fade-in). */
|
|
20745
|
+
armSidebarAfterglow() {
|
|
20746
|
+
this.sidebarBadge = "fading";
|
|
20747
|
+
if (this.#afterglowTimer !== null) clearTimeout(this.#afterglowTimer);
|
|
20748
|
+
this.#afterglowTimer = setTimeout(() => {
|
|
20749
|
+
this.sidebarBadge = null;
|
|
20750
|
+
this.#afterglowTimer = null;
|
|
20751
|
+
}, 1e4);
|
|
20752
|
+
}
|
|
20753
|
+
/** A new gutter drag cancels any armed afterglow. */
|
|
20754
|
+
cancelSidebarAfterglow() {
|
|
20755
|
+
if (this.#afterglowTimer !== null) {
|
|
20756
|
+
clearTimeout(this.#afterglowTimer);
|
|
20757
|
+
this.#afterglowTimer = null;
|
|
20758
|
+
}
|
|
20759
|
+
this.sidebarBadge = "live";
|
|
20760
|
+
}
|
|
20761
|
+
};
|
|
20762
|
+
var pagePrefs = new PagePrefs();
|
|
20763
|
+
//#endregion
|
|
20168
20764
|
//#region src/lib/components/common/layout/AppSidebar.svelte
|
|
20169
20765
|
function AppSidebar($$renderer, $$props) {
|
|
20170
20766
|
$$renderer.component(($$renderer) => {
|
|
@@ -20267,7 +20863,16 @@ function AppSidebar($$renderer, $$props) {
|
|
|
20267
20863
|
$$renderer.push(`<!----></aside>`);
|
|
20268
20864
|
} else {
|
|
20269
20865
|
$$renderer.push("<!--[-1-->");
|
|
20270
|
-
$$renderer.push(`<div data-svelte="AppSidebar" class="rail-wrap svelte-113gpvg" data-testid="app-sidebar"${attr_style(`width: ${stringify(width)}px`)}
|
|
20866
|
+
$$renderer.push(`<div data-svelte="AppSidebar" class="rail-wrap svelte-113gpvg" data-testid="app-sidebar"${attr_style(`width: ${stringify(width)}px`)}>`);
|
|
20867
|
+
if (pagePrefs.sidebarBadge !== null) {
|
|
20868
|
+
$$renderer.push("<!--[0-->");
|
|
20869
|
+
WidthBadge($$renderer, {
|
|
20870
|
+
phase: pagePrefs.sidebarBadge,
|
|
20871
|
+
width,
|
|
20872
|
+
testid: "sidebar-width-badge"
|
|
20873
|
+
});
|
|
20874
|
+
} else $$renderer.push("<!--[-1-->");
|
|
20875
|
+
$$renderer.push(`<!--]--> <aside class="rail svelte-113gpvg">`);
|
|
20271
20876
|
AppSidebarHeader($$renderer, {
|
|
20272
20877
|
captureContainer,
|
|
20273
20878
|
trayContainer,
|
|
@@ -21193,15 +21798,25 @@ function parseCommand(text) {
|
|
|
21193
21798
|
let rest = args === "" ? [] : args.split(/\s+/);
|
|
21194
21799
|
let agentId;
|
|
21195
21800
|
let ws;
|
|
21801
|
+
let title;
|
|
21196
21802
|
let addPanel = false;
|
|
21197
|
-
if (rest.length > 0 && rest[0].startsWith("@") && rest[0].length > 1) {
|
|
21198
|
-
agentId = rest[0].slice(1);
|
|
21199
|
-
rest = rest.slice(1);
|
|
21200
|
-
}
|
|
21201
21803
|
if (rest.length > 0 && rest[rest.length - 1] === "--add") {
|
|
21202
21804
|
addPanel = true;
|
|
21203
21805
|
rest = rest.slice(0, -1);
|
|
21204
21806
|
}
|
|
21807
|
+
const titleIdx = rest.indexOf("--title");
|
|
21808
|
+
if (titleIdx !== -1) {
|
|
21809
|
+
if (titleIdx === rest.length - 1) return {
|
|
21810
|
+
type: "new",
|
|
21811
|
+
args
|
|
21812
|
+
};
|
|
21813
|
+
title = rest.slice(titleIdx + 1).join(" ");
|
|
21814
|
+
rest = rest.slice(0, titleIdx);
|
|
21815
|
+
}
|
|
21816
|
+
if (rest.length > 0 && rest[0].startsWith("@") && rest[0].length > 1) {
|
|
21817
|
+
agentId = rest[0].slice(1);
|
|
21818
|
+
rest = rest.slice(1);
|
|
21819
|
+
}
|
|
21205
21820
|
if (rest.length === 1 && !rest[0].startsWith("@") && !rest[0].startsWith("--") && rest[0] !== "?") {
|
|
21206
21821
|
ws = rest[0];
|
|
21207
21822
|
rest = [];
|
|
@@ -21215,6 +21830,7 @@ function parseCommand(text) {
|
|
|
21215
21830
|
args: "",
|
|
21216
21831
|
...agentId !== void 0 ? { agentId } : {},
|
|
21217
21832
|
...ws !== void 0 ? { ws } : {},
|
|
21833
|
+
...title !== void 0 ? { title } : {},
|
|
21218
21834
|
...addPanel ? { addPanel: true } : {}
|
|
21219
21835
|
};
|
|
21220
21836
|
}
|
|
@@ -21358,7 +21974,7 @@ function commandHelpTopic(text) {
|
|
|
21358
21974
|
* PRESET_TABLE (permission-state); ids/examples mirror command-parser. */
|
|
21359
21975
|
var COMMAND_HELP = {
|
|
21360
21976
|
new: {
|
|
21361
|
-
usage: "/new [@agent] [workspace] [--add]",
|
|
21977
|
+
usage: "/new [@agent] [workspace] [--title <title>] [--add]",
|
|
21362
21978
|
summary: "Creates a fresh session — it inherits this session's workspace and agent. Name a registered workspace to land THERE instead of inheriting (unique title, or the full path). Default: it replaces this panel. With --add: it opens in a NEW panel to the right, and focus stays here.",
|
|
21363
21979
|
params: [
|
|
21364
21980
|
{
|
|
@@ -21369,6 +21985,10 @@ var COMMAND_HELP = {
|
|
|
21369
21985
|
name: "workspace",
|
|
21370
21986
|
description: "Optional registered workspace — a unique title (recipe-ws) or the full path (/home/u/recipe-ws). The new session runs there instead of inheriting; an ambiguous name lists the candidates instead of guessing."
|
|
21371
21987
|
},
|
|
21988
|
+
{
|
|
21989
|
+
name: "--title <title>",
|
|
21990
|
+
description: "Optional title for the new session — everything after --title is the title, verbatim. Applied after the session is created; a failed rename keeps the default title."
|
|
21991
|
+
},
|
|
21372
21992
|
{
|
|
21373
21993
|
name: "--add",
|
|
21374
21994
|
description: "Open the new session in a NEW panel placed to the RIGHT of the current panel; the current panel keeps the selection and the caret (the default panel swap never runs)."
|
|
@@ -21388,8 +22008,8 @@ var COMMAND_HELP = {
|
|
|
21388
22008
|
description: "New session inside the registered recipe-ws workspace."
|
|
21389
22009
|
},
|
|
21390
22010
|
{
|
|
21391
|
-
line: "/new @app-dev --add",
|
|
21392
|
-
description: "New app-dev session in a panel to the right — this panel keeps focus."
|
|
22011
|
+
line: "/new @app-dev --title Refactor Auth --add",
|
|
22012
|
+
description: "New app-dev session titled Refactor Auth in a panel to the right — this panel keeps focus."
|
|
21393
22013
|
}
|
|
21394
22014
|
]
|
|
21395
22015
|
},
|
|
@@ -21917,14 +22537,17 @@ function ContextConsumption($$renderer, $$props) {
|
|
|
21917
22537
|
* ContextConsumption — context window usage indicator (OCI port,
|
|
21918
22538
|
* 2026-08-23; percentage wired 2026-08-24). Two display modes:
|
|
21919
22539
|
*
|
|
21920
|
-
* both values
|
|
21921
|
-
*
|
|
22540
|
+
* both values, → OCI's exact bar: colored progress (green <60%,
|
|
22541
|
+
* used > 0 amber <85%, red ≥85%) + percentage label
|
|
21922
22542
|
* used only → DSI fallback: "≈12.3k ctx" text label. The DSH
|
|
21923
22543
|
* wire reports per-step usage but no model context
|
|
21924
22544
|
* window, so when the model is unknown to the
|
|
21925
22545
|
* local catalog (context-window.ts) the bar has
|
|
21926
22546
|
* no denominator — the label keeps the slot
|
|
21927
22547
|
* honest instead of dead.
|
|
22548
|
+
* used = 0 → the fallback label too ("≈0 ctx"): a zero-usage
|
|
22549
|
+
* turn would otherwise paint a 0%-wide bar — a dead
|
|
22550
|
+
* slot (SC#1, 2026-11-01).
|
|
21928
22551
|
* neither → renders nothing (OCI contract).
|
|
21929
22552
|
*
|
|
21930
22553
|
* `used` = what the LAST model request consumed: input + cache-read +
|
|
@@ -21934,7 +22557,7 @@ function ContextConsumption($$renderer, $$props) {
|
|
|
21934
22557
|
* overrides), never wire truth — the bar's tooltip says so.
|
|
21935
22558
|
*/
|
|
21936
22559
|
let { used = void 0, limit = void 0 } = $$props;
|
|
21937
|
-
const percent = derived(() => used !== void 0 && limit !== void 0 && limit > 0 ? Math.round(used / limit * 100) : void 0);
|
|
22560
|
+
const percent = derived(() => used !== void 0 && used > 0 && limit !== void 0 && limit > 0 ? Math.round(used / limit * 100) : void 0);
|
|
21938
22561
|
function formatK(n) {
|
|
21939
22562
|
return n >= 1e3 ? `${(n / 1e3).toFixed(1)}k` : String(n);
|
|
21940
22563
|
}
|
|
@@ -23596,7 +24219,7 @@ function workspaceFileTitle(path) {
|
|
|
23596
24219
|
*/
|
|
23597
24220
|
function panelHeaderLabel(panel) {
|
|
23598
24221
|
if (panel.kind === "terminal") return "Terminal";
|
|
23599
|
-
if (panel.kind === "browser") return "Browser";
|
|
24222
|
+
if (panel.kind === "browser") return "Glass Browser";
|
|
23600
24223
|
if (panel.kind === "prompt-manager") return MANAGER_ROW_TITLE;
|
|
23601
24224
|
if (panel.kind === "skill-shelf") return "Skill Shelf";
|
|
23602
24225
|
if (panel.kind === "plugin-rack") return "Plugin Rack";
|
|
@@ -23630,7 +24253,7 @@ function panelRowsFor(input) {
|
|
|
23630
24253
|
const openerDepth = p.openedBy !== void 0 ? lineageFacts.depthById.get(p.openedBy) ?? 0 : 0;
|
|
23631
24254
|
return {
|
|
23632
24255
|
panel: p,
|
|
23633
|
-
title: "Browser",
|
|
24256
|
+
title: "Glass Browser",
|
|
23634
24257
|
workspace: null,
|
|
23635
24258
|
dead: false,
|
|
23636
24259
|
running: false,
|
|
@@ -24749,7 +25372,8 @@ function EditingTitle($$renderer, $$props) {
|
|
|
24749
25372
|
* from SessionIdAndName: BOTH title states inside one component —
|
|
24750
25373
|
*
|
|
24751
25374
|
* display — the rename trigger button (title="Rename this session")
|
|
24752
|
-
* editing — the inline form (input +
|
|
25375
|
+
* editing — the inline form (input + ✓/✕ icon verbs + error line;
|
|
25376
|
+
* ADR-0044: the verbs are icon-only, words on tooltips)
|
|
24753
25377
|
*
|
|
24754
25378
|
* Rename is fully owned here: draft, in-flight lock, the POST
|
|
24755
25379
|
* (session.rename via the page’s /api/dsh route), the error surface,
|
|
@@ -25070,10 +25694,10 @@ function ToolsAndStatusHeader($$renderer, $$props) {
|
|
|
25070
25694
|
});
|
|
25071
25695
|
}
|
|
25072
25696
|
//#endregion
|
|
25073
|
-
//#region src/lib/components/conversation/header/
|
|
25074
|
-
function
|
|
25697
|
+
//#region src/lib/components/conversation/header/BrowserButton.svelte
|
|
25698
|
+
function BrowserButton($$renderer, $$props) {
|
|
25075
25699
|
$$renderer.component(($$renderer) => {
|
|
25076
|
-
$$renderer.push(`<button data-svelte="
|
|
25700
|
+
$$renderer.push(`<button data-svelte="BrowserButton" type="button" class="rounded border border-surface-border px-1.5 py-0.5 text-xs hover:bg-surface-active" data-testid="open-browser"${attr("title", browseropentitle2())}>${escape_html(browserchiplabel2())}</button>`);
|
|
25077
25701
|
});
|
|
25078
25702
|
}
|
|
25079
25703
|
//#endregion
|
|
@@ -25103,7 +25727,7 @@ function ConversationHeader($$renderer, $$props) {
|
|
|
25103
25727
|
$$renderer.push(`<!----> `);
|
|
25104
25728
|
if (onOpenBrowser) {
|
|
25105
25729
|
$$renderer.push("<!--[0-->");
|
|
25106
|
-
|
|
25730
|
+
BrowserButton($$renderer);
|
|
25107
25731
|
} else $$renderer.push("<!--[-1-->");
|
|
25108
25732
|
$$renderer.push(`<!--]--> `);
|
|
25109
25733
|
ToolsAndStatusHeader($$renderer, {
|
|
@@ -25556,7 +26180,7 @@ async function resolveWorkspaceToken(token) {
|
|
|
25556
26180
|
/** The /new verb (moved verbatim from the executeCommand body). */
|
|
25557
26181
|
async function runNewLine(command, ctx, onNote) {
|
|
25558
26182
|
if (command.args !== "") {
|
|
25559
|
-
const usage = "usage: /new [@agent] [workspace] [--add]";
|
|
26183
|
+
const usage = "usage: /new [@agent] [workspace] [--title <title>] [--add]";
|
|
25560
26184
|
onNote?.(false, usage);
|
|
25561
26185
|
return {
|
|
25562
26186
|
ok: false,
|
|
@@ -25603,6 +26227,13 @@ async function runNewLine(command, ctx, onNote) {
|
|
|
25603
26227
|
note
|
|
25604
26228
|
};
|
|
25605
26229
|
}
|
|
26230
|
+
if (command.title !== void 0 && command.title !== "") try {
|
|
26231
|
+
await fetch(`/api/dsh/session/${encodeURIComponent(body.sessionId)}/rename`, {
|
|
26232
|
+
method: "POST",
|
|
26233
|
+
headers: { "content-type": "application/json" },
|
|
26234
|
+
body: JSON.stringify({ title: command.title })
|
|
26235
|
+
});
|
|
26236
|
+
} catch {}
|
|
25606
26237
|
if (command.addPanel === true) {
|
|
25607
26238
|
if (!addPanelFromSidebar({
|
|
25608
26239
|
sessionId: body.sessionId,
|
|
@@ -26765,7 +27396,7 @@ function groupTurns(entries) {
|
|
|
26765
27396
|
continue;
|
|
26766
27397
|
}
|
|
26767
27398
|
if (entry.kind === "user-message") {
|
|
26768
|
-
if (entry.meta) {
|
|
27399
|
+
if (entry.meta && entry.imageRefs === void 0) {
|
|
26769
27400
|
const last = groups[groups.length - 1];
|
|
26770
27401
|
if (last?.kind === "prompt") {
|
|
26771
27402
|
last.context.push(entry);
|
|
@@ -27034,6 +27665,346 @@ function LoadOlderSentinel($$renderer, $$props) {
|
|
|
27034
27665
|
});
|
|
27035
27666
|
}
|
|
27036
27667
|
//#endregion
|
|
27668
|
+
//#region src/lib/utils/markdown.ts
|
|
27669
|
+
/**
|
|
27670
|
+
* markdown — render markdown to sanitized HTML (Wave 2, task 2.1;
|
|
27671
|
+
* PRD §3.3 shared layer; BC-12).
|
|
27672
|
+
*
|
|
27673
|
+
* Pure function, no I/O, no Svelte, no DOM: runs server-side (SSR cold load)
|
|
27674
|
+
* and client-side alike. Two-stage pipeline with an allow-list escape hatch —
|
|
27675
|
+
* raw HTML never reaches the output:
|
|
27676
|
+
*
|
|
27677
|
+
* 1. ESCAPE every <, >, &, ", ' in the source text. Any markup-like
|
|
27678
|
+
* construct in the transcript is now inert character data; the markdown
|
|
27679
|
+
* tokenizer can no longer emit an HTML node from user/wire content.
|
|
27680
|
+
* 2. Convert the escaped text with a small CommonMark-subset tokenizer
|
|
27681
|
+
* whose emitter can ONLY produce the allow-listed tags below (p, strong,
|
|
27682
|
+
* em, del, code, pre, h1-h4, ul/ol/li, blockquote, hr, a, table/
|
|
27683
|
+
* thead/tbody/tr/th/td) — plus ONE structured exception: a ```mermaid
|
|
27684
|
+
* fence emits a bare placeholder <div class="mermaid-diagram"> whose
|
|
27685
|
+
* only attribute is the base64 diagram source; the SVG itself is
|
|
27686
|
+
* produced client-side by the mermaid runtime, never by this emitter.
|
|
27687
|
+
* Inline
|
|
27688
|
+
* code and code fences re-inject their (already-escaped) bodies verbatim
|
|
27689
|
+
* — code renders as characters, never markup (tool-payload rule).
|
|
27690
|
+
* Paragraph soft line breaks stay as raw \n (the bubble renders with
|
|
27691
|
+
* whitespace-pre-wrap — no <br> node needed).
|
|
27692
|
+
* 3. Links: only http(s) schemes survive; every other scheme (javascript:,
|
|
27693
|
+
* data:, vbscript:, file:, mailto:…) is reduced to plain text. Emitted
|
|
27694
|
+
* <a> tags carry rel="noopener noreferrer" target="_blank".
|
|
27695
|
+
*
|
|
27696
|
+
* Why not a dependency: the project has zero render deps today; the subset
|
|
27697
|
+
* below is what the harness transcripts actually use (bold, inline code,
|
|
27698
|
+
* fenced blocks, lists, headings) — pinned by markdown.test.ts. The escape-
|
|
27699
|
+
* first order makes sanitization structural rather than a block-list chase.
|
|
27700
|
+
*/
|
|
27701
|
+
/** Escape HTML-significant characters — stage 1 of the pipeline. */
|
|
27702
|
+
function escapeHtml(text) {
|
|
27703
|
+
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
27704
|
+
}
|
|
27705
|
+
/**
|
|
27706
|
+
* GFM table row: two or more pipe-delimited cells. Cells may ALL be empty —
|
|
27707
|
+
* a header-less table (`| | | |\n|---|---|---|\n…`, GitHub renders these)
|
|
27708
|
+
* must still start a table; requiring content here swallowed the header,
|
|
27709
|
+
* the delimiter row, and every body row into one raw pipe paragraph
|
|
27710
|
+
* (2026-08-26 fix, found via a header-less lineage table rendering as text).
|
|
27711
|
+
* Over-triggering is structurally impossible: a row only becomes a table
|
|
27712
|
+
* when the NEXT line is a strict delimiter row; and `| just a pipe line`
|
|
27713
|
+
* stays one cell.
|
|
27714
|
+
*/
|
|
27715
|
+
function isTableRow(line) {
|
|
27716
|
+
if (!line.includes("|")) return false;
|
|
27717
|
+
return splitRow(line).length >= 2;
|
|
27718
|
+
}
|
|
27719
|
+
/** GFM delimiter row: cells of only -, :, optional spaces (e.g. |---|:--:|). */
|
|
27720
|
+
function isDelimiterRow(line) {
|
|
27721
|
+
if (!line.includes("|") && !/^[-:\s]+$/.test(line)) return false;
|
|
27722
|
+
const stripped = line.replace(/\|/g, "").trim();
|
|
27723
|
+
if (stripped === "" || !/^[-:\s]+$/.test(stripped)) return false;
|
|
27724
|
+
return splitRow(line).length >= 2 && splitRow(line).every((c) => /^:?-+:?$/.test(c.trim()));
|
|
27725
|
+
}
|
|
27726
|
+
/** Split one pipe row into cells: trim outer pipes, split on inner ones. */
|
|
27727
|
+
function splitRow(line) {
|
|
27728
|
+
let s = line.trim();
|
|
27729
|
+
if (s.startsWith("|")) s = s.slice(1);
|
|
27730
|
+
if (s.endsWith("|")) s = s.slice(0, -1);
|
|
27731
|
+
const literals = [];
|
|
27732
|
+
s = s.replace(/\\\|/g, () => {
|
|
27733
|
+
literals.push("|");
|
|
27734
|
+
return `\u0001${literals.length - 1}\u0001`;
|
|
27735
|
+
});
|
|
27736
|
+
return s.split("|").map((c) => c.replace(/\u0001(\d+)\u0001/g, (_m, idx) => literals[Number(idx)] ?? "").trim());
|
|
27737
|
+
}
|
|
27738
|
+
/** List item line: indent, bullet (- * +) or ordered (N. / N)) marker, body. */
|
|
27739
|
+
var LIST_ITEM_RE = /^(\s*)([-*+]|\d+[.)])\s+(.*)$/;
|
|
27740
|
+
/** Indent width in spaces — a tab advances to the next multiple of 4. */
|
|
27741
|
+
function indentWidth(s) {
|
|
27742
|
+
let w = 0;
|
|
27743
|
+
for (const ch of s) if (ch === " ") w += 4 - w % 4;
|
|
27744
|
+
else w += 1;
|
|
27745
|
+
return w;
|
|
27746
|
+
}
|
|
27747
|
+
/**
|
|
27748
|
+
* Parse one list run from lines[start] (a list item): consecutive item
|
|
27749
|
+
* lines at ANY indent plus lazy plain-text continuations.
|
|
27750
|
+
*
|
|
27751
|
+
* deeper indent than the innermost open item → nests INSIDE it;
|
|
27752
|
+
* same indent → sibling;
|
|
27753
|
+
* kind change (bullet ⇄ ordered) at an EXISTING depth → ends the run
|
|
27754
|
+
* (the outer scan then emits the next list as its own block — the
|
|
27755
|
+
* pre-nesting behavior of two sibling lists is kept);
|
|
27756
|
+
* blank line / fence / heading / quote → run over.
|
|
27757
|
+
*
|
|
27758
|
+
* Mixed kinds still nest when the indent is deeper — a numbered plan
|
|
27759
|
+
* under a bullet is legal CommonMark and common in transcripts.
|
|
27760
|
+
*/
|
|
27761
|
+
function parseListRun(lines, start) {
|
|
27762
|
+
const items = [];
|
|
27763
|
+
const stack = [];
|
|
27764
|
+
let i = start;
|
|
27765
|
+
while (i < lines.length) {
|
|
27766
|
+
const l = lines[i];
|
|
27767
|
+
const m = LIST_ITEM_RE.exec(l);
|
|
27768
|
+
if (m) {
|
|
27769
|
+
const indent = indentWidth(m[1]);
|
|
27770
|
+
const ordered = /^\d/.test(m[2]);
|
|
27771
|
+
while (stack.length > 0 && stack[stack.length - 1].indent > indent) stack.pop();
|
|
27772
|
+
if (stack.length === 0) {
|
|
27773
|
+
if (items.length > 0 && ordered !== items[0].ordered) break;
|
|
27774
|
+
const it = {
|
|
27775
|
+
indent,
|
|
27776
|
+
ordered,
|
|
27777
|
+
text: m[3],
|
|
27778
|
+
children: []
|
|
27779
|
+
};
|
|
27780
|
+
items.push(it);
|
|
27781
|
+
stack.push(it);
|
|
27782
|
+
} else {
|
|
27783
|
+
const top = stack[stack.length - 1];
|
|
27784
|
+
if (indent === top.indent && ordered !== top.ordered) break;
|
|
27785
|
+
const it = {
|
|
27786
|
+
indent,
|
|
27787
|
+
ordered,
|
|
27788
|
+
text: m[3],
|
|
27789
|
+
children: []
|
|
27790
|
+
};
|
|
27791
|
+
if (indent > top.indent) top.children.push(it);
|
|
27792
|
+
else {
|
|
27793
|
+
const parent = stack.length >= 2 ? stack[stack.length - 2] : null;
|
|
27794
|
+
if (parent) parent.children.push(it);
|
|
27795
|
+
else items.push(it);
|
|
27796
|
+
stack.pop();
|
|
27797
|
+
}
|
|
27798
|
+
stack.push(it);
|
|
27799
|
+
}
|
|
27800
|
+
i += 1;
|
|
27801
|
+
continue;
|
|
27802
|
+
}
|
|
27803
|
+
if (stack.length > 0 && l.trim() !== "" && !/^(#{1,6})\s|^```|^>/.test(l)) {
|
|
27804
|
+
stack[stack.length - 1].text += ` ${l.trim()}`;
|
|
27805
|
+
i += 1;
|
|
27806
|
+
continue;
|
|
27807
|
+
}
|
|
27808
|
+
break;
|
|
27809
|
+
}
|
|
27810
|
+
return {
|
|
27811
|
+
items,
|
|
27812
|
+
next: i
|
|
27813
|
+
};
|
|
27814
|
+
}
|
|
27815
|
+
/** Emit an item tree — one inline pass per item, children inside the <li>. */
|
|
27816
|
+
function emitList(items) {
|
|
27817
|
+
const tag = items[0].ordered ? "ol" : "ul";
|
|
27818
|
+
return `<${tag}>${items.map((it) => `<li>${renderInline(it.text)}${it.children.length > 0 ? emitList(it.children) : ""}</li>`).join("")}</${tag}>`;
|
|
27819
|
+
}
|
|
27820
|
+
/** Reverse stage-1 escaping — mermaid parses the ORIGINAL syntax, not entities. */
|
|
27821
|
+
function unescapeEntities(text) {
|
|
27822
|
+
return text.replaceAll("<", "<").replaceAll(">", ">").replaceAll(""", "\"").replaceAll("'", "'").replaceAll("&", "&");
|
|
27823
|
+
}
|
|
27824
|
+
/** Base64 that survives non-ASCII (diagram labels are arbitrary text). */
|
|
27825
|
+
function btoaUnicode(text) {
|
|
27826
|
+
return btoa(String.fromCharCode(...new TextEncoder().encode(text)));
|
|
27827
|
+
}
|
|
27828
|
+
var ESCAPED_CODE_FENCE = /^```/;
|
|
27829
|
+
/**
|
|
27830
|
+
* Stage 0 — the harness wraps tool-result file paths in <path>…</path>
|
|
27831
|
+
* blocks (every attached image rides one). Escaped by stage 1, they
|
|
27832
|
+
* rendered as dead literal text. This pass rewrites each block to a
|
|
27833
|
+
* [basename](full path) markdown link BEFORE escaping, so the existing
|
|
27834
|
+
* machinery takes over: links() emits the scheme-free anchor (its refusal
|
|
27835
|
+
* rules still guard the href) and MarkdownContent's File Link Intent
|
|
27836
|
+
* (ADR 2026-09-25 D2) opens the file on click.
|
|
27837
|
+
*
|
|
27838
|
+
* Fenced code runs are carved out FIRST and passed through verbatim —
|
|
27839
|
+
* the tool-payload rule: a <path> quoted inside a transcript paste is
|
|
27840
|
+
* data, never a link.
|
|
27841
|
+
*/
|
|
27842
|
+
function pathBlocksToLinks(text) {
|
|
27843
|
+
const parts = [];
|
|
27844
|
+
const fence = /```[\s\S]*?(```|$)/g;
|
|
27845
|
+
let last = 0;
|
|
27846
|
+
for (const m of text.matchAll(fence)) {
|
|
27847
|
+
parts.push(transformPaths(text.slice(last, m.index)));
|
|
27848
|
+
parts.push(m[0]);
|
|
27849
|
+
last = (m.index ?? 0) + m[0].length;
|
|
27850
|
+
}
|
|
27851
|
+
parts.push(transformPaths(text.slice(last)));
|
|
27852
|
+
return parts.join("");
|
|
27853
|
+
}
|
|
27854
|
+
function transformPaths(text) {
|
|
27855
|
+
return text.replace(/<path>\s*([^\n<]+?)\s*<\/path>/g, (_m, p) => {
|
|
27856
|
+
return `[${p.split("/").pop() || p}](<${p}>)`;
|
|
27857
|
+
});
|
|
27858
|
+
}
|
|
27859
|
+
/**
|
|
27860
|
+
* Render markdown to sanitized HTML (single entry point, BC-12).
|
|
27861
|
+
* Output uses ONLY the allow-listed tags; empty input renders ''.
|
|
27862
|
+
*/
|
|
27863
|
+
function renderMarkdown(text) {
|
|
27864
|
+
if (text === "") return "";
|
|
27865
|
+
const escaped = escapeHtml(pathBlocksToLinks(text));
|
|
27866
|
+
const out = [];
|
|
27867
|
+
const lines = escaped.split("\n");
|
|
27868
|
+
let i = 0;
|
|
27869
|
+
while (i < lines.length) {
|
|
27870
|
+
const line = lines[i];
|
|
27871
|
+
if (ESCAPED_CODE_FENCE.test(line.trimStart())) {
|
|
27872
|
+
const opener = line.trimStart().slice(3).trim().toLowerCase();
|
|
27873
|
+
const body = [];
|
|
27874
|
+
i += 1;
|
|
27875
|
+
while (i < lines.length && !ESCAPED_CODE_FENCE.test(lines[i].trimStart())) {
|
|
27876
|
+
body.push(lines[i]);
|
|
27877
|
+
i += 1;
|
|
27878
|
+
}
|
|
27879
|
+
i += 1;
|
|
27880
|
+
if (opener === "mermaid") {
|
|
27881
|
+
const encoded = btoaUnicode(unescapeEntities(body.join("\n")));
|
|
27882
|
+
out.push(`<div class="mermaid-diagram" data-source="${encoded}" data-processed="false"></div>`);
|
|
27883
|
+
continue;
|
|
27884
|
+
}
|
|
27885
|
+
out.push(`<pre><code>${body.join("\n")}</code></pre>`);
|
|
27886
|
+
continue;
|
|
27887
|
+
}
|
|
27888
|
+
if (line.trim() === "") {
|
|
27889
|
+
i += 1;
|
|
27890
|
+
continue;
|
|
27891
|
+
}
|
|
27892
|
+
const heading = /^(#{1,6})\s+(.*)$/.exec(line);
|
|
27893
|
+
if (heading) {
|
|
27894
|
+
const level = Math.min(4, heading[1].length);
|
|
27895
|
+
out.push(`<h${level}>${renderInline(heading[2])}</h${level}>`);
|
|
27896
|
+
i += 1;
|
|
27897
|
+
continue;
|
|
27898
|
+
}
|
|
27899
|
+
if (/^([-*_])(\s*\1){2,}\s*$/.test(line)) {
|
|
27900
|
+
out.push("<hr />");
|
|
27901
|
+
i += 1;
|
|
27902
|
+
continue;
|
|
27903
|
+
}
|
|
27904
|
+
if (isTableRow(line) && i + 1 < lines.length && isDelimiterRow(lines[i + 1])) {
|
|
27905
|
+
const header = splitRow(line);
|
|
27906
|
+
i += 2;
|
|
27907
|
+
const body = [];
|
|
27908
|
+
while (i < lines.length && isTableRow(lines[i]) && !isDelimiterRow(lines[i])) {
|
|
27909
|
+
body.push(splitRow(lines[i]));
|
|
27910
|
+
i += 1;
|
|
27911
|
+
}
|
|
27912
|
+
const thead = `<thead><tr>${header.map((c) => `<th>${renderInline(c)}</th>`).join("")}</tr></thead>`;
|
|
27913
|
+
const tbody = `<tbody>${body.map((row) => `<tr>${row.map((c) => `<td>${renderInline(c)}</td>`).join("")}</tr>`).join("")}</tbody>`;
|
|
27914
|
+
out.push(`<table>${thead}${tbody}</table>`);
|
|
27915
|
+
continue;
|
|
27916
|
+
}
|
|
27917
|
+
if (/^>\s?/.test(line)) {
|
|
27918
|
+
const body = [];
|
|
27919
|
+
while (i < lines.length && /^>\s?/.test(lines[i])) {
|
|
27920
|
+
body.push(lines[i].replace(/^>\s?/, ""));
|
|
27921
|
+
i += 1;
|
|
27922
|
+
}
|
|
27923
|
+
out.push(`<blockquote><p>${renderInline(body.join(" "))}</p></blockquote>`);
|
|
27924
|
+
continue;
|
|
27925
|
+
}
|
|
27926
|
+
if (LIST_ITEM_RE.test(line)) {
|
|
27927
|
+
const run = parseListRun(lines, i);
|
|
27928
|
+
out.push(emitList(run.items));
|
|
27929
|
+
i = run.next;
|
|
27930
|
+
continue;
|
|
27931
|
+
}
|
|
27932
|
+
const para = [];
|
|
27933
|
+
while (i < lines.length && lines[i].trim() !== "" && !ESCAPED_CODE_FENCE.test(lines[i].trimStart()) && !/^#{1,6}\s/.test(lines[i]) && !/^>\s?/.test(lines[i]) && !/^(\s*)([-*+]|\d+[.)])\s+/.test(lines[i]) && !/^([-*_])(\s*\1){2,}\s*$/.test(lines[i]) && !(isTableRow(lines[i]) && i + 1 < lines.length && isDelimiterRow(lines[i + 1]))) {
|
|
27934
|
+
para.push(lines[i]);
|
|
27935
|
+
i += 1;
|
|
27936
|
+
}
|
|
27937
|
+
if (para.length > 0) out.push(`<p>${renderInline(para.join("\n"))}</p>`);
|
|
27938
|
+
}
|
|
27939
|
+
return out.join("\n");
|
|
27940
|
+
}
|
|
27941
|
+
/**
|
|
27942
|
+
* Inline pass: code spans first (their bodies stay verbatim), then emphasis,
|
|
27943
|
+
* then links. Escaped text in, allow-listed tags out.
|
|
27944
|
+
*/
|
|
27945
|
+
function renderInline(text) {
|
|
27946
|
+
const codeSpans = [];
|
|
27947
|
+
let rest = text.replace(/`([^`\n]+)`/g, (_m, body) => {
|
|
27948
|
+
const raw = unescapeEntities(body);
|
|
27949
|
+
if (/^https?:\/\/\S+$/i.test(raw)) codeSpans.push(externalAnchor(raw));
|
|
27950
|
+
else codeSpans.push(`<code>${body}</code>`);
|
|
27951
|
+
return `\u0000${codeSpans.length - 1}\u0000`;
|
|
27952
|
+
});
|
|
27953
|
+
rest = emphasis(rest);
|
|
27954
|
+
rest = links(rest);
|
|
27955
|
+
rest = autolinkBareUrls(rest);
|
|
27956
|
+
return rest.replace(/\u0000(\d+)\u0000/g, (_m, idx) => codeSpans[Number(idx)] ?? "");
|
|
27957
|
+
}
|
|
27958
|
+
/** One hardened external anchor from a RAW url — display is origin+path
|
|
27959
|
+
* (query/fragment stripped), href keeps everything (BC-12 attributes). */
|
|
27960
|
+
function externalAnchor(rawUrl) {
|
|
27961
|
+
let cut = rawUrl.length;
|
|
27962
|
+
for (const c of ["?", "#"]) {
|
|
27963
|
+
const i = rawUrl.indexOf(c);
|
|
27964
|
+
if (i !== -1 && i < cut) cut = i;
|
|
27965
|
+
}
|
|
27966
|
+
return `<a href="${rawUrl.replaceAll("\"", """)}" rel="noopener noreferrer" target="_blank">${rawUrl.slice(0, cut)}</a>`;
|
|
27967
|
+
}
|
|
27968
|
+
/**
|
|
27969
|
+
* Bare-URL autolink (2026-09-27): an http(s) URL in plain text becomes an
|
|
27970
|
+
* anchor whose DISPLAY TEXT is the origin+path with the query/hash stripped
|
|
27971
|
+
* (transcript URLs like …new?merge_request[source_branch]=… render short)
|
|
27972
|
+
* while the HREF keeps the FULL URL. Runs after [label](href) parsing and
|
|
27973
|
+
* skips text inside existing anchors/code placeholders (\u0000N\u0000 markers).
|
|
27974
|
+
* Trailing punctuation ),.,;:!?'"] and matching surrounding parens stay
|
|
27975
|
+
* outside the link (CommonMark's autolink tail rule).
|
|
27976
|
+
*/
|
|
27977
|
+
function autolinkBareUrls(text) {
|
|
27978
|
+
return text.replace(/https?:\/\/[^\s<>"'\u0000]+/gi, (whole, offset, full) => {
|
|
27979
|
+
const before = full.slice(Math.max(0, offset - 2e3), offset);
|
|
27980
|
+
if (/<a\s[^>]*$/i.test(before) || /<code>[^<]*$/i.test(before)) return whole;
|
|
27981
|
+
let url = whole;
|
|
27982
|
+
while (url.endsWith(")") && (url.match(/\(/g)?.length ?? 0) < (url.match(/\)/g)?.length ?? 0)) url = url.slice(0, -1);
|
|
27983
|
+
url = url.replace(/[.,;:!?]+$/, "");
|
|
27984
|
+
const tail = whole.slice(url.length);
|
|
27985
|
+
return `${externalAnchor(url)}${tail}`;
|
|
27986
|
+
});
|
|
27987
|
+
}
|
|
27988
|
+
/** ***bold-italic***, **bold**, *italic*, _italic_, ~~strike~~. */
|
|
27989
|
+
function emphasis(text) {
|
|
27990
|
+
return text.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>").replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>").replace(/\*(.+?)\*/g, "<em>$1</em>").replace(/(?<![\w])_(.+?)_(?![\w])/g, "<em>$1</em>").replace(/~~(.+?)~~/g, "<del>$1</del>");
|
|
27991
|
+
}
|
|
27992
|
+
/**
|
|
27993
|
+
* [label](href) — http(s) hrefs become hardened external anchors; SCHEME-FREE
|
|
27994
|
+
* relative hrefs (assistant file links like [card](src/lib/…)) become same-
|
|
27995
|
+
* origin anchors; anything carrying a scheme (javascript:, data:, mailto:,
|
|
27996
|
+
* //evil.com protocol-relative, …) stays inert text (BC-12).
|
|
27997
|
+
*/
|
|
27998
|
+
function links(text) {
|
|
27999
|
+
return text.replace(/\[([^\]]+)\]\((?:<([^>]*?)>|([^)\s]+))\)/g, (whole, labelA, angleHref, bareHref) => {
|
|
28000
|
+
const label = labelA;
|
|
28001
|
+
const bare = (angleHref !== void 0 ? angleHref : bareHref).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll(""", "\"").replaceAll("'", "'").replace(/^<(.+)>$/, "$1");
|
|
28002
|
+
if (/^https?:\/\//i.test(bare)) return `<a href="${bare.replaceAll("\"", """)}" rel="noopener noreferrer" target="_blank">${label}</a>`;
|
|
28003
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(bare) || bare.startsWith("//")) return whole;
|
|
28004
|
+
return `<a href="${bare.replaceAll("\"", """)}">${label}</a>`;
|
|
28005
|
+
});
|
|
28006
|
+
}
|
|
28007
|
+
//#endregion
|
|
27037
28008
|
//#region src/lib/utils/file-link.ts
|
|
27038
28009
|
/**
|
|
27039
28010
|
* file-link — pure predicates for transcript file links (File Link Intent
|
|
@@ -27949,7 +28920,7 @@ function MessageBubble($$renderer, $$props) {
|
|
|
27949
28920
|
* stamp mount at the content edge (hover-reveal family, OCI
|
|
27950
28921
|
* placement); children-only mounts (context chips) get neither.
|
|
27951
28922
|
*/
|
|
27952
|
-
let { role, skin, text, time, showSave = true, children, onFileLink } = $$props;
|
|
28923
|
+
let { role, skin, text, time, showSave = true, children, onFileLink, hideMarkdown = false } = $$props;
|
|
27953
28924
|
/** Raw ⇄ rendered flip state — owned here, wired to ToolsMessage. */
|
|
27954
28925
|
let showRaw = false;
|
|
27955
28926
|
/** Bubble element ref — capture target for the canvas copy button. */
|
|
@@ -27959,7 +28930,7 @@ function MessageBubble($$renderer, $$props) {
|
|
|
27959
28930
|
let $$inner_renderer;
|
|
27960
28931
|
function $$render_inner($$renderer) {
|
|
27961
28932
|
$$renderer.push(`<div data-svelte="MessageBubble"${attr_class(`group/bubble relative max-w-[80%] rounded-2xl ${tail()} border px-4 pt-2 pb-3 text-sm leading-relaxed text-text-primary ${stringify(skin)}`)} data-testid="message-bubble"${attr("data-role", role)}>`);
|
|
27962
|
-
if (text !== void 0) {
|
|
28933
|
+
if (text !== void 0 && !hideMarkdown) {
|
|
27963
28934
|
$$renderer.push("<!--[0-->");
|
|
27964
28935
|
if (showRaw) {
|
|
27965
28936
|
$$renderer.push("<!--[0-->");
|
|
@@ -28032,10 +29003,19 @@ function MessageImages($$renderer, $$props) {
|
|
|
28032
29003
|
let { refs = []} = $$props;
|
|
28033
29004
|
/** Per-slot render state, keyed by attachmentId. */
|
|
28034
29005
|
let slots = {};
|
|
28035
|
-
|
|
29006
|
+
/** The crash guard (each_key_duplicate, operator report 2026-10-31): the
|
|
29007
|
+
* attachment id IS the content hash, so one prompt's ledger can carry
|
|
29008
|
+
* the same image twice — and a keyed each may not. Two refs with one
|
|
29009
|
+
* id are ONE image: keep the first occurrence, render the distinct
|
|
29010
|
+
* set. The boundary is robust against already-written ledgers. */
|
|
29011
|
+
const uniqueRefs = derived(() => {
|
|
29012
|
+
const seen = /* @__PURE__ */ new Set();
|
|
29013
|
+
return refs.filter((r) => seen.has(r.attachmentId) ? false : (seen.add(r.attachmentId), true));
|
|
29014
|
+
});
|
|
29015
|
+
if (uniqueRefs().length > 0) {
|
|
28036
29016
|
$$renderer.push("<!--[0-->");
|
|
28037
29017
|
$$renderer.push(`<div data-svelte="MessageImages" class="flex flex-wrap justify-end gap-1.5" data-testid="message-images" role="list"${attr("aria-label", t(attachedimages1))}><!--[-->`);
|
|
28038
|
-
const each_array = ensure_array_like(
|
|
29018
|
+
const each_array = ensure_array_like(uniqueRefs());
|
|
28039
29019
|
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
28040
29020
|
let ref = each_array[$$index];
|
|
28041
29021
|
if (slots[ref.attachmentId]?.url) {
|
|
@@ -28056,6 +29036,33 @@ function MessageImages($$renderer, $$props) {
|
|
|
28056
29036
|
});
|
|
28057
29037
|
}
|
|
28058
29038
|
//#endregion
|
|
29039
|
+
//#region src/lib/utils/injected-path-table.ts
|
|
29040
|
+
/** The whole trimmed text must be EXACTLY this trio — nothing before or
|
|
29041
|
+
* after, so prose that merely quotes the tags stays inert (the same
|
|
29042
|
+
* rule as markdown.ts's fence carve-out). */
|
|
29043
|
+
var TRIO = /^<path>\s*([^\n<]+?)\s*<\/path>\s*<type>\s*([^\n<]+?)\s*<\/type>\s*<content>\s*([\s\S]+?)\s*<\/content>\s*$/;
|
|
29044
|
+
function parseInjectedPathTable(text) {
|
|
29045
|
+
const m = TRIO.exec(text.trim());
|
|
29046
|
+
if (!m) return null;
|
|
29047
|
+
const path = m[1].trim();
|
|
29048
|
+
if (path === "") return null;
|
|
29049
|
+
return [
|
|
29050
|
+
{
|
|
29051
|
+
key: "path",
|
|
29052
|
+
value: path,
|
|
29053
|
+
href: path
|
|
29054
|
+
},
|
|
29055
|
+
{
|
|
29056
|
+
key: "type",
|
|
29057
|
+
value: m[2].trim()
|
|
29058
|
+
},
|
|
29059
|
+
{
|
|
29060
|
+
key: "content",
|
|
29061
|
+
value: m[3].trim().replaceAll("\n", " ")
|
|
29062
|
+
}
|
|
29063
|
+
];
|
|
29064
|
+
}
|
|
29065
|
+
//#endregion
|
|
28059
29066
|
//#region src/lib/components/message/prompt/PromptBubble.svelte
|
|
28060
29067
|
function PromptBubble($$renderer, $$props) {
|
|
28061
29068
|
$$renderer.component(($$renderer) => {
|
|
@@ -28095,8 +29102,13 @@ function PromptBubble($$renderer, $$props) {
|
|
|
28095
29102
|
* the row, OCI placement). Assistant responses live in AssistantTurn —
|
|
28096
29103
|
* this bubble is user-side only.
|
|
28097
29104
|
*/
|
|
28098
|
-
let { text, time, tone = "prompt", imageRefs = [], sessionId, children, onFileLink } = $$props;
|
|
29105
|
+
let { text, time, tone = "prompt", imageRefs = [], sessionId, children, onFileLink, meta } = $$props;
|
|
28099
29106
|
const skin = derived(() => tone === "context" ? "bg-accent-blue/10 border-accent-blue/20" : "bg-accent-blue/15 border-accent-blue/20");
|
|
29107
|
+
/** 2026-10-29: an INJECTED message whose text is exactly the harness's
|
|
29108
|
+
* <path>/<type>/<content> trio renders as a key/value table (path value
|
|
29109
|
+
* is a file link) instead of dead escaped tags. Human prompts and
|
|
29110
|
+
* quoting prose never match (the parser is whole-block strict). */
|
|
29111
|
+
const injectedRows = derived(() => meta === "injected" && text !== void 0 ? parseInjectedPathTable(text) : null);
|
|
28100
29112
|
$$renderer.push(`<div data-svelte="PromptBubble" class="flex w-full min-w-0 flex-col items-end gap-1.5">`);
|
|
28101
29113
|
if (imageRefs.length > 0 && sessionId !== void 0) {
|
|
28102
29114
|
$$renderer.push("<!--[0-->");
|
|
@@ -28112,7 +29124,29 @@ function PromptBubble($$renderer, $$props) {
|
|
|
28112
29124
|
text,
|
|
28113
29125
|
time,
|
|
28114
29126
|
onFileLink,
|
|
29127
|
+
hideMarkdown: injectedRows() !== null,
|
|
29128
|
+
showSave: injectedRows() === null,
|
|
28115
29129
|
children: ($$renderer) => {
|
|
29130
|
+
if (injectedRows()) {
|
|
29131
|
+
$$renderer.push("<!--[0-->");
|
|
29132
|
+
$$renderer.push(`<table class="injected-data-table w-full border-collapse text-xs" data-testid="injected-data-table"><tbody><!--[-->`);
|
|
29133
|
+
const each_array = ensure_array_like(injectedRows());
|
|
29134
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
29135
|
+
let row = each_array[$$index];
|
|
29136
|
+
$$renderer.push(`<tr class="border-b border-surface-border/40"><td class="k w-20 shrink-0 py-1 pr-2 align-top font-medium opacity-60">${escape_html(row.key)}</td><td class="v py-1 break-all">`);
|
|
29137
|
+
if (row.href && onFileLink) {
|
|
29138
|
+
$$renderer.push("<!--[0-->");
|
|
29139
|
+
row.href;
|
|
29140
|
+
$$renderer.push(`<button type="button" class="cursor-pointer text-left underline underline-offset-2 hover:opacity-80">${escape_html(row.value.split("/").pop())}</button>`);
|
|
29141
|
+
} else {
|
|
29142
|
+
$$renderer.push("<!--[-1-->");
|
|
29143
|
+
$$renderer.push(`${escape_html(row.value)}`);
|
|
29144
|
+
}
|
|
29145
|
+
$$renderer.push(`<!--]--></td></tr>`);
|
|
29146
|
+
}
|
|
29147
|
+
$$renderer.push(`<!--]--></tbody></table>`);
|
|
29148
|
+
} else $$renderer.push("<!--[-1-->");
|
|
29149
|
+
$$renderer.push(`<!--]--> `);
|
|
28116
29150
|
if (children) {
|
|
28117
29151
|
$$renderer.push("<!--[0-->");
|
|
28118
29152
|
children($$renderer);
|
|
@@ -28155,6 +29189,9 @@ function ContextInjectionChip($$renderer, $$props) {
|
|
|
28155
29189
|
"skill-catalog": () => ctxchipskills2(),
|
|
28156
29190
|
"skill-invocation": () => ctxchipskill2(),
|
|
28157
29191
|
"user-approval": () => ctxchipuserapproval3(),
|
|
29192
|
+
goal: () => ctxchipgoal2(),
|
|
29193
|
+
"tool-goal": () => ctxchiptoolgoal3(),
|
|
29194
|
+
"time-context": () => ctxchiptimecontext3(),
|
|
28158
29195
|
compaction: () => ctxchipcompact2(),
|
|
28159
29196
|
plugin: () => ctxchipplugin2(),
|
|
28160
29197
|
recall: () => ctxchiprecall2(),
|
|
@@ -28172,7 +29209,14 @@ function ContextInjectionChip($$renderer, $$props) {
|
|
|
28172
29209
|
if (producer === "plugin" || producer === "injected") return name;
|
|
28173
29210
|
return label;
|
|
28174
29211
|
});
|
|
28175
|
-
|
|
29212
|
+
const WIRE_NAMED = [
|
|
29213
|
+
"goal",
|
|
29214
|
+
"tool-goal",
|
|
29215
|
+
"time-context"
|
|
29216
|
+
];
|
|
29217
|
+
const wireName = derived(() => name !== void 0 && name !== "" && WIRE_NAMED.includes(producer) ? name : void 0);
|
|
29218
|
+
const aria = derived(() => wireName() === void 0 ? title() : `${title()} (${wireName()})`);
|
|
29219
|
+
$$renderer.push(`<div data-svelte="ContextInjectionChip" class="text-xs" data-testid="context-injection-chip"${attr("data-producer", producer)}${attr("data-open", open)}><span class="inline-flex items-center"><button type="button"${attr("aria-expanded", open)} data-testid="context-injection-toggle"${attr("aria-label", aria())}${attr("title", wireName())}${attr_class(`chip-button inline-flex items-center gap-1 px-1.5 py-0.5 rounded-md text-xs font-mono font-medium max-w-full mx-0.5 my-0.5 align-middle shrink-0 transition-colors select-none cursor-pointer ${open ? "bg-accent-purple/20 text-accent-purple border border-accent-purple/30" : "bg-surface0/10 text-text-secondary border border-text-muted/20 hover:bg-surface0/20 hover:text-text-primary"}`, "svelte-hhkfw6")}>`);
|
|
28176
29220
|
if (open) {
|
|
28177
29221
|
$$renderer.push("<!--[0-->");
|
|
28178
29222
|
Chevron_down($$renderer, { size: 10 });
|
|
@@ -28207,7 +29251,11 @@ function chipNameOf(meta, metaSource) {
|
|
|
28207
29251
|
return str(refs[0]?.label);
|
|
28208
29252
|
}
|
|
28209
29253
|
case "plugin": return str(metaSource?.plugin);
|
|
29254
|
+
case "goal":
|
|
29255
|
+
case "tool-goal":
|
|
29256
|
+
case "time-context": return str(metaSource?.plugin) ?? str(metaSource?.kind);
|
|
28210
29257
|
case "injected": return str(metaSource?.kind);
|
|
29258
|
+
case "user-approval": return str(metaSource?.plugin) ?? str(metaSource?.kind);
|
|
28211
29259
|
default: return;
|
|
28212
29260
|
}
|
|
28213
29261
|
}
|
|
@@ -30842,6 +31890,7 @@ function ConversationScrollArea($$renderer, $$props) {
|
|
|
30842
31890
|
time: group.kind === "prompt" ? group.entry.time : group.entries[0]?.time,
|
|
30843
31891
|
tone: group.kind === "prompt" ? "prompt" : "context",
|
|
30844
31892
|
imageRefs: group.kind === "prompt" ? group.entry.imageRefs : void 0,
|
|
31893
|
+
meta: group.kind === "prompt" ? group.entry.meta : void 0,
|
|
30845
31894
|
sessionId,
|
|
30846
31895
|
onFileLink,
|
|
30847
31896
|
children: ($$renderer) => {
|
|
@@ -31955,6 +33004,17 @@ function focusedInsertionSlot(panels, selectedIndex, parentOf) {
|
|
|
31955
33004
|
* re-export hub, never by importing another sibling directly.
|
|
31956
33005
|
*/
|
|
31957
33006
|
var d$4 = floorSeam;
|
|
33007
|
+
/** The rack's tab intent (The Plugin Rack ADR, 2026-09-27): same
|
|
33008
|
+
* persisted-entry write as the shelf's - panel-prefs saves the blob,
|
|
33009
|
+
* a hard reload restores the active tab. */
|
|
33010
|
+
function setRackTab(panelId, tab) {
|
|
33011
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
33012
|
+
if (idx < 0 || st.panels[idx].kind !== "plugin-rack") return;
|
|
33013
|
+
st.panels = st.panels.with(idx, {
|
|
33014
|
+
...st.panels[idx],
|
|
33015
|
+
tab
|
|
33016
|
+
});
|
|
33017
|
+
}
|
|
31958
33018
|
/** Chip click action: ONE explorer per WORKSPACE root across ALL
|
|
31959
33019
|
* sessions — a click on any session sharing the root FOCUSES the open
|
|
31960
33020
|
* explorer (dedupe key = root, D1); a fresh root lands at the focused
|
|
@@ -32071,6 +33131,11 @@ function activateExplorerTab(panelId, path) {
|
|
|
32071
33131
|
function setExplorerTreePct(_panelId, pct) {
|
|
32072
33132
|
d$4().setTreePct(clampTreePct(pct));
|
|
32073
33133
|
}
|
|
33134
|
+
/** Explorer hide/show (2026-10-31): one DESK fact like the tree percent —
|
|
33135
|
+
* the toggle flips it through the configured setter (pagePrefs persist). */
|
|
33136
|
+
function setExplorerHidden(_panelId, hidden) {
|
|
33137
|
+
d$4().setExplorerHidden?.(hidden);
|
|
33138
|
+
}
|
|
32074
33139
|
/** Git Eye repo-collapse intent (2026-09-13): the collapsed repo set is
|
|
32075
33140
|
* PERSISTED on the entry. Default is EXPANDED. */
|
|
32076
33141
|
function toggleExplorerRepo(panelId, repoRel) {
|
|
@@ -33216,12 +34281,17 @@ function ConversationPanel($$renderer, $$props) {
|
|
|
33216
34281
|
/** Context consumption (2026-08-23): the LAST assistant usage record
|
|
33217
34282
|
* across the ledger — what the most recent model request consumed
|
|
33218
34283
|
* (uncached input + cache-read + cache-write = the full prompt seen).
|
|
33219
|
-
* Wire truth via DsiTokenUsage;
|
|
34284
|
+
* Wire truth via DsiTokenUsage; 0 once the session has ledger entries
|
|
34285
|
+
* but no usage yet (aborted turn / pre-first-finalize — SC#1
|
|
34286
|
+
* 2026-11-01: an aborted turn leaves no usage record, and the honest
|
|
34287
|
+
* display is "≈0 ctx", not a dead slot). Undefined only on an empty
|
|
34288
|
+
* session (no entries at all). */
|
|
33220
34289
|
const contextTokens = derived(() => {
|
|
33221
34290
|
for (let i = store.entries.length - 1; i >= 0; i--) {
|
|
33222
34291
|
const e = store.entries[i];
|
|
33223
34292
|
if (e.kind === "assistant-message" && e.usage !== void 0) return e.usage.inputTokens + (e.usage.cacheReadTokens ?? 0) + (e.usage.cacheWriteTokens ?? 0);
|
|
33224
34293
|
}
|
|
34294
|
+
return store.entries.length > 0 ? 0 : void 0;
|
|
33225
34295
|
});
|
|
33226
34296
|
const totalContextLimit = derived(() => contextWindowOf());
|
|
33227
34297
|
/** Session baseline (ADR 2026-09-08 "The Stats Bar", D2): this
|
|
@@ -33471,6 +34541,132 @@ function ConversationPanel($$renderer, $$props) {
|
|
|
33471
34541
|
});
|
|
33472
34542
|
}
|
|
33473
34543
|
//#endregion
|
|
34544
|
+
//#region src/lib/utils/key-chords.ts
|
|
34545
|
+
/**
|
|
34546
|
+
* key-chords.ts — the Alt+S width-preset chord machine (ADR-0006a).
|
|
34547
|
+
*
|
|
34548
|
+
* A PURE reducer: every transition is (state, event, facts) -> { state,
|
|
34549
|
+
* action }. No DOM, no stores, no timers — the caller owns the clock
|
|
34550
|
+
* (now) and the wiring (which element heard the key). This is what makes
|
|
34551
|
+
* the chord unit-testable to every branch, and keeps the route keydown
|
|
34552
|
+
* listener a three-line adapter.
|
|
34553
|
+
*
|
|
34554
|
+
* Grammar: press-and-release Alt+S arms a CHORD_WINDOW_MS window; a
|
|
34555
|
+
* following digit 1..9 fires { apply, n }; any other key or the window
|
|
34556
|
+
* expiring disarms. Alt+S never arms when the floor has no presets (D4:
|
|
34557
|
+
* silent absence — the feature gates itself).
|
|
34558
|
+
*/
|
|
34559
|
+
var CHORD_WINDOW_MS = 2e3;
|
|
34560
|
+
var IDLE_CHORD = {
|
|
34561
|
+
armed: false};
|
|
34562
|
+
/** Verb → label (the palette renders these; D16). */
|
|
34563
|
+
var CHORD_VERB_LABELS = {
|
|
34564
|
+
a: "Close agent extras (terminals + sub-agents + explorers)",
|
|
34565
|
+
b: "Close all glass browsers",
|
|
34566
|
+
g: "Toggle plugin manager",
|
|
34567
|
+
k: "Toggle skill manager",
|
|
34568
|
+
c: "Close config explorers",
|
|
34569
|
+
n: "New session, same agent + workspace",
|
|
34570
|
+
p: "Toggle prompt manager",
|
|
34571
|
+
s: "Toggle sidebar",
|
|
34572
|
+
t: "Toggle terminal",
|
|
34573
|
+
w: "Close workspace explorers"
|
|
34574
|
+
};
|
|
34575
|
+
/** The live palette rows (D16): derived PURELY from what exists right now.
|
|
34576
|
+
* presets gate the digit lanes (D4), panelKinds (+ subagentCount) gate the
|
|
34577
|
+
* verbs; the p/t toggles are always live — their add path creates the
|
|
34578
|
+
* target. No registry import: the wiring feeds the facts in. */
|
|
34579
|
+
function chordOptions(facts) {
|
|
34580
|
+
const rows = [];
|
|
34581
|
+
const slots = /* @__PURE__ */ new Set([
|
|
34582
|
+
...Object.keys(facts.presets.agent).map(Number),
|
|
34583
|
+
...Object.keys(facts.presets.glass).map(Number),
|
|
34584
|
+
...Object.keys(facts.presets.sidebar).map(Number),
|
|
34585
|
+
...Object.keys(facts.presets.zoom ?? {}).map(Number)
|
|
34586
|
+
]);
|
|
34587
|
+
for (const n of [...slots].sort((x, y) => x - y)) rows.push({
|
|
34588
|
+
key: String(n),
|
|
34589
|
+
label: `Width preset ${n}`
|
|
34590
|
+
});
|
|
34591
|
+
const kinds = new Set(facts.panelKinds);
|
|
34592
|
+
if (kinds.has("terminal") || kinds.has("workspace-explorer") || kinds.has("plugin-rack") || kinds.has("skill-shelf") || facts.subagentCount > 0) rows.push({
|
|
34593
|
+
key: "a",
|
|
34594
|
+
label: CHORD_VERB_LABELS.a
|
|
34595
|
+
});
|
|
34596
|
+
if (kinds.has("browser")) rows.push({
|
|
34597
|
+
key: "b",
|
|
34598
|
+
label: CHORD_VERB_LABELS.b
|
|
34599
|
+
});
|
|
34600
|
+
if (kinds.has("settings-home") || kinds.has("skill-shelf") || kinds.has("plugin-rack")) rows.push({
|
|
34601
|
+
key: "c",
|
|
34602
|
+
label: CHORD_VERB_LABELS.c
|
|
34603
|
+
});
|
|
34604
|
+
rows.push({
|
|
34605
|
+
key: "p",
|
|
34606
|
+
label: CHORD_VERB_LABELS.p
|
|
34607
|
+
});
|
|
34608
|
+
rows.push({
|
|
34609
|
+
key: "g",
|
|
34610
|
+
label: CHORD_VERB_LABELS.g
|
|
34611
|
+
});
|
|
34612
|
+
rows.push({
|
|
34613
|
+
key: "k",
|
|
34614
|
+
label: CHORD_VERB_LABELS.k
|
|
34615
|
+
});
|
|
34616
|
+
rows.push({
|
|
34617
|
+
key: "t",
|
|
34618
|
+
label: CHORD_VERB_LABELS.t
|
|
34619
|
+
});
|
|
34620
|
+
if (facts.focusedConversation) rows.push({
|
|
34621
|
+
key: "n",
|
|
34622
|
+
label: CHORD_VERB_LABELS.n
|
|
34623
|
+
});
|
|
34624
|
+
rows.push({
|
|
34625
|
+
key: "s",
|
|
34626
|
+
label: CHORD_VERB_LABELS.s
|
|
34627
|
+
});
|
|
34628
|
+
if (kinds.has("workspace-explorer")) rows.push({
|
|
34629
|
+
key: "w",
|
|
34630
|
+
label: CHORD_VERB_LABELS.w
|
|
34631
|
+
});
|
|
34632
|
+
return rows.sort((x, y) => x.key.localeCompare(y.key));
|
|
34633
|
+
}
|
|
34634
|
+
//#endregion
|
|
34635
|
+
//#region src/lib/components/panels/ChordPalette.svelte
|
|
34636
|
+
function ChordPalette($$renderer, $$props) {
|
|
34637
|
+
$$renderer.component(($$renderer) => {
|
|
34638
|
+
/**
|
|
34639
|
+
* ChordPalette — the armed Alt+S chord's face (ADR-0006a amendment
|
|
34640
|
+
* D16/D18, 2026-10-31). Centered on the viewport; while armed it fills
|
|
34641
|
+
* a footer progress bar 0→100% across IDLE_CLOSE_MS — pastel-green
|
|
34642
|
+
* while the chord's 2s action window (CHORD_WINDOW_MS) is open,
|
|
34643
|
+
* pastel-yellow after — and at 100% fires `onexpire` (the route resets
|
|
34644
|
+
* the chord to idle). The clock is THIS component's visibility
|
|
34645
|
+
* lifecycle (D18: view-lifecycle, not reducer state); every other rule
|
|
34646
|
+
* of the pure view stands: no stores, no key handlers.
|
|
34647
|
+
*/
|
|
34648
|
+
/** The 10s idle window before the palette closes itself (D18). */
|
|
34649
|
+
const IDLE_CLOSE_MS = 1e4;
|
|
34650
|
+
let { open, rows} = $$props;
|
|
34651
|
+
let now = Date.now();
|
|
34652
|
+
const elapsed = derived(() => open ? Math.max(0, Math.min(now - (Date.now()), IDLE_CLOSE_MS)) : 0);
|
|
34653
|
+
const pct = derived(() => Math.round(elapsed() / IDLE_CLOSE_MS * 100));
|
|
34654
|
+
const inActionWindow = derived(() => elapsed() < CHORD_WINDOW_MS);
|
|
34655
|
+
const barColor = derived(() => inActionWindow() ? "bg-green-300" : "bg-yellow-200");
|
|
34656
|
+
if (open) {
|
|
34657
|
+
$$renderer.push("<!--[0-->");
|
|
34658
|
+
$$renderer.push(`<div data-svelte="ChordPalette" class="fixed top-1/2 left-1/2 z-50 w-72 -translate-x-1/2 -translate-y-1/2 rounded-lg border border-black/10 bg-white/95 px-3 py-2 shadow-lg backdrop-blur dark:border-white/15 dark:bg-neutral-900/95" data-testid="chord-palette"${attr("data-chord-elapsed", elapsed())} aria-live="polite"${attr("aria-label", t(() => chordarmedlabel2()))}><div class="mb-1 text-[10px] font-semibold tracking-wide text-neutral-400 uppercase">${escape_html(t(() => chordarmedtitle2()))}</div> <ul class="m-0 list-none space-y-0.5 p-0"><!--[-->`);
|
|
34659
|
+
const each_array = ensure_array_like(rows);
|
|
34660
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
34661
|
+
let row = each_array[$$index];
|
|
34662
|
+
$$renderer.push(`<li class="flex items-center gap-2 text-xs" data-testid="chord-palette-row"${attr("data-chord-key", row.key)}><kbd class="min-w-5 rounded border border-black/15 bg-neutral-100 px-1 text-center font-mono text-[11px] dark:border-white/20 dark:bg-neutral-800">${escape_html(row.key)}</kbd> <span class="text-neutral-700 dark:text-neutral-200">${escape_html(row.label)}</span></li>`);
|
|
34663
|
+
}
|
|
34664
|
+
$$renderer.push(`<!--]--></ul> <div class="mt-2 h-1 w-full overflow-hidden rounded bg-neutral-200 dark:bg-neutral-700" data-testid="chord-palette-decay"><div${attr_class(`h-full ${barColor()} transition-[width] duration-100 ease-linear`)}${attr_style(`width: ${stringify(pct())}%`)} data-testid="chord-palette-progress"${attr("data-chord-phase", inActionWindow() ? "action" : "idle")}></div></div></div>`);
|
|
34665
|
+
} else $$renderer.push("<!--[-1-->");
|
|
34666
|
+
$$renderer.push(`<!--]-->`);
|
|
34667
|
+
});
|
|
34668
|
+
}
|
|
34669
|
+
//#endregion
|
|
33474
34670
|
//#region src/lib/components/terminal/frame-state.ts
|
|
33475
34671
|
var initialTerminalPanelState = {
|
|
33476
34672
|
lastSettle: null,
|
|
@@ -33520,24 +34716,71 @@ function TerminalPanel($$renderer, $$props) {
|
|
|
33520
34716
|
//#endregion
|
|
33521
34717
|
//#region src/lib/components/terminal/TerminalTabHeader.svelte
|
|
33522
34718
|
function TerminalTabHeader($$renderer, $$props) {
|
|
33523
|
-
|
|
33524
|
-
|
|
33525
|
-
|
|
33526
|
-
|
|
33527
|
-
|
|
33528
|
-
|
|
33529
|
-
|
|
33530
|
-
|
|
33531
|
-
|
|
33532
|
-
|
|
33533
|
-
|
|
34719
|
+
$$renderer.component(($$renderer) => {
|
|
34720
|
+
/**
|
|
34721
|
+
* TerminalTabHeader — the desk's tablist strip (Terminal Desk ADR D1,
|
|
34722
|
+
* Wave 2; amended 2026-11-03 D5a/D5b): presentation only; the desk owns
|
|
34723
|
+
* selection state. The strip SCROLLS when crowded (overflow-x) and the
|
|
34724
|
+
* sticky clear control sits in a fixed slot at the right edge, OUTSIDE
|
|
34725
|
+
* the scroller. The popover's three scope verbs (Clear all / Clear jobs /
|
|
34726
|
+
* Clear terminals) emit ONE onClear intent — the desk resolves scope.
|
|
34727
|
+
* No Cancel verb: outside click or Esc cancels.
|
|
34728
|
+
*/
|
|
34729
|
+
let { children, actions, onClear } = $$props;
|
|
34730
|
+
let clearOpen = false;
|
|
34731
|
+
$$renderer.push(`<div data-svelte="TerminalTabHeader" class="flex min-w-0 items-center gap-1 border-b border-slate-800 px-1 py-0.5" data-testid="terminal-tab-header"><div class="strip flex min-w-0 flex-1 items-center gap-1 overflow-x-auto" role="tablist" data-testid="terminal-tabstrip">`);
|
|
34732
|
+
children($$renderer);
|
|
34733
|
+
$$renderer.push(`<!----></div> `);
|
|
34734
|
+
if (onClear) {
|
|
34735
|
+
$$renderer.push("<!--[0-->");
|
|
34736
|
+
$$renderer.push(`<div class="clear-slot relative flex flex-none items-center" data-testid="terminal-tabstrip-clear-slot"><button type="button" class="clear-btn flex h-5 w-5 items-center justify-center rounded border border-slate-600 text-[0.8rem] leading-none text-slate-400 hover:bg-slate-700 hover:text-slate-200" data-testid="terminal-tabstrip-clear"${attr("aria-label", t(terminaltabsclear2))}${attr("title", t(terminaltabsclear2))}${attr("aria-expanded", clearOpen)}>×</button> `);
|
|
34737
|
+
$$renderer.push("<!--[-1-->");
|
|
34738
|
+
$$renderer.push(`<!--]--></div>`);
|
|
34739
|
+
} else $$renderer.push("<!--[-1-->");
|
|
34740
|
+
$$renderer.push(`<!--]--> `);
|
|
34741
|
+
if (actions) {
|
|
34742
|
+
$$renderer.push("<!--[0-->");
|
|
34743
|
+
$$renderer.push(`<div class="ml-auto flex flex-none items-center" data-testid="terminal-tab-header-actions">`);
|
|
34744
|
+
actions($$renderer);
|
|
34745
|
+
$$renderer.push(`<!----></div>`);
|
|
34746
|
+
} else $$renderer.push("<!--[-1-->");
|
|
34747
|
+
$$renderer.push(`<!--]--></div>`);
|
|
34748
|
+
});
|
|
34749
|
+
}
|
|
34750
|
+
//#endregion
|
|
34751
|
+
//#region src/lib/components/common/buttons/CloseButton.svelte
|
|
34752
|
+
function CloseButton($$renderer, $$props) {
|
|
34753
|
+
$$renderer.component(($$renderer) => {
|
|
34754
|
+
/**
|
|
34755
|
+
* CloseButton — the tab-strip ✕ as a reusable button (extracted from
|
|
34756
|
+
* BrowserTab 2026-11-02; TerminalTabButton's inline ✕ span migrated same
|
|
34757
|
+
* day). Presentational (house button pattern, see ReloadButton): the
|
|
34758
|
+
* CALLER owns what closing means and ALL the chrome — pass Tailwind
|
|
34759
|
+
* classes via `class`; the button renders the glyph and reports the click.
|
|
34760
|
+
*
|
|
34761
|
+
* Contract: the click NEVER bubbles (both tab callers stopPropagation'd —
|
|
34762
|
+
* the strip's select must not fire when the ✕ is hit) and the button is
|
|
34763
|
+
* focusable only when the caller says so (`tabindex` — the terminal tab
|
|
34764
|
+
* passes -1 so keyboard focus lands on the tab, not the close).
|
|
34765
|
+
*/
|
|
34766
|
+
let { onclick, label, testid, tabindex = void 0, class: className = "" } = $$props;
|
|
34767
|
+
$$renderer.push(`<button data-svelte="CloseButton" type="button"${attr_class(clsx(className))}${attr("data-testid", testid)}${attr("title", label)}${attr("aria-label", label)}${attr("tabindex", tabindex)}>✕</button>`);
|
|
34768
|
+
});
|
|
33534
34769
|
}
|
|
33535
34770
|
//#endregion
|
|
33536
34771
|
//#region src/lib/components/terminal/TerminalTabButton.svelte
|
|
33537
34772
|
function TerminalTabButton($$renderer, $$props) {
|
|
33538
34773
|
$$renderer.component(($$renderer) => {
|
|
33539
34774
|
let { index, selected, label, title, onSelect, onClose } = $$props;
|
|
33540
|
-
$$renderer.push(`<div data-svelte="TerminalTabButton" role="tab"${attr("title", title ?? label)}${attr("aria-selected", selected)} tabindex="0"${attr_class(`flex cursor-pointer items-center gap-1 rounded px-2 py-0.5 text-[10px] ${selected ? "bg-slate-700 text-slate-100" : "text-slate-400 hover:bg-slate-800"}`)}${attr("data-testid", `terminal-tab-button-${stringify(index)}`)}${attr("data-selected", selected ? "true" : "false")}><span>${escape_html(label)}</span>
|
|
34775
|
+
$$renderer.push(`<div data-svelte="TerminalTabButton" role="tab"${attr("title", title ?? label)}${attr("aria-selected", selected)} tabindex="0"${attr_class(`flex cursor-pointer items-center gap-1 rounded px-2 py-0.5 text-[10px] ${selected ? "bg-slate-700 text-slate-100" : "text-slate-400 hover:bg-slate-800"}`)}${attr("data-testid", `terminal-tab-button-${stringify(index)}`)}${attr("data-selected", selected ? "true" : "false")}><span>${escape_html(label)}</span> `);
|
|
34776
|
+
CloseButton($$renderer, {
|
|
34777
|
+
class: "ml-1 rounded px-1 text-slate-500 hover:bg-slate-600 hover:text-slate-200",
|
|
34778
|
+
label: t(terminaltabclose2) + " " + label,
|
|
34779
|
+
testid: `terminal-tab-close-${stringify(index)}`,
|
|
34780
|
+
tabindex: -1,
|
|
34781
|
+
onclick: () => onClose()
|
|
34782
|
+
});
|
|
34783
|
+
$$renderer.push(`<!----></div>`);
|
|
33541
34784
|
});
|
|
33542
34785
|
}
|
|
33543
34786
|
//#endregion
|
|
@@ -33713,7 +34956,14 @@ function JobTail($$renderer, $$props) {
|
|
|
33713
34956
|
$$renderer.push(`<!--]--> `);
|
|
33714
34957
|
if (tail().lines.length === 0) {
|
|
33715
34958
|
$$renderer.push("<!--[0-->");
|
|
33716
|
-
|
|
34959
|
+
if (tail().settled) {
|
|
34960
|
+
$$renderer.push("<!--[0-->");
|
|
34961
|
+
$$renderer.push(`<div class="text-slate-500" data-testid="job-tail-empty">${escape_html(jobtailempty2())}</div>`);
|
|
34962
|
+
} else {
|
|
34963
|
+
$$renderer.push("<!--[-1-->");
|
|
34964
|
+
$$renderer.push(`<div class="text-slate-500" data-testid="job-tail-empty">${escape_html(jobtailwaiting2())}</div>`);
|
|
34965
|
+
}
|
|
34966
|
+
$$renderer.push(`<!--]-->`);
|
|
33717
34967
|
} else $$renderer.push("<!--[-1-->");
|
|
33718
34968
|
$$renderer.push(`<!--]--> <!--[-->`);
|
|
33719
34969
|
const each_array = ensure_array_like(tail().lines);
|
|
@@ -33867,6 +35117,42 @@ function TerminalDesk($$renderer, $$props) {
|
|
|
33867
35117
|
}
|
|
33868
35118
|
selectedTab = Math.min(tabIndex, tabs.length - 1);
|
|
33869
35119
|
}
|
|
35120
|
+
/** Ladder-close ONE row's session without touching the tab arrays —
|
|
35121
|
+
* the clear verb's per-session half (ADR D5c amendment 2026-11-03). */
|
|
35122
|
+
function killRow(row) {
|
|
35123
|
+
if (!row.assigned) return;
|
|
35124
|
+
fetch("/api/terminal/" + row.assigned.sessionId + "/send", {
|
|
35125
|
+
method: "POST",
|
|
35126
|
+
headers: { "content-type": "application/json" },
|
|
35127
|
+
body: JSON.stringify({
|
|
35128
|
+
token: row.assigned.token,
|
|
35129
|
+
action: "close"
|
|
35130
|
+
}),
|
|
35131
|
+
keepalive: true
|
|
35132
|
+
}).catch(() => void 0);
|
|
35133
|
+
}
|
|
35134
|
+
/** The clear verb's scope resolution (ADR D5b/D5c amendment 2026-11-03):
|
|
35135
|
+
* jobs ⇒ close every job-follower tab (roster unwatch, PTYs untouched);
|
|
35136
|
+
* terminals ⇒ ladder-close every shell session, then mint ONE fresh T1
|
|
35137
|
+
* and select it — the fresh-T1 rule: the desk slot is NEVER removed by
|
|
35138
|
+
* a clear verb, so D5's last-shell onShellExit cascade does not run
|
|
35139
|
+
* here. all ⇒ both, ending in fresh T1. */
|
|
35140
|
+
function clearScope(scope) {
|
|
35141
|
+
if (scope === "jobs" || scope === "all") for (const job of [...jobTabs]) closeJobTab(job);
|
|
35142
|
+
if (scope === "terminals" || scope === "all") {
|
|
35143
|
+
for (const tab of tabs) for (const row of tab.rows) killRow(row);
|
|
35144
|
+
tabs.splice(0, tabs.length);
|
|
35145
|
+
(async () => {
|
|
35146
|
+
const row = await mintSession();
|
|
35147
|
+
if (!row) return;
|
|
35148
|
+
tabs.push({
|
|
35149
|
+
key: mkKey(),
|
|
35150
|
+
rows: [row]
|
|
35151
|
+
});
|
|
35152
|
+
selectedTab = 0;
|
|
35153
|
+
})();
|
|
35154
|
+
}
|
|
35155
|
+
}
|
|
33870
35156
|
/** Shell exit in a row (D5): the session is already dead — shrink the
|
|
33871
35157
|
* tab; an empty tab closes (selection rules as closeTab); the desk's
|
|
33872
35158
|
* last shell dying removes the slot (if only one terminal overall, it
|
|
@@ -33890,6 +35176,7 @@ function TerminalDesk($$renderer, $$props) {
|
|
|
33890
35176
|
} else {
|
|
33891
35177
|
$$renderer.push("<!--[-1-->");
|
|
33892
35178
|
TerminalTabHeader($$renderer, {
|
|
35179
|
+
onClear: clearScope,
|
|
33893
35180
|
children: ($$renderer) => {
|
|
33894
35181
|
$$renderer.push(`<!--[-->`);
|
|
33895
35182
|
const each_array = ensure_array_like(tabs);
|
|
@@ -33902,20 +35189,19 @@ function TerminalDesk($$renderer, $$props) {
|
|
|
33902
35189
|
onSelect: () => selectedTab = i,
|
|
33903
35190
|
onClose: () => closeTab(i)
|
|
33904
35191
|
});
|
|
33905
|
-
|
|
33906
|
-
|
|
33907
|
-
|
|
33908
|
-
|
|
33909
|
-
|
|
33910
|
-
|
|
33911
|
-
|
|
33912
|
-
|
|
33913
|
-
|
|
33914
|
-
|
|
33915
|
-
|
|
33916
|
-
|
|
33917
|
-
}
|
|
33918
|
-
$$renderer.push(`<!--]-->`);
|
|
35192
|
+
}
|
|
35193
|
+
$$renderer.push(`<!--]--> <!--[-->`);
|
|
35194
|
+
const each_array_1 = ensure_array_like(jobTabs);
|
|
35195
|
+
for (let ji = 0, $$length = each_array_1.length; ji < $$length; ji++) {
|
|
35196
|
+
let job = each_array_1[ji];
|
|
35197
|
+
TerminalTabButton($$renderer, {
|
|
35198
|
+
index: tabs.length + ji,
|
|
35199
|
+
label: "T" + (tabs.length + ji + 1) + "-J",
|
|
35200
|
+
title: job.label || job.jobId,
|
|
35201
|
+
selected: tabs.length + ji === selectedTab,
|
|
35202
|
+
onSelect: () => selectedTab = tabs.length + ji,
|
|
35203
|
+
onClose: () => closeJobTab(job)
|
|
35204
|
+
});
|
|
33919
35205
|
}
|
|
33920
35206
|
$$renderer.push(`<!--]-->`);
|
|
33921
35207
|
}});
|
|
@@ -34045,19 +35331,170 @@ function removeBrowserSlot(sessionId, storage = defaultStorage()) {
|
|
|
34045
35331
|
function primeBrowserSlotStore(storage = defaultStorage()) {
|
|
34046
35332
|
browserSlotStore.set(readBrowserSlots(storage));
|
|
34047
35333
|
}
|
|
35334
|
+
var SS_KEY = "dsi.harness.sessionKey.v2";
|
|
35335
|
+
var capturedKey = null;
|
|
35336
|
+
function tabStorage() {
|
|
35337
|
+
try {
|
|
35338
|
+
return typeof sessionStorage !== "undefined" ? sessionStorage : null;
|
|
35339
|
+
} catch {
|
|
35340
|
+
return null;
|
|
35341
|
+
}
|
|
35342
|
+
}
|
|
35343
|
+
/** Called once at page init, BEFORE the URL cleanup, with the still-present
|
|
35344
|
+
* sessionKey query param. A real key WINS over any tab memory (the tab was
|
|
35345
|
+
* (re)seeded with a concrete conversation) and is remembered for reloads;
|
|
35346
|
+
* null means "bare load" — fall back to the tab memory, never clear it. */
|
|
35347
|
+
function captureHarnessSessionKey(key) {
|
|
35348
|
+
const ss = tabStorage();
|
|
35349
|
+
if (key !== null && key.length > 0) {
|
|
35350
|
+
capturedKey = key;
|
|
35351
|
+
try {
|
|
35352
|
+
ss?.setItem(SS_KEY, key);
|
|
35353
|
+
} catch {}
|
|
35354
|
+
return;
|
|
35355
|
+
}
|
|
35356
|
+
if (!capturedKey) try {
|
|
35357
|
+
capturedKey = ss?.getItem(SS_KEY) ?? null;
|
|
35358
|
+
} catch {
|
|
35359
|
+
capturedKey = null;
|
|
35360
|
+
}
|
|
35361
|
+
}
|
|
35362
|
+
/** The harness conversation session key — the client-side source of the D7
|
|
35363
|
+
* ownership fact. Order: load-time capture → tab memory → live URL.
|
|
35364
|
+
* Null when all three are absent (degraded: legacy behavior). */
|
|
35365
|
+
function harnessSessionKey() {
|
|
35366
|
+
if (capturedKey) return capturedKey;
|
|
35367
|
+
try {
|
|
35368
|
+
const stored = tabStorage()?.getItem(SS_KEY) ?? null;
|
|
35369
|
+
if (stored) {
|
|
35370
|
+
capturedKey = stored;
|
|
35371
|
+
return stored;
|
|
35372
|
+
}
|
|
35373
|
+
} catch {}
|
|
35374
|
+
try {
|
|
35375
|
+
if (typeof location === "undefined") return null;
|
|
35376
|
+
const k = new URLSearchParams(location.search).get("sessionKey");
|
|
35377
|
+
return k !== null && k.length > 0 ? k : null;
|
|
35378
|
+
} catch {
|
|
35379
|
+
return null;
|
|
35380
|
+
}
|
|
35381
|
+
}
|
|
34048
35382
|
//#endregion
|
|
34049
|
-
//#region src/lib/components/
|
|
35383
|
+
//#region src/lib/components/common/buttons/ReloadButton.svelte
|
|
35384
|
+
function ReloadButton($$renderer, $$props) {
|
|
35385
|
+
/**
|
|
35386
|
+
* ReloadButton — the refresh icon with the CanvasCopyButton feedback
|
|
35387
|
+
* machine (extracted from WorkspaceFileToolbar 2026-10-28): idle
|
|
35388
|
+
* RotateCw → busy Loader2 spin → done Check → idle. Presentational
|
|
35389
|
+
* (house button pattern): the CALLER owns the state machine and what
|
|
35390
|
+
* a reload means — the button renders the state and reports the click.
|
|
35391
|
+
*
|
|
35392
|
+
* Styling: no chrome of its own — pass Tailwind classes via `class`
|
|
35393
|
+
* (the CanvasCopyButton pattern); each surface keeps its own chip
|
|
35394
|
+
* grammar and `data-testid`.
|
|
35395
|
+
*/
|
|
35396
|
+
let { state = "idle", onclick, label, testid, disabled = false, size = 14, class: className = "" } = $$props;
|
|
35397
|
+
$$renderer.push(`<button data-svelte="ReloadButton" type="button"${attr_class(clsx(className))}${attr("data-testid", testid)}${attr("data-state", state)}${attr("title", label)}${attr("aria-label", label)}${attr("disabled", disabled, true)}>`);
|
|
35398
|
+
if (state === "done") {
|
|
35399
|
+
$$renderer.push("<!--[0-->");
|
|
35400
|
+
Check($$renderer, {
|
|
35401
|
+
size,
|
|
35402
|
+
class: "text-status-pass"
|
|
35403
|
+
});
|
|
35404
|
+
} else if (state === "busy") {
|
|
35405
|
+
$$renderer.push("<!--[1-->");
|
|
35406
|
+
Loader_circle($$renderer, {
|
|
35407
|
+
size,
|
|
35408
|
+
class: "animate-spin"
|
|
35409
|
+
});
|
|
35410
|
+
} else {
|
|
35411
|
+
$$renderer.push("<!--[-1-->");
|
|
35412
|
+
Rotate_cw($$renderer, { size });
|
|
35413
|
+
}
|
|
35414
|
+
$$renderer.push(`<!--]--></button>`);
|
|
35415
|
+
}
|
|
35416
|
+
//#endregion
|
|
35417
|
+
//#region src/lib/components/browser/buttons/BrowserClosed.svelte
|
|
34050
35418
|
function BrowserClosed($$renderer, $$props) {
|
|
34051
35419
|
$$renderer.component(($$renderer) => {
|
|
34052
35420
|
let { closing = false} = $$props;
|
|
34053
|
-
$$renderer.push(`<button data-svelte="BrowserClosed" class="rounded hover:bg-surface-active svelte-
|
|
35421
|
+
$$renderer.push(`<button data-svelte="BrowserClosed" class="rounded hover:bg-surface-active svelte-1kvjut5" data-testid="browse-close"${attr("aria-label", browserclosedelete2())}${attr("title", browserclosedelete2())}${attr("disabled", closing, true)}><svg class="browser-icon-trash" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"></path><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"></path><path d="M10 11v6"></path><path d="M14 11v6"></path></svg></button>`);
|
|
35422
|
+
});
|
|
35423
|
+
}
|
|
35424
|
+
//#endregion
|
|
35425
|
+
//#region src/lib/components/browser/buttons/BackButton.svelte
|
|
35426
|
+
function BackButton($$renderer, $$props) {
|
|
35427
|
+
/**
|
|
35428
|
+
* BackButton — the nav ← glyph (extracted from BrowserHeader 2026-11-02).
|
|
35429
|
+
* Contract (ADR long-press history): press-and-HOLD arms the history
|
|
35430
|
+
* menu via the caller's hold machine; a quick CLICK navigates one step.
|
|
35431
|
+
* Presentational (house pattern): the caller owns canBack/busy and the
|
|
35432
|
+
* hold/menu state — this button renders the glyph and reports hold
|
|
35433
|
+
* down/up plus the click.
|
|
35434
|
+
*/
|
|
35435
|
+
let { label, testid, disabled = false, class: className = "" } = $$props;
|
|
35436
|
+
$$renderer.push(`<button data-svelte="BackButton" type="button"${attr_class(clsx(className))}${attr("data-testid", testid)}${attr("aria-label", label)}${attr("title", label)}${attr("disabled", disabled, true)}>←</button>`);
|
|
35437
|
+
}
|
|
35438
|
+
//#endregion
|
|
35439
|
+
//#region src/lib/components/browser/buttons/ForwardButton.svelte
|
|
35440
|
+
function ForwardButton($$renderer, $$props) {
|
|
35441
|
+
/**
|
|
35442
|
+
* ForwardButton — the nav → glyph (extracted from BrowserHeader
|
|
35443
|
+
* 2026-11-02), BackButton's twin: press-and-HOLD arms the history menu
|
|
35444
|
+
* via the caller's hold machine; a quick CLICK navigates one step.
|
|
35445
|
+
* Presentational (house pattern): the caller owns canForward/busy and
|
|
35446
|
+
* the hold/menu state — this button renders the glyph and reports hold
|
|
35447
|
+
* down/up plus the click.
|
|
35448
|
+
*/
|
|
35449
|
+
let { label, testid, disabled = false, class: className = "" } = $$props;
|
|
35450
|
+
$$renderer.push(`<button data-svelte="ForwardButton" type="button"${attr_class(clsx(className))}${attr("data-testid", testid)}${attr("aria-label", label)}${attr("title", label)}${attr("disabled", disabled, true)}>→</button>`);
|
|
35451
|
+
}
|
|
35452
|
+
//#endregion
|
|
35453
|
+
//#region src/lib/components/browser/buttons/UrlCopy.svelte
|
|
35454
|
+
function UrlCopy($$renderer, $$props) {
|
|
35455
|
+
/**
|
|
35456
|
+
* UrlCopy — the prefix copy-URL chip (extracted from BrowserHeader
|
|
35457
|
+
* 2026-11-02; the focus-polish correction that put the icon on the
|
|
35458
|
+
* LEADING edge of the input, prefix-icon style). Copies the FOCUSED
|
|
35459
|
+
* tab's URL; the copied state flips the icon to a check. Presentational
|
|
35460
|
+
* (house pattern): the caller owns what copying means and when the
|
|
35461
|
+
* check reverts — this chip renders the state and reports the intent.
|
|
35462
|
+
*/
|
|
35463
|
+
let { copied = false, disabled = false, label, copiedLabel, testid, class: className = "" } = $$props;
|
|
35464
|
+
$$renderer.push(`<button data-svelte="UrlCopy" type="button"${attr_class(clsx(className))}${attr("data-testid", testid)}${attr("aria-label", copied ? copiedLabel ?? label : label)}${attr("title", copied ? copiedLabel ?? label : label)}${attr("disabled", disabled, true)}>`);
|
|
35465
|
+
if (copied) {
|
|
35466
|
+
$$renderer.push("<!--[0-->");
|
|
35467
|
+
Check($$renderer, { size: 12 });
|
|
35468
|
+
} else {
|
|
35469
|
+
$$renderer.push("<!--[-1-->");
|
|
35470
|
+
Copy($$renderer, { size: 12 });
|
|
35471
|
+
}
|
|
35472
|
+
$$renderer.push(`<!--]--></button>`);
|
|
35473
|
+
}
|
|
35474
|
+
//#endregion
|
|
35475
|
+
//#region src/lib/components/browser/buttons/UrlInput.svelte
|
|
35476
|
+
function UrlInput($$renderer, $$props) {
|
|
35477
|
+
$$renderer.component(($$renderer) => {
|
|
35478
|
+
/**
|
|
35479
|
+
* UrlInput — the search-style URL box (extracted from BrowserHeader
|
|
35480
|
+
* 2026-11-02; glass-tab-ids Task 4 grammar): Escape restores the
|
|
35481
|
+
* placeholder (clears the draft), Enter submits; the panel's answer —
|
|
35482
|
+
* never Enter — is what settles the value. IME safety: Enter during
|
|
35483
|
+
* composition confirms the candidate string, never the omnibox command.
|
|
35484
|
+
* Presentational (house pattern): the caller owns what a submit means.
|
|
35485
|
+
*/
|
|
35486
|
+
let { value = "", placeholder = "", disabled = false, onsubmit, testid, class: className = "" } = $$props;
|
|
35487
|
+
$$renderer.push(`<input data-svelte="UrlInput"${attr_class(clsx(className))} type="text"${attr("data-testid", testid)}${attr("placeholder", placeholder)}${attr("disabled", disabled, true)}${attr("value", value)}/>`);
|
|
35488
|
+
bind_props($$props, { value });
|
|
34054
35489
|
});
|
|
34055
35490
|
}
|
|
34056
35491
|
//#endregion
|
|
34057
35492
|
//#region src/lib/components/browser/BrowserHeader.svelte
|
|
34058
35493
|
function BrowserHeader($$renderer, $$props) {
|
|
34059
35494
|
$$renderer.component(($$renderer) => {
|
|
34060
|
-
let { status, reBound = false, sessionId = null, closing = false, busy = false, canBack = false, canForward = false, onclose, onnavigate, onreload, onhistory } = $$props;
|
|
35495
|
+
let { status, reBound = false, sessionId = null, closing = false, busy = false, canBack = false, canForward = false, onclose, onnavigate, onreload, onhistory, focusTargetId = null, onhistoryto, placeholder = void 0, copyUrl = null } = $$props;
|
|
35496
|
+
/** Copy feedback: the icon swaps to a check for ~1.5s — no toast. */
|
|
35497
|
+
let copied = false;
|
|
34061
35498
|
/** Ephemeral intent, never state (D2): the panel clears it on the
|
|
34062
35499
|
* route ANSWER via clearInput() — success or refusal both answer. */
|
|
34063
35500
|
let urlText = "";
|
|
@@ -34065,16 +35502,85 @@ function BrowserHeader($$renderer, $$props) {
|
|
|
34065
35502
|
function clearInput() {
|
|
34066
35503
|
urlText = "";
|
|
34067
35504
|
}
|
|
34068
|
-
|
|
34069
|
-
|
|
34070
|
-
|
|
34071
|
-
|
|
34072
|
-
}
|
|
34073
|
-
|
|
34074
|
-
|
|
34075
|
-
|
|
34076
|
-
|
|
34077
|
-
|
|
35505
|
+
/** glass-tab-ids Task 4: query-active echoes the active tab's address
|
|
35506
|
+
* ("tab:N <url>") into the box — readable and re-editable. */
|
|
35507
|
+
function setOmniboxValue(v) {
|
|
35508
|
+
urlText = v;
|
|
35509
|
+
}
|
|
35510
|
+
function submit() {
|
|
35511
|
+
const t = urlText.trim();
|
|
35512
|
+
if (!t) return;
|
|
35513
|
+
onnavigate?.(t);
|
|
35514
|
+
}
|
|
35515
|
+
let $$settled = true;
|
|
35516
|
+
let $$inner_renderer;
|
|
35517
|
+
function $$render_inner($$renderer) {
|
|
35518
|
+
$$renderer.push(`<div data-svelte="BrowserHeader" class="flex items-center gap-1 border-b border-surface-border px-2 py-1 text-xs"><span class="flex min-w-0 flex-1 items-center gap-2"><span class="relative flex items-center gap-1">`);
|
|
35519
|
+
BackButton($$renderer, {
|
|
35520
|
+
class: "browser-glyph flex h-6 w-6 items-center justify-center rounded border border-surface-border bg-surface text-[18px] leading-none hover:bg-surface-active disabled:opacity-40",
|
|
35521
|
+
label: browserback1(),
|
|
35522
|
+
testid: "browser-back",
|
|
35523
|
+
disabled: busy || !canBack});
|
|
35524
|
+
$$renderer.push(`<!----> `);
|
|
35525
|
+
ForwardButton($$renderer, {
|
|
35526
|
+
class: "browser-glyph flex h-6 w-6 items-center justify-center rounded border border-surface-border bg-surface text-[18px] leading-none hover:bg-surface-active disabled:opacity-40",
|
|
35527
|
+
label: browserforward1(),
|
|
35528
|
+
testid: "browser-forward",
|
|
35529
|
+
disabled: busy || !canForward});
|
|
35530
|
+
$$renderer.push(`<!----> `);
|
|
35531
|
+
$$renderer.push("<!--[-1-->");
|
|
35532
|
+
$$renderer.push(`<!--]--></span> `);
|
|
35533
|
+
ReloadButton($$renderer, {
|
|
35534
|
+
onclick: () => onreload?.(),
|
|
35535
|
+
label: browserreload1(),
|
|
35536
|
+
testid: "browser-reload",
|
|
35537
|
+
disabled: status !== "live" || busy,
|
|
35538
|
+
size: 12,
|
|
35539
|
+
class: "browser-glyph flex h-6 w-6 items-center justify-center rounded border border-surface-border bg-surface text-[18px] leading-none hover:bg-surface-active disabled:opacity-40"
|
|
35540
|
+
});
|
|
35541
|
+
$$renderer.push(`<!----> `);
|
|
35542
|
+
UrlCopy($$renderer, {
|
|
35543
|
+
class: "flex h-6 w-6 shrink-0 items-center justify-center rounded border border-surface-border bg-surface text-surface-muted hover:bg-surface-active disabled:opacity-40",
|
|
35544
|
+
copied,
|
|
35545
|
+
copiedLabel: "Copied",
|
|
35546
|
+
label: "Copy focused tab URL",
|
|
35547
|
+
testid: "browser-copy-url",
|
|
35548
|
+
disabled: !copyUrl});
|
|
35549
|
+
$$renderer.push(`<!----> `);
|
|
35550
|
+
UrlInput($$renderer, {
|
|
35551
|
+
class: "min-w-0 flex-1 rounded border border-surface-border bg-surface px-2 py-0.5",
|
|
35552
|
+
placeholder: placeholder ?? browserurlplaceholder2(),
|
|
35553
|
+
disabled: status !== "live" || busy,
|
|
35554
|
+
testid: "browser-url-input",
|
|
35555
|
+
onsubmit: submit,
|
|
35556
|
+
get value() {
|
|
35557
|
+
return urlText;
|
|
35558
|
+
},
|
|
35559
|
+
set value($$value) {
|
|
35560
|
+
urlText = $$value;
|
|
35561
|
+
$$settled = false;
|
|
35562
|
+
}
|
|
35563
|
+
});
|
|
35564
|
+
$$renderer.push(`<!----></span> <span class="flex items-center gap-2" data-testid="browser-status"${attr("data-status", status)}${attr("data-rebound", reBound)}><span${attr_class(`inline-block h-2 w-2 rounded-full ${status === "live" ? "bg-emerald-500" : status === "failed" || status === "closed" ? "bg-red-500" : "bg-amber-400"}`)}></span> `);
|
|
35565
|
+
if (sessionId) {
|
|
35566
|
+
$$renderer.push("<!--[0-->");
|
|
35567
|
+
$$renderer.push(`<span class="rounded-t-md border border-b-0 border-surface-border bg-surface-elevated px-2 py-0.5 font-mono text-[10px] opacity-80" data-testid="browser-session-tab">${escape_html(sessionId.slice(0, 8))}</span>`);
|
|
35568
|
+
} else $$renderer.push("<!--[-1-->");
|
|
35569
|
+
$$renderer.push(`<!--]--> `);
|
|
35570
|
+
BrowserClosed($$renderer, {
|
|
35571
|
+
closing});
|
|
35572
|
+
$$renderer.push(`<!----></span></div>`);
|
|
35573
|
+
}
|
|
35574
|
+
do {
|
|
35575
|
+
$$settled = true;
|
|
35576
|
+
$$inner_renderer = $$renderer.copy();
|
|
35577
|
+
$$render_inner($$inner_renderer);
|
|
35578
|
+
} while (!$$settled);
|
|
35579
|
+
$$renderer.subsume($$inner_renderer);
|
|
35580
|
+
bind_props($$props, {
|
|
35581
|
+
clearInput,
|
|
35582
|
+
setOmniboxValue
|
|
35583
|
+
});
|
|
34078
35584
|
});
|
|
34079
35585
|
}
|
|
34080
35586
|
//#endregion
|
|
@@ -34103,8 +35609,11 @@ function BrowserContent($$renderer, $$props) {
|
|
|
34103
35609
|
$$renderer.push(`<!--]--> <button type="button" class="block w-full px-3 py-1.5 text-left text-zinc-900 hover:bg-zinc-200" data-testid="browser-ctxmenu-item">${escape_html(browserreload1())}</button> <div class="my-1 border-t border-zinc-300"></div> <button type="button" class="block w-full px-3 py-1.5 text-left text-zinc-900 hover:bg-zinc-200" data-testid="browser-ctxmenu-item">${escape_html(browserctxsendrightclick4())}</button></div>`);
|
|
34104
35610
|
} else $$renderer.push("<!--[-1-->");
|
|
34105
35611
|
$$renderer.push(`<!--]--> `);
|
|
34106
|
-
if (status
|
|
35612
|
+
if (status === "closed") {
|
|
34107
35613
|
$$renderer.push("<!--[0-->");
|
|
35614
|
+
$$renderer.push(`<div class="absolute inset-0 grid place-items-center text-xs opacity-80" data-testid="browser-closed">${escape_html(browsersessiondead2())}</div>`);
|
|
35615
|
+
} else if (status !== "live") {
|
|
35616
|
+
$$renderer.push("<!--[1-->");
|
|
34108
35617
|
$$renderer.push(`<div class="absolute inset-0 grid place-items-center text-xs opacity-60" data-testid="browser-placeholder">${escape_html(status === "opening" ? browserlaunching1() : browserwaitingframes2())}</div>`);
|
|
34109
35618
|
} else $$renderer.push("<!--[-1-->");
|
|
34110
35619
|
$$renderer.push(`<!--]--></div>`);
|
|
@@ -34120,14 +35629,92 @@ function BrowserContent($$renderer, $$props) {
|
|
|
34120
35629
|
//#region src/lib/components/browser/BrowserTab.svelte
|
|
34121
35630
|
function BrowserTab($$renderer, $$props) {
|
|
34122
35631
|
$$renderer.component(($$renderer) => {
|
|
34123
|
-
let { tab, disabled = false} = $$props;
|
|
34124
|
-
|
|
34125
|
-
|
|
34126
|
-
|
|
34127
|
-
|
|
34128
|
-
|
|
34129
|
-
|
|
34130
|
-
|
|
35632
|
+
let { tab, position = void 0, disabled = false, onclose } = $$props;
|
|
35633
|
+
/** Focus polish 2026-10-28: the badge reads the strip position — the same
|
|
35634
|
+
* number Alt+N dispatches on — while PROMPT GRAMMAR stays tab:{id}
|
|
35635
|
+
* (the registry is untouched; this is display-only). */
|
|
35636
|
+
/** Real-favicon upgrade (fix round 2): the same cheap s2 path the menu
|
|
35637
|
+
* uses; non-http(s) tabs keep the colored dot (the img never renders). */
|
|
35638
|
+
function faviconUrl(u) {
|
|
35639
|
+
try {
|
|
35640
|
+
const p = new URL(u);
|
|
35641
|
+
return p.protocol === "http:" || p.protocol === "https:" ? "https://www.google.com/s2/favicons?domain=" + p.hostname + "&sz=32" : "";
|
|
35642
|
+
} catch {
|
|
35643
|
+
return "";
|
|
35644
|
+
}
|
|
35645
|
+
}
|
|
35646
|
+
const ordinalLabel = derived(() => position !== void 0 ? "t" + position + ":" + tab.tabId : "tab:" + tab.tabId);
|
|
35647
|
+
$$renderer.push(`<div data-svelte="BrowserTab" class="group/tab relative flex shrink-0 items-stretch"><button type="button"${attr_class(`flex h-6 w-36 items-center gap-1 truncate rounded-t-md border border-b-0 px-1.5 text-left whitespace-nowrap ${tab.active ? "border-transparent bg-blue-100 text-blue-900 font-medium shadow-sm" : "border-transparent text-zinc-600 hover:bg-zinc-100 hover:border-surface-border"}`)}${attr("disabled", disabled || tab.active, true)} data-testid="browser-tab"${attr("data-active", tab.active)}${attr("title", tab.url)}><span class="relative flex h-3.5 w-3.5 shrink-0 items-center justify-center" data-testid="browser-tab-favicon"><span${attr_class(`absolute h-1.5 w-1.5 rounded-full ${tab.active ? "bg-emerald-500" : "bg-zinc-400"}`)}></span> `);
|
|
35648
|
+
if (faviconUrl(tab.url)) {
|
|
35649
|
+
$$renderer.push("<!--[0-->");
|
|
35650
|
+
$$renderer.push(`<img${attr("src", faviconUrl(tab.url))} alt="" class="relative h-3.5 w-3.5 rounded-sm" onerror="this.__e=event"/>`);
|
|
35651
|
+
} else $$renderer.push("<!--[-1-->");
|
|
35652
|
+
$$renderer.push(`<!--]--></span> `);
|
|
35653
|
+
if (tab.tabId !== void 0) {
|
|
35654
|
+
$$renderer.push("<!--[0-->");
|
|
35655
|
+
$$renderer.push(`<span class="shrink-0 rounded-sm bg-black/5 px-0.5 font-mono text-[9px] leading-tight opacity-80" data-testid="browser-tab-ordinal">${escape_html(ordinalLabel())}</span>`);
|
|
35656
|
+
} else $$renderer.push("<!--[-1-->");
|
|
35657
|
+
$$renderer.push(`<!--]--> <span class="min-w-0 flex-1 truncate">${escape_html(tab.title || tab.url || "tab")}</span></button> `);
|
|
35658
|
+
CloseButton($$renderer, {
|
|
35659
|
+
class: "browser-glyph browser-glyph-destructive absolute right-0 top-1/2 flex h-5 w-5 -translate-y-1/2 items-center justify-center rounded font-semibold opacity-0 leading-none transition-opacity group-hover/tab:opacity-100 hover:bg-red-500 focus-visible:opacity-100",
|
|
35660
|
+
label: browsertabclosetitle3(),
|
|
35661
|
+
testid: "browser-tab-close",
|
|
35662
|
+
onclick: () => onclose?.(tab.targetId)
|
|
35663
|
+
});
|
|
35664
|
+
$$renderer.push(`<!----></div>`);
|
|
35665
|
+
});
|
|
35666
|
+
}
|
|
35667
|
+
//#endregion
|
|
35668
|
+
//#region src/lib/components/browser/buttons/BrowserNew.svelte
|
|
35669
|
+
function BrowserNew($$renderer, $$props) {
|
|
35670
|
+
/**
|
|
35671
|
+
* BrowserNew — the tab-strip + chip as a reusable button (extracted from
|
|
35672
|
+
* BrowserPanel 2026-11-02, CloseButton day): ADR-0042 D3's tab CREATE —
|
|
35673
|
+
* an absent-URL opentab; the CALLER owns what creating means and the
|
|
35674
|
+
* chrome (pass Tailwind classes via `class`).
|
|
35675
|
+
*
|
|
35676
|
+
* Icon: lucide Plus at rest, CirclePlus on hover — the hover swap is the
|
|
35677
|
+
* component's own contract (named group `new` on the button itself, so
|
|
35678
|
+
* the swap works wherever the chip mounts, no parent group needed).
|
|
35679
|
+
* CirclePlus is the canonical name — PlusCircle is the deprecated alias.
|
|
35680
|
+
*/
|
|
35681
|
+
let { label, testid, disabled = false, size = 12, class: className = "" } = $$props;
|
|
35682
|
+
$$renderer.push(`<button data-svelte="BrowserNew" type="button"${attr_class(`group/new ${stringify(className)}`)}${attr("data-testid", testid)}${attr("title", label)}${attr("aria-label", label)}${attr("disabled", disabled, true)}>`);
|
|
35683
|
+
Plus($$renderer, {
|
|
35684
|
+
size,
|
|
35685
|
+
class: "group-hover/new:hidden"
|
|
35686
|
+
});
|
|
35687
|
+
$$renderer.push(`<!----> `);
|
|
35688
|
+
Circle_plus($$renderer, {
|
|
35689
|
+
size,
|
|
35690
|
+
class: "hidden group-hover/new:block"
|
|
35691
|
+
});
|
|
35692
|
+
$$renderer.push(`<!----></button>`);
|
|
35693
|
+
}
|
|
35694
|
+
//#endregion
|
|
35695
|
+
//#region src/lib/components/browser/BrowserProvenance.svelte
|
|
35696
|
+
function BrowserProvenance($$renderer, $$props) {
|
|
35697
|
+
$$renderer.component(($$renderer) => {
|
|
35698
|
+
/**
|
|
35699
|
+
* BrowserProvenance — the lineage chip row (ADR-0036 D3): who asked for
|
|
35700
|
+
* this glass. The title rides the spine merge the route resolved; a
|
|
35701
|
+
* pruned opener degrades to the raw session id. Depth tint like the
|
|
35702
|
+
* transcript. Owns the live zoom slider when the knob is enabled.
|
|
35703
|
+
*/
|
|
35704
|
+
let { openedBy, parentTitle, focusedTitle, depth} = $$props;
|
|
35705
|
+
$$renderer.push(`<div data-svelte="BrowserProvenance"${attr_class("browser-provenance flex items-center gap-1 border-b border-surface-border px-2 py-0.5 text-[10px] text-surface-muted svelte-ifad3s", void 0, { "depth-tinted": depth > 0 })} data-testid="browser-provenance"${attr("title", openedBy)}><span class="opacity-70">⌥</span> <span class="flex min-w-0 items-center gap-1 truncate text-[12px] font-bold"><span class="text-[color:var(--color-accent-purple)]">${escape_html(parentTitle ?? openedBy)}</span>`);
|
|
35706
|
+
if (focusedTitle) {
|
|
35707
|
+
$$renderer.push("<!--[0-->");
|
|
35708
|
+
$$renderer.push(`<span class="text-text-muted">|</span><span class="text-[color:var(--color-accent-blue)]">${escape_html(focusedTitle)}</span>`);
|
|
35709
|
+
} else $$renderer.push("<!--[-1-->");
|
|
35710
|
+
$$renderer.push(`<!--]--></span> `);
|
|
35711
|
+
if (depth > 0) {
|
|
35712
|
+
$$renderer.push("<!--[0-->");
|
|
35713
|
+
$$renderer.push(`<span class="opacity-60">·d${escape_html(depth)}</span>`);
|
|
35714
|
+
} else $$renderer.push("<!--[-1-->");
|
|
35715
|
+
$$renderer.push(`<!--]--> `);
|
|
35716
|
+
$$renderer.push("<!--[-1-->");
|
|
35717
|
+
$$renderer.push(`<!--]--></div>`);
|
|
34131
35718
|
});
|
|
34132
35719
|
}
|
|
34133
35720
|
//#endregion
|
|
@@ -34174,98 +35761,97 @@ function createMoveCoalescer(raf, fire) {
|
|
|
34174
35761
|
} };
|
|
34175
35762
|
}
|
|
34176
35763
|
//#endregion
|
|
34177
|
-
//#region src/lib/
|
|
34178
|
-
/**
|
|
34179
|
-
|
|
34180
|
-
|
|
34181
|
-
|
|
34182
|
-
|
|
34183
|
-
|
|
34184
|
-
|
|
34185
|
-
|
|
34186
|
-
|
|
34187
|
-
|
|
34188
|
-
|
|
34189
|
-
|
|
34190
|
-
|
|
34191
|
-
|
|
34192
|
-
|
|
34193
|
-
|
|
34194
|
-
|
|
34195
|
-
|
|
34196
|
-
function clampSidebarWidth(width) {
|
|
34197
|
-
const { minWidth, maxWidth } = appConfig().sidebar;
|
|
34198
|
-
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
34199
|
-
}
|
|
34200
|
-
/** Config-driven default width (clamped through the single bound site). */
|
|
34201
|
-
function defaultSidebarWidth() {
|
|
34202
|
-
return clampSidebarWidth(appConfig().sidebar.defaultWidth);
|
|
34203
|
-
}
|
|
34204
|
-
/** Persisted defaults when nothing (usable) is stored. */
|
|
34205
|
-
function defaultSidebarPrefs() {
|
|
34206
|
-
return {
|
|
34207
|
-
collapsed: false,
|
|
34208
|
-
width: defaultSidebarWidth()
|
|
35764
|
+
//#region src/lib/browser/tab-grammar.ts
|
|
35765
|
+
/** URL-shaped: has a scheme (foo://…) or a dotted host (example.com). */
|
|
35766
|
+
function isUrlShaped(s) {
|
|
35767
|
+
return /^[a-z][a-z0-9+.-]*:\/\//i.test(s) || /^[^\s/]+\.[^\s/]{2,}$/.test(s);
|
|
35768
|
+
}
|
|
35769
|
+
/** "tab:N" with N a positive integer, else null. */
|
|
35770
|
+
function matchTabRef(s) {
|
|
35771
|
+
const m = /^tab:(\d+)$/i.exec(s);
|
|
35772
|
+
if (!m) return null;
|
|
35773
|
+
const n = Number(m[1]);
|
|
35774
|
+
return n >= 1 ? n : null;
|
|
35775
|
+
}
|
|
35776
|
+
function parseTabCommand(input) {
|
|
35777
|
+
const text = input.trim();
|
|
35778
|
+
const lower = text.toLowerCase();
|
|
35779
|
+
if (lower === "active") return { kind: "query-active" };
|
|
35780
|
+
if (lower === "close active") return {
|
|
35781
|
+
kind: "close",
|
|
35782
|
+
tabId: "active"
|
|
34209
35783
|
};
|
|
34210
|
-
|
|
34211
|
-
|
|
34212
|
-
|
|
34213
|
-
|
|
34214
|
-
|
|
34215
|
-
|
|
34216
|
-
|
|
34217
|
-
if (typeof localStorage === "undefined") return defaultSidebarPrefs();
|
|
34218
|
-
try {
|
|
34219
|
-
const raw = localStorage.getItem(dsiKey(STORAGE_KEY, profile));
|
|
34220
|
-
if (!raw) return defaultSidebarPrefs();
|
|
34221
|
-
const parsed = JSON.parse(raw);
|
|
34222
|
-
if (parsed === null || typeof parsed !== "object") return defaultSidebarPrefs();
|
|
35784
|
+
if (/^close\s+tab:\S+$/i.test(lower)) {
|
|
35785
|
+
const ref = text.slice(text.indexOf(":") + 1);
|
|
35786
|
+
const n = Number(ref);
|
|
35787
|
+
if (Number.isInteger(n) && n >= 1) return {
|
|
35788
|
+
kind: "close",
|
|
35789
|
+
tabId: n
|
|
35790
|
+
};
|
|
34223
35791
|
return {
|
|
34224
|
-
|
|
34225
|
-
|
|
35792
|
+
kind: "error",
|
|
35793
|
+
error: `invalid tab reference: tab:${ref}`
|
|
34226
35794
|
};
|
|
34227
|
-
} catch {
|
|
34228
|
-
return defaultSidebarPrefs();
|
|
34229
35795
|
}
|
|
34230
|
-
|
|
34231
|
-
|
|
34232
|
-
|
|
34233
|
-
|
|
34234
|
-
|
|
34235
|
-
|
|
34236
|
-
|
|
34237
|
-
|
|
34238
|
-
|
|
34239
|
-
|
|
34240
|
-
|
|
34241
|
-
|
|
34242
|
-
|
|
34243
|
-
|
|
34244
|
-
|
|
34245
|
-
|
|
34246
|
-
|
|
34247
|
-
|
|
34248
|
-
* "svelte-ignore state_referenced_locally" comments: prefs seed the
|
|
34249
|
-
* layout once; later writes go through the save effects. */
|
|
34250
|
-
init(profile) {
|
|
34251
|
-
this.#initialised = true;
|
|
34252
|
-
this.#profile = profile;
|
|
34253
|
-
const floor = loadPanelPrefs(profile);
|
|
34254
|
-
this.panelWidth = clampPanelWidth(floor.panelWidth);
|
|
34255
|
-
this.zoom = clampPanelZoom(floor.zoom);
|
|
34256
|
-
this.treePct = clampTreePct(floor.treePct);
|
|
34257
|
-
const sidebar = loadSidebarPrefs(profile);
|
|
34258
|
-
this.sidebarCollapsed = sidebar.collapsed;
|
|
34259
|
-
this.sidebarWidth = sidebar.width;
|
|
35796
|
+
const reuse = /^reuse\s+(\S+)(?:\s+(\S+))?$/i.exec(text);
|
|
35797
|
+
if (reuse) {
|
|
35798
|
+
const n = matchTabRef(reuse[1]);
|
|
35799
|
+
if (n !== null) {
|
|
35800
|
+
const url = reuse[2];
|
|
35801
|
+
return url ? {
|
|
35802
|
+
kind: "focus",
|
|
35803
|
+
tabId: n,
|
|
35804
|
+
url
|
|
35805
|
+
} : {
|
|
35806
|
+
kind: "focus",
|
|
35807
|
+
tabId: n
|
|
35808
|
+
};
|
|
35809
|
+
}
|
|
35810
|
+
return {
|
|
35811
|
+
kind: "error",
|
|
35812
|
+
error: `invalid tab reference: ${reuse[1]}`
|
|
35813
|
+
};
|
|
34260
35814
|
}
|
|
34261
|
-
|
|
34262
|
-
|
|
35815
|
+
const change = /^change(?:\s+to)?\s+(\S+)$/i.exec(text);
|
|
35816
|
+
if (change) {
|
|
35817
|
+
const n = matchTabRef(change[1]);
|
|
35818
|
+
if (n !== null) return {
|
|
35819
|
+
kind: "focus",
|
|
35820
|
+
tabId: n
|
|
35821
|
+
};
|
|
35822
|
+
return {
|
|
35823
|
+
kind: "error",
|
|
35824
|
+
error: `invalid tab reference: ${change[1]}`
|
|
35825
|
+
};
|
|
34263
35826
|
}
|
|
34264
|
-
|
|
34265
|
-
|
|
34266
|
-
|
|
34267
|
-
|
|
34268
|
-
|
|
35827
|
+
if (/^tab:/i.test(text)) {
|
|
35828
|
+
const n = matchTabRef(text);
|
|
35829
|
+
if (n !== null) return {
|
|
35830
|
+
kind: "focus",
|
|
35831
|
+
tabId: n
|
|
35832
|
+
};
|
|
35833
|
+
return {
|
|
35834
|
+
kind: "error",
|
|
35835
|
+
error: `invalid tab reference: ${text}`
|
|
35836
|
+
};
|
|
35837
|
+
}
|
|
35838
|
+
if (lower === "glass") return { kind: "open" };
|
|
35839
|
+
if (/^glass\s+/i.test(text)) {
|
|
35840
|
+
const rest = text.replace(/^glass\s+/i, "");
|
|
35841
|
+
if (isUrlShaped(rest)) return {
|
|
35842
|
+
kind: "open",
|
|
35843
|
+
url: rest
|
|
35844
|
+
};
|
|
35845
|
+
return {
|
|
35846
|
+
kind: "open",
|
|
35847
|
+
text: rest
|
|
35848
|
+
};
|
|
35849
|
+
}
|
|
35850
|
+
return {
|
|
35851
|
+
kind: "url-or-search",
|
|
35852
|
+
text: input
|
|
35853
|
+
};
|
|
35854
|
+
}
|
|
34269
35855
|
//#endregion
|
|
34270
35856
|
//#region src/lib/components/browser/BrowserPanel.svelte
|
|
34271
35857
|
function BrowserPanel($$renderer, $$props) {
|
|
@@ -34286,10 +35872,39 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
34286
35872
|
let proxyBusy = false;
|
|
34287
35873
|
let canBack = false;
|
|
34288
35874
|
let canForward = false;
|
|
35875
|
+
const SEARCH_URL = "https://www.google.com/search?q=";
|
|
35876
|
+
/** glass-tab-ids Task 4: the focused tab's URL IS the omnibox hint, but
|
|
35877
|
+
* a 2000-char SPA URL would eat the strip — truncate the hint at 64. */
|
|
35878
|
+
const OMNIBOX_PLACEHOLDER_MAX = 64;
|
|
35879
|
+
/** The omnibox placeholder: the ACTIVE tab's URL (64-char truncated) when
|
|
35880
|
+
* one is active; the localized "Search or type a URL" when none is.
|
|
35881
|
+
* Empty OR about:blank (any case, optional fragment suffix like
|
|
35882
|
+
* 'about:blank#blocked') is NO URL — a fresh tab must show the
|
|
35883
|
+
* original placeholder, not the blank URL. */
|
|
35884
|
+
function isNoUrl(u) {
|
|
35885
|
+
const s = u.toLowerCase();
|
|
35886
|
+
return !s || s === "about:blank" || s.startsWith("about:blank#") || s.startsWith("data:");
|
|
35887
|
+
}
|
|
35888
|
+
const omniboxPlaceholder = derived(() => {
|
|
35889
|
+
const url = tabs.find((tb) => tb.active)?.url ?? "";
|
|
35890
|
+
if (isNoUrl(url)) return t(browserurlplaceholder2);
|
|
35891
|
+
return url.length > OMNIBOX_PLACEHOLDER_MAX ? url.slice(0, OMNIBOX_PLACEHOLDER_MAX) : url;
|
|
35892
|
+
});
|
|
34289
35893
|
/** ADR-0040 D5: the tab strip — the registry's tab list mirrored here;
|
|
34290
35894
|
* the SERVER stays the authority (activeTargetId), this is a view. */
|
|
34291
35895
|
let tabs = [];
|
|
34292
35896
|
let switching = false;
|
|
35897
|
+
/** Focus polish 2026-10-28: the FOCUSED tab's facts for the header's
|
|
35898
|
+
* prefix copy-URL icon (null = no real URL — the isNoUrl guard, so an
|
|
35899
|
+
* empty/about:blank tab disables the copy) and the info line's
|
|
35900
|
+
* '{sessionTitle} | {tab title}' suffix (FULL text; CSS truncates). */
|
|
35901
|
+
const focusedTab = derived(() => tabs.find((tb) => tb.active) ?? null);
|
|
35902
|
+
const focusedTitle = derived(() => focusedTab()?.title ?? "");
|
|
35903
|
+
const focusedUrl = derived(() => focusedTab() && !isNoUrl(focusedTab().url) ? focusedTab().url : null);
|
|
35904
|
+
/** ADR-0040 D4: activate paints the BOUNDARY frame from the response —
|
|
35905
|
+
* the panel never waits on a blank paint — then re-attaches the SSE at
|
|
35906
|
+
* the carried seq so the stream resumes on the new relay's ring. */
|
|
35907
|
+
async function activateTab(targetId) {}
|
|
34293
35908
|
const moves = createMoveCoalescer((cb) => requestAnimationFrame(cb), (x, y) => void post());
|
|
34294
35909
|
async function post(input) {}
|
|
34295
35910
|
function toViewportCx(e) {
|
|
@@ -34362,6 +35977,9 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
34362
35977
|
* the blank signal, never a literal about:blank. Callers own their own
|
|
34363
35978
|
* ctxClose(). */
|
|
34364
35979
|
async function openTab(url) {}
|
|
35980
|
+
async function ctxCloseTab(targetId) {
|
|
35981
|
+
ctxClose();
|
|
35982
|
+
}
|
|
34365
35983
|
function ctxAct(action) {
|
|
34366
35984
|
const m = ctxMenu;
|
|
34367
35985
|
ctxClose();
|
|
@@ -34399,16 +36017,65 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
34399
36017
|
text: e.type === "keydown" && e.key.length === 1 ? e.key : void 0
|
|
34400
36018
|
});
|
|
34401
36019
|
}
|
|
36020
|
+
/** A URL/search phrase is a URL when the route would take it verbatim;
|
|
36021
|
+
* anything else rides the search engine (ADR-0031 D2). glass-tab-ids
|
|
36022
|
+
* Task 4 adds the dotted-host arm: "example.com" navigates, it does not
|
|
36023
|
+
* search (the same shape the tab-grammar parser accepts after "glass"). */
|
|
36024
|
+
function toTarget(text) {
|
|
36025
|
+
return /^[a-z][a-z0-9+.-]*:\/\/|^data:text\/html/.test(text) || /^([^\s/]+\.[^\s/]{2,})$/.test(text) ? text : SEARCH_URL + encodeURIComponent(text);
|
|
36026
|
+
}
|
|
36027
|
+
/** glass-tab-ids Task 4: the omnibox speaks tab grammar. A parsed command
|
|
36028
|
+
* acts (open/focus/close/query-active); anything the parser passes over
|
|
36029
|
+
* falls through to the classic URL-or-search split in the ACTIVE tab.
|
|
36030
|
+
* tabId→targetId resolution is PANEL-LOCAL — read off the tabs payload
|
|
36031
|
+
* the strip poll already holds; no server round-trip resolves it. */
|
|
36032
|
+
async function handleOmniboxSubmit(text) {
|
|
36033
|
+
const cmd = parseTabCommand(text);
|
|
36034
|
+
if (cmd.kind === "open") {
|
|
36035
|
+
await openTab(cmd.url ?? SEARCH_URL + encodeURIComponent(cmd.text ?? ""));
|
|
36036
|
+
return;
|
|
36037
|
+
}
|
|
36038
|
+
if (cmd.kind === "focus") {
|
|
36039
|
+
const target = tabs.find((tb) => tb.tabId === cmd.tabId)?.targetId;
|
|
36040
|
+
if (!target) {
|
|
36041
|
+
console.warn("[browser-panel] omnibox: no tab tab:" + cmd.tabId);
|
|
36042
|
+
return;
|
|
36043
|
+
}
|
|
36044
|
+
await activateTab();
|
|
36045
|
+
if (cmd.url) await proxy({ url: toTarget(cmd.url) });
|
|
36046
|
+
return;
|
|
36047
|
+
}
|
|
36048
|
+
if (cmd.kind === "close") {
|
|
36049
|
+
const target = cmd.tabId === "active" ? tabs.find((tb) => tb.active)?.targetId : tabs.find((tb) => tb.tabId === cmd.tabId)?.targetId;
|
|
36050
|
+
if (!target) {
|
|
36051
|
+
console.warn("[browser-panel] omnibox: close resolved to no tab", cmd.tabId);
|
|
36052
|
+
return;
|
|
36053
|
+
}
|
|
36054
|
+
await ctxCloseTab();
|
|
36055
|
+
return;
|
|
36056
|
+
}
|
|
36057
|
+
if (cmd.kind === "query-active") {
|
|
36058
|
+
if (tabs.find((tb) => tb.active));
|
|
36059
|
+
return;
|
|
36060
|
+
}
|
|
36061
|
+
if (cmd.kind === "error") {
|
|
36062
|
+
console.warn("[browser-panel] omnibox:", cmd.error);
|
|
36063
|
+
return;
|
|
36064
|
+
}
|
|
36065
|
+
proxy();
|
|
36066
|
+
}
|
|
34402
36067
|
/** One POST for every proxy verb; the ANSWER (success or refusal)
|
|
34403
36068
|
* clears the input and refreshes the history bounds. A dead session
|
|
34404
36069
|
* surfaces as the closed status, never a crash (404/409). */
|
|
34405
36070
|
async function proxy(body) {}
|
|
34406
|
-
function submitUrl(text) {
|
|
34407
|
-
proxy();
|
|
34408
|
-
}
|
|
34409
36071
|
function goHistory(dir) {
|
|
34410
36072
|
proxy();
|
|
34411
36073
|
}
|
|
36074
|
+
/** Long-press history dropdown (operator-approved 2026-10-28): the
|
|
36075
|
+
* header reports the picked list index; the panel performs the TRUE
|
|
36076
|
+
* travel POST (Page.navigateToHistoryEntry — no new history entry)
|
|
36077
|
+
* and the answer refreshes the bounds exactly like a proxy verb. */
|
|
36078
|
+
async function goHistoryTo(index) {}
|
|
34412
36079
|
/** The FOLD (ADR-0037 D1): the header close button only reports
|
|
34413
36080
|
* upward - the route's onclose is removePanel, the panel leaves the
|
|
34414
36081
|
* floor, and the SERVER SESSION STAYS ALIVE (the reaper is the
|
|
@@ -34419,11 +36086,12 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
34419
36086
|
function fold() {
|
|
34420
36087
|
onclose?.();
|
|
34421
36088
|
}
|
|
34422
|
-
onDestroy(() => {
|
|
36089
|
+
onDestroy(() => {
|
|
36090
|
+
});
|
|
34423
36091
|
let $$settled = true;
|
|
34424
36092
|
let $$inner_renderer;
|
|
34425
36093
|
function $$render_inner($$renderer) {
|
|
34426
|
-
$$renderer.push(`<div data-svelte="BrowserPanel" class="relative flex h-full flex-col bg-surface-elevated" data-testid="panel-browser">`);
|
|
36094
|
+
$$renderer.push(`<div data-svelte="BrowserPanel" class="glass-browser-icons relative flex h-full flex-col bg-surface-elevated svelte-283365" data-testid="panel-browser">`);
|
|
34427
36095
|
BrowserHeader($$renderer, {
|
|
34428
36096
|
status,
|
|
34429
36097
|
reBound,
|
|
@@ -34433,32 +36101,45 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
34433
36101
|
canBack,
|
|
34434
36102
|
canForward,
|
|
34435
36103
|
onclose: () => fold(),
|
|
34436
|
-
onnavigate:
|
|
36104
|
+
onnavigate: handleOmniboxSubmit,
|
|
36105
|
+
placeholder: omniboxPlaceholder(),
|
|
34437
36106
|
onreload: () => void proxy(),
|
|
34438
|
-
onhistory: goHistory
|
|
36107
|
+
onhistory: goHistory,
|
|
36108
|
+
focusTargetId: focusedTab()?.targetId ?? null,
|
|
36109
|
+
onhistoryto: (i) => void goHistoryTo(),
|
|
36110
|
+
copyUrl: focusedUrl()
|
|
34439
36111
|
});
|
|
34440
36112
|
$$renderer.push(`<!----> `);
|
|
34441
36113
|
if (openedBy) {
|
|
34442
36114
|
$$renderer.push("<!--[0-->");
|
|
34443
|
-
$$renderer
|
|
34444
|
-
|
|
34445
|
-
|
|
34446
|
-
|
|
34447
|
-
|
|
34448
|
-
|
|
36115
|
+
BrowserProvenance($$renderer, {
|
|
36116
|
+
openedBy,
|
|
36117
|
+
parentTitle,
|
|
36118
|
+
focusedTitle: focusedTitle(),
|
|
36119
|
+
depth,
|
|
36120
|
+
zoomLabel: t(browserzoom1)});
|
|
34449
36121
|
} else $$renderer.push("<!--[-1-->");
|
|
34450
36122
|
$$renderer.push(`<!--]--> `);
|
|
34451
36123
|
if (tabs.length >= 1) {
|
|
34452
36124
|
$$renderer.push("<!--[0-->");
|
|
34453
36125
|
$$renderer.push(`<div class="flex items-center gap-1 overflow-x-auto border-b border-surface-border px-1 py-0.5 text-[11px]" data-testid="browser-tab-strip"><!--[-->`);
|
|
34454
36126
|
const each_array = ensure_array_like(tabs);
|
|
34455
|
-
for (let
|
|
34456
|
-
let t = each_array[
|
|
36127
|
+
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
|
|
36128
|
+
let t = each_array[i];
|
|
34457
36129
|
BrowserTab($$renderer, {
|
|
34458
36130
|
tab: t,
|
|
34459
|
-
|
|
36131
|
+
position: i + 1,
|
|
36132
|
+
disabled: switching,
|
|
36133
|
+
onclose: (id) => void ctxCloseTab()
|
|
36134
|
+
});
|
|
34460
36135
|
}
|
|
34461
|
-
$$renderer.push(`<!--]-->
|
|
36136
|
+
$$renderer.push(`<!--]--> `);
|
|
36137
|
+
BrowserNew($$renderer, {
|
|
36138
|
+
class: "flex h-5 w-5 shrink-0 items-center justify-center rounded border border-accent-blue/20 bg-accent-blue/10 text-text-secondary hover:bg-accent-blue/20 disabled:opacity-40",
|
|
36139
|
+
label: t(browsernewtab2),
|
|
36140
|
+
testid: "browser-tab-new",
|
|
36141
|
+
disabled: true});
|
|
36142
|
+
$$renderer.push(`<!----></div>`);
|
|
34462
36143
|
} else $$renderer.push("<!--[-1-->");
|
|
34463
36144
|
$$renderer.push(`<!--]--> `);
|
|
34464
36145
|
BrowserContent($$renderer, {
|
|
@@ -34529,19 +36210,62 @@ function SettingsSkillsToolbar($$renderer, $$props) {
|
|
|
34529
36210
|
});
|
|
34530
36211
|
}
|
|
34531
36212
|
//#endregion
|
|
36213
|
+
//#region src/lib/components/common/tabs/SegmentedTabs.svelte
|
|
36214
|
+
function SegmentedTabs($$renderer, $$props) {
|
|
36215
|
+
$$renderer.component(($$renderer) => {
|
|
36216
|
+
/**
|
|
36217
|
+
* SegmentedTabs — THE one joined-pill tab grammar (The Plugin Rack
|
|
36218
|
+
* ADR, amendment IV 2026-10-31): the scoped-CSS pill lived
|
|
36219
|
+
* copy-pasted in PluginManagerHeaderTabs, SettingsSkillsHeaderTabs
|
|
36220
|
+
* and WorkspaceFileTabGroup; this Tailwind component replaces all
|
|
36221
|
+
* three (zero gap, outer curves only, active = accent blue).
|
|
36222
|
+
* Presentational: no state lives here — the owner owns `active`
|
|
36223
|
+
* and speaks its own tab vocabulary through `tabs`/`onchange`.
|
|
36224
|
+
* The on/off states are MUTUALLY EXCLUSIVE class sets (v4 lesson:
|
|
36225
|
+
* bg-transparent + bg-accent-blue in one list fight by stylesheet
|
|
36226
|
+
* order, and transparent won — the white-on-white pill).
|
|
36227
|
+
*/
|
|
36228
|
+
/** The owner's tab id — echoed back through onchange. */
|
|
36229
|
+
/** The visible (already localized) label. */
|
|
36230
|
+
/** Renders the segment disabled (e.g. a locked Diff). */
|
|
36231
|
+
/** The owner's test hook (data-testid). */
|
|
36232
|
+
let { tabs, active, ariaLabel, groupTestid, onchange } = $$props;
|
|
36233
|
+
$$renderer.push(`<div data-svelte="SegmentedTabs" class="inline-flex shrink-0" role="group"${attr("aria-label", ariaLabel)}${attr("data-testid", groupTestid)}><!--[-->`);
|
|
36234
|
+
const each_array = ensure_array_like(tabs);
|
|
36235
|
+
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
|
|
36236
|
+
let seg = each_array[i];
|
|
36237
|
+
$$renderer.push(`<button type="button"${attr_class(`cursor-pointer border px-2 py-[0.1rem] text-[0.6875rem] leading-normal transition-colors ${i === 0 ? "rounded-l-sm" : "rounded-r-sm border-l-0"} ${active === seg.id ? "border-accent-blue bg-accent-blue text-white" : "border-border bg-transparent"} disabled:cursor-not-allowed disabled:opacity-50`)}${attr("aria-pressed", active === seg.id)}${attr("disabled", seg.disabled === true, true)}${attr("data-testid", seg.testid)}>${escape_html(seg.label)}</button>`);
|
|
36238
|
+
}
|
|
36239
|
+
$$renderer.push(`<!--]--></div>`);
|
|
36240
|
+
});
|
|
36241
|
+
}
|
|
36242
|
+
//#endregion
|
|
34532
36243
|
//#region src/lib/components/settings-skills/SettingsSkillsHeaderTabs.svelte
|
|
34533
36244
|
function SettingsSkillsHeaderTabs($$renderer, $$props) {
|
|
34534
36245
|
$$renderer.component(($$renderer) => {
|
|
34535
36246
|
/**
|
|
34536
|
-
* SettingsSkillsHeaderTabs — the shelf's
|
|
34537
|
-
* Chrome, D3): the joined-pill
|
|
34538
|
-
*
|
|
34539
|
-
*
|
|
34540
|
-
*
|
|
34541
|
-
* renders the two segments and reports picks.
|
|
36247
|
+
* SettingsSkillsHeaderTabs — the shelf's tab pill (The Shelf
|
|
36248
|
+
* Chrome, D3; Plugin Rack amendment IV 2026-10-31): the joined-pill
|
|
36249
|
+
* grammar now lives ONCE in the shared SegmentedTabs (Tailwind) —
|
|
36250
|
+
* this is a thin adapter speaking the shelf's native tab names.
|
|
36251
|
+
* Presentational: the panel owns the tab state.
|
|
34542
36252
|
*/
|
|
34543
|
-
let { tab = "install"} = $$props;
|
|
34544
|
-
$$renderer
|
|
36253
|
+
let { tab = "install", ontabchange } = $$props;
|
|
36254
|
+
SegmentedTabs($$renderer, {
|
|
36255
|
+
active: tab,
|
|
36256
|
+
groupTestid: "shelf-tab-group",
|
|
36257
|
+
ariaLabel: t(skillsshelftitle2),
|
|
36258
|
+
onchange: (id) => ontabchange?.(id === "uninstall" ? "uninstall" : "install"),
|
|
36259
|
+
tabs: [{
|
|
36260
|
+
id: "install",
|
|
36261
|
+
label: t(skillsshelftabinstall3),
|
|
36262
|
+
testid: "shelf-tab-install"
|
|
36263
|
+
}, {
|
|
36264
|
+
id: "uninstall",
|
|
36265
|
+
label: t(skillsshelftabuninstall3),
|
|
36266
|
+
testid: "shelf-tab-uninstall"
|
|
36267
|
+
}]
|
|
36268
|
+
});
|
|
34545
36269
|
});
|
|
34546
36270
|
}
|
|
34547
36271
|
//#endregion
|
|
@@ -34626,10 +36350,12 @@ function SettingsSkillsHeader($$renderer, $$props) {
|
|
|
34626
36350
|
* lineage-fold pill (cross-tab by contract, ADR D2). Presentational:
|
|
34627
36351
|
* every verb and all state are owned by SettingsSkillsPanel.
|
|
34628
36352
|
*/
|
|
34629
|
-
let { tab, reloadState, busy} = $$props;
|
|
36353
|
+
let { tab, ontabchange, reloadState, busy} = $$props;
|
|
34630
36354
|
$$renderer.push(`<div data-svelte="SettingsSkillsHeader" class="shelf-header svelte-17gmpcz" data-testid="shelf-header">`);
|
|
34631
36355
|
SettingsSkillsHeaderTabs($$renderer, {
|
|
34632
|
-
tab
|
|
36356
|
+
tab,
|
|
36357
|
+
ontabchange
|
|
36358
|
+
});
|
|
34633
36359
|
$$renderer.push(`<!----> `);
|
|
34634
36360
|
SettingsSkillsHeaderActions($$renderer, {
|
|
34635
36361
|
tab,
|
|
@@ -34678,6 +36404,7 @@ function SettingsSkillsPanel($$renderer, $$props) {
|
|
|
34678
36404
|
$$renderer.push(`<!----> `);
|
|
34679
36405
|
SettingsSkillsHeader($$renderer, {
|
|
34680
36406
|
tab,
|
|
36407
|
+
ontabchange: (v) => tab = v,
|
|
34681
36408
|
reloadState: reloadState(),
|
|
34682
36409
|
busy});
|
|
34683
36410
|
$$renderer.push(`<!----> `);
|
|
@@ -34701,13 +36428,28 @@ function PluginManagerHeaderTabs($$renderer, $$props) {
|
|
|
34701
36428
|
$$renderer.component(($$renderer) => {
|
|
34702
36429
|
/**
|
|
34703
36430
|
* PluginManagerHeaderTabs - the rack's install/uninstall tab pill
|
|
34704
|
-
* (The Plugin Rack ADR, 2026-09-27, D1
|
|
34705
|
-
* joined-pill
|
|
34706
|
-
*
|
|
34707
|
-
*
|
|
36431
|
+
* (The Plugin Rack ADR, 2026-09-27, D1; amendment IV 2026-10-31):
|
|
36432
|
+
* the joined-pill grammar now lives ONCE in the shared
|
|
36433
|
+
* SegmentedTabs (Tailwind) — this is a thin adapter speaking the
|
|
36434
|
+
* rack's native tab vocabulary and keeping the rack testids.
|
|
36435
|
+
* Presentational - tab state lives in PluginManagerPanel.
|
|
34708
36436
|
*/
|
|
34709
|
-
let { tab} = $$props;
|
|
34710
|
-
$$renderer
|
|
36437
|
+
let { tab, ontabchange } = $$props;
|
|
36438
|
+
SegmentedTabs($$renderer, {
|
|
36439
|
+
active: tab,
|
|
36440
|
+
groupTestid: "rack-tabs",
|
|
36441
|
+
ariaLabel: t(pluginracktitle2),
|
|
36442
|
+
onchange: (id) => ontabchange(id === "uninstall" ? "uninstall" : "install"),
|
|
36443
|
+
tabs: [{
|
|
36444
|
+
id: "install",
|
|
36445
|
+
label: t(pluginrackinstall2),
|
|
36446
|
+
testid: "rack-tab-install"
|
|
36447
|
+
}, {
|
|
36448
|
+
id: "uninstall",
|
|
36449
|
+
label: t(pluginrackuninstall2),
|
|
36450
|
+
testid: "rack-tab-uninstall"
|
|
36451
|
+
}]
|
|
36452
|
+
});
|
|
34711
36453
|
});
|
|
34712
36454
|
}
|
|
34713
36455
|
//#endregion
|
|
@@ -34764,10 +36506,12 @@ function PluginManagerHeader($$renderer, $$props) {
|
|
|
34764
36506
|
* Presentational: every verb and all state are owned by
|
|
34765
36507
|
* PluginManagerPanel.
|
|
34766
36508
|
*/
|
|
34767
|
-
let { tab, loading, floorBounce} = $$props;
|
|
36509
|
+
let { tab, ontabchange, loading, floorBounce} = $$props;
|
|
34768
36510
|
$$renderer.push(`<div data-svelte="PluginManagerHeader" class="rack-head svelte-1lc924" data-testid="rack-header">`);
|
|
34769
36511
|
PluginManagerHeaderTabs($$renderer, {
|
|
34770
|
-
tab
|
|
36512
|
+
tab,
|
|
36513
|
+
ontabchange
|
|
36514
|
+
});
|
|
34771
36515
|
$$renderer.push(`<!----> `);
|
|
34772
36516
|
PluginManagerHeaderActions($$renderer, {
|
|
34773
36517
|
loading,
|
|
@@ -34809,10 +36553,14 @@ function PluginManagerPanel($$renderer, $$props) {
|
|
|
34809
36553
|
/** Persisted chrome (the explorer-tab pattern): the active pill tab.
|
|
34810
36554
|
* Junk sanitizes to 'install'. */
|
|
34811
36555
|
/** Reports the active tab up to the panel entry (hard-reload survival). */
|
|
34812
|
-
let { initialTab = "install"} = $$props;
|
|
36556
|
+
let { initialTab = "install", ontabchange } = $$props;
|
|
34813
36557
|
let loading = true;
|
|
34814
36558
|
let floorBounce = false;
|
|
34815
36559
|
let tab = initialTab === "uninstall" ? "uninstall" : "install";
|
|
36560
|
+
function setTab(next) {
|
|
36561
|
+
tab = next;
|
|
36562
|
+
ontabchange?.(next);
|
|
36563
|
+
}
|
|
34816
36564
|
let searchQ = "";
|
|
34817
36565
|
let $$settled = true;
|
|
34818
36566
|
let $$inner_renderer;
|
|
@@ -34832,7 +36580,8 @@ function PluginManagerPanel($$renderer, $$props) {
|
|
|
34832
36580
|
PluginManagerHeader($$renderer, {
|
|
34833
36581
|
tab,
|
|
34834
36582
|
loading,
|
|
34835
|
-
floorBounce
|
|
36583
|
+
floorBounce,
|
|
36584
|
+
ontabchange: setTab});
|
|
34836
36585
|
$$renderer.push(`<!----> `);
|
|
34837
36586
|
{
|
|
34838
36587
|
$$renderer.push("<!--[1-->");
|
|
@@ -35034,12 +36783,23 @@ function InjectedDocPanel($$renderer, $$props) {
|
|
|
35034
36783
|
//#region src/lib/components/workspace-explorer/WorkspaceExplorerButtons.svelte
|
|
35035
36784
|
function WorkspaceExplorerButtons($$renderer, $$props) {
|
|
35036
36785
|
$$renderer.component(($$renderer) => {
|
|
35037
|
-
|
|
35038
|
-
|
|
36786
|
+
/**
|
|
36787
|
+
* WorkspaceExplorerButtons — the toolbar's action cluster, extracted
|
|
36788
|
+
* from WorkspaceExplorerToolbar (2026-09-13): Refresh and
|
|
36789
|
+
* Collapse-all. INTENT ONLY (Module
|
|
36790
|
+
* Communication Map): the buttons emit onRefresh / onCollapseAll —
|
|
36791
|
+
* the panel owns the state the intents act on.
|
|
36792
|
+
*/
|
|
36793
|
+
let { onRefresh} = $$props;
|
|
36794
|
+
$$renderer.push(`<div data-svelte="WorkspaceExplorerButtons" class="actions svelte-57vdun">`);
|
|
36795
|
+
ReloadButton($$renderer, {
|
|
36796
|
+
onclick: onRefresh,
|
|
36797
|
+
label: t(refresh),
|
|
36798
|
+
testid: "explorer-refresh",
|
|
35039
36799
|
size: 12,
|
|
35040
|
-
|
|
36800
|
+
class: "head-btn"
|
|
35041
36801
|
});
|
|
35042
|
-
$$renderer.push(
|
|
36802
|
+
$$renderer.push(`<!----> <button class="head-btn" data-testid="explorer-collapse-all"${attr("aria-label", t(collapseall1))}${attr("title", t(collapseall1))}>`);
|
|
35043
36803
|
Chevrons_down_up($$renderer, {
|
|
35044
36804
|
size: 12,
|
|
35045
36805
|
"aria-hidden": "true"
|
|
@@ -35051,9 +36811,10 @@ function WorkspaceExplorerButtons($$renderer, $$props) {
|
|
|
35051
36811
|
//#region src/lib/components/workspace-explorer/WorkspaceExplorerToolbar.svelte
|
|
35052
36812
|
function WorkspaceExplorerToolbar($$renderer, $$props) {
|
|
35053
36813
|
$$renderer.component(($$renderer) => {
|
|
35054
|
-
let { activeTab = "explorer"} = $$props;
|
|
36814
|
+
let { onRefresh, activeTab = "explorer"} = $$props;
|
|
35055
36815
|
$$renderer.push(`<div data-svelte="WorkspaceExplorerToolbar" class="explorer-toolbar svelte-wowz6p" data-testid="explorer-toolbar"><div class="tabs svelte-wowz6p" role="tablist" data-testid="explorer-tabs"><button role="tab"${attr_class("tab svelte-wowz6p", void 0, { "active": activeTab === "explorer" })}${attr("aria-selected", activeTab === "explorer")} data-testid="git-tab-explorer">${escape_html(t(giteyetabexplorer3))}</button> <button role="tab"${attr_class("tab svelte-wowz6p", void 0, { "active": activeTab === "changes" })}${attr("aria-selected", activeTab === "changes")} data-testid="git-tab-changes">${escape_html(t(giteyetabchanges3))}</button></div> `);
|
|
35056
|
-
WorkspaceExplorerButtons($$renderer
|
|
36816
|
+
WorkspaceExplorerButtons($$renderer, {
|
|
36817
|
+
onRefresh});
|
|
35057
36818
|
$$renderer.push(`<!----></div>`);
|
|
35058
36819
|
});
|
|
35059
36820
|
}
|
|
@@ -35072,8 +36833,6 @@ function WorkspaceExplorerTree($$renderer, $$props) {
|
|
|
35072
36833
|
* the levels cache, the fetches, and the git state — this component
|
|
35073
36834
|
* reads them as props and emits toggle / open-file intents back.
|
|
35074
36835
|
*/
|
|
35075
|
-
/** One listing row (workspaceFiles/list WorkspaceDirectoryEntry). */
|
|
35076
|
-
/** Viewing state for one fetched level (owner-held, never persisted). */
|
|
35077
36836
|
let { root, levels, expanded, repoMaps, changedPaths, changedDirs, activeFile = null } = $$props;
|
|
35078
36837
|
/** The row's child rel path (the listing's names are basenames). */
|
|
35079
36838
|
function childRel(rel, name) {
|
|
@@ -35294,9 +37053,10 @@ function WorkspaceExplorer($$renderer, $$props) {
|
|
|
35294
37053
|
* never scroll itself; the scroll lives on .tree-scroll so the toolbar
|
|
35295
37054
|
* stays pinned (the toolbar-scrolls-away bug).
|
|
35296
37055
|
*/
|
|
35297
|
-
let { root, activeTab, levels, expanded, repoMaps, changedPaths, changedDirs, activeFile = null, changesRepos, changesStatuses, collapsedRepos} = $$props;
|
|
37056
|
+
let { root, activeTab, onRefresh, levels, expanded, repoMaps, changedPaths, changedDirs, activeFile = null, changesRepos, changesStatuses, collapsedRepos} = $$props;
|
|
35298
37057
|
$$renderer.push(`<div data-svelte="WorkspaceExplorer" class="explorer svelte-td8lru">`);
|
|
35299
37058
|
WorkspaceExplorerToolbar($$renderer, {
|
|
37059
|
+
onRefresh,
|
|
35300
37060
|
activeTab});
|
|
35301
37061
|
$$renderer.push(`<!----> `);
|
|
35302
37062
|
if (activeTab === "changes") {
|
|
@@ -35330,14 +37090,137 @@ function WorkspaceExplorer($$renderer, $$props) {
|
|
|
35330
37090
|
function WorkspaceFileTabGroup($$renderer, $$props) {
|
|
35331
37091
|
$$renderer.component(($$renderer) => {
|
|
35332
37092
|
/**
|
|
35333
|
-
* WorkspaceFileTabGroup — the File Eye toggle (ADR D6
|
|
35334
|
-
*
|
|
35335
|
-
*
|
|
35336
|
-
*
|
|
35337
|
-
*
|
|
37093
|
+
* WorkspaceFileTabGroup — the File Eye toggle (ADR D6; Plugin Rack
|
|
37094
|
+
* amendment IV 2026-10-31): the joined-pill grammar now lives ONCE
|
|
37095
|
+
* in the shared SegmentedTabs (Tailwind) — a thin adapter speaking
|
|
37096
|
+
* the File Eye's edit/diff vocabulary and keeping the dirty-buffer
|
|
37097
|
+
* lock on the Diff segment (ADR D3). Presentational: the parent
|
|
37098
|
+
* owns the view state and the change intent.
|
|
37099
|
+
*/
|
|
37100
|
+
let { view = "edit", onviewchange } = $$props;
|
|
37101
|
+
SegmentedTabs($$renderer, {
|
|
37102
|
+
active: view,
|
|
37103
|
+
groupTestid: "file-view-toggle",
|
|
37104
|
+
ariaLabel: t(fileeyetogglelabel3),
|
|
37105
|
+
onchange: (id) => onviewchange?.(id === "diff" ? "diff" : "edit"),
|
|
37106
|
+
tabs: [{
|
|
37107
|
+
id: "edit",
|
|
37108
|
+
label: t(fileeyepreview2),
|
|
37109
|
+
testid: "file-view-edit"
|
|
37110
|
+
}, {
|
|
37111
|
+
id: "diff",
|
|
37112
|
+
label: t(fileeyediff2),
|
|
37113
|
+
testid: "file-view-diff"
|
|
37114
|
+
}]
|
|
37115
|
+
});
|
|
37116
|
+
});
|
|
37117
|
+
}
|
|
37118
|
+
//#endregion
|
|
37119
|
+
//#region src/lib/components/workspace-file/toolbar/PreviewTab.svelte
|
|
37120
|
+
function PreviewTab($$renderer, $$props) {
|
|
37121
|
+
$$renderer.component(($$renderer) => {
|
|
37122
|
+
/**
|
|
37123
|
+
* PreviewTab — the preview segment of the file toolbar's tab pair:
|
|
37124
|
+
* icon-only (Presentation glyph), the paraglide label rides
|
|
37125
|
+
* aria-label + title so the accessible name survives.
|
|
37126
|
+
*/
|
|
37127
|
+
let { active} = $$props;
|
|
37128
|
+
$$renderer.push(`<button data-svelte="PreviewTab" role="tab"${attr("aria-selected", active)} data-testid="tab-preview"${attr("aria-label", t(workspacefilepreview2))}${attr("title", t(workspacefilepreview2))}${attr_class("svelte-1f747f8", void 0, { "active": active })}>`);
|
|
37129
|
+
Presentation($$renderer, {
|
|
37130
|
+
size: 12,
|
|
37131
|
+
"aria-hidden": "true"
|
|
37132
|
+
});
|
|
37133
|
+
$$renderer.push(`<!----></button>`);
|
|
37134
|
+
});
|
|
37135
|
+
}
|
|
37136
|
+
//#endregion
|
|
37137
|
+
//#region src/lib/components/workspace-file/toolbar/EditTab.svelte
|
|
37138
|
+
function EditTab($$renderer, $$props) {
|
|
37139
|
+
$$renderer.component(($$renderer) => {
|
|
37140
|
+
/**
|
|
37141
|
+
* EditTab — the source segment of the file toolbar's tab pair:
|
|
37142
|
+
* icon-only (CodeXml glyph), the paraglide label rides
|
|
37143
|
+
* aria-label + title so the accessible name survives.
|
|
35338
37144
|
*/
|
|
35339
|
-
let {
|
|
35340
|
-
$$renderer.push(`<
|
|
37145
|
+
let { active} = $$props;
|
|
37146
|
+
$$renderer.push(`<button data-svelte="EditTab" role="tab"${attr("aria-selected", active)} data-testid="tab-edit"${attr("aria-label", t(workspacefilesource2))}${attr("title", t(workspacefilesource2))}${attr_class("svelte-z03alu", void 0, { "active": active })}>`);
|
|
37147
|
+
Code_xml($$renderer, {
|
|
37148
|
+
size: 12,
|
|
37149
|
+
"aria-hidden": "true"
|
|
37150
|
+
});
|
|
37151
|
+
$$renderer.push(`<!----></button>`);
|
|
37152
|
+
});
|
|
37153
|
+
}
|
|
37154
|
+
//#endregion
|
|
37155
|
+
//#region src/lib/components/workspace-file/toolbar/FileEdit.svelte
|
|
37156
|
+
function FileEdit($$renderer, $$props) {
|
|
37157
|
+
$$renderer.component(($$renderer) => {
|
|
37158
|
+
/**
|
|
37159
|
+
* FileEdit — The Single Edit (ADR D2/D6): the mode verb. Icon-only
|
|
37160
|
+
* (Pencil when idle, X while editing); the label rides aria-label +
|
|
37161
|
+
* title and flips Edit -> Cancel with the mode.
|
|
37162
|
+
*/
|
|
37163
|
+
let { editing = false} = $$props;
|
|
37164
|
+
$$renderer.push(`<button data-svelte="FileEdit" type="button" class="head-chip svelte-1nxrcih" data-testid="file-edit"${attr("aria-label", editing ? t(workspacefilecancel2) : t(workspacefileedit2))}${attr("title", editing ? t(workspacefilecancel2) : t(workspacefileedit2))}>`);
|
|
37165
|
+
if (editing) {
|
|
37166
|
+
$$renderer.push("<!--[0-->");
|
|
37167
|
+
Undo_dot($$renderer, {
|
|
37168
|
+
size: 12,
|
|
37169
|
+
"aria-hidden": "true"
|
|
37170
|
+
});
|
|
37171
|
+
} else {
|
|
37172
|
+
$$renderer.push("<!--[-1-->");
|
|
37173
|
+
Pencil($$renderer, {
|
|
37174
|
+
size: 12,
|
|
37175
|
+
"aria-hidden": "true"
|
|
37176
|
+
});
|
|
37177
|
+
}
|
|
37178
|
+
$$renderer.push(`<!--]--></button>`);
|
|
37179
|
+
});
|
|
37180
|
+
}
|
|
37181
|
+
//#endregion
|
|
37182
|
+
//#region src/lib/components/workspace-file/toolbar/FileSave.svelte
|
|
37183
|
+
function FileSave($$renderer, $$props) {
|
|
37184
|
+
$$renderer.component(($$renderer) => {
|
|
37185
|
+
/**
|
|
37186
|
+
* FileSave — The Single Edit (ADR D3): Save renders ONLY while a draft
|
|
37187
|
+
* exists (the owner gates the mount). Icon-only (Save glyph); disabled
|
|
37188
|
+
* while the delegated save is in flight.
|
|
37189
|
+
*/
|
|
37190
|
+
let { saving = false} = $$props;
|
|
37191
|
+
$$renderer.push(`<button data-svelte="FileSave" type="button" class="head-chip save-btn svelte-k5ua2k" data-testid="file-save"${attr("aria-label", saving ? t(workspacefilesaving2) : t(workspacefilesave2))}${attr("title", saving ? t(workspacefilesaving2) : t(workspacefilesave2))}${attr("disabled", saving, true)}>`);
|
|
37192
|
+
Save($$renderer, {
|
|
37193
|
+
size: 12,
|
|
37194
|
+
"aria-hidden": "true"
|
|
37195
|
+
});
|
|
37196
|
+
$$renderer.push(`<!----></button>`);
|
|
37197
|
+
});
|
|
37198
|
+
}
|
|
37199
|
+
//#endregion
|
|
37200
|
+
//#region src/lib/components/workspace-file/toolbar/HeadChip.svelte
|
|
37201
|
+
function HeadChip($$renderer, $$props) {
|
|
37202
|
+
$$renderer.component(($$renderer) => {
|
|
37203
|
+
/**
|
|
37204
|
+
* HeadChip — the workspace-explorer hide/show toggle (2026-10-31):
|
|
37205
|
+
* icon-only bordered chip; the glyph reflects the lane's visibility
|
|
37206
|
+
* and the paraglide label rides aria-label + title.
|
|
37207
|
+
*/
|
|
37208
|
+
let { hidden = false} = $$props;
|
|
37209
|
+
$$renderer.push(`<button data-svelte="HeadChip" type="button" class="head-chip svelte-1u072cb" data-testid="explorer-toggle"${attr("aria-label", hidden ? t(workspaceexplorershow2) : t(workspaceexplorerhide2))}${attr("title", hidden ? t(workspaceexplorershow2) : t(workspaceexplorerhide2))}>`);
|
|
37210
|
+
if (hidden) {
|
|
37211
|
+
$$renderer.push("<!--[0-->");
|
|
37212
|
+
Panel_left_open($$renderer, {
|
|
37213
|
+
size: 12,
|
|
37214
|
+
"aria-hidden": "true"
|
|
37215
|
+
});
|
|
37216
|
+
} else {
|
|
37217
|
+
$$renderer.push("<!--[-1-->");
|
|
37218
|
+
Panel_left_close($$renderer, {
|
|
37219
|
+
size: 12,
|
|
37220
|
+
"aria-hidden": "true"
|
|
37221
|
+
});
|
|
37222
|
+
}
|
|
37223
|
+
$$renderer.push(`<!--]--></button>`);
|
|
35341
37224
|
});
|
|
35342
37225
|
}
|
|
35343
37226
|
//#endregion
|
|
@@ -35348,19 +37231,49 @@ function WorkspaceFileToolbar($$renderer, $$props) {
|
|
|
35348
37231
|
* (idle → busy spinner → done check → idle), mirrored per the 2026-10-27
|
|
35349
37232
|
* UX-parity operator request: a click that shows nothing happening "sucks". */
|
|
35350
37233
|
let reloadState = "idle";
|
|
37234
|
+
async function handleReload() {
|
|
37235
|
+
if (reloadState === "busy" || !onreload) return;
|
|
37236
|
+
reloadState = "busy";
|
|
37237
|
+
try {
|
|
37238
|
+
await onreload();
|
|
37239
|
+
reloadState = "done";
|
|
37240
|
+
setTimeout(() => reloadState = "idle", 2e3);
|
|
37241
|
+
} catch {
|
|
37242
|
+
reloadState = "idle";
|
|
37243
|
+
}
|
|
37244
|
+
}
|
|
35351
37245
|
let columnEl = null;
|
|
35352
|
-
let { dirty, saveState = "idle", stale = false, staleNote = "", hasTabs = false, tab = "preview", view = "edit", showToggle = false,
|
|
37246
|
+
let { dirty, saveState = "idle", stale = false, staleNote = "", hasTabs = false, tab = "preview", view = "edit", showToggle = false, editing = false, ontoggledit, readonly = false, onviewchange, onsave, onreload, ontoggleexplorer, explorerHidden = false, path } = $$props;
|
|
35353
37247
|
$$renderer.push(`<div data-svelte="WorkspaceFileToolbar" class="file-toolbar svelte-1vsjf39" data-testid="file-toolbar"><span class="path svelte-1vsjf39"${attr("title", path)}>${escape_html(path)}</span> `);
|
|
35354
37248
|
if (showToggle) {
|
|
35355
37249
|
$$renderer.push("<!--[0-->");
|
|
35356
37250
|
WorkspaceFileTabGroup($$renderer, {
|
|
35357
37251
|
view,
|
|
35358
|
-
|
|
37252
|
+
onviewchange
|
|
37253
|
+
});
|
|
37254
|
+
} else $$renderer.push("<!--[-1-->");
|
|
37255
|
+
$$renderer.push(`<!--]--> `);
|
|
37256
|
+
if (hasTabs) {
|
|
37257
|
+
$$renderer.push("<!--[0-->");
|
|
37258
|
+
$$renderer.push(`<div class="tabs svelte-1vsjf39" role="tablist">`);
|
|
37259
|
+
PreviewTab($$renderer, {
|
|
37260
|
+
active: tab === "preview"});
|
|
37261
|
+
$$renderer.push(`<!----> `);
|
|
37262
|
+
EditTab($$renderer, {
|
|
37263
|
+
active: tab === "edit"});
|
|
37264
|
+
$$renderer.push(`<!----></div>`);
|
|
35359
37265
|
} else $$renderer.push("<!--[-1-->");
|
|
35360
37266
|
$$renderer.push(`<!--]--> `);
|
|
35361
37267
|
if (!readonly) {
|
|
35362
37268
|
$$renderer.push("<!--[0-->");
|
|
35363
|
-
$$renderer
|
|
37269
|
+
FileEdit($$renderer, {
|
|
37270
|
+
editing});
|
|
37271
|
+
} else $$renderer.push("<!--[-1-->");
|
|
37272
|
+
$$renderer.push(`<!--]--> `);
|
|
37273
|
+
if (!readonly && editing && dirty) {
|
|
37274
|
+
$$renderer.push("<!--[0-->");
|
|
37275
|
+
FileSave($$renderer, {
|
|
37276
|
+
saving: saveState === "saving"});
|
|
35364
37277
|
} else $$renderer.push("<!--[-1-->");
|
|
35365
37278
|
$$renderer.push(`<!--]--> `);
|
|
35366
37279
|
if (dirty) {
|
|
@@ -35378,17 +37291,21 @@ function WorkspaceFileToolbar($$renderer, $$props) {
|
|
|
35378
37291
|
$$renderer.push(`<span class="stale svelte-1vsjf39" data-testid="file-stale-external">${escape_html(staleNote)}</span>`);
|
|
35379
37292
|
} else $$renderer.push("<!--[-1-->");
|
|
35380
37293
|
$$renderer.push(`<!--]--> `);
|
|
35381
|
-
if (
|
|
37294
|
+
if (onreload) {
|
|
35382
37295
|
$$renderer.push("<!--[0-->");
|
|
35383
|
-
$$renderer
|
|
37296
|
+
ReloadButton($$renderer, {
|
|
37297
|
+
state: reloadState,
|
|
37298
|
+
onclick: handleReload,
|
|
37299
|
+
label: t(refresh),
|
|
37300
|
+
testid: "file-reload",
|
|
37301
|
+
class: "reload-btn"
|
|
37302
|
+
});
|
|
35384
37303
|
} else $$renderer.push("<!--[-1-->");
|
|
35385
37304
|
$$renderer.push(`<!--]--> `);
|
|
35386
|
-
if (
|
|
37305
|
+
if (ontoggleexplorer) {
|
|
35387
37306
|
$$renderer.push("<!--[0-->");
|
|
35388
|
-
$$renderer
|
|
35389
|
-
|
|
35390
|
-
Rotate_cw($$renderer, { size: 14 });
|
|
35391
|
-
$$renderer.push(`<!--]--></button>`);
|
|
37307
|
+
HeadChip($$renderer, {
|
|
37308
|
+
hidden: explorerHidden});
|
|
35392
37309
|
} else $$renderer.push("<!--[-1-->");
|
|
35393
37310
|
$$renderer.push(`<!--]--> <span class="copy-slot svelte-1vsjf39">`);
|
|
35394
37311
|
CanvasCopyButton($$renderer, {
|
|
@@ -35421,7 +37338,7 @@ function WorkspaceFile($$renderer, $$props) {
|
|
|
35421
37338
|
* old overflow:auto container made the hosts content-sized and the
|
|
35422
37339
|
* page-level scrollbar stole the height.
|
|
35423
37340
|
*/
|
|
35424
|
-
let { tab = void 0, dirty, fullPath, saveState, fileStale, staleNote, hasTabs, activeView, showToggle,
|
|
37341
|
+
let { tab = void 0, dirty, fullPath, saveState, fileStale, staleNote, hasTabs, activeView, showToggle, editing, onToggleEdit, readonly, onViewChange, onSave, onReload, onToggleExplorer, explorerHidden = false, saveError, saveFailedNote, loadingNote, loadFailedNote, truncatedNote, newFileNote, phase, errorCode, title, isImage, bytesSrc, isHtml, text, isMarkdown, noHead, eof, editorHost = null, diffHost = null } = $$props;
|
|
35425
37342
|
let $$settled = true;
|
|
35426
37343
|
let $$inner_renderer;
|
|
35427
37344
|
function $$render_inner($$renderer) {
|
|
@@ -35435,11 +37352,14 @@ function WorkspaceFile($$renderer, $$props) {
|
|
|
35435
37352
|
hasTabs,
|
|
35436
37353
|
view: activeView,
|
|
35437
37354
|
showToggle,
|
|
35438
|
-
|
|
37355
|
+
editing,
|
|
37356
|
+
ontoggledit: onToggleEdit,
|
|
35439
37357
|
readonly,
|
|
35440
37358
|
onviewchange: onViewChange,
|
|
35441
37359
|
onsave: onSave,
|
|
35442
37360
|
onreload: onReload,
|
|
37361
|
+
ontoggleexplorer: onToggleExplorer,
|
|
37362
|
+
explorerHidden,
|
|
35443
37363
|
get tab() {
|
|
35444
37364
|
return tab;
|
|
35445
37365
|
},
|
|
@@ -35528,7 +37448,7 @@ function WorkspaceFilePanel($$renderer, $$props) {
|
|
|
35528
37448
|
* outside-workspace, too-large, not-text, not-regular-file.
|
|
35529
37449
|
*/
|
|
35530
37450
|
/** The read receipt (api/dsh/workspace-file body, DshWorkspaceFileText). */
|
|
35531
|
-
let { sessionId, path, root, view = "edit", onviewchange, onclose, highlightLines = null, onhighlightdone } = $$props;
|
|
37451
|
+
let { sessionId, path, root, view = "edit", onviewchange, onclose, highlightLines = null, onhighlightdone, ontoggleexplorer, explorerHidden = false, ondirtychange } = $$props;
|
|
35532
37452
|
let viewOverride = null;
|
|
35533
37453
|
const activeView = derived(() => viewOverride ?? view);
|
|
35534
37454
|
let tab = "preview";
|
|
@@ -35538,6 +37458,22 @@ function WorkspaceFilePanel($$renderer, $$props) {
|
|
|
35538
37458
|
let eof = true;
|
|
35539
37459
|
/** Dirty = the edit buffer differs from the baseline. */
|
|
35540
37460
|
let dirty = false;
|
|
37461
|
+
/** Clear-scope surfacing (ADR D5c amendment 2026-11-03): the explorer
|
|
37462
|
+
* panel keeps a per-path dirty map so its tab strip can tint dirty
|
|
37463
|
+
* tabs and resolve Clear non-dirty. Optional — standalone file
|
|
37464
|
+
* panels pass no listener and lose nothing. */
|
|
37465
|
+
/** The Single Edit (ADR D2): the operator-facing edit mode — the raw
|
|
37466
|
+
* editor mounts writable only while this is true. Cancel reverts the
|
|
37467
|
+
* buffer to the baseline. */
|
|
37468
|
+
let editing = false;
|
|
37469
|
+
/** Edit-mode intent: entering carries the live buffer; Cancel (D2)
|
|
37470
|
+
* reverts to baseline and clears dirty. */
|
|
37471
|
+
function setEditing(next) {
|
|
37472
|
+
if (next === editing) return;
|
|
37473
|
+
if (!next) dirty = false;
|
|
37474
|
+
editing = next;
|
|
37475
|
+
if (next && isMarkdown() && tab !== "edit") tab = "edit";
|
|
37476
|
+
}
|
|
35541
37477
|
/** The delegated save's progress (ADR D4): idle → saving → saved /
|
|
35542
37478
|
* failed; a further edit re-arms the button from any state. */
|
|
35543
37479
|
let saveState = "idle";
|
|
@@ -35615,11 +37551,14 @@ function WorkspaceFilePanel($$renderer, $$props) {
|
|
|
35615
37551
|
hasTabs: hasTabs(),
|
|
35616
37552
|
activeView: activeView(),
|
|
35617
37553
|
showToggle: false,
|
|
35618
|
-
|
|
37554
|
+
editing,
|
|
37555
|
+
onToggleEdit: setEditing,
|
|
35619
37556
|
readonly: false,
|
|
35620
37557
|
onViewChange: setView,
|
|
35621
37558
|
onSave: save,
|
|
35622
37559
|
onReload: refreshFile,
|
|
37560
|
+
onToggleExplorer: ontoggleexplorer,
|
|
37561
|
+
explorerHidden,
|
|
35623
37562
|
saveError,
|
|
35624
37563
|
saveFailedNote: t(workspacefilesavefailed3),
|
|
35625
37564
|
loadingNote: t(workspaceexplorerloading2),
|
|
@@ -35745,30 +37684,44 @@ function WorkspaceFileTabs($$renderer, $$props) {
|
|
|
35745
37684
|
* PRESENTATION ONLY (Module Communication Map): the open-tab list, the
|
|
35746
37685
|
* active path, and every fetch arrive as PROPS from the owning
|
|
35747
37686
|
* WorkspaceExplorerPanel; the only things leaving are INTENT callbacks
|
|
35748
|
-
* — onActivate (focus an open tab), onClose (the per-tab [x])
|
|
35749
|
-
*
|
|
35750
|
-
*
|
|
37687
|
+
* — onActivate (focus an open tab), onClose (the per-tab [x]), and
|
|
37688
|
+
* onClearAll (the sticky clear's blanket confirm, ADR D5c amendment
|
|
37689
|
+
* 2026-11-03). The content region is the parent's children snippet, so
|
|
37690
|
+
* the panel hosts WorkspaceFile itself and this component never fetches.
|
|
35751
37691
|
*
|
|
35752
37692
|
* A closed panel drops the tabs with it (D5) — nothing here persists.
|
|
35753
37693
|
*/
|
|
35754
37694
|
/** One open file tab — the panel's component state, deduped by path. */
|
|
35755
37695
|
/** Root-relative path — identity within the panel's tab list. */
|
|
35756
|
-
|
|
37696
|
+
/** Unsaved edit-buffer flag — the panel computes it from its
|
|
37697
|
+
* baseline (ADR D5d amendment 2026-11-03); drives the tint. */
|
|
37698
|
+
let { tabs, activePath, onClearAll, children } = $$props;
|
|
35757
37699
|
/** Tab label — the leaf name; the full root-relative path rides the
|
|
35758
37700
|
* title attribute (ADR D5). */
|
|
35759
37701
|
function leaf(path) {
|
|
35760
37702
|
const idx = path.lastIndexOf("/");
|
|
35761
37703
|
return idx === -1 ? path : path.slice(idx + 1);
|
|
35762
37704
|
}
|
|
37705
|
+
let clearOpen = false;
|
|
35763
37706
|
$$renderer.push(`<div data-svelte="WorkspaceFileTabs" class="file-tabs svelte-1xheh2q" data-testid="workspace-file-tabs">`);
|
|
35764
37707
|
if (tabs.length > 0) {
|
|
35765
37708
|
$$renderer.push("<!--[0-->");
|
|
35766
|
-
$$renderer.push(`<div class="strip svelte-1xheh2q" role="tablist" data-testid="workspace-file-tabstrip"><!--[-->`);
|
|
37709
|
+
$$renderer.push(`<div class="strip-row svelte-1xheh2q"><div class="strip svelte-1xheh2q" role="tablist" data-testid="workspace-file-tabstrip"><!--[-->`);
|
|
35767
37710
|
const each_array = ensure_array_like(tabs);
|
|
35768
37711
|
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
35769
37712
|
let tab = each_array[$$index];
|
|
35770
|
-
$$renderer.push(`<button type="button" role="tab"${attr_class("tab svelte-1xheh2q", void 0, {
|
|
37713
|
+
$$renderer.push(`<button type="button" role="tab"${attr_class("tab svelte-1xheh2q", void 0, {
|
|
37714
|
+
"active": tab.path === activePath,
|
|
37715
|
+
"dirty": tab.dirty === true
|
|
37716
|
+
})}${attr("data-testid", `workspace-file-tab-${stringify(tab.path)}`)}${attr("title", tab.path)}${attr("aria-selected", tab.path === activePath)}><span class="label svelte-1xheh2q">${escape_html(leaf(tab.path))}</span> <span role="button" tabindex="-1" class="close svelte-1xheh2q"${attr("data-testid", `workspace-file-tabclose-${stringify(tab.path)}`)}${attr("aria-label", t(close))}${attr("title", t(close))}>×</span></button>`);
|
|
35771
37717
|
}
|
|
37718
|
+
$$renderer.push(`<!--]--></div> `);
|
|
37719
|
+
if (onClearAll) {
|
|
37720
|
+
$$renderer.push("<!--[0-->");
|
|
37721
|
+
$$renderer.push(`<div class="clear-slot svelte-1xheh2q" data-testid="workspace-file-tabstrip-clear-slot"><button type="button" class="clear-btn svelte-1xheh2q" data-testid="workspace-file-tabstrip-clear"${attr("aria-label", t(workspacefiletabsclear3))}${attr("title", t(workspacefiletabsclear3))}${attr("aria-expanded", clearOpen)}>×</button> `);
|
|
37722
|
+
$$renderer.push("<!--[-1-->");
|
|
37723
|
+
$$renderer.push(`<!--]--></div>`);
|
|
37724
|
+
} else $$renderer.push("<!--[-1-->");
|
|
35772
37725
|
$$renderer.push(`<!--]--></div> <div class="body svelte-1xheh2q">`);
|
|
35773
37726
|
children($$renderer);
|
|
35774
37727
|
$$renderer.push(`<!----></div>`);
|
|
@@ -35811,7 +37764,7 @@ function ResizeGutter($$renderer, $$props) {
|
|
|
35811
37764
|
//#region src/lib/components/workspace-explorer/WorkspaceExplorerPanel.svelte
|
|
35812
37765
|
function WorkspaceExplorerPanel($$renderer, $$props) {
|
|
35813
37766
|
$$renderer.component(($$renderer) => {
|
|
35814
|
-
let { sessionId, root, home, expanded, onToggle, onOpenFile, onCollapseAll, tab = "explorer", onTabChange, collapsedRepos, onToggleRepo, onCollapseAllRepos, treePct = 30, onTreePctChange, pendingOpenFile = null, onPendingOpenConsumed, openTabs = [], activeFile = null, onOpenTab, onCloseTab, onActivateTab } = $$props;
|
|
37767
|
+
let { sessionId, root, home, expanded, onToggle, onOpenFile, onCollapseAll, tab = "explorer", onTabChange, collapsedRepos, onToggleRepo, onCollapseAllRepos, treePct = 30, onTreePctChange, pendingOpenFile = null, onPendingOpenConsumed, openTabs = [], activeFile = null, onOpenTab, onCloseTab, onActivateTab, ontoggleexplorer, explorerHidden = false } = $$props;
|
|
35815
37768
|
/** Rel path → level state. Key '' is the root level. */
|
|
35816
37769
|
let levels = {};
|
|
35817
37770
|
let repoMaps = {};
|
|
@@ -35853,6 +37806,19 @@ function WorkspaceExplorerPanel($$renderer, $$props) {
|
|
|
35853
37806
|
}
|
|
35854
37807
|
return out;
|
|
35855
37808
|
});
|
|
37809
|
+
/** Refresh intent: drop the whole levels cache — the effect re-fetches
|
|
37810
|
+
* the root level and every still-expanded path once each. */
|
|
37811
|
+
function refresh() {
|
|
37812
|
+
levels = {};
|
|
37813
|
+
invalidateGit();
|
|
37814
|
+
}
|
|
37815
|
+
/** The git caches ONLY (Index Pulse W3): the tree structure did not
|
|
37816
|
+
* change, so the levels cache survives — the probes and status fetches
|
|
37817
|
+
* re-run through the same guarded effects as a full Refresh. */
|
|
37818
|
+
function invalidateGit() {
|
|
37819
|
+
repoMaps = {};
|
|
37820
|
+
changesStatuses = {};
|
|
37821
|
+
}
|
|
35856
37822
|
let pulseSource = null;
|
|
35857
37823
|
function closePulse() {
|
|
35858
37824
|
pulseSource?.close();
|
|
@@ -35866,28 +37832,47 @@ function WorkspaceExplorerPanel($$renderer, $$props) {
|
|
|
35866
37832
|
/** The rendered tree lane: the settled px, or the narrow-lane default
|
|
35867
37833
|
* before the first measurement. Percent lives only in treePct. */
|
|
35868
37834
|
const treeBasis = derived(() => 280);
|
|
35869
|
-
|
|
35870
|
-
|
|
35871
|
-
|
|
35872
|
-
|
|
35873
|
-
|
|
35874
|
-
|
|
35875
|
-
|
|
35876
|
-
|
|
35877
|
-
|
|
35878
|
-
|
|
35879
|
-
|
|
35880
|
-
|
|
35881
|
-
|
|
35882
|
-
|
|
35883
|
-
|
|
35884
|
-
|
|
35885
|
-
|
|
35886
|
-
|
|
35887
|
-
|
|
37835
|
+
/** Hide/show (2026-10-31): a hidden lane collapses the basis to zero —
|
|
37836
|
+
* the tree and the gutter unmount, the file region takes the width. */
|
|
37837
|
+
const laneBasis = derived(() => explorerHidden ? 0 : treeBasis());
|
|
37838
|
+
let dirtyMap = {};
|
|
37839
|
+
$$renderer.push(`<div data-svelte="WorkspaceExplorerPanel" data-testid="workspace-explorer" class="split svelte-ldghfc"${attr_style(`--tree-basis: ${stringify(laneBasis())}px`)}>`);
|
|
37840
|
+
if (!explorerHidden) {
|
|
37841
|
+
$$renderer.push("<!--[0-->");
|
|
37842
|
+
WorkspaceExplorer($$renderer, {
|
|
37843
|
+
activeFile,
|
|
37844
|
+
root,
|
|
37845
|
+
activeTab: activeTab(),
|
|
37846
|
+
onRefresh: refresh,
|
|
37847
|
+
levels,
|
|
37848
|
+
expanded,
|
|
37849
|
+
repoMaps,
|
|
37850
|
+
changedPaths: changedPaths(),
|
|
37851
|
+
changedDirs: changedDirs(),
|
|
37852
|
+
changesRepos: changesRepos(),
|
|
37853
|
+
changesStatuses,
|
|
37854
|
+
collapsedRepos});
|
|
37855
|
+
$$renderer.push(`<!----> `);
|
|
37856
|
+
ResizeGutter($$renderer, {
|
|
37857
|
+
index: 0,
|
|
37858
|
+
onDragStart: startSplitDrag
|
|
37859
|
+
});
|
|
37860
|
+
$$renderer.push(`<!---->`);
|
|
37861
|
+
} else $$renderer.push("<!--[-1-->");
|
|
37862
|
+
$$renderer.push(`<!--]--> `);
|
|
35888
37863
|
WorkspaceFileTabs($$renderer, {
|
|
35889
|
-
tabs: openTabs.map((p) => ({
|
|
37864
|
+
tabs: openTabs.map((p) => ({
|
|
37865
|
+
path: p,
|
|
37866
|
+
dirty: dirtyMap[p] === true
|
|
37867
|
+
})),
|
|
35890
37868
|
activePath: activeFile,
|
|
37869
|
+
onClearAll: (scope) => {
|
|
37870
|
+
const doomed = scope === "all" ? [...openTabs] : openTabs.filter((p) => dirtyMap[p] !== true);
|
|
37871
|
+
for (const path of doomed) {
|
|
37872
|
+
onCloseTab?.(path);
|
|
37873
|
+
delete dirtyMap[path];
|
|
37874
|
+
}
|
|
37875
|
+
},
|
|
35891
37876
|
children: ($$renderer) => {
|
|
35892
37877
|
if (activeFile !== null) {
|
|
35893
37878
|
$$renderer.push("<!--[0-->");
|
|
@@ -35905,7 +37890,12 @@ function WorkspaceExplorerPanel($$renderer, $$props) {
|
|
|
35905
37890
|
root,
|
|
35906
37891
|
highlightLines: lineTarget,
|
|
35907
37892
|
onhighlightdone: () => lineTarget = null,
|
|
35908
|
-
onclose: () => {}
|
|
37893
|
+
onclose: () => {},
|
|
37894
|
+
ontoggleexplorer,
|
|
37895
|
+
explorerHidden,
|
|
37896
|
+
ondirtychange: (d) => {
|
|
37897
|
+
dirtyMap[activeFile] = d;
|
|
37898
|
+
}
|
|
35909
37899
|
});
|
|
35910
37900
|
} else $$renderer.push("<!--[-1-->");
|
|
35911
37901
|
$$renderer.push(`<!--]-->`);
|
|
@@ -36065,7 +38055,10 @@ function PanelColumn($$renderer, $$props) {
|
|
|
36065
38055
|
$$renderer.push(`<!----> `);
|
|
36066
38056
|
if (widthBadge !== null) {
|
|
36067
38057
|
$$renderer.push("<!--[0-->");
|
|
36068
|
-
$$renderer
|
|
38058
|
+
WidthBadge($$renderer, {
|
|
38059
|
+
phase: widthBadge,
|
|
38060
|
+
width: panel.width
|
|
38061
|
+
});
|
|
36069
38062
|
} else $$renderer.push("<!--[-1-->");
|
|
36070
38063
|
$$renderer.push(`<!--]--> <div class="body svelte-1cuodug">`);
|
|
36071
38064
|
children($$renderer);
|
|
@@ -36379,6 +38372,7 @@ function _page($$renderer, $$props) {
|
|
|
36379
38372
|
const fromQuery = page.url.searchParams.get("sessionKey");
|
|
36380
38373
|
return fromQuery !== null && fromQuery.length > 0 ? fromQuery : null;
|
|
36381
38374
|
}
|
|
38375
|
+
captureHarnessSessionKey(seedSessionId());
|
|
36382
38376
|
const seededInitially = seedSessionId() !== null;
|
|
36383
38377
|
const seedCold = seedColdOf(page.data);
|
|
36384
38378
|
pagePrefs.init(activeProfile);
|
|
@@ -36394,6 +38388,7 @@ function _page($$renderer, $$props) {
|
|
|
36394
38388
|
getPanelWidth: () => pagePrefs.panelWidth,
|
|
36395
38389
|
setPanelWidthPreset: (w) => pagePrefs.panelWidth = w,
|
|
36396
38390
|
setTreePct: (pct) => pagePrefs.treePct = pct,
|
|
38391
|
+
setExplorerHidden: (hidden) => pagePrefs.explorerHidden = hidden,
|
|
36397
38392
|
getSettingsHomes: () => appConfig().settingsHomes,
|
|
36398
38393
|
applyTerminalDeskAction: (a) => void 0,
|
|
36399
38394
|
releaseGlasses: (ids) => void releaseGlasses(ids)
|
|
@@ -36401,22 +38396,35 @@ function _page($$renderer, $$props) {
|
|
|
36401
38396
|
initFloor(seededInitially ? [makePanel(seedSessionId(), seedCold?.agentPreset ?? null)] : initialPrefs.panels, seededInitially ? null : initialPrefs.selectedPanelId);
|
|
36402
38397
|
if (seededInitially) selectPanel(floor.panels[0]?.id ?? null);
|
|
36403
38398
|
if (seededInitially && seedCold !== void 0) pageFeeds.primeSeed(seedSessionId(), seedCold);
|
|
38399
|
+
let restoringGlasses = false;
|
|
36404
38400
|
async function restoreBrowserGlasses() {
|
|
38401
|
+
if (restoringGlasses) return;
|
|
38402
|
+
restoringGlasses = true;
|
|
36405
38403
|
try {
|
|
36406
38404
|
if (floor.panels.some((panel) => panel.kind === "browser")) return;
|
|
36407
38405
|
const res = await fetch("/api/browser");
|
|
36408
38406
|
if (!res.ok) return;
|
|
36409
38407
|
const body = await res.json();
|
|
38408
|
+
const ownSessions = new Set(floor.panels.filter((p) => p.kind === "conversation").map((p) => p.sessionId));
|
|
38409
|
+
const pageKey = harnessSessionKey();
|
|
38410
|
+
if (pageKey) ownSessions.add(pageKey);
|
|
36410
38411
|
const live = new Set((body.sessions ?? []).map((s) => s.id));
|
|
38412
|
+
const ownerOf = new Map((body.sessions ?? []).map((s) => [s.id, s.ownerSessionId ?? null]));
|
|
38413
|
+
const mine = (id) => {
|
|
38414
|
+
const owner = ownerOf.get(id);
|
|
38415
|
+
return owner == null || ownSessions.has(owner);
|
|
38416
|
+
};
|
|
36411
38417
|
const slots = readBrowserSlots();
|
|
36412
|
-
const dead = slots.filter((s) => s.sessionId && !live.has(s.sessionId));
|
|
38418
|
+
const dead = slots.filter((s) => s.sessionId && (!live.has(s.sessionId) || !mine(s.sessionId)));
|
|
36413
38419
|
if (dead.length > 0) persistBrowserSlots(slots.filter((s) => !dead.includes(s)));
|
|
36414
38420
|
for (const slot of slots) {
|
|
36415
38421
|
if (slot.folded) continue;
|
|
36416
|
-
if (!slot.sessionId || !live.has(slot.sessionId)) continue;
|
|
38422
|
+
if (!slot.sessionId || !live.has(slot.sessionId) || !mine(slot.sessionId)) continue;
|
|
36417
38423
|
summonGlass(slot);
|
|
36418
38424
|
}
|
|
36419
|
-
} catch {}
|
|
38425
|
+
} catch {} finally {
|
|
38426
|
+
restoringGlasses = false;
|
|
38427
|
+
}
|
|
36420
38428
|
}
|
|
36421
38429
|
/** Bring ONE folded glass back (the summon; the replace verb is the
|
|
36422
38430
|
* same re-bind — the glass owns its slot identity, D4). keepSelection:
|
|
@@ -36467,6 +38475,22 @@ function _page($$renderer, $$props) {
|
|
|
36467
38475
|
function startSidebarResize(e) {
|
|
36468
38476
|
e.preventDefault();
|
|
36469
38477
|
e.clientX, pagePrefs.sidebarWidth;
|
|
38478
|
+
pagePrefs.cancelSidebarAfterglow();
|
|
38479
|
+
}
|
|
38480
|
+
let chord = IDLE_CHORD;
|
|
38481
|
+
function subagentConversationCount() {
|
|
38482
|
+
const subagents = floorSeam().getLineageFacts().subagentIds;
|
|
38483
|
+
return floor.panels.filter((p) => p.kind === "conversation" && subagents.has(p.sessionId)).length;
|
|
38484
|
+
}
|
|
38485
|
+
function chordPaletteRows() {
|
|
38486
|
+
const kinds = [...new Set(floor.panels.map((p) => p.kind))];
|
|
38487
|
+
const selected = floor.panels.find((p) => p.id === floor.selectedPanelId);
|
|
38488
|
+
return chordOptions({
|
|
38489
|
+
presets: appConfig().panel.presets,
|
|
38490
|
+
panelKinds: kinds,
|
|
38491
|
+
subagentCount: subagentConversationCount(),
|
|
38492
|
+
focusedConversation: selected?.kind === "conversation"
|
|
38493
|
+
});
|
|
36470
38494
|
}
|
|
36471
38495
|
function sidebarRail($$renderer) {
|
|
36472
38496
|
AppSidebar($$renderer, {
|
|
@@ -36504,7 +38528,9 @@ function _page($$renderer, $$props) {
|
|
|
36504
38528
|
$$renderer.push(`<div class="panel-manager-body svelte-1uha8ag" data-testid="panel-terminal">`);
|
|
36505
38529
|
TerminalDesk($$renderer, {
|
|
36506
38530
|
restored: panel.desk ?? null,
|
|
36507
|
-
onMirror: (m) =>
|
|
38531
|
+
onMirror: (m) => {
|
|
38532
|
+
terminalDeskMirrors[panel.id] = m;
|
|
38533
|
+
},
|
|
36508
38534
|
onShellExit: () => removePanel(panel.id)
|
|
36509
38535
|
});
|
|
36510
38536
|
$$renderer.push(`<!----></div>`);
|
|
@@ -36541,7 +38567,9 @@ function _page($$renderer, $$props) {
|
|
|
36541
38567
|
$$renderer.push(`<div class="panel-manager-body svelte-1uha8ag" data-testid="panel-plugins">`);
|
|
36542
38568
|
PluginManagerPanel($$renderer, {
|
|
36543
38569
|
refreshToken: panel.refresh ?? 0,
|
|
36544
|
-
initialTab: panel.tab ?? "install"
|
|
38570
|
+
initialTab: panel.tab ?? "install",
|
|
38571
|
+
ontabchange: (v) => setRackTab(panel.id, v)
|
|
38572
|
+
});
|
|
36545
38573
|
$$renderer.push(`<!----></div>`);
|
|
36546
38574
|
} else if (panel.kind === "skill-shelf") {
|
|
36547
38575
|
$$renderer.push("<!--[5-->");
|
|
@@ -36582,6 +38610,8 @@ function _page($$renderer, $$props) {
|
|
|
36582
38610
|
onCollapseAllRepos: (repos) => collapseExplorerRepos(panel.id, repos),
|
|
36583
38611
|
treePct: pagePrefs.treePct,
|
|
36584
38612
|
onTreePctChange: (pct) => setExplorerTreePct(panel.id, pct),
|
|
38613
|
+
explorerHidden: pagePrefs.explorerHidden,
|
|
38614
|
+
ontoggleexplorer: () => setExplorerHidden(panel.id, !pagePrefs.explorerHidden),
|
|
36585
38615
|
pendingOpenFile: pendingFileIntents()[panel.id] ?? null,
|
|
36586
38616
|
onPendingOpenConsumed: (nonce) => consumeFileIntent(panel.id, nonce),
|
|
36587
38617
|
openTabs: panel.openTabs ?? [],
|
|
@@ -36684,7 +38714,10 @@ function _page($$renderer, $$props) {
|
|
|
36684
38714
|
$$renderer.push(`<title>Workspace — deepseek-insight</title>`);
|
|
36685
38715
|
});
|
|
36686
38716
|
});
|
|
36687
|
-
$$renderer
|
|
38717
|
+
ChordPalette($$renderer, {
|
|
38718
|
+
open: chord.armed,
|
|
38719
|
+
rows: chordPaletteRows()});
|
|
38720
|
+
$$renderer.push(`<!----> <div data-svelte="ConversationPage" class="flex h-dvh conversation-page svelte-1uha8ag">`);
|
|
36688
38721
|
if (!sidebarInZoom()) {
|
|
36689
38722
|
$$renderer.push("<!--[0-->");
|
|
36690
38723
|
sidebarRail($$renderer);
|
|
@@ -36753,4 +38786,4 @@ function _page($$renderer, $$props) {
|
|
|
36753
38786
|
}
|
|
36754
38787
|
|
|
36755
38788
|
export { _page as default };
|
|
36756
|
-
//# sourceMappingURL=_page.svelte.js-
|
|
38789
|
+
//# sourceMappingURL=_page.svelte.js-DQWBiRk1.js.map
|