@deepseek-insight/dsi 0.8.3 → 0.8.5
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/SKILL.md +143 -0
- package/build/client/_app/immutable/assets/0.C6AGVUc8.css +2 -0
- package/build/client/_app/immutable/assets/{2.BPprd30B.css → 2.gXzZuuwh.css} +1 -1
- package/build/client/_app/immutable/chunks/BFOY8uwF.js +1 -0
- package/build/client/_app/immutable/chunks/CrTRqozz.js +1 -0
- package/build/client/_app/immutable/chunks/DxGYLnDH.js +1 -0
- package/build/client/_app/immutable/chunks/HD-mJtOS.js +6 -0
- package/build/client/_app/immutable/chunks/{BoHeiMOU.js → b4-Ro8NH.js} +1 -1
- package/build/client/_app/immutable/chunks/hC0DBYN6.js +2 -0
- package/build/client/_app/immutable/entry/{app.S_mxIoOg.js → app.DHewwbUQ.js} +2 -2
- package/build/client/_app/immutable/entry/start.C0PcwkeZ.js +1 -0
- package/build/client/_app/immutable/nodes/{0.6dTmg1Xv.js → 0.CP10wY64.js} +1 -1
- package/build/client/_app/immutable/nodes/{1.D20V6eTe.js → 1.qWvE0DiU.js} +1 -1
- package/build/client/_app/immutable/nodes/{2.BHcBdFqH.js → 2.Nw7iFtoh.js} +224 -223
- package/build/client/_app/version.json +1 -1
- package/build/handler.js +4 -4
- package/build/index.js +4 -4
- package/build/server/chunks/chunks/{app-config.svelte.js-BM4WbMFB.js → app-config.svelte.js-DCc9d7A4.js} +6 -2
- package/build/server/chunks/chunks/{config.js-vThvQeMn.js → config.js-s6iKwHD7.js} +3 -2
- package/build/server/chunks/chunks/{db.js-DQm6CZ_r.js → db.js-CxxWK5sn.js} +2 -2
- package/build/server/chunks/chunks/{db2.js-DUhFxA3a.js → db2.js-DwJ9lySe.js} +2 -2
- package/build/server/chunks/chunks/{dsh-connection.js-BgeraFA2.js → dsh-connection.js-Chtudg1p.js} +3 -3
- package/build/server/chunks/chunks/{dsh-events.js-BUkLR6ZV.js → dsh-events.js-BUdvZQmd.js} +6 -3
- package/build/server/chunks/chunks/{git-probe.js-CLF37SRh.js → git-probe.js-BX9FPnet.js} +3 -3
- package/build/server/chunks/chunks/{insight-config.js-Dp_2gB5J.js → insight-config.js-Db5fe5Df.js} +9 -5
- package/build/server/chunks/chunks/{internal2.js-Ba5p8uFM.js → internal2.js-CaZaz-a9.js} +3 -3
- package/build/server/chunks/chunks/ledger-stats.js-BWACyDPg.js +72 -0
- package/build/server/chunks/chunks/{registry.js-C2MdrfNv.js → registry.js-syaTZ_-A.js} +403 -34
- package/build/server/chunks/chunks/{settings-document.js-Gw1puaik.js → settings-document.js-BHESJ7im.js} +2 -2
- package/build/server/chunks/chunks/{state.js-BSiAgink.js → state.js-oYjf745s.js} +3 -3
- package/build/server/chunks/chunks/{watcher.js-BVKnoQUw.js → watcher.js-Ci9jsM5l.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-BjzdVwdY.js → _server.ts.js-CHaYhzjy.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-3kQCQuHT.js → _server.ts.js-CdyqA85c.js} +8 -8
- package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-BUBTCLFn.js → _server.ts.js-DO_FS5b4.js} +8 -8
- package/build/server/chunks/entries/endpoints/api/browser/_id_/activate/{_server.ts.js-CogDOHKu.js → _server.ts.js-D7Be4JUf.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/close/{_server.ts.js-xOt7LnS1.js → _server.ts.js-CGkm2H-U.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/closetab/{_server.ts.js-CSmVPvSM.js → _server.ts.js-D7SLUfOo.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/element/{_server.ts.js-BA40oCDW.js → _server.ts.js-C3d_JV-q.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/input/{_server.ts.js-EX7eVzjp.js → _server.ts.js-DW0hyVML.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/mcp/{_server.ts.js-B_EcmyFt.js → _server.ts.js-Ev-hdBlf.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/navigate/{_server.ts.js-C3dYbyS3.js → _server.ts.js-DZ8-wocV.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/opentab/{_server.ts.js-CMhJJO25.js → _server.ts.js-aapPrIQK.js} +11 -9
- package/build/server/chunks/entries/endpoints/api/browser/_id_/page/{_server.ts.js-DIW4uI2S.js → _server.ts.js-DANA_hMd.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/stream/{_server.ts.js-CIPIlq5X.js → _server.ts.js-BqfseXFy.js} +26 -9
- package/build/server/chunks/entries/endpoints/api/browser/_id_/tabs/{_server.ts.js-CoEdOiml.js → _server.ts.js-DFFF9qe-.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/viewport/{_server.ts.js-CdELUoGT.js → _server.ts.js-ek6-D4Zm.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/browser/{_server.ts.js-ea6HpNGh.js → _server.ts.js-CPjKy3ma.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-C8XDnDwe.js → _server.ts.js-CWE9NP6g.js} +12 -5
- package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-BFmWshpv.js → _server.ts.js-D-raYQon.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/{_server.ts.js-DATWy5mQ.js → _server.ts.js-CI4dEHFY.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/follow/{_server.ts.js-CugOD1Zd.js → _server.ts.js-cnjoSLtY.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-DCupM4da.js → _server.ts.js-0UUtapX5.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-Bh1btvr9.js → _server.ts.js-MK5ezU8u.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/{_server.ts.js-Cb8SBWVw.js → _server.ts.js-CEiMgzjC.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-WI9yH2iG.js → _server.ts.js-wGEl1fuF.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-bN9adUqz.js → _server.ts.js-Bz7u2BlD.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/changes/{_server.ts.js-Bxlm966G.js → _server.ts.js-yue5aEjr.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-CM-raN_Q.js → _server.ts.js-BFSs5T2m.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-BzP30TXW.js → _server.ts.js-C2i85wQy.js} +7 -70
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-DvNkrTaY.js → _server.ts.js-_toO4f4W.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-DXbCrefw.js → _server.ts.js-BGJnDV85.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-B7YRQhuJ.js → _server.ts.js-CQCJg8U8.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-C_AEaLLJ.js → _server.ts.js-0ADvdE79.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-Dj-pF5ik.js → _server.ts.js-DyO4T1Ro.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-BX9FWJ6g.js → _server.ts.js-CIY7oimw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-CQ2Bmtu4.js → _server.ts.js-B-9faNHX.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-Ha7xjnKW.js → _server.ts.js-E7-0zfiH.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-BOg6llHk.js → _server.ts.js-CODtLQ3Q.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-DBqGALzZ.js → _server.ts.js-BiSxsU-j.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-CvA8WDDb.js → _server.ts.js-C0WJnv2b.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/subagents/_server.ts.js-D5bc4xg4.js +72 -0
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-BfjNH40j.js → _server.ts.js-23ycAyUg.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-De_qumyr.js → _server.ts.js-B4w5Jh7f.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-tFpJJHCb.js → _server.ts.js-VQLxDbFE.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-DVx5GGA_.js → _server.ts.js-vs5N5Cya.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-DuKT-aZp.js → _server.ts.js-BOWhoBHV.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-DsWFidFY.js → _server.ts.js-aDEAGfJe.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-C6j0adQs.js → _server.ts.js-BZ-nRrTp.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/prompts/use/{_server.ts.js-BChAg4hm.js → _server.ts.js-CkDY1PQ7.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-BPSHqbZN.js → _server.ts.js-CHvgF47Y.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/terminal/{_server.ts.js-D5CbUe5k.js → _server.ts.js-CbRT4vBo.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-B-5YihUA.js → _server.ts.js-BwD0KaXy.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-DT5jRZFE.js → _server.ts.js-DgbMRh3d.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-DtW-utrd.js → _server.ts.js-DRqZawic.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-8AIAo9jX.js → _server.ts.js-CTXwwwB1.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-CMw96vjY.js → _server.ts.js-B4aJBY2w.js} +7 -7
- package/build/server/chunks/entries/endpoints/api/workspace/write-gate/{_server.ts.js-DKufa14_.js → _server.ts.js-CDJJA18L.js} +7 -7
- package/build/server/chunks/entries/{hooks.server.js-B-e4_ekh.js → hooks.server.js-Iel6oE7w.js} +3 -3
- package/build/server/chunks/entries/pages/{_error.svelte.js-D8-G0evO.js → _error.svelte.js-B-wdFjVG.js} +4 -4
- package/build/server/chunks/entries/pages/{_page.server.ts.js-7x6ZfGoB.js → _page.server.ts.js-CaoeQzem.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.svelte.js-7xWLRsiZ.js → _page.svelte.js-CY7zcWr4.js} +1713 -1077
- package/build/server/chunks/{handler-BedQ0jP-.js → handler-DYk4NJto.js} +3 -3
- package/build/server/chunks/{index.js-BF6tPPQs.js → index.js-kL9MZ99b.js} +2 -2
- package/build/server/chunks/{manifest.js-3c0p7QAl.js → manifest.js-BrMLQqec.js} +67 -60
- package/build/server/chunks/nodes/{0.js-B3i7sGR_.js → 0.js-BembYTTr.js} +3 -3
- package/build/server/chunks/nodes/1.js-CKJjyWGZ.js +9 -0
- package/build/server/chunks/nodes/{2.js-CgnRGwm6.js → 2.js-BezA2RPm.js} +10 -10
- package/package.json +1 -1
- package/skills/{dsi-kb-scenario → dsi-fc-scenario}/SKILL.md +11 -6
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/template/.dsi/settings.yaml +2 -2
- package/build/client/_app/immutable/assets/0.DyOAkKS-.css +0 -2
- package/build/client/_app/immutable/chunks/C9QAOGL1.js +0 -2
- package/build/client/_app/immutable/chunks/D-Rolhzs.js +0 -1
- package/build/client/_app/immutable/chunks/NcOjFWr3.js +0 -6
- package/build/client/_app/immutable/chunks/QJuSx3RG.js +0 -1
- package/build/client/_app/immutable/chunks/sC_8Ss7w.js +0 -1
- package/build/client/_app/immutable/entry/start.BPQAB3iV.js +0 -1
- package/build/server/chunks/nodes/1.js-eUf50uxI.js +0 -9
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { a as __exportAll, o as onDestroy } from '../../chunks/index-server.js-DmIEbDVz.js';
|
|
2
2
|
import '../../chunks/exports.js-DH_tjtdv.js';
|
|
3
3
|
import { M as derived, V as head, T as writable, W as escape_html, X as attr, Y as bind_props, a as setContext, Z as attr_class, _ as attr_style, $ as store_get, a0 as spread_props, a1 as stringify, a2 as attributes, a3 as clsx, a4 as ensure_array_like, a5 as element, g as getContext, a6 as unsubscribe_stores, a7 as html, r as run, a8 as props_id } from '../../chunks/server.js-B1bDXhHu.js';
|
|
4
|
-
import { U as UI_LOCALES } from '../../chunks/config.js-
|
|
4
|
+
import { U as UI_LOCALES } from '../../chunks/config.js-s6iKwHD7.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-DCc9d7A4.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-oYjf745s.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-CaZaz-a9.js';
|
|
25
25
|
import '../../chunks/utils.js-CAdNO8Tu.js';
|
|
26
26
|
|
|
27
27
|
//#region src/lib/paraglide/messages/abort.js
|
|
@@ -984,6 +984,166 @@ var browserclosedelete2 = ((inputs = {}, options = {}) => {
|
|
|
984
984
|
return en_browserclosedelete2();
|
|
985
985
|
});
|
|
986
986
|
//#endregion
|
|
987
|
+
//#region src/lib/paraglide/messages/browserctxcopyimage3.js
|
|
988
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
989
|
+
/** @typedef {{}} Browserctxcopyimage3Inputs */
|
|
990
|
+
var en_browserctxcopyimage3 = () => {
|
|
991
|
+
return `Copy image address`;
|
|
992
|
+
};
|
|
993
|
+
var zh_browserctxcopyimage3 = () => {
|
|
994
|
+
return `复制图片地址`;
|
|
995
|
+
};
|
|
996
|
+
var id_browserctxcopyimage3 = () => {
|
|
997
|
+
return `Salin alamat gambar`;
|
|
998
|
+
};
|
|
999
|
+
var es_browserctxcopyimage3 = () => {
|
|
1000
|
+
return `Copiar la dirección de la imagen`;
|
|
1001
|
+
};
|
|
1002
|
+
/**
|
|
1003
|
+
* | output |
|
|
1004
|
+
* | --- |
|
|
1005
|
+
* | "Copy image address" |
|
|
1006
|
+
*
|
|
1007
|
+
* @param {Browserctxcopyimage3Inputs} inputs
|
|
1008
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1009
|
+
* @returns {LocalizedString}
|
|
1010
|
+
*/
|
|
1011
|
+
var browserctxcopyimage3 = ((inputs = {}, options = {}) => {
|
|
1012
|
+
const locale = options.locale ?? getLocale();
|
|
1013
|
+
if (locale === "zh") return zh_browserctxcopyimage3();
|
|
1014
|
+
if (locale === "id") return id_browserctxcopyimage3();
|
|
1015
|
+
if (locale === "es") return es_browserctxcopyimage3();
|
|
1016
|
+
return en_browserctxcopyimage3();
|
|
1017
|
+
});
|
|
1018
|
+
//#endregion
|
|
1019
|
+
//#region src/lib/paraglide/messages/browserctxcopylink3.js
|
|
1020
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1021
|
+
/** @typedef {{}} Browserctxcopylink3Inputs */
|
|
1022
|
+
var en_browserctxcopylink3 = () => {
|
|
1023
|
+
return `Copy link address`;
|
|
1024
|
+
};
|
|
1025
|
+
var zh_browserctxcopylink3 = () => {
|
|
1026
|
+
return `复制链接地址`;
|
|
1027
|
+
};
|
|
1028
|
+
var id_browserctxcopylink3 = () => {
|
|
1029
|
+
return `Salin alamat tautan`;
|
|
1030
|
+
};
|
|
1031
|
+
var es_browserctxcopylink3 = () => {
|
|
1032
|
+
return `Copiar la dirección del enlace`;
|
|
1033
|
+
};
|
|
1034
|
+
/**
|
|
1035
|
+
* | output |
|
|
1036
|
+
* | --- |
|
|
1037
|
+
* | "Copy link address" |
|
|
1038
|
+
*
|
|
1039
|
+
* @param {Browserctxcopylink3Inputs} inputs
|
|
1040
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1041
|
+
* @returns {LocalizedString}
|
|
1042
|
+
*/
|
|
1043
|
+
var browserctxcopylink3 = ((inputs = {}, options = {}) => {
|
|
1044
|
+
const locale = options.locale ?? getLocale();
|
|
1045
|
+
if (locale === "zh") return zh_browserctxcopylink3();
|
|
1046
|
+
if (locale === "id") return id_browserctxcopylink3();
|
|
1047
|
+
if (locale === "es") return es_browserctxcopylink3();
|
|
1048
|
+
return en_browserctxcopylink3();
|
|
1049
|
+
});
|
|
1050
|
+
//#endregion
|
|
1051
|
+
//#region src/lib/paraglide/messages/browserctxopenimage3.js
|
|
1052
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1053
|
+
/** @typedef {{}} Browserctxopenimage3Inputs */
|
|
1054
|
+
var en_browserctxopenimage3 = () => {
|
|
1055
|
+
return `Open image in new tab`;
|
|
1056
|
+
};
|
|
1057
|
+
var zh_browserctxopenimage3 = () => {
|
|
1058
|
+
return `在新标签页中打开图片`;
|
|
1059
|
+
};
|
|
1060
|
+
var id_browserctxopenimage3 = () => {
|
|
1061
|
+
return `Buka gambar di tab baru`;
|
|
1062
|
+
};
|
|
1063
|
+
var es_browserctxopenimage3 = () => {
|
|
1064
|
+
return `Abrir imagen en una pestaña nueva`;
|
|
1065
|
+
};
|
|
1066
|
+
/**
|
|
1067
|
+
* | output |
|
|
1068
|
+
* | --- |
|
|
1069
|
+
* | "Open image in new tab" |
|
|
1070
|
+
*
|
|
1071
|
+
* @param {Browserctxopenimage3Inputs} inputs
|
|
1072
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1073
|
+
* @returns {LocalizedString}
|
|
1074
|
+
*/
|
|
1075
|
+
var browserctxopenimage3 = ((inputs = {}, options = {}) => {
|
|
1076
|
+
const locale = options.locale ?? getLocale();
|
|
1077
|
+
if (locale === "zh") return zh_browserctxopenimage3();
|
|
1078
|
+
if (locale === "id") return id_browserctxopenimage3();
|
|
1079
|
+
if (locale === "es") return es_browserctxopenimage3();
|
|
1080
|
+
return en_browserctxopenimage3();
|
|
1081
|
+
});
|
|
1082
|
+
//#endregion
|
|
1083
|
+
//#region src/lib/paraglide/messages/browserctxopenlink3.js
|
|
1084
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1085
|
+
/** @typedef {{}} Browserctxopenlink3Inputs */
|
|
1086
|
+
var en_browserctxopenlink3 = () => {
|
|
1087
|
+
return `Open link in new tab`;
|
|
1088
|
+
};
|
|
1089
|
+
var zh_browserctxopenlink3 = () => {
|
|
1090
|
+
return `在新标签页中打开链接`;
|
|
1091
|
+
};
|
|
1092
|
+
var id_browserctxopenlink3 = () => {
|
|
1093
|
+
return `Buka tautan di tab baru`;
|
|
1094
|
+
};
|
|
1095
|
+
var es_browserctxopenlink3 = () => {
|
|
1096
|
+
return `Abrir enlace en una pestaña nueva`;
|
|
1097
|
+
};
|
|
1098
|
+
/**
|
|
1099
|
+
* | output |
|
|
1100
|
+
* | --- |
|
|
1101
|
+
* | "Open link in new tab" |
|
|
1102
|
+
*
|
|
1103
|
+
* @param {Browserctxopenlink3Inputs} inputs
|
|
1104
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1105
|
+
* @returns {LocalizedString}
|
|
1106
|
+
*/
|
|
1107
|
+
var browserctxopenlink3 = ((inputs = {}, options = {}) => {
|
|
1108
|
+
const locale = options.locale ?? getLocale();
|
|
1109
|
+
if (locale === "zh") return zh_browserctxopenlink3();
|
|
1110
|
+
if (locale === "id") return id_browserctxopenlink3();
|
|
1111
|
+
if (locale === "es") return es_browserctxopenlink3();
|
|
1112
|
+
return en_browserctxopenlink3();
|
|
1113
|
+
});
|
|
1114
|
+
//#endregion
|
|
1115
|
+
//#region src/lib/paraglide/messages/browserctxsendrightclick4.js
|
|
1116
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1117
|
+
/** @typedef {{}} Browserctxsendrightclick4Inputs */
|
|
1118
|
+
var en_browserctxsendrightclick4 = () => {
|
|
1119
|
+
return `Send right-click to the page`;
|
|
1120
|
+
};
|
|
1121
|
+
var zh_browserctxsendrightclick4 = () => {
|
|
1122
|
+
return `向页面发送右键点击`;
|
|
1123
|
+
};
|
|
1124
|
+
var id_browserctxsendrightclick4 = () => {
|
|
1125
|
+
return `Kirim klik kanan ke halaman`;
|
|
1126
|
+
};
|
|
1127
|
+
var es_browserctxsendrightclick4 = () => {
|
|
1128
|
+
return `Enviar clic derecho a la página`;
|
|
1129
|
+
};
|
|
1130
|
+
/**
|
|
1131
|
+
* | output |
|
|
1132
|
+
* | --- |
|
|
1133
|
+
* | "Send right-click to the page" |
|
|
1134
|
+
*
|
|
1135
|
+
* @param {Browserctxsendrightclick4Inputs} inputs
|
|
1136
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1137
|
+
* @returns {LocalizedString}
|
|
1138
|
+
*/
|
|
1139
|
+
var browserctxsendrightclick4 = ((inputs = {}, options = {}) => {
|
|
1140
|
+
const locale = options.locale ?? getLocale();
|
|
1141
|
+
if (locale === "zh") return zh_browserctxsendrightclick4();
|
|
1142
|
+
if (locale === "id") return id_browserctxsendrightclick4();
|
|
1143
|
+
if (locale === "es") return es_browserctxsendrightclick4();
|
|
1144
|
+
return en_browserctxsendrightclick4();
|
|
1145
|
+
});
|
|
1146
|
+
//#endregion
|
|
987
1147
|
//#region src/lib/paraglide/messages/browserforward1.js
|
|
988
1148
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
989
1149
|
/** @typedef {{}} Browserforward1Inputs */
|
|
@@ -1048,6 +1208,38 @@ var browserlaunching1 = ((inputs = {}, options = {}) => {
|
|
|
1048
1208
|
return en_browserlaunching1();
|
|
1049
1209
|
});
|
|
1050
1210
|
//#endregion
|
|
1211
|
+
//#region src/lib/paraglide/messages/browsernewtab2.js
|
|
1212
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1213
|
+
/** @typedef {{}} Browsernewtab2Inputs */
|
|
1214
|
+
var en_browsernewtab2 = () => {
|
|
1215
|
+
return `New tab`;
|
|
1216
|
+
};
|
|
1217
|
+
var zh_browsernewtab2 = () => {
|
|
1218
|
+
return `新标签页`;
|
|
1219
|
+
};
|
|
1220
|
+
var id_browsernewtab2 = () => {
|
|
1221
|
+
return `Tab baru`;
|
|
1222
|
+
};
|
|
1223
|
+
var es_browsernewtab2 = () => {
|
|
1224
|
+
return `Nueva pestaña`;
|
|
1225
|
+
};
|
|
1226
|
+
/**
|
|
1227
|
+
* | output |
|
|
1228
|
+
* | --- |
|
|
1229
|
+
* | "New tab" |
|
|
1230
|
+
*
|
|
1231
|
+
* @param {Browsernewtab2Inputs} inputs
|
|
1232
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1233
|
+
* @returns {LocalizedString}
|
|
1234
|
+
*/
|
|
1235
|
+
var browsernewtab2 = ((inputs = {}, options = {}) => {
|
|
1236
|
+
const locale = options.locale ?? getLocale();
|
|
1237
|
+
if (locale === "zh") return zh_browsernewtab2();
|
|
1238
|
+
if (locale === "id") return id_browsernewtab2();
|
|
1239
|
+
if (locale === "es") return es_browsernewtab2();
|
|
1240
|
+
return en_browsernewtab2();
|
|
1241
|
+
});
|
|
1242
|
+
//#endregion
|
|
1051
1243
|
//#region src/lib/paraglide/messages/browseropentitle2.js
|
|
1052
1244
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1053
1245
|
/** @typedef {{}} Browseropentitle2Inputs */
|
|
@@ -1176,6 +1368,38 @@ var browsersessionfailed2 = ((inputs, options = {}) => {
|
|
|
1176
1368
|
return en_browsersessionfailed2(inputs);
|
|
1177
1369
|
});
|
|
1178
1370
|
//#endregion
|
|
1371
|
+
//#region src/lib/paraglide/messages/browsertabclosetitle3.js
|
|
1372
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1373
|
+
/** @typedef {{}} Browsertabclosetitle3Inputs */
|
|
1374
|
+
var en_browsertabclosetitle3 = () => {
|
|
1375
|
+
return `Close tab`;
|
|
1376
|
+
};
|
|
1377
|
+
var zh_browsertabclosetitle3 = () => {
|
|
1378
|
+
return `关闭标签页`;
|
|
1379
|
+
};
|
|
1380
|
+
var id_browsertabclosetitle3 = () => {
|
|
1381
|
+
return `Tutup tab`;
|
|
1382
|
+
};
|
|
1383
|
+
var es_browsertabclosetitle3 = () => {
|
|
1384
|
+
return `Cerrar pestaña`;
|
|
1385
|
+
};
|
|
1386
|
+
/**
|
|
1387
|
+
* | output |
|
|
1388
|
+
* | --- |
|
|
1389
|
+
* | "Close tab" |
|
|
1390
|
+
*
|
|
1391
|
+
* @param {Browsertabclosetitle3Inputs} inputs
|
|
1392
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
1393
|
+
* @returns {LocalizedString}
|
|
1394
|
+
*/
|
|
1395
|
+
var browsertabclosetitle3 = ((inputs = {}, options = {}) => {
|
|
1396
|
+
const locale = options.locale ?? getLocale();
|
|
1397
|
+
if (locale === "zh") return zh_browsertabclosetitle3();
|
|
1398
|
+
if (locale === "id") return id_browsertabclosetitle3();
|
|
1399
|
+
if (locale === "es") return es_browsertabclosetitle3();
|
|
1400
|
+
return en_browsertabclosetitle3();
|
|
1401
|
+
});
|
|
1402
|
+
//#endregion
|
|
1179
1403
|
//#region src/lib/paraglide/messages/browserurlplaceholder2.js
|
|
1180
1404
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
1181
1405
|
/** @typedef {{}} Browserurlplaceholder2Inputs */
|
|
@@ -12376,6 +12600,70 @@ var streaming = ((inputs = {}, options = {}) => {
|
|
|
12376
12600
|
return en_streaming();
|
|
12377
12601
|
});
|
|
12378
12602
|
//#endregion
|
|
12603
|
+
//#region src/lib/paraglide/messages/subagentanchorlabel2.js
|
|
12604
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
12605
|
+
/** @typedef {{}} Subagentanchorlabel2Inputs */
|
|
12606
|
+
var en_subagentanchorlabel2 = () => {
|
|
12607
|
+
return `Subagents`;
|
|
12608
|
+
};
|
|
12609
|
+
var zh_subagentanchorlabel2 = () => {
|
|
12610
|
+
return `子代理`;
|
|
12611
|
+
};
|
|
12612
|
+
var id_subagentanchorlabel2 = () => {
|
|
12613
|
+
return `Subagen`;
|
|
12614
|
+
};
|
|
12615
|
+
var es_subagentanchorlabel2 = () => {
|
|
12616
|
+
return `Subagentes`;
|
|
12617
|
+
};
|
|
12618
|
+
/**
|
|
12619
|
+
* | output |
|
|
12620
|
+
* | --- |
|
|
12621
|
+
* | "Subagents" |
|
|
12622
|
+
*
|
|
12623
|
+
* @param {Subagentanchorlabel2Inputs} inputs
|
|
12624
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
12625
|
+
* @returns {LocalizedString}
|
|
12626
|
+
*/
|
|
12627
|
+
var subagentanchorlabel2 = ((inputs = {}, options = {}) => {
|
|
12628
|
+
const locale = options.locale ?? getLocale();
|
|
12629
|
+
if (locale === "zh") return zh_subagentanchorlabel2();
|
|
12630
|
+
if (locale === "id") return id_subagentanchorlabel2();
|
|
12631
|
+
if (locale === "es") return es_subagentanchorlabel2();
|
|
12632
|
+
return en_subagentanchorlabel2();
|
|
12633
|
+
});
|
|
12634
|
+
//#endregion
|
|
12635
|
+
//#region src/lib/paraglide/messages/subagentcloseallpanels3.js
|
|
12636
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
12637
|
+
/** @typedef {{}} Subagentcloseallpanels3Inputs */
|
|
12638
|
+
var en_subagentcloseallpanels3 = () => {
|
|
12639
|
+
return `del panel(s)`;
|
|
12640
|
+
};
|
|
12641
|
+
var zh_subagentcloseallpanels3 = () => {
|
|
12642
|
+
return `删除面板`;
|
|
12643
|
+
};
|
|
12644
|
+
var id_subagentcloseallpanels3 = () => {
|
|
12645
|
+
return `hapus panel`;
|
|
12646
|
+
};
|
|
12647
|
+
var es_subagentcloseallpanels3 = () => {
|
|
12648
|
+
return `eliminar panel(es)`;
|
|
12649
|
+
};
|
|
12650
|
+
/**
|
|
12651
|
+
* | output |
|
|
12652
|
+
* | --- |
|
|
12653
|
+
* | "del panel(s)" |
|
|
12654
|
+
*
|
|
12655
|
+
* @param {Subagentcloseallpanels3Inputs} inputs
|
|
12656
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
12657
|
+
* @returns {LocalizedString}
|
|
12658
|
+
*/
|
|
12659
|
+
var subagentcloseallpanels3 = ((inputs = {}, options = {}) => {
|
|
12660
|
+
const locale = options.locale ?? getLocale();
|
|
12661
|
+
if (locale === "zh") return zh_subagentcloseallpanels3();
|
|
12662
|
+
if (locale === "id") return id_subagentcloseallpanels3();
|
|
12663
|
+
if (locale === "es") return es_subagentcloseallpanels3();
|
|
12664
|
+
return en_subagentcloseallpanels3();
|
|
12665
|
+
});
|
|
12666
|
+
//#endregion
|
|
12379
12667
|
//#region src/lib/paraglide/messages/subagentmany1.js
|
|
12380
12668
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
12381
12669
|
/** @typedef {{ n: NonNullable<unknown> }} Subagentmany1Inputs */
|
|
@@ -13496,6 +13784,38 @@ var tooltitlewrite2 = ((inputs = {}, options = {}) => {
|
|
|
13496
13784
|
return en_tooltitlewrite2();
|
|
13497
13785
|
});
|
|
13498
13786
|
//#endregion
|
|
13787
|
+
//#region src/lib/paraglide/messages/totaltokens1.js
|
|
13788
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13789
|
+
/** @typedef {{}} Totaltokens1Inputs */
|
|
13790
|
+
var en_totaltokens1 = () => {
|
|
13791
|
+
return `Total tokens`;
|
|
13792
|
+
};
|
|
13793
|
+
var zh_totaltokens1 = () => {
|
|
13794
|
+
return `总 Token 数`;
|
|
13795
|
+
};
|
|
13796
|
+
var id_totaltokens1 = () => {
|
|
13797
|
+
return `Total token`;
|
|
13798
|
+
};
|
|
13799
|
+
var es_totaltokens1 = () => {
|
|
13800
|
+
return `Tokens totales`;
|
|
13801
|
+
};
|
|
13802
|
+
/**
|
|
13803
|
+
* | output |
|
|
13804
|
+
* | --- |
|
|
13805
|
+
* | "Total tokens" |
|
|
13806
|
+
*
|
|
13807
|
+
* @param {Totaltokens1Inputs} inputs
|
|
13808
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
13809
|
+
* @returns {LocalizedString}
|
|
13810
|
+
*/
|
|
13811
|
+
var totaltokens1 = ((inputs = {}, options = {}) => {
|
|
13812
|
+
const locale = options.locale ?? getLocale();
|
|
13813
|
+
if (locale === "zh") return zh_totaltokens1();
|
|
13814
|
+
if (locale === "id") return id_totaltokens1();
|
|
13815
|
+
if (locale === "es") return es_totaltokens1();
|
|
13816
|
+
return en_totaltokens1();
|
|
13817
|
+
});
|
|
13818
|
+
//#endregion
|
|
13499
13819
|
//#region src/lib/paraglide/messages/turnfailed1.js
|
|
13500
13820
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
13501
13821
|
/** @typedef {{}} Turnfailed1Inputs */
|
|
@@ -14873,12 +15193,19 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
14873
15193
|
browserBack: () => browserback1,
|
|
14874
15194
|
browserChipLabel: () => browserchiplabel2,
|
|
14875
15195
|
browserCloseDelete: () => browserclosedelete2,
|
|
15196
|
+
browserCtxCopyImage: () => browserctxcopyimage3,
|
|
15197
|
+
browserCtxCopyLink: () => browserctxcopylink3,
|
|
15198
|
+
browserCtxOpenImage: () => browserctxopenimage3,
|
|
15199
|
+
browserCtxOpenLink: () => browserctxopenlink3,
|
|
15200
|
+
browserCtxSendRightClick: () => browserctxsendrightclick4,
|
|
14876
15201
|
browserForward: () => browserforward1,
|
|
14877
15202
|
browserLaunching: () => browserlaunching1,
|
|
15203
|
+
browserNewTab: () => browsernewtab2,
|
|
14878
15204
|
browserOpenTitle: () => browseropentitle2,
|
|
14879
15205
|
browserPanelTitle: () => browserpaneltitle2,
|
|
14880
15206
|
browserReload: () => browserreload1,
|
|
14881
15207
|
browserSessionFailed: () => browsersessionfailed2,
|
|
15208
|
+
browserTabCloseTitle: () => browsertabclosetitle3,
|
|
14882
15209
|
browserUrlPlaceholder: () => browserurlplaceholder2,
|
|
14883
15210
|
browserWaitingFrames: () => browserwaitingframes2,
|
|
14884
15211
|
cacheHit: () => cachehit1,
|
|
@@ -15232,6 +15559,8 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15232
15559
|
stop: () => stop,
|
|
15233
15560
|
stopStreaming: () => stopstreaming1,
|
|
15234
15561
|
streaming: () => streaming,
|
|
15562
|
+
subagentAnchorLabel: () => subagentanchorlabel2,
|
|
15563
|
+
subagentCloseAllPanels: () => subagentcloseallpanels3,
|
|
15235
15564
|
subagentMany: () => subagentmany1,
|
|
15236
15565
|
subagentOne: () => subagentone1,
|
|
15237
15566
|
subagentTitleOwns: () => subagenttitleowns2,
|
|
@@ -15267,6 +15596,7 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
15267
15596
|
toolTitleSearch: () => tooltitlesearch2,
|
|
15268
15597
|
toolTitleToolCall: () => tooltitletoolcall3,
|
|
15269
15598
|
toolTitleWrite: () => tooltitlewrite2,
|
|
15599
|
+
totalTokens: () => totaltokens1,
|
|
15270
15600
|
turnFailed: () => turnfailed1,
|
|
15271
15601
|
turnInFlight: () => turninflight2,
|
|
15272
15602
|
turnStopped: () => turnstopped1,
|
|
@@ -15345,12 +15675,19 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15345
15675
|
browserBack: () => browserback1,
|
|
15346
15676
|
browserChipLabel: () => browserchiplabel2,
|
|
15347
15677
|
browserCloseDelete: () => browserclosedelete2,
|
|
15678
|
+
browserCtxCopyImage: () => browserctxcopyimage3,
|
|
15679
|
+
browserCtxCopyLink: () => browserctxcopylink3,
|
|
15680
|
+
browserCtxOpenImage: () => browserctxopenimage3,
|
|
15681
|
+
browserCtxOpenLink: () => browserctxopenlink3,
|
|
15682
|
+
browserCtxSendRightClick: () => browserctxsendrightclick4,
|
|
15348
15683
|
browserForward: () => browserforward1,
|
|
15349
15684
|
browserLaunching: () => browserlaunching1,
|
|
15685
|
+
browserNewTab: () => browsernewtab2,
|
|
15350
15686
|
browserOpenTitle: () => browseropentitle2,
|
|
15351
15687
|
browserPanelTitle: () => browserpaneltitle2,
|
|
15352
15688
|
browserReload: () => browserreload1,
|
|
15353
15689
|
browserSessionFailed: () => browsersessionfailed2,
|
|
15690
|
+
browserTabCloseTitle: () => browsertabclosetitle3,
|
|
15354
15691
|
browserUrlPlaceholder: () => browserurlplaceholder2,
|
|
15355
15692
|
browserWaitingFrames: () => browserwaitingframes2,
|
|
15356
15693
|
cacheHit: () => cachehit1,
|
|
@@ -15705,6 +16042,8 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15705
16042
|
stop: () => stop,
|
|
15706
16043
|
stopStreaming: () => stopstreaming1,
|
|
15707
16044
|
streaming: () => streaming,
|
|
16045
|
+
subagentAnchorLabel: () => subagentanchorlabel2,
|
|
16046
|
+
subagentCloseAllPanels: () => subagentcloseallpanels3,
|
|
15708
16047
|
subagentMany: () => subagentmany1,
|
|
15709
16048
|
subagentOne: () => subagentone1,
|
|
15710
16049
|
subagentTitleOwns: () => subagenttitleowns2,
|
|
@@ -15740,6 +16079,7 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15740
16079
|
toolTitleSearch: () => tooltitlesearch2,
|
|
15741
16080
|
toolTitleToolCall: () => tooltitletoolcall3,
|
|
15742
16081
|
toolTitleWrite: () => tooltitlewrite2,
|
|
16082
|
+
totalTokens: () => totaltokens1,
|
|
15743
16083
|
turnFailed: () => turnfailed1,
|
|
15744
16084
|
turnInFlight: () => turninflight2,
|
|
15745
16085
|
turnStopped: () => turnstopped1,
|
|
@@ -16552,6 +16892,22 @@ function Target($$renderer, $$props) {
|
|
|
16552
16892
|
]));
|
|
16553
16893
|
}
|
|
16554
16894
|
//#endregion
|
|
16895
|
+
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/trash-2.svelte
|
|
16896
|
+
function Trash_2($$renderer, $$props) {
|
|
16897
|
+
let { $$slots, $$events, ...props } = $$props;
|
|
16898
|
+
Icon($$renderer, spread_props([
|
|
16899
|
+
{ name: "trash-2" },
|
|
16900
|
+
props,
|
|
16901
|
+
{ iconNode: [
|
|
16902
|
+
["path", { "d": "M10 11v6" }],
|
|
16903
|
+
["path", { "d": "M14 11v6" }],
|
|
16904
|
+
["path", { "d": "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }],
|
|
16905
|
+
["path", { "d": "M3 6h18" }],
|
|
16906
|
+
["path", { "d": "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }]
|
|
16907
|
+
] }
|
|
16908
|
+
]));
|
|
16909
|
+
}
|
|
16910
|
+
//#endregion
|
|
16555
16911
|
//#region node_modules/.pnpm/@lucide+svelte@1.35.0_svelte@5.56.10/node_modules/@lucide/svelte/dist/icons/wrench.svelte
|
|
16556
16912
|
function Wrench($$renderer, $$props) {
|
|
16557
16913
|
let { $$slots, $$events, ...props } = $$props;
|
|
@@ -17619,7 +17975,7 @@ function ThemeToggle($$renderer, $$props) {
|
|
|
17619
17975
|
}
|
|
17620
17976
|
//#endregion
|
|
17621
17977
|
//#region package.json
|
|
17622
|
-
var version = "0.8.
|
|
17978
|
+
var version = "0.8.5";
|
|
17623
17979
|
var dsh = { "webVersion": "0.2.1-rc.3" };
|
|
17624
17980
|
//#endregion
|
|
17625
17981
|
//#region src/lib/version.ts
|
|
@@ -19311,6 +19667,10 @@ function clampPanelWidth(width, kind) {
|
|
|
19311
19667
|
const { minWidth, maxWidth } = appConfig().panel;
|
|
19312
19668
|
if (kind === "workspace-explorer") return Math.max(520, Math.min(PANEL_WORKSPACE_FILE_MAX_WIDTH, width));
|
|
19313
19669
|
if (kind === "workspace-file") return Math.max(520, Math.min(PANEL_WORKSPACE_FILE_MAX_WIDTH, width));
|
|
19670
|
+
if (kind === "browser") {
|
|
19671
|
+
const { maxWidth: browserMax } = appConfig().browserWidths;
|
|
19672
|
+
return Math.max(minWidth, Math.min(browserMax, width));
|
|
19673
|
+
}
|
|
19314
19674
|
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
19315
19675
|
}
|
|
19316
19676
|
/** The single zoom bound site — load-side sanitizing and the zoom slider. */
|
|
@@ -19322,6 +19682,11 @@ function clampPanelZoom(zoom) {
|
|
|
19322
19682
|
function defaultPanelWidth() {
|
|
19323
19683
|
return clampPanelWidth(appConfig().panel.defaultWidth);
|
|
19324
19684
|
}
|
|
19685
|
+
/** The glass panel's config-driven default (browser.defaultWidth, clamped
|
|
19686
|
+
* through the browser band) — chip-spawned glasses mint at this width. */
|
|
19687
|
+
function browserPanelWidth() {
|
|
19688
|
+
return clampPanelWidth(appConfig().browserWidths.defaultWidth, "browser");
|
|
19689
|
+
}
|
|
19325
19690
|
/**
|
|
19326
19691
|
* The skill shelf's born width (The Shelf Chrome ADR, D5): a name list,
|
|
19327
19692
|
* not a five-column table — the shelf pins 480 (DEFAULT_PANEL_MIN_WIDTH)
|
|
@@ -22925,7 +23290,7 @@ function blockBounds(panels, idx, facts) {
|
|
|
22925
23290
|
while (i > 0 && panels[i - 1].kind === "browser") i--;
|
|
22926
23291
|
const head = panels[i - 1];
|
|
22927
23292
|
const inFamily = (id, root) => {
|
|
22928
|
-
if (id === void 0) return false;
|
|
23293
|
+
if (id === void 0 || root === void 0) return false;
|
|
22929
23294
|
let cur = id;
|
|
22930
23295
|
for (let guard = 0; guard < panels.length + 1 && cur !== null; guard++) {
|
|
22931
23296
|
if (cur === root) return true;
|
|
@@ -22946,6 +23311,7 @@ function blockBounds(panels, idx, facts) {
|
|
|
22946
23311
|
sessionId = head.sessionId;
|
|
22947
23312
|
}
|
|
22948
23313
|
}
|
|
23314
|
+
if (sessionId === null) return [idx, idx];
|
|
22949
23315
|
for (let guard = 0; guard < panels.length + 1; guard++) {
|
|
22950
23316
|
const parent = facts.parentOf.get(sessionId) ?? null;
|
|
22951
23317
|
if (parent === null) break;
|
|
@@ -23281,7 +23647,7 @@ function panelRowsFor(input) {
|
|
|
23281
23647
|
}
|
|
23282
23648
|
if (p.kind === "terminal" || p.kind === "prompt-manager" || p.kind === "settings-editor" || p.kind === "skill-shelf" || p.kind === "plugin-rack") return {
|
|
23283
23649
|
panel: p,
|
|
23284
|
-
title: p.kind === "terminal" ? "Terminal" : p.kind === "
|
|
23650
|
+
title: p.kind === "terminal" ? "Terminal" : p.kind === "prompt-manager" ? MANAGER_ROW_TITLE : p.kind === "skill-shelf" ? "Skill Shelf" : p.kind === "plugin-rack" ? "Plugin Rack" : p.kind === "settings-editor" ? SETTINGS_ROW_TITLE[p.target] : "",
|
|
23285
23651
|
workspace: null,
|
|
23286
23652
|
dead: false,
|
|
23287
23653
|
running: false,
|
|
@@ -24724,7 +25090,7 @@ function ConversationHeader($$renderer, $$props) {
|
|
|
24724
25090
|
* upward.
|
|
24725
25091
|
*/
|
|
24726
25092
|
let { sessionId, title, workspace = null, workspaces = [], access = null, agent, agentId = null, isStreaming, transcript = null, subagent = false, plan = null, parentSessionId = null, focused = false, onOpenExplorer = void 0, onOpenBrowser = void 0 } = $$props;
|
|
24727
|
-
$$renderer.push(`<header data-svelte="ConversationHeader"${attr_class(`flex items-center gap-
|
|
25093
|
+
$$renderer.push(`<header data-svelte="ConversationHeader"${attr_class(`flex items-center gap-1 border-b border-surface-border px-2 py-1 ${focused ? "bg-header-wash" : "bg-surface-elevated"}`)} data-testid="conversation-header"${attr("data-focused", focused ? "true" : "false")}>`);
|
|
24728
25094
|
SessionIdAndName($$renderer, {
|
|
24729
25095
|
sessionId,
|
|
24730
25096
|
title,
|
|
@@ -30827,13 +31193,13 @@ function FloatingAnchorContainerPopup($$renderer, $$props) {
|
|
|
30827
31193
|
* `titleTestId` exists because the header's data-testid is part of
|
|
30828
31194
|
* each leaf's pinned surface (plan-popup-header, user-message-jumper-header).
|
|
30829
31195
|
*/
|
|
30830
|
-
let { open = false, triggerEl = void 0, title = void 0, titleTestId = void 0, popupTestId = "floating-anchor-popup", fitWidth = false, children } = $$props;
|
|
31196
|
+
let { open = false, triggerEl = void 0, title = void 0, titleTestId = void 0, popupTestId = "floating-anchor-popup", fitWidth = false, placement = "left", children } = $$props;
|
|
30831
31197
|
/** Focus the box — leaves call it through bind:this when an action
|
|
30832
31198
|
* must hand focus back (the jumper's stay-open jump). */
|
|
30833
31199
|
function focus() {}
|
|
30834
31200
|
if (open) {
|
|
30835
31201
|
$$renderer.push("<!--[0-->");
|
|
30836
|
-
$$renderer.push(`<div data-svelte="FloatingAnchorContainerPopup" tabindex="-1"${attr_class(`pointer-events-auto absolute right-full top-1/2 z-50
|
|
31202
|
+
$$renderer.push(`<div data-svelte="FloatingAnchorContainerPopup" tabindex="-1"${attr_class(`pointer-events-auto absolute ${placement === "right" ? "left-full ml-2" : placement === "below" ? "right-0 top-full mt-2" : "right-full mr-2"} ${placement === "below" ? "" : "top-1/2 -translate-y-1/2"} z-50 max-h-[60vh] max-w-[80vw] overflow-y-auto rounded-lg border border-surface-border bg-surface-elevated py-1 shadow-xl outline-none focus:outline-none ${fitWidth ? "w-fit" : "w-96"}`)}${attr("data-testid", popupTestId)}>`);
|
|
30837
31203
|
if (title !== void 0) {
|
|
30838
31204
|
$$renderer.push("<!--[0-->");
|
|
30839
31205
|
$$renderer.push(`<div class="border-b border-surface-border px-2.5 py-1.5 text-[10px] font-medium uppercase tracking-wider text-text-muted"${attr("data-testid", titleTestId)}>${escape_html(title)}</div>`);
|
|
@@ -31449,341 +31815,1096 @@ function InjectedShelfButton($$renderer, $$props) {
|
|
|
31449
31815
|
});
|
|
31450
31816
|
}
|
|
31451
31817
|
//#endregion
|
|
31452
|
-
//#region src/lib/
|
|
31453
|
-
|
|
31454
|
-
/**
|
|
31455
|
-
|
|
31456
|
-
|
|
31457
|
-
|
|
31458
|
-
|
|
31459
|
-
|
|
31460
|
-
|
|
31461
|
-
*
|
|
31462
|
-
*/
|
|
31463
|
-
|
|
31464
|
-
|
|
31465
|
-
|
|
31466
|
-
|
|
31467
|
-
|
|
31468
|
-
|
|
31469
|
-
|
|
31470
|
-
DeliverablesButton($$renderer, {
|
|
31471
|
-
deliveries: deliverables,
|
|
31472
|
-
onfileopen
|
|
31473
|
-
});
|
|
31474
|
-
$$renderer.push(`<!----> `);
|
|
31475
|
-
JobsButton($$renderer, { sessionId: jobsessionid });
|
|
31476
|
-
$$renderer.push(`<!----> `);
|
|
31477
|
-
if (shelfentries !== void 0) {
|
|
31478
|
-
$$renderer.push("<!--[0-->");
|
|
31479
|
-
InjectedShelfButton($$renderer, {
|
|
31480
|
-
entries: shelfentries,
|
|
31481
|
-
sessionId: shelfsessionid,
|
|
31482
|
-
workspace: shelfworkspace,
|
|
31483
|
-
panelId: shelfpanelid,
|
|
31484
|
-
onnote: onshelfnote
|
|
31485
|
-
});
|
|
31486
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31487
|
-
$$renderer.push(`<!--]--> `);
|
|
31488
|
-
UserMessagesButton($$renderer, {
|
|
31489
|
-
groups,
|
|
31490
|
-
container
|
|
31491
|
-
});
|
|
31492
|
-
$$renderer.push(`<!----> `);
|
|
31493
|
-
BackToTheEdgeButton($$renderer);
|
|
31494
|
-
$$renderer.push(`<!---->`);
|
|
31495
|
-
}});
|
|
31496
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31497
|
-
$$renderer.push(`<!--]-->`);
|
|
31498
|
-
}
|
|
31499
|
-
//#endregion
|
|
31500
|
-
//#region src/lib/components/conversation/panel/A2aChipStack.svelte
|
|
31501
|
-
function A2aChipStack($$renderer, $$props) {
|
|
31502
|
-
$$renderer.component(($$renderer) => {
|
|
31503
|
-
/**
|
|
31504
|
-
* A2aChipStack — the sender panel's read-only delegation-ledger join
|
|
31505
|
-
* (W4 4.2): one floating chip per recent exchange THIS panel sent,
|
|
31506
|
-
* rendered beside the transcript on the floating-anchor pattern
|
|
31507
|
-
* (right-middle stack, per-panel via the embedded anchor host).
|
|
31508
|
-
*
|
|
31509
|
-
* Honesty contract (PRD risk "Attribution overclaim in UI" + spec-check
|
|
31510
|
-
* GAP-5): chip text derives from the row's `state` VERBATIM, all six
|
|
31511
|
-
* states distinguished — `replied_approx` renders "may have replied",
|
|
31512
|
-
* NEVER the confident "replied" string. The ledger is the truth; this
|
|
31513
|
-
* component claims nothing the row does not say.
|
|
31514
|
-
*
|
|
31515
|
-
* Read-only by construction (BC-2): rows arrive as a prop from the
|
|
31516
|
-
* page's EXISTING spine-cadence poll of GET /api/a2a?from= — the chip
|
|
31517
|
-
* owns NO fetch, NO timer. Click = the existing panel doorway
|
|
31518
|
-
* (addPanelFromSidebar dedupe→select). Dismiss is LOCAL-ONLY visual:
|
|
31519
|
-
* rows are durable; the next poll brings a dismissed chip back only
|
|
31520
|
-
* when it is still in the page's fetched window.
|
|
31521
|
-
*/
|
|
31522
|
-
let { rows, titles } = $$props;
|
|
31523
|
-
/** Local-only visual dismissal — rows are durable; the ledger is truth. */
|
|
31524
|
-
let dismissed = /* @__PURE__ */ new Set();
|
|
31525
|
-
/** The cap: newest 3 visible + one overflow indicator (spec 4.2). */
|
|
31526
|
-
const CHIP_CAP = 3;
|
|
31527
|
-
const visible = derived(() => rows.filter((r) => !dismissed.has(r.id)));
|
|
31528
|
-
const capped = derived(() => visible().slice(0, CHIP_CAP));
|
|
31529
|
-
const overflow = derived(() => Math.max(visible().length - CHIP_CAP, 0));
|
|
31530
|
-
/**
|
|
31531
|
-
* Chip text derives from the state VERBATIM (spec-check GAP-5): every
|
|
31532
|
-
* state distinguished, `replied_approx` hedged as "may have replied" —
|
|
31533
|
-
* never a confident claim the row cannot support.
|
|
31534
|
-
*/
|
|
31535
|
-
function labelFor(state) {
|
|
31536
|
-
switch (state) {
|
|
31537
|
-
case "waiting": return "waiting";
|
|
31538
|
-
case "replied_exact": return "replied (exact)";
|
|
31539
|
-
case "replied": return "replied";
|
|
31540
|
-
case "replied_approx": return "may have replied";
|
|
31541
|
-
case "timeout": return "no reply (timeout)";
|
|
31542
|
-
case "gone": return "target gone";
|
|
31543
|
-
}
|
|
31544
|
-
}
|
|
31545
|
-
/** The target's display title — the spine title, else the id prefix. */
|
|
31546
|
-
function titleFor(toSession) {
|
|
31547
|
-
return titles[toSession] ?? toSession.replace(/^session-/, "").slice(0, 8);
|
|
31548
|
-
}
|
|
31549
|
-
if (visible().length > 0) {
|
|
31550
|
-
$$renderer.push("<!--[0-->");
|
|
31551
|
-
FloatingAnchor($$renderer, {
|
|
31552
|
-
children: ($$renderer) => {
|
|
31553
|
-
$$renderer.push(`<!--[-->`);
|
|
31554
|
-
const each_array = ensure_array_like(capped());
|
|
31555
|
-
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
31556
|
-
let row = each_array[$$index];
|
|
31557
|
-
$$renderer.push(`<div class="a2a-chip-wrap" data-testid="a2a-chip"${attr("data-a2a-state", row.state)}${attr("data-a2a-id", row.id)}><button type="button"${attr_class("a2a-chip", void 0, {
|
|
31558
|
-
"tone-waiting": row.state === "waiting",
|
|
31559
|
-
"tone-replied-exact": row.state === "replied_exact",
|
|
31560
|
-
"tone-replied": row.state === "replied",
|
|
31561
|
-
"tone-replied-approx": row.state === "replied_approx",
|
|
31562
|
-
"tone-timeout": row.state === "timeout",
|
|
31563
|
-
"tone-gone": row.state === "gone"
|
|
31564
|
-
})} data-testid="a2a-chip-button"${attr("title", `${stringify(titleFor(row.toSession))} — ${stringify(labelFor(row.state))}`)}>`);
|
|
31565
|
-
if (row.state === "waiting") {
|
|
31566
|
-
$$renderer.push("<!--[0-->");
|
|
31567
|
-
Hourglass($$renderer, { size: 13 });
|
|
31568
|
-
} else if (row.state === "replied_exact" || row.state === "replied") {
|
|
31569
|
-
$$renderer.push("<!--[1-->");
|
|
31570
|
-
Check($$renderer, { size: 13 });
|
|
31571
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31572
|
-
$$renderer.push(`<!--]--> <span class="a2a-chip-label">${escape_html(labelFor(row.state))}</span></button> <button type="button" class="a2a-dismiss" data-testid="a2a-chip-dismiss" title="hide this chip (the ledger row stays)">`);
|
|
31573
|
-
X($$renderer, { size: 11 });
|
|
31574
|
-
$$renderer.push(`<!----></button></div>`);
|
|
31575
|
-
}
|
|
31576
|
-
$$renderer.push(`<!--]--> `);
|
|
31577
|
-
if (overflow() > 0) {
|
|
31578
|
-
$$renderer.push("<!--[0-->");
|
|
31579
|
-
$$renderer.push(`<div class="a2a-chip-overflow" data-testid="a2a-chip-overflow">+${escape_html(overflow())} more</div>`);
|
|
31580
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31581
|
-
$$renderer.push(`<!--]-->`);
|
|
31582
|
-
}});
|
|
31583
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31584
|
-
$$renderer.push(`<!--]-->`);
|
|
31585
|
-
});
|
|
31586
|
-
}
|
|
31587
|
-
//#endregion
|
|
31588
|
-
//#region src/lib/components/conversation/panel/ConversationStatsBar.svelte
|
|
31589
|
-
function ConversationStatsBar($$renderer, $$props) {
|
|
31590
|
-
$$renderer.component(($$renderer) => {
|
|
31591
|
-
/**
|
|
31592
|
-
* ConversationStatsBar — the panel's session baseline (ADR 2026-09-08
|
|
31593
|
-
* "The Stats Bar", D1/D3/D5): one fixed-height line under the transcript
|
|
31594
|
-
* showing what the ledger already proves — turns, steps, tool time,
|
|
31595
|
-
* token totals, cache hit. Pure presentation: the panel derives the
|
|
31596
|
-
* stats and hands them down; segments whose inputs never reached DSI
|
|
31597
|
-
* are omitted, never approximated. Renders nothing before the first
|
|
31598
|
-
* assistant message (D5 gate lives in the derive's null return).
|
|
31599
|
-
*/
|
|
31600
|
-
let { stats } = $$props;
|
|
31601
|
-
/** 85000 -> "1m25s"; 2400000 -> "40m"; 5400000 -> "1h30m"; 250 -> "250ms". */
|
|
31602
|
-
function formatDuration(ms) {
|
|
31603
|
-
if (ms < 1e3) return `${ms}ms`;
|
|
31604
|
-
const totalSec = Math.floor(ms / 1e3);
|
|
31605
|
-
const h = Math.floor(totalSec / 3600);
|
|
31606
|
-
const m = Math.floor(totalSec % 3600 / 60);
|
|
31607
|
-
const s = totalSec % 60;
|
|
31608
|
-
if (h > 0) return `${h}h${m}m`;
|
|
31609
|
-
if (m > 0) return s > 0 ? `${m}m${s}s` : `${m}m`;
|
|
31610
|
-
return `${s}s`;
|
|
31818
|
+
//#region src/lib/services/conversation/subagent-clock.svelte.ts
|
|
31819
|
+
var SubagentClock = class {
|
|
31820
|
+
/** sessionId → first-sight epoch ms (running rows only). */
|
|
31821
|
+
firstSeen = {};
|
|
31822
|
+
/** sessionId → frozen elapsed ms, set once at the settle observation. */
|
|
31823
|
+
frozen = {};
|
|
31824
|
+
/** The tick's reading — read by elapsedMs so a live tick re-renders. */
|
|
31825
|
+
now = Date.now();
|
|
31826
|
+
/** Feed one spine tick: register unseen running ids, freeze settled
|
|
31827
|
+
* ones, expire ids gone from the feed. Call on every fetch (the
|
|
31828
|
+
* button's poll cadence), not on a timer — this IS the sighting lane. */
|
|
31829
|
+
observe(rows) {
|
|
31830
|
+
const t = Date.now();
|
|
31831
|
+
const seen = /* @__PURE__ */ new Set();
|
|
31832
|
+
for (const row of rows) {
|
|
31833
|
+
seen.add(row.sessionId);
|
|
31834
|
+
if (row.running && this.firstSeen[row.sessionId] === void 0) this.firstSeen[row.sessionId] = t;
|
|
31835
|
+
if (!row.running && this.firstSeen[row.sessionId] !== void 0 && this.frozen[row.sessionId] === void 0) this.frozen[row.sessionId] = t - this.firstSeen[row.sessionId];
|
|
31611
31836
|
}
|
|
31612
|
-
|
|
31613
|
-
|
|
31614
|
-
|
|
31615
|
-
if (n >= 1e3) return `${(n / 1e3).toFixed(1).replace(/\.0$/, "")}K`;
|
|
31616
|
-
return String(n);
|
|
31837
|
+
for (const id of Object.keys(this.firstSeen)) if (!seen.has(id)) {
|
|
31838
|
+
delete this.firstSeen[id];
|
|
31839
|
+
delete this.frozen[id];
|
|
31617
31840
|
}
|
|
31618
|
-
|
|
31619
|
-
if (stats === null) return [];
|
|
31620
|
-
const parts = [`${stats.turns} turns · ${stats.steps} steps`];
|
|
31621
|
-
const durations = [];
|
|
31622
|
-
if (stats.llmMs !== void 0 && stats.llmMs > 0) durations.push(`LLM ${formatDuration(stats.llmMs)}`);
|
|
31623
|
-
if (stats.toolMs > 0) durations.push(`Tool ${formatDuration(stats.toolMs)}`);
|
|
31624
|
-
if (durations.length > 0) parts.push(durations.join(" · "));
|
|
31625
|
-
const speeds = [];
|
|
31626
|
-
if (stats.ttftSteps !== void 0 && stats.ttftSteps > 0 && stats.ttftMs !== void 0) speeds.push(`TTFT avg ${formatDuration(stats.ttftMs / stats.ttftSteps)}`);
|
|
31627
|
-
if (stats.decodeMs !== void 0 && stats.decodeMs > 0 && stats.decodeTokens !== void 0) speeds.push(`${Math.max(1, Math.round(stats.decodeTokens / (stats.decodeMs / 1e3)))} tok/s`);
|
|
31628
|
-
if (speeds.length > 0) parts.push(speeds.join(" · "));
|
|
31629
|
-
const inputTotal = stats.billedInputTokens ?? stats.inputTokens;
|
|
31630
|
-
if (inputTotal !== void 0) parts.push(`Input ${formatTokens(inputTotal)} tok · Output ${formatTokens(stats.outputTokens ?? 0)} tok`);
|
|
31631
|
-
if (stats.cacheHitPercent !== void 0) parts.push(`Cache hit ${stats.cacheHitPercent}%`);
|
|
31632
|
-
return parts;
|
|
31633
|
-
});
|
|
31634
|
-
if (stats !== null) {
|
|
31635
|
-
$$renderer.push("<!--[0-->");
|
|
31636
|
-
$$renderer.push(`<div data-svelte="ConversationStatsBar" class="stats-bar svelte-hnxn10" data-testid="conversation-stats-bar"${attr("title", segments().join(" | "))}><!--[-->`);
|
|
31637
|
-
const each_array = ensure_array_like(segments());
|
|
31638
|
-
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
|
|
31639
|
-
let segment = each_array[i];
|
|
31640
|
-
if (i > 0) {
|
|
31641
|
-
$$renderer.push("<!--[0-->");
|
|
31642
|
-
$$renderer.push(`<span class="sep svelte-hnxn10" aria-hidden="true">|</span>`);
|
|
31643
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31644
|
-
$$renderer.push(`<!--]--> <span class="segment svelte-hnxn10" data-testid="stats-segment">${escape_html(segment)}</span>`);
|
|
31645
|
-
}
|
|
31646
|
-
$$renderer.push(`<!--]--></div>`);
|
|
31647
|
-
} else $$renderer.push("<!--[-1-->");
|
|
31648
|
-
$$renderer.push(`<!--]-->`);
|
|
31649
|
-
});
|
|
31650
|
-
}
|
|
31651
|
-
//#endregion
|
|
31652
|
-
//#region src/lib/components/conversation/panel/submit-ladder.svelte.ts
|
|
31653
|
-
var SubmitLadder = class {
|
|
31654
|
-
deps;
|
|
31655
|
-
/** True while the plain-send rung is in flight — the footer's sending flag. */
|
|
31656
|
-
submitted = false;
|
|
31657
|
-
/** Inline command feedback (role=status, auto-dismiss 5s) — the ONLY
|
|
31658
|
-
* command UI surface; the input has already cleared by intercept time.
|
|
31659
|
-
* The wire work lives in command-executor (Prompt Macro W1 1.2): the
|
|
31660
|
-
* /new create+swap, /permission route, and mention delivery are the
|
|
31661
|
-
* SAME bytes the typed path always sent — the panel now renders
|
|
31662
|
-
* outcomes only (banner kind from result.ok). */
|
|
31663
|
-
commandNote = null;
|
|
31664
|
-
commandNoteTimer;
|
|
31665
|
-
constructor(deps) {
|
|
31666
|
-
this.deps = deps;
|
|
31667
|
-
}
|
|
31668
|
-
/** Inline command feedback — every rung banners through here. */
|
|
31669
|
-
noteCommand(kind, text) {
|
|
31670
|
-
this.commandNote = {
|
|
31671
|
-
kind,
|
|
31672
|
-
text
|
|
31673
|
-
};
|
|
31674
|
-
if (this.commandNoteTimer !== void 0) clearTimeout(this.commandNoteTimer);
|
|
31675
|
-
this.commandNoteTimer = setTimeout(() => this.commandNote = null, 5e3);
|
|
31841
|
+
this.now = t;
|
|
31676
31842
|
}
|
|
31677
|
-
|
|
31678
|
-
|
|
31679
|
-
|
|
31680
|
-
|
|
31681
|
-
id: -1
|
|
31682
|
-
}, false);
|
|
31683
|
-
return true;
|
|
31684
|
-
}
|
|
31685
|
-
const command = parseCommand(text);
|
|
31686
|
-
if (command !== null) {
|
|
31687
|
-
let bannered = false;
|
|
31688
|
-
const result = await executeCommand(command, this.deps.ctx(), (ok, note) => {
|
|
31689
|
-
bannered = true;
|
|
31690
|
-
this.noteCommand(ok ? "ok" : "error", note);
|
|
31691
|
-
});
|
|
31692
|
-
if (!bannered && result.note !== void 0) this.noteCommand(result.ok ? "ok" : "error", result.note);
|
|
31693
|
-
return true;
|
|
31694
|
-
}
|
|
31695
|
-
if (text.trim().length === 0 && images.length === 0) return false;
|
|
31696
|
-
const slashCatalog = this.deps.slashCatalog;
|
|
31697
|
-
if (slashCatalog?.state === "ready") {
|
|
31698
|
-
if (resolveHostCommand(text, slashCatalog.commands) !== null) return (await executeHostCommand(text, this.deps.ctx(), (ok, note) => this.noteCommand(ok ? "ok" : "error", note))).ok;
|
|
31699
|
-
}
|
|
31700
|
-
this.submitted = true;
|
|
31701
|
-
try {
|
|
31702
|
-
return (await sendPrompt(text, this.deps.ctx(), (t) => this.deps.orchestrator.submit(t, images))).ok;
|
|
31703
|
-
} finally {
|
|
31704
|
-
this.submitted = false;
|
|
31705
|
-
}
|
|
31843
|
+
/** Live tick — the open popup calls this on its 1s interval so a
|
|
31844
|
+
* running row's elapsed advances between polls. */
|
|
31845
|
+
tick() {
|
|
31846
|
+
this.now = Date.now();
|
|
31706
31847
|
}
|
|
31707
|
-
|
|
31708
|
-
|
|
31848
|
+
/** Elapsed ms for one id: the frozen settle delta, or now − firstSeen
|
|
31849
|
+
* for a running row, or null when there is NO honest sample (never
|
|
31850
|
+
* sighted running, or first seen already settled). */
|
|
31851
|
+
elapsedMs(id) {
|
|
31852
|
+
const frozen = this.frozen[id];
|
|
31853
|
+
if (frozen !== void 0) return frozen;
|
|
31854
|
+
const t0 = this.firstSeen[id];
|
|
31855
|
+
if (t0 === void 0) return null;
|
|
31856
|
+
return Math.max(0, this.now - t0);
|
|
31709
31857
|
}
|
|
31710
|
-
/**
|
|
31711
|
-
|
|
31712
|
-
|
|
31713
|
-
async onpickcommand(line) {
|
|
31714
|
-
return (await executeHostCommand(line, this.deps.ctx(), (ok, note) => this.noteCommand(ok ? "ok" : "error", note))).ok;
|
|
31858
|
+
/** Does the id carry any sample at all (frozen or live)? */
|
|
31859
|
+
sighted(id) {
|
|
31860
|
+
return this.frozen[id] !== void 0 || this.firstSeen[id] !== void 0;
|
|
31715
31861
|
}
|
|
31716
31862
|
};
|
|
31717
|
-
|
|
31718
|
-
|
|
31719
|
-
/**
|
|
31720
|
-
*
|
|
31721
|
-
*
|
|
31722
|
-
|
|
31723
|
-
|
|
31724
|
-
|
|
31725
|
-
|
|
31726
|
-
|
|
31727
|
-
|
|
31863
|
+
/** The desk-lifetime singleton — one registry per page visit (ADR D3). */
|
|
31864
|
+
var subagentClock = new SubagentClock();
|
|
31865
|
+
/**
|
|
31866
|
+
* The open workspace explorer for a workspace ROOT — The Shared Tree ADR
|
|
31867
|
+
* (2026-09-17) D1's dedupe key: ONE explorer per ROOT across ALL sessions,
|
|
31868
|
+
* so a chip click on any session sharing the root FOCUSES instead of
|
|
31869
|
+
* adding (a duplicate is a bug, not a feature). The retired per-session
|
|
31870
|
+
* key ("two sessions sharing one workspace hold distinct explorers",
|
|
31871
|
+
* Workspace Explorer D4) produced N byte-identical trees for N sessions.
|
|
31872
|
+
*/
|
|
31873
|
+
function findWorkspaceExplorerPanel(panels, root) {
|
|
31874
|
+
return panels.find((p) => p.kind === "workspace-explorer" && p.root === root);
|
|
31728
31875
|
}
|
|
31729
|
-
/**
|
|
31730
|
-
*
|
|
31731
|
-
|
|
31732
|
-
|
|
31876
|
+
/**
|
|
31877
|
+
* The explorer's slot (The Shared Tree ADR 2026-09-17, D3): the FOCUSED
|
|
31878
|
+
* slot — the explorer is NOT a lineage child; a workspace tree has no
|
|
31879
|
+
* parent session, only an opener. The retired after-source rule
|
|
31880
|
+
* (Workspace Explorer D3, "Parent → explorer → file") interposed the
|
|
31881
|
+
* panel inside a conversation's family unit — the family clamp inside
|
|
31882
|
+
* focusedInsertionSlot still keeps any real family unsplit.
|
|
31883
|
+
*/
|
|
31884
|
+
function workspaceExplorerSlot(panels, selectedIndex, facts) {
|
|
31885
|
+
return focusedInsertionSlot(panels, selectedIndex, facts.parentOf);
|
|
31733
31886
|
}
|
|
31734
|
-
|
|
31735
|
-
|
|
31736
|
-
|
|
31737
|
-
|
|
31738
|
-
|
|
31739
|
-
|
|
31740
|
-
|
|
31741
|
-
|
|
31742
|
-
|
|
31743
|
-
|
|
31744
|
-
|
|
31745
|
-
|
|
31746
|
-
|
|
31747
|
-
|
|
31748
|
-
|
|
31749
|
-
|
|
31750
|
-
|
|
31751
|
-
|
|
31752
|
-
|
|
31753
|
-
|
|
31754
|
-
|
|
31755
|
-
|
|
31756
|
-
|
|
31757
|
-
|
|
31758
|
-
|
|
31759
|
-
|
|
31760
|
-
|
|
31761
|
-
|
|
31762
|
-
|
|
31763
|
-
|
|
31764
|
-
|
|
31765
|
-
|
|
31766
|
-
|
|
31767
|
-
|
|
31768
|
-
|
|
31769
|
-
|
|
31770
|
-
|
|
31771
|
-
|
|
31772
|
-
|
|
31773
|
-
|
|
31774
|
-
|
|
31775
|
-
|
|
31776
|
-
|
|
31777
|
-
|
|
31778
|
-
|
|
31779
|
-
|
|
31780
|
-
|
|
31781
|
-
|
|
31782
|
-
|
|
31783
|
-
|
|
31784
|
-
}
|
|
31785
|
-
|
|
31786
|
-
|
|
31887
|
+
/**
|
|
31888
|
+
* The glass FIRST slot under its opener (operator ruling 2026-10-24):
|
|
31889
|
+
* a summoned/spawned glass lands DIRECTLY below its opener - past the
|
|
31890
|
+
* opener document tail, BEFORE every adopted child - matching the
|
|
31891
|
+
* spine tree wire order -1 (the ghost always reads as the first
|
|
31892
|
+
* child). Supersedes the region-end placement for the glass only.
|
|
31893
|
+
*/
|
|
31894
|
+
function glassFirstSlot(panels, openedBy) {
|
|
31895
|
+
const openerIdx = panels.findIndex((p) => p.kind === "conversation" && p.sessionId === openedBy);
|
|
31896
|
+
if (openerIdx === -1) return panels.length;
|
|
31897
|
+
return docTailEnd(panels, openerIdx, openedBy) + 1;
|
|
31898
|
+
}
|
|
31899
|
+
/**
|
|
31900
|
+
* Insert-before-focused slot (operator spec, 2026-08-31): a fresh panel
|
|
31901
|
+
* lands at the FOCUSED panel's index — immediately before it — and takes
|
|
31902
|
+
* focus (the route selects it). 0 when nothing is focused (empty floor,
|
|
31903
|
+
* stale selection) — the old front-add stays the fallback. Math.max keeps
|
|
31904
|
+
* splice's negative-index semantics out of the no-selection case.
|
|
31905
|
+
*
|
|
31906
|
+
* Family clamp (lineage I2): a slot strictly inside a family would wedge
|
|
31907
|
+
* the newcomer between a spawner and its pinned child — unitOf/blockBounds,
|
|
31908
|
+
* the sidebar's familyRenderOrder, and the adoption slot walk all assume
|
|
31909
|
+
* families stay contiguous on the floor. When the focus is a family CHILD,
|
|
31910
|
+
* the slot climbs to the family head — the nearest non-splitting slot left
|
|
31911
|
+
* of the focus (parentOf only carries on-floor parents, so an orphan child
|
|
31912
|
+
* is a root here, its own unit). A lone panel or a family head keeps the
|
|
31913
|
+
* exact focus slot.
|
|
31914
|
+
*
|
|
31915
|
+
* Manager focus (ADR D6): no session, no family — the slot is the focus
|
|
31916
|
+
* itself.
|
|
31917
|
+
*
|
|
31918
|
+
* Workspace member focus (2026-09-10): the explorer/file pair is a family
|
|
31919
|
+
* unit in the SAME block math (blockBounds — the Loadinjected D3 walk-back
|
|
31920
|
+
* grammar), so the clamp is the SAME one: insert at the unit head — the
|
|
31921
|
+
* PARENT position, left of the block — never between explorer and file.
|
|
31922
|
+
*/
|
|
31923
|
+
function focusedInsertionSlot(panels, selectedIndex, parentOf) {
|
|
31924
|
+
const focus = Math.max(0, selectedIndex);
|
|
31925
|
+
const focused = panels[focus];
|
|
31926
|
+
if (focused === void 0) return 0;
|
|
31927
|
+
if (focused.kind === "workspace-explorer" || focused.kind === "workspace-file" || focused.kind === "browser") {
|
|
31928
|
+
const block = blockBounds(panels, focus, { parentOf });
|
|
31929
|
+
return block === null ? focus : block[0];
|
|
31930
|
+
}
|
|
31931
|
+
if (focused.kind !== "conversation") return focus;
|
|
31932
|
+
let head = focused.sessionId;
|
|
31933
|
+
for (;;) {
|
|
31934
|
+
const parent = parentOf.get(head) ?? null;
|
|
31935
|
+
if (parent === null) break;
|
|
31936
|
+
head = parent;
|
|
31937
|
+
}
|
|
31938
|
+
if (head === focused.sessionId) return focus;
|
|
31939
|
+
const headIndex = panels.findIndex((p) => p.kind === "conversation" && p.sessionId === head);
|
|
31940
|
+
return headIndex >= 0 ? Math.min(headIndex, focus) : focus;
|
|
31941
|
+
}
|
|
31942
|
+
//#endregion
|
|
31943
|
+
//#region src/lib/services/panels/floor-registry/chrome.ts
|
|
31944
|
+
/**
|
|
31945
|
+
* floor-registry/chrome — panel chrome intents + explorer + file-intent
|
|
31946
|
+
* mailbox + removal (ADR-0022 W3).
|
|
31947
|
+
*
|
|
31948
|
+
* Moved WHOLE from the state home (floor-registry.svelte.ts): the
|
|
31949
|
+
* skill-shelf / plugin-rack chrome setters, the ONE-explorer-per-workspace
|
|
31950
|
+
* open grammar, the explorer tree/tab/git intents, the file-intent
|
|
31951
|
+
* publish/consume mailbox, and family-close removal. Plain module: every
|
|
31952
|
+
* write goes through the state home's reactive `st` hub and its
|
|
31953
|
+
* primitives (ADR-0019 D2: exactly ONE writer home for floor state).
|
|
31954
|
+
* Sibling rule: factories/slots are reached through the state home's
|
|
31955
|
+
* re-export hub, never by importing another sibling directly.
|
|
31956
|
+
*/
|
|
31957
|
+
var d$4 = floorSeam;
|
|
31958
|
+
/** Chip click action: ONE explorer per WORKSPACE root across ALL
|
|
31959
|
+
* sessions — a click on any session sharing the root FOCUSES the open
|
|
31960
|
+
* explorer (dedupe key = root, D1); a fresh root lands at the focused
|
|
31961
|
+
* slot (D3, non-lineage — the explorer is not a lineage child).
|
|
31962
|
+
* sessionId rides the fresh panel as PROVENANCE (D4), never identity. */
|
|
31963
|
+
function openWorkspaceExplorer(sessionId, workspace) {
|
|
31964
|
+
const open = findWorkspaceExplorerPanel(st.panels, workspace);
|
|
31965
|
+
if (open) {
|
|
31966
|
+
st.selectedPanelId = open.id;
|
|
31967
|
+
return;
|
|
31968
|
+
}
|
|
31969
|
+
insertPanel(makeWorkspaceExplorerPanel(sessionId, workspace), workspaceExplorerSlot(st.panels, selectedIndex_(), d$4().getMoveFacts()));
|
|
31970
|
+
}
|
|
31971
|
+
/** Chip click action (The Glass Browser spec W2, ADR-0029 D4): ONE live
|
|
31972
|
+
* browser panel across the floor — the terminal singleton rule (Terminal
|
|
31973
|
+
* Desk ADR D2). A click on an open browser FOCUSES it; a miss inserts at
|
|
31974
|
+
* the focused slot. */
|
|
31975
|
+
function openBrowserPanel(index, keepSelection = false, width, openedBy, sessionId) {
|
|
31976
|
+
const open = st.panels.find((p) => p.kind === "browser" && p.openedBy === openedBy);
|
|
31977
|
+
if (open) {
|
|
31978
|
+
st.selectedPanelId = open.id;
|
|
31979
|
+
return;
|
|
31980
|
+
}
|
|
31981
|
+
const prevSelected = st.selectedPanelId;
|
|
31982
|
+
const slot = index !== void 0 ? Math.max(0, Math.min(index, st.panels.length)) : openedBy !== void 0 ? glassFirstSlot(st.panels, openedBy) : insertionSlot();
|
|
31983
|
+
insertPanel(makeBrowserPanel(width, openedBy, sessionId), slot);
|
|
31984
|
+
if (keepSelection && prevSelected !== null && prevSelected !== void 0) {
|
|
31985
|
+
if (st.panels.some((p) => p.id === prevSelected)) st.selectedPanelId = prevSelected;
|
|
31986
|
+
}
|
|
31987
|
+
}
|
|
31988
|
+
/** The open explorer for a session's workspace (The Shared Tree D1):
|
|
31989
|
+
* matched by ROOT across sessions — the panel's provenance sessionId
|
|
31990
|
+
* is not the key. */
|
|
31991
|
+
function sessionWorkspaceExplorer(sessionId) {
|
|
31992
|
+
const root = d$4().getWorkspaceFor(sessionId);
|
|
31993
|
+
return root === null ? void 0 : findWorkspaceExplorerPanel(st.panels, root);
|
|
31994
|
+
}
|
|
31995
|
+
/** Explorer tree intents: the panel emits toggle/open-file; the owner
|
|
31996
|
+
* mutates expanded (the persisted part) — the levels cache stays
|
|
31997
|
+
* component-local. */
|
|
31998
|
+
function toggleExplorerPath(panelId, path) {
|
|
31999
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32000
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32001
|
+
const explorer = st.panels[idx];
|
|
32002
|
+
const next = explorer.expanded.includes(path) ? explorer.expanded.filter((p) => p !== path) : [...explorer.expanded, path];
|
|
32003
|
+
st.panels = st.panels.with(idx, {
|
|
32004
|
+
...explorer,
|
|
32005
|
+
expanded: next
|
|
32006
|
+
});
|
|
32007
|
+
}
|
|
32008
|
+
/** Explorer collapse-all intent: the panel emits; the owner empties the
|
|
32009
|
+
* expanded list (the persisted part). */
|
|
32010
|
+
function collapseExplorerPaths(panelId) {
|
|
32011
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32012
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32013
|
+
st.panels = st.panels.with(idx, {
|
|
32014
|
+
...st.panels[idx],
|
|
32015
|
+
expanded: []
|
|
32016
|
+
});
|
|
32017
|
+
}
|
|
32018
|
+
/** Git Eye tab intent (2026-09-12): the active tab is PERSISTED on the
|
|
32019
|
+
* entry — a hard reload restores it. */
|
|
32020
|
+
function setExplorerTab(panelId, tab) {
|
|
32021
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32022
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32023
|
+
st.panels = st.panels.with(idx, {
|
|
32024
|
+
...st.panels[idx],
|
|
32025
|
+
tab
|
|
32026
|
+
});
|
|
32027
|
+
}
|
|
32028
|
+
/** Explorer Layout tabs (amendment 2026-09-16): the tab list and the
|
|
32029
|
+
* active tab are OWNER-PERSISTED entry facts. The file tabs die with
|
|
32030
|
+
* the panel (D5). */
|
|
32031
|
+
function openExplorerTab(panelId, path) {
|
|
32032
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32033
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32034
|
+
const ex = st.panels[idx];
|
|
32035
|
+
const tabs = ex.openTabs ?? [];
|
|
32036
|
+
const openTabs = tabs.includes(path) ? tabs : [...tabs, path];
|
|
32037
|
+
st.panels = st.panels.with(idx, {
|
|
32038
|
+
...ex,
|
|
32039
|
+
openTabs,
|
|
32040
|
+
activeFile: path
|
|
32041
|
+
});
|
|
32042
|
+
}
|
|
32043
|
+
function closeExplorerTab(panelId, path) {
|
|
32044
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32045
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32046
|
+
const ex = st.panels[idx];
|
|
32047
|
+
const tabs = ex.openTabs ?? [];
|
|
32048
|
+
const closedAt = tabs.indexOf(path);
|
|
32049
|
+
if (closedAt === -1) return;
|
|
32050
|
+
const openTabs = tabs.filter((p) => p !== path);
|
|
32051
|
+
const activeFile = ex.activeFile === path ? openTabs.length === 0 ? null : openTabs[Math.max(0, closedAt - 1)] : ex.activeFile ?? null;
|
|
32052
|
+
st.panels = st.panels.with(idx, {
|
|
32053
|
+
...ex,
|
|
32054
|
+
openTabs,
|
|
32055
|
+
activeFile
|
|
32056
|
+
});
|
|
32057
|
+
}
|
|
32058
|
+
function activateExplorerTab(panelId, path) {
|
|
32059
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32060
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32061
|
+
const ex = st.panels[idx];
|
|
32062
|
+
if (!(ex.openTabs ?? []).includes(path)) return;
|
|
32063
|
+
st.panels = st.panels.with(idx, {
|
|
32064
|
+
...ex,
|
|
32065
|
+
activeFile: path
|
|
32066
|
+
});
|
|
32067
|
+
}
|
|
32068
|
+
/** The Explorer Layout drag settle (ADR D4): one DESK fact — the split
|
|
32069
|
+
* is desk state, persisted with the floor blob, NOT per entry. The
|
|
32070
|
+
* panel already clamped; clamp again at the single bound site. */
|
|
32071
|
+
function setExplorerTreePct(_panelId, pct) {
|
|
32072
|
+
d$4().setTreePct(clampTreePct(pct));
|
|
32073
|
+
}
|
|
32074
|
+
/** Git Eye repo-collapse intent (2026-09-13): the collapsed repo set is
|
|
32075
|
+
* PERSISTED on the entry. Default is EXPANDED. */
|
|
32076
|
+
function toggleExplorerRepo(panelId, repoRel) {
|
|
32077
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32078
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32079
|
+
const explorer = st.panels[idx];
|
|
32080
|
+
const prev = explorer.collapsedRepos ?? [];
|
|
32081
|
+
const next = prev.includes(repoRel) ? prev.filter((r) => r !== repoRel) : [...prev, repoRel];
|
|
32082
|
+
st.panels = st.panels.with(idx, {
|
|
32083
|
+
...explorer,
|
|
32084
|
+
collapsedRepos: next
|
|
32085
|
+
});
|
|
32086
|
+
}
|
|
32087
|
+
/** Git Eye collapse-all-repos intent (2026-09-13): collapses EVERY known
|
|
32088
|
+
* repo — persisted like the single-repo toggle. */
|
|
32089
|
+
function collapseExplorerRepos(panelId, repos) {
|
|
32090
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32091
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
32092
|
+
const explorer = st.panels[idx];
|
|
32093
|
+
const prev = explorer.collapsedRepos ?? [];
|
|
32094
|
+
const next = [...prev, ...repos.filter((r) => !prev.includes(r))];
|
|
32095
|
+
st.panels = st.panels.with(idx, {
|
|
32096
|
+
...explorer,
|
|
32097
|
+
collapsedRepos: next
|
|
32098
|
+
});
|
|
32099
|
+
}
|
|
32100
|
+
/** File Eye view intent (2026-09-13): diff vs edit is PERSISTED on the
|
|
32101
|
+
* entry. */
|
|
32102
|
+
function setFileView(panelId, view) {
|
|
32103
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32104
|
+
if (idx < 0 || st.panels[idx].kind !== "workspace-file") return;
|
|
32105
|
+
st.panels = st.panels.with(idx, {
|
|
32106
|
+
...st.panels[idx],
|
|
32107
|
+
view
|
|
32108
|
+
});
|
|
32109
|
+
}
|
|
32110
|
+
/** Tree file-click action (The Settings Tree ADR 2026-09-18 D1): the
|
|
32111
|
+
* intent publishes to the session's explorer, which opens/focuses a
|
|
32112
|
+
* tab. No open explorer ⇒ the intent drops. */
|
|
32113
|
+
function openWorkspaceFile(sessionId, path, lines) {
|
|
32114
|
+
const host = sessionWorkspaceExplorer(sessionId);
|
|
32115
|
+
if (host) publishFileIntent(host.id, path, lines);
|
|
32116
|
+
}
|
|
32117
|
+
/** Publish a file intent to an explorer panel and focus it. `lines` is
|
|
32118
|
+
* the optional #L anchor target — display metadata, not persisted. */
|
|
32119
|
+
function publishFileIntent(explorerId, path, lines) {
|
|
32120
|
+
st.pendingFileIntents[explorerId] = {
|
|
32121
|
+
path,
|
|
32122
|
+
nonce: ++st.fileIntentSeq,
|
|
32123
|
+
lines: lines ?? null
|
|
32124
|
+
};
|
|
32125
|
+
st.selectedPanelId = explorerId;
|
|
32126
|
+
}
|
|
32127
|
+
/** The panel consumed intent nonce N — clear exactly that publish. */
|
|
32128
|
+
function consumeFileIntent(explorerId, nonce) {
|
|
32129
|
+
if (st.pendingFileIntents[explorerId]?.nonce === nonce) st.pendingFileIntents[explorerId] = null;
|
|
32130
|
+
}
|
|
32131
|
+
/** Remove a panel; family close walks the wire lineage transitively
|
|
32132
|
+
* (every descendant sub-agent goes with it, nested included). The
|
|
32133
|
+
* Shift+Click amendment (2026-09-01): family === false opts OUT — only
|
|
32134
|
+
* THAT panel drops, the children re-root as orphan family heads.
|
|
32135
|
+
*
|
|
32136
|
+
* The session's workspace pair closes with it (2026-09-10); closing an
|
|
32137
|
+
* EXPLORER dooms its file children BY PANEL ID — the stored
|
|
32138
|
+
* explorerPanelId edge, with the legacy null-edge fallback. A
|
|
32139
|
+
* settings-home explorer (sessionId null) dies with the close. */
|
|
32140
|
+
function removePanel(panelId, opts = {}) {
|
|
32141
|
+
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
32142
|
+
if (idx < 0) return;
|
|
32143
|
+
const root = st.panels[idx];
|
|
32144
|
+
const rootSessionId = root.kind === "conversation" ? root.sessionId : null;
|
|
32145
|
+
const doomed = new SvelteSet(rootSessionId !== null ? [rootSessionId] : []);
|
|
32146
|
+
if (opts.family !== false && rootSessionId !== null) {
|
|
32147
|
+
const stack = [rootSessionId];
|
|
32148
|
+
while (stack.length > 0) for (const kid of d$4().getLineageFacts().childrenByParent.get(stack.pop()) ?? []) if (!doomed.has(kid.sessionId)) {
|
|
32149
|
+
doomed.add(kid.sessionId);
|
|
32150
|
+
stack.push(kid.sessionId);
|
|
32151
|
+
}
|
|
32152
|
+
}
|
|
32153
|
+
const doomedPanelIds = new SvelteSet();
|
|
32154
|
+
if (opts.family !== false && rootSessionId !== null) {
|
|
32155
|
+
for (const p of st.panels) if (p.kind === "browser" && p.openedBy !== void 0 && doomed.has(p.openedBy)) doomedPanelIds.add(p.id);
|
|
32156
|
+
}
|
|
32157
|
+
if (opts.family !== false && root.kind === "workspace-explorer") {
|
|
32158
|
+
for (const p of st.panels) if (p.kind === "workspace-file" && (p.explorerPanelId === root.id || p.explorerPanelId === null && p.sessionId === root.sessionId)) doomedPanelIds.add(p.id);
|
|
32159
|
+
}
|
|
32160
|
+
st.panels = st.panels.filter((p) => p.id !== root.id && !doomedPanelIds.has(p.id) && (p.kind === "conversation" ? !doomed.has(p.sessionId) : !("sessionId" in p) || p.sessionId === null || opts.family !== false && !doomed.has(p.sessionId)));
|
|
32161
|
+
if (st.selectedPanelId !== null && !st.panels.some((p) => p.id === st.selectedPanelId)) st.selectedPanelId = st.panels[Math.min(idx, st.panels.length - 1)]?.id ?? null;
|
|
32162
|
+
clearLoupeIfGone();
|
|
32163
|
+
}
|
|
32164
|
+
//#endregion
|
|
32165
|
+
//#region src/lib/services/panels/floor-registry/drag.svelte.ts
|
|
32166
|
+
var d$2 = floorSeam;
|
|
32167
|
+
/** Honest-slider's "slider sets all panels" leg (REALTIME, 2026-08-27):
|
|
32168
|
+
* one width for every CONVERSATION column + the uniform preset.
|
|
32169
|
+
* 2026-09-13: the workspace kinds are FIXED lanes — the explorer and
|
|
32170
|
+
* file panels keep their own widths. */
|
|
32171
|
+
function resizeAll(width) {
|
|
32172
|
+
const w = clampPanelWidth(width);
|
|
32173
|
+
d$2().setPanelWidthPreset(w);
|
|
32174
|
+
st.panels = st.panels.map((p) => p.kind === "conversation" ? {
|
|
32175
|
+
...p,
|
|
32176
|
+
width: w
|
|
32177
|
+
} : p);
|
|
32178
|
+
}
|
|
32179
|
+
/** A transcript file link publishes ONLY after the tree route proves
|
|
32180
|
+
* the file exists inside the session's workspace — the gate lives in
|
|
32181
|
+
* the shared util; anything else drops the click. No navigation ever
|
|
32182
|
+
* happens. No explorer yet ⇒ OPEN ONE (amendment 2026-09-25): the link
|
|
32183
|
+
* itself opens the panel; without a workspace root there is nothing to
|
|
32184
|
+
* open. W2 (T2.3): moved wholesale from the route — pure machine over
|
|
32185
|
+
* the deps seam + the shared utils. */
|
|
32186
|
+
async function openFileLinkFromMarkdown(sessionId, rawHref) {
|
|
32187
|
+
const { path, lines } = parseFileLinkHref(rawHref);
|
|
32188
|
+
if (path === "") return;
|
|
32189
|
+
const target = await resolveFileLinkTarget(sessionId, path, d$2().getWorkspaceFor(sessionId), void 0, workspaceRootDirs);
|
|
32190
|
+
if (target === null) return;
|
|
32191
|
+
if (!sessionWorkspaceExplorer(sessionId)) {
|
|
32192
|
+
const root = d$2().getWorkspaceFor(sessionId);
|
|
32193
|
+
if (!root) return;
|
|
32194
|
+
openWorkspaceExplorer(sessionId, root);
|
|
32195
|
+
}
|
|
32196
|
+
openWorkspaceFile(sessionId, target, lines);
|
|
32197
|
+
}
|
|
32198
|
+
/** /events?full=1 carries entries+lastSeq+running+pending/settled
|
|
32199
|
+
* answers (the ledger-tail resync surface); /history carries hasMore.
|
|
32200
|
+
* Its beforeSeq anchor needs the tail's lastSeq, so the events response
|
|
32201
|
+
* resolves first — the only serialization. W2 (T2.6): moved wholesale
|
|
32202
|
+
* from the route — a pure wire read over the global fetch. */
|
|
32203
|
+
async function fetchColdFromWire(sessionId) {
|
|
32204
|
+
const eventsRes = await fetch(`/api/dsh/session/${encodeURIComponent(sessionId)}/events?full=1`);
|
|
32205
|
+
if (!eventsRes.ok) return null;
|
|
32206
|
+
const events = await eventsRes.json();
|
|
32207
|
+
if (!events.ok) return null;
|
|
32208
|
+
const lastSeq = events.lastSeq ?? -1;
|
|
32209
|
+
let hasMore = false;
|
|
32210
|
+
const historyRes = await fetch(`/api/dsh/session/${encodeURIComponent(sessionId)}/history?beforeSeq=${lastSeq + 1}`);
|
|
32211
|
+
if (historyRes.ok) {
|
|
32212
|
+
const history = await historyRes.json();
|
|
32213
|
+
if (history.ok) hasMore = (history.entries?.length ?? 0) > 0 || history.hasMore === true;
|
|
32214
|
+
}
|
|
32215
|
+
return {
|
|
32216
|
+
title: null,
|
|
32217
|
+
workspace: null,
|
|
32218
|
+
agentPreset: null,
|
|
32219
|
+
entries: events.entries ?? [],
|
|
32220
|
+
lastSeq,
|
|
32221
|
+
running: events.running ?? false,
|
|
32222
|
+
hasMore,
|
|
32223
|
+
pendingAnswers: events.pendingAnswers ?? [],
|
|
32224
|
+
settledAnswers: events.settledAnswers ?? [],
|
|
32225
|
+
permission: events.permission ?? null,
|
|
32226
|
+
imageLimits: events.imageLimits ?? null,
|
|
32227
|
+
knobEvents: events.knobEvents ?? [],
|
|
32228
|
+
deliverables: events.deliverables ?? []
|
|
32229
|
+
};
|
|
32230
|
+
}
|
|
32231
|
+
//#endregion
|
|
32232
|
+
//#region src/lib/services/panels/floor-registry/factories.ts
|
|
32233
|
+
/**
|
|
32234
|
+
* floor-registry/factories — panel factories + placement slots (ADR-0022 W2).
|
|
32235
|
+
*
|
|
32236
|
+
* Moved WHOLE from the state home (floor-registry.svelte.ts): the eight
|
|
32237
|
+
* make* panel factories and the slot grammar (insertPanel, insertionSlot,
|
|
32238
|
+
* pinnedSlotIndex). Plain module: no runes here — every write goes through
|
|
32239
|
+
* the state home's reactive `st` hub and its primitives (ADR-0019 D2:
|
|
32240
|
+
* exactly ONE writer home for floor state). Sibling rule: this file never
|
|
32241
|
+
* imports another sibling; shared needs come from the state home.
|
|
32242
|
+
*/
|
|
32243
|
+
var d$1 = floorSeam;
|
|
32244
|
+
function makePanel(sessionId, agentPreset) {
|
|
32245
|
+
return {
|
|
32246
|
+
id: nextPanelId(),
|
|
32247
|
+
kind: "conversation",
|
|
32248
|
+
sessionId,
|
|
32249
|
+
agentPreset,
|
|
32250
|
+
width: clampPanelWidth(d$1().getPanelWidth())
|
|
32251
|
+
};
|
|
32252
|
+
}
|
|
32253
|
+
/** width: the reload-restored panel re-mints at the width the operator
|
|
32254
|
+
* dragged before (browser-slot persistence, RCA 2026-10-22); absent for
|
|
32255
|
+
* chip clicks and legacy slots — the honest-slider preset.
|
|
32256
|
+
* openedBy: the opener session's provenance, recorded ONCE at spawn and
|
|
32257
|
+
* never rewritten (ADR-0036 D1/D2); undefined = no conversation context. */
|
|
32258
|
+
function makeBrowserPanel(width, openedBy, sessionId) {
|
|
32259
|
+
return {
|
|
32260
|
+
id: nextPanelId(),
|
|
32261
|
+
kind: "browser",
|
|
32262
|
+
width: clampPanelWidth(width ?? browserPanelWidth(), "browser"),
|
|
32263
|
+
...openedBy !== void 0 ? { openedBy } : {},
|
|
32264
|
+
...sessionId !== void 0 ? { browserSessionId: sessionId } : {}
|
|
32265
|
+
};
|
|
32266
|
+
}
|
|
32267
|
+
function makeWorkspaceExplorerPanel(sessionId, root) {
|
|
32268
|
+
return {
|
|
32269
|
+
id: nextPanelId(),
|
|
32270
|
+
kind: "workspace-explorer",
|
|
32271
|
+
sessionId,
|
|
32272
|
+
root,
|
|
32273
|
+
expanded: [],
|
|
32274
|
+
width: clampPanelWidth(850, "workspace-explorer")
|
|
32275
|
+
};
|
|
32276
|
+
}
|
|
32277
|
+
function insertPanel(entry, index) {
|
|
32278
|
+
const next = [...st.panels];
|
|
32279
|
+
next.splice(Math.min(index, next.length), 0, entry);
|
|
32280
|
+
st.panels = next;
|
|
32281
|
+
st.selectedPanelId = entry.id;
|
|
32282
|
+
}
|
|
32283
|
+
function insertionSlot() {
|
|
32284
|
+
return focusedInsertionSlot(st.panels, selectedIndex_(), d$1().getMoveFacts().parentOf);
|
|
32285
|
+
}
|
|
32286
|
+
//#endregion
|
|
32287
|
+
//#region src/lib/services/panels/floor-registry.svelte.ts
|
|
32288
|
+
var deps = null;
|
|
32289
|
+
function configureFloorRegistry(d0) {
|
|
32290
|
+
deps = d0;
|
|
32291
|
+
}
|
|
32292
|
+
function d() {
|
|
32293
|
+
if (deps === null) throw new Error("floor-registry: configureFloorRegistry() was never called");
|
|
32294
|
+
return deps;
|
|
32295
|
+
}
|
|
32296
|
+
/** Sibling-module access to the dep seam (ADR-0022 W2): the ONE outside-reads
|
|
32297
|
+
* channel; siblings never open their own config channel. */
|
|
32298
|
+
function floorSeam() {
|
|
32299
|
+
return d();
|
|
32300
|
+
}
|
|
32301
|
+
var st = {
|
|
32302
|
+
panels: [],
|
|
32303
|
+
selectedPanelId: null,
|
|
32304
|
+
loupePanelId: null,
|
|
32305
|
+
focusComposerId: null,
|
|
32306
|
+
panelIdSeq: 0,
|
|
32307
|
+
terminalDeskMirrors: {},
|
|
32308
|
+
pendingFileIntents: {},
|
|
32309
|
+
fileIntentSeq: 0,
|
|
32310
|
+
drag: null,
|
|
32311
|
+
widthBadgeFading: false
|
|
32312
|
+
};
|
|
32313
|
+
/** Non-reactive gesture refs (drag start index, fade timer, badge ids) —
|
|
32314
|
+
* written by floor-registry/drag.svelte.ts; the ids set is a live
|
|
32315
|
+
* SvelteSet so badge visibility stays reactive. */
|
|
32316
|
+
var dragRefs = {
|
|
32317
|
+
ids: new SvelteSet()
|
|
32318
|
+
};
|
|
32319
|
+
var floor = {
|
|
32320
|
+
get panels() {
|
|
32321
|
+
return st.panels;
|
|
32322
|
+
},
|
|
32323
|
+
get selectedPanelId() {
|
|
32324
|
+
return st.selectedPanelId;
|
|
32325
|
+
},
|
|
32326
|
+
get loupePanelId() {
|
|
32327
|
+
return st.loupePanelId;
|
|
32328
|
+
},
|
|
32329
|
+
get focusComposerId() {
|
|
32330
|
+
return st.focusComposerId;
|
|
32331
|
+
},
|
|
32332
|
+
get terminalDeskMirrors() {
|
|
32333
|
+
return st.terminalDeskMirrors;
|
|
32334
|
+
},
|
|
32335
|
+
get pendingFileIntents() {
|
|
32336
|
+
return st.pendingFileIntents;
|
|
32337
|
+
},
|
|
32338
|
+
get drag() {
|
|
32339
|
+
return st.drag;
|
|
32340
|
+
},
|
|
32341
|
+
get widthBadgeFading() {
|
|
32342
|
+
return st.widthBadgeFading;
|
|
32343
|
+
},
|
|
32344
|
+
get widthBadgeIds() {
|
|
32345
|
+
return dragRefs.ids;
|
|
32346
|
+
},
|
|
32347
|
+
get selected() {
|
|
32348
|
+
return st.panels.find((p) => p.id === st.selectedPanelId) ?? null;
|
|
32349
|
+
},
|
|
32350
|
+
get loupePanel() {
|
|
32351
|
+
return st.panels.find((p) => p.id === st.loupePanelId) ?? null;
|
|
32352
|
+
}
|
|
32353
|
+
};
|
|
32354
|
+
function nextPanelId() {
|
|
32355
|
+
st.panelIdSeq += 1;
|
|
32356
|
+
return "panel-" + st.panelIdSeq;
|
|
32357
|
+
}
|
|
32358
|
+
function syncPanelIdSeq(entries) {
|
|
32359
|
+
for (const p of entries) {
|
|
32360
|
+
const m = /^panel-(\d+)$/.exec(p.id);
|
|
32361
|
+
if (m) st.panelIdSeq = Math.max(st.panelIdSeq, Number(m[1]));
|
|
32362
|
+
}
|
|
32363
|
+
}
|
|
32364
|
+
function initFloor(entries, selectedId) {
|
|
32365
|
+
st.panels = entries;
|
|
32366
|
+
st.selectedPanelId = selectedId;
|
|
32367
|
+
syncPanelIdSeq(entries);
|
|
32368
|
+
}
|
|
32369
|
+
/** The fresh panel mounted and its composer took focus — clear the
|
|
32370
|
+
* swap-focus marker (a marker whose panel never mounts stays inert:
|
|
32371
|
+
* panel ids are unique and never remount). */
|
|
32372
|
+
function clearFocusComposer() {
|
|
32373
|
+
st.focusComposerId = null;
|
|
32374
|
+
}
|
|
32375
|
+
function selectPanel(panelId) {
|
|
32376
|
+
if (st.panels.some((p) => p.id === panelId)) st.selectedPanelId = panelId;
|
|
32377
|
+
}
|
|
32378
|
+
function closeLoupe() {
|
|
32379
|
+
st.loupePanelId = null;
|
|
32380
|
+
}
|
|
32381
|
+
function clearLoupeIfGone() {
|
|
32382
|
+
if (st.loupePanelId !== null && !st.panels.some((p) => p.id === st.loupePanelId)) st.loupePanelId = null;
|
|
32383
|
+
}
|
|
32384
|
+
function selectedIndex_() {
|
|
32385
|
+
return st.panels.findIndex((p) => p.id === st.selectedPanelId);
|
|
32386
|
+
}
|
|
32387
|
+
//#endregion
|
|
32388
|
+
//#region src/lib/utils/compact-number.ts
|
|
32389
|
+
/** Compact number formatting for narrow UI badges: 1829 -> '1.8K',
|
|
32390
|
+
* 4200000 -> '4.2M'. Locale-stable ('en') so rack rows keep their width. */
|
|
32391
|
+
var compact = new Intl.NumberFormat("en", {
|
|
32392
|
+
notation: "compact",
|
|
32393
|
+
maximumFractionDigits: 1
|
|
32394
|
+
});
|
|
32395
|
+
function formatCompact(n) {
|
|
32396
|
+
return compact.format(n);
|
|
32397
|
+
}
|
|
32398
|
+
//#endregion
|
|
32399
|
+
//#region src/lib/components/anchor/subagent-anchor/SubagentPopup.svelte
|
|
32400
|
+
function SubagentPopup($$renderer, $$props) {
|
|
32401
|
+
$$renderer.component(($$renderer) => {
|
|
32402
|
+
/**
|
|
32403
|
+
* SubagentPopup — the ledger half of the Subagent Anchor (Subagent
|
|
32404
|
+
* Anchor ADR D1/D5, amendment D6/D7): every spawned session as ONE flat
|
|
32405
|
+
* row — title · tokens · elapsed — inside the house popup shell (Esc /
|
|
32406
|
+
* outside close, right-full placement, width cap). The popup owns NO
|
|
32407
|
+
* state: rows arrive as props from the anchor button's poll; elapsed
|
|
32408
|
+
* lives only in the subagent-clock registry; lineage is re-derived
|
|
32409
|
+
* per fetch upstream, never written here.
|
|
32410
|
+
*
|
|
32411
|
+
* D6 header: shell title row + the count chip (N helpers, M running).
|
|
32412
|
+
* D5 sort: running first, then token spend descending (nulls last).
|
|
32413
|
+
* D7 footer: Σ over EXACTLY the header's rows; any null-degraded row
|
|
32414
|
+
* flips it to the honest Σ-incomplete marker — a partial sum must never
|
|
32415
|
+
* read as whole. Elapsed is NOT summed (concurrent wall-clocks add to
|
|
32416
|
+
* nothing). The footnote states the one-tick first-sight bias.
|
|
32417
|
+
*/
|
|
32418
|
+
let { open = false, triggerEl = void 0, rows, onopenrow } = $$props;
|
|
32419
|
+
const spend = (row) => row.tokens === null ? -1 : row.tokens.input + row.tokens.output;
|
|
32420
|
+
/** D5: running first, then token spend desc (unknown spends last),
|
|
32421
|
+
* then session id for a stable tiebreak. */
|
|
32422
|
+
const sorted = derived(() => [...rows].sort((a, b) => Number(b.running) - Number(a.running) || spend(b) - spend(a) || a.sessionId.localeCompare(b.sessionId)));
|
|
32423
|
+
const runningCount = derived(() => rows.filter((r) => r.running).length);
|
|
32424
|
+
const anyUnknown = derived(() => rows.some((r) => r.tokens === null));
|
|
32425
|
+
const totalTokens = derived(() => rows.reduce((acc, r) => r.tokens === null ? acc : acc + r.tokens.input + r.tokens.output, 0));
|
|
32426
|
+
/** True when this helper's panel is already open on the floor — the
|
|
32427
|
+
* row tints so the operator sees which helpers live in the zoom. */
|
|
32428
|
+
function onFloor(sessionId) {
|
|
32429
|
+
return floorPanelId(sessionId) !== null;
|
|
32430
|
+
}
|
|
32431
|
+
/** The floor panel id hosting this helper, null when not open. */
|
|
32432
|
+
function floorPanelId(sessionId) {
|
|
32433
|
+
return floor.panels.find((panel) => "sessionId" in panel && panel.sessionId === sessionId)?.id ?? null;
|
|
32434
|
+
}
|
|
32435
|
+
/** Any helper live on the floor — the close-all X's visibility. */
|
|
32436
|
+
const anyOnFloor = derived(() => rows.some((r) => onFloor(r.sessionId)));
|
|
32437
|
+
/** Compact ledger form, DSH GUI parity — null renders the dash (never 0). */
|
|
32438
|
+
function tokensLabel(row) {
|
|
32439
|
+
if (row.tokens === null) return "—";
|
|
32440
|
+
return `${formatCompact(row.tokens.input + row.tokens.output)} tok`;
|
|
32441
|
+
}
|
|
32442
|
+
/** Elapsed label — the ledger's operate time (llmMs, the stats bar's
|
|
32443
|
+
* own 'LLM …' number, settled rows included). The first-sight clock is
|
|
32444
|
+
* the FALLBACK for rows the host cannot date; null renders the dash
|
|
32445
|
+
* (never a guess). */
|
|
32446
|
+
function elapsedLabel(row) {
|
|
32447
|
+
let ms;
|
|
32448
|
+
if (typeof row.operateMs === "number") ms = row.operateMs;
|
|
32449
|
+
else ms = subagentClock.elapsedMs(row.sessionId);
|
|
32450
|
+
if (ms === null) return "—";
|
|
32451
|
+
const s = Math.floor(ms / 1e3);
|
|
32452
|
+
if (s < 60) return `${s}s`;
|
|
32453
|
+
const m = Math.floor(s / 60);
|
|
32454
|
+
if (m < 60) return `${m}m ${s % 60}s`;
|
|
32455
|
+
return `${Math.floor(m / 60)}h ${m % 60}m`;
|
|
32456
|
+
}
|
|
32457
|
+
let $$settled = true;
|
|
32458
|
+
let $$inner_renderer;
|
|
32459
|
+
function $$render_inner($$renderer) {
|
|
32460
|
+
FloatingAnchorContainerPopup($$renderer, {
|
|
32461
|
+
triggerEl,
|
|
32462
|
+
popupTestId: "subagent-popup",
|
|
32463
|
+
get open() {
|
|
32464
|
+
return open;
|
|
32465
|
+
},
|
|
32466
|
+
set open($$value) {
|
|
32467
|
+
open = $$value;
|
|
32468
|
+
$$settled = false;
|
|
32469
|
+
},
|
|
32470
|
+
children: ($$renderer) => {
|
|
32471
|
+
$$renderer.push(`<div class="flex items-center border-b border-surface-border px-2.5 py-1 text-[10px] uppercase tracking-wider text-text-muted" data-testid="subagent-popup-chip"><span class="flex-1">${escape_html(rows.length)}
|
|
32472
|
+
${escape_html(rows.length === 1 ? "subagent" : "subagents")} · ${escape_html(runningCount())} running</span> `);
|
|
32473
|
+
if (anyOnFloor()) {
|
|
32474
|
+
$$renderer.push("<!--[0-->");
|
|
32475
|
+
$$renderer.push(`<button type="button" class="shrink-0 transition-colors"${attr("title", t(subagentcloseallpanels3))}${attr("aria-label", t(subagentcloseallpanels3))} data-testid="subagent-popup-close-all">`);
|
|
32476
|
+
Trash_2($$renderer, {
|
|
32477
|
+
size: 14,
|
|
32478
|
+
"aria-hidden": "true",
|
|
32479
|
+
style: "stroke: red;"
|
|
32480
|
+
});
|
|
32481
|
+
$$renderer.push(`<!----></button>`);
|
|
32482
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32483
|
+
$$renderer.push(`<!--]--></div> <!--[-->`);
|
|
32484
|
+
const each_array = ensure_array_like(sorted());
|
|
32485
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
32486
|
+
let row = each_array[$$index];
|
|
32487
|
+
$$renderer.push(`<button type="button"${attr_class(`flex w-full items-center gap-2 px-2.5 py-1.5 text-left text-xs transition-colors hover:bg-surface-hover ${onFloor(row.sessionId) ? "row-on-floor" : ""}`, "svelte-1lupp7r")} data-testid="subagent-row"><span${attr_class(`flex shrink-0 items-center ${row.running ? "text-amber-500" : "text-text-muted"}`)} data-testid="subagent-row-glyph">`);
|
|
32488
|
+
if (row.running) {
|
|
32489
|
+
$$renderer.push("<!--[0-->");
|
|
32490
|
+
Loader_circle($$renderer, {
|
|
32491
|
+
size: 11,
|
|
32492
|
+
class: "animate-spin"
|
|
32493
|
+
});
|
|
32494
|
+
} else {
|
|
32495
|
+
$$renderer.push("<!--[-1-->");
|
|
32496
|
+
Circle_dashed($$renderer, { size: 11 });
|
|
32497
|
+
}
|
|
32498
|
+
$$renderer.push(`<!--]--></span> <span class="min-w-0 flex-1 truncate">${escape_html(row.title ?? "—")}</span> <span class="w-20 shrink-0 text-right font-variant-numeric tabular-nums" data-testid="subagent-row-tokens">${escape_html(tokensLabel(row))}</span> <span class="w-14 shrink-0 text-right text-text-muted tabular-nums" data-testid="subagent-row-elapsed">${escape_html(elapsedLabel(row))}</span></button>`);
|
|
32499
|
+
}
|
|
32500
|
+
$$renderer.push(`<!--]--> <div${attr_class(`sticky bottom-0 flex items-center border-t border-surface-border bg-surface-elevated px-2.5 py-1.5 text-[12px] font-medium tracking-wider ${anyUnknown() ? "text-text-muted" : "text-text-primary"}`)} data-testid="subagent-popup-footer" style="padding-right: 6em;"><span class="flex-1 text-right">${escape_html(t(() => totaltokens1()))}</span> <span class="w-20 shrink-0 text-right font-variant-numeric tabular-nums" data-testid="subagent-popup-footer-tokens">${escape_html(anyUnknown() ? "—" : `${formatCompact(totalTokens())} tok`)}</span></div>`);
|
|
32501
|
+
},
|
|
32502
|
+
$$slots: { default: true }
|
|
32503
|
+
});
|
|
32504
|
+
}
|
|
32505
|
+
do {
|
|
32506
|
+
$$settled = true;
|
|
32507
|
+
$$inner_renderer = $$renderer.copy();
|
|
32508
|
+
$$render_inner($$inner_renderer);
|
|
32509
|
+
} while (!$$settled);
|
|
32510
|
+
$$renderer.subsume($$inner_renderer);
|
|
32511
|
+
bind_props($$props, { open });
|
|
32512
|
+
});
|
|
32513
|
+
}
|
|
32514
|
+
//#endregion
|
|
32515
|
+
//#region src/lib/components/anchor/subagent-anchor/SubagentAnchorButton.svelte
|
|
32516
|
+
function SubagentAnchorButton($$renderer, $$props) {
|
|
32517
|
+
$$renderer.component(($$renderer) => {
|
|
32518
|
+
/**
|
|
32519
|
+
* SubagentAnchorButton — the ledger leaf of the conversation page's
|
|
32520
|
+
* FloatingAnchor stack (Subagent Anchor ADR D1, placement REVISED
|
|
32521
|
+
* 2026-10-26: the operator's 'anchor' means the right-edge icon
|
|
32522
|
+
* column beside the transcript — JobsButton's seat — NOT the sidebar
|
|
32523
|
+
* header). Lists THIS conversation's sub-agents only (the ?parent
|
|
32524
|
+
* scoping, DSH dropdown parity) — one click: title, tokens, elapsed.
|
|
32525
|
+
* Hidden at zero rows so the stack keeps its shape. Owns the poll:
|
|
32526
|
+
* one GET per few seconds while mounted, each answer fed to the
|
|
32527
|
+
* subagent-clock registry as its spine tick (ADR D3).
|
|
32528
|
+
*/
|
|
32529
|
+
let { onopensession = void 0} = $$props;
|
|
32530
|
+
let rows = [];
|
|
32531
|
+
let open = false;
|
|
32532
|
+
/** The toggle's wrapper — the shell's close-contract exclusion. */
|
|
32533
|
+
let triggerEl = void 0;
|
|
32534
|
+
const runningCount = derived(() => rows.filter((r) => r.running).length);
|
|
32535
|
+
let $$settled = true;
|
|
32536
|
+
let $$inner_renderer;
|
|
32537
|
+
function $$render_inner($$renderer) {
|
|
32538
|
+
if (rows.length > 0) {
|
|
32539
|
+
$$renderer.push("<!--[0-->");
|
|
32540
|
+
$$renderer.push(`<div data-svelte="SubagentAnchorButton" class="relative" data-testid="subagent-anchor-button"><button type="button"${attr_class(`floating-anchor-btn ${runningCount() > 0 ? "tone-purple" : "tone-idle"}`, "svelte-1vxt4fg", { "active": open })}${attr("title", t(subagentanchorlabel2))}${attr("aria-label", t(subagentanchorlabel2))} data-testid="subagent-anchor-trigger">`);
|
|
32541
|
+
Bot($$renderer, {
|
|
32542
|
+
size: 13,
|
|
32543
|
+
"aria-hidden": "true"
|
|
32544
|
+
});
|
|
32545
|
+
$$renderer.push(`<!----> <span data-testid="subagent-anchor-badge">${escape_html(runningCount() > 0 ? runningCount() : rows.length)}</span></button> `);
|
|
32546
|
+
SubagentPopup($$renderer, {
|
|
32547
|
+
triggerEl,
|
|
32548
|
+
rows,
|
|
32549
|
+
onopenrow: onopensession,
|
|
32550
|
+
get open() {
|
|
32551
|
+
return open;
|
|
32552
|
+
},
|
|
32553
|
+
set open($$value) {
|
|
32554
|
+
open = $$value;
|
|
32555
|
+
$$settled = false;
|
|
32556
|
+
}
|
|
32557
|
+
});
|
|
32558
|
+
$$renderer.push(`<!----></div>`);
|
|
32559
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32560
|
+
$$renderer.push(`<!--]-->`);
|
|
32561
|
+
}
|
|
32562
|
+
do {
|
|
32563
|
+
$$settled = true;
|
|
32564
|
+
$$inner_renderer = $$renderer.copy();
|
|
32565
|
+
$$render_inner($$inner_renderer);
|
|
32566
|
+
} while (!$$settled);
|
|
32567
|
+
$$renderer.subsume($$inner_renderer);
|
|
32568
|
+
});
|
|
32569
|
+
}
|
|
32570
|
+
//#endregion
|
|
32571
|
+
//#region src/lib/components/conversation/panel/ConversationFloatingAnchor.svelte
|
|
32572
|
+
function ConversationFloatingAnchor($$renderer, $$props) {
|
|
32573
|
+
/**
|
|
32574
|
+
* ConversationFloatingAnchor — the conversation page's floating action
|
|
32575
|
+
* stack (OCI Floating Host port, 2026-08-23; extracted from the page
|
|
32576
|
+
* 2026-08-24): jump and scroll actions beside the transcript they act
|
|
32577
|
+
* on — the User Messages button (self-contained with its popup jumper
|
|
32578
|
+
* since 2026-08-26; renders only when prompt groups exist) and the
|
|
32579
|
+
* far-edge jump. Purely presentational — the viewport and turn groups
|
|
32580
|
+
* arrive as props.
|
|
32581
|
+
*/
|
|
32582
|
+
let { groups, container, todos = null, deliverables = null, onfileopen = void 0, jobsessionid = "", shelfentries = void 0, shelfsessionid = "", shelfworkspace = null, shelfpanelid = null, onshelfnote } = $$props;
|
|
32583
|
+
if (container !== void 0) {
|
|
32584
|
+
$$renderer.push("<!--[0-->");
|
|
32585
|
+
FloatingAnchor($$renderer, {
|
|
32586
|
+
children: ($$renderer) => {
|
|
32587
|
+
PlanButton($$renderer, { todos: todos ?? [] });
|
|
32588
|
+
$$renderer.push(`<!----> `);
|
|
32589
|
+
DeliverablesButton($$renderer, {
|
|
32590
|
+
deliveries: deliverables,
|
|
32591
|
+
onfileopen
|
|
32592
|
+
});
|
|
32593
|
+
$$renderer.push(`<!----> `);
|
|
32594
|
+
JobsButton($$renderer, { sessionId: jobsessionid });
|
|
32595
|
+
$$renderer.push(`<!----> `);
|
|
32596
|
+
SubagentAnchorButton($$renderer, { });
|
|
32597
|
+
$$renderer.push(`<!----> `);
|
|
32598
|
+
if (shelfentries !== void 0) {
|
|
32599
|
+
$$renderer.push("<!--[0-->");
|
|
32600
|
+
InjectedShelfButton($$renderer, {
|
|
32601
|
+
entries: shelfentries,
|
|
32602
|
+
sessionId: shelfsessionid,
|
|
32603
|
+
workspace: shelfworkspace,
|
|
32604
|
+
panelId: shelfpanelid,
|
|
32605
|
+
onnote: onshelfnote
|
|
32606
|
+
});
|
|
32607
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32608
|
+
$$renderer.push(`<!--]--> `);
|
|
32609
|
+
UserMessagesButton($$renderer, {
|
|
32610
|
+
groups,
|
|
32611
|
+
container
|
|
32612
|
+
});
|
|
32613
|
+
$$renderer.push(`<!----> `);
|
|
32614
|
+
BackToTheEdgeButton($$renderer);
|
|
32615
|
+
$$renderer.push(`<!---->`);
|
|
32616
|
+
}});
|
|
32617
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32618
|
+
$$renderer.push(`<!--]-->`);
|
|
32619
|
+
}
|
|
32620
|
+
//#endregion
|
|
32621
|
+
//#region src/lib/components/conversation/panel/A2aChipStack.svelte
|
|
32622
|
+
function A2aChipStack($$renderer, $$props) {
|
|
32623
|
+
$$renderer.component(($$renderer) => {
|
|
32624
|
+
/**
|
|
32625
|
+
* A2aChipStack — the sender panel's read-only delegation-ledger join
|
|
32626
|
+
* (W4 4.2): one floating chip per recent exchange THIS panel sent,
|
|
32627
|
+
* rendered beside the transcript on the floating-anchor pattern
|
|
32628
|
+
* (right-middle stack, per-panel via the embedded anchor host).
|
|
32629
|
+
*
|
|
32630
|
+
* Honesty contract (PRD risk "Attribution overclaim in UI" + spec-check
|
|
32631
|
+
* GAP-5): chip text derives from the row's `state` VERBATIM, all six
|
|
32632
|
+
* states distinguished — `replied_approx` renders "may have replied",
|
|
32633
|
+
* NEVER the confident "replied" string. The ledger is the truth; this
|
|
32634
|
+
* component claims nothing the row does not say.
|
|
32635
|
+
*
|
|
32636
|
+
* Read-only by construction (BC-2): rows arrive as a prop from the
|
|
32637
|
+
* page's EXISTING spine-cadence poll of GET /api/a2a?from= — the chip
|
|
32638
|
+
* owns NO fetch, NO timer. Click = the existing panel doorway
|
|
32639
|
+
* (addPanelFromSidebar dedupe→select). Dismiss is LOCAL-ONLY visual:
|
|
32640
|
+
* rows are durable; the next poll brings a dismissed chip back only
|
|
32641
|
+
* when it is still in the page's fetched window.
|
|
32642
|
+
*/
|
|
32643
|
+
let { rows, titles } = $$props;
|
|
32644
|
+
/** Local-only visual dismissal — rows are durable; the ledger is truth. */
|
|
32645
|
+
let dismissed = /* @__PURE__ */ new Set();
|
|
32646
|
+
/** The cap: newest 3 visible + one overflow indicator (spec 4.2). */
|
|
32647
|
+
const CHIP_CAP = 3;
|
|
32648
|
+
const visible = derived(() => rows.filter((r) => !dismissed.has(r.id)));
|
|
32649
|
+
const capped = derived(() => visible().slice(0, CHIP_CAP));
|
|
32650
|
+
const overflow = derived(() => Math.max(visible().length - CHIP_CAP, 0));
|
|
32651
|
+
/**
|
|
32652
|
+
* Chip text derives from the state VERBATIM (spec-check GAP-5): every
|
|
32653
|
+
* state distinguished, `replied_approx` hedged as "may have replied" —
|
|
32654
|
+
* never a confident claim the row cannot support.
|
|
32655
|
+
*/
|
|
32656
|
+
function labelFor(state) {
|
|
32657
|
+
switch (state) {
|
|
32658
|
+
case "waiting": return "waiting";
|
|
32659
|
+
case "replied_exact": return "replied (exact)";
|
|
32660
|
+
case "replied": return "replied";
|
|
32661
|
+
case "replied_approx": return "may have replied";
|
|
32662
|
+
case "timeout": return "no reply (timeout)";
|
|
32663
|
+
case "gone": return "target gone";
|
|
32664
|
+
}
|
|
32665
|
+
}
|
|
32666
|
+
/** The target's display title — the spine title, else the id prefix. */
|
|
32667
|
+
function titleFor(toSession) {
|
|
32668
|
+
return titles[toSession] ?? toSession.replace(/^session-/, "").slice(0, 8);
|
|
32669
|
+
}
|
|
32670
|
+
if (visible().length > 0) {
|
|
32671
|
+
$$renderer.push("<!--[0-->");
|
|
32672
|
+
FloatingAnchor($$renderer, {
|
|
32673
|
+
children: ($$renderer) => {
|
|
32674
|
+
$$renderer.push(`<!--[-->`);
|
|
32675
|
+
const each_array = ensure_array_like(capped());
|
|
32676
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
32677
|
+
let row = each_array[$$index];
|
|
32678
|
+
$$renderer.push(`<div class="a2a-chip-wrap" data-testid="a2a-chip"${attr("data-a2a-state", row.state)}${attr("data-a2a-id", row.id)}><button type="button"${attr_class("a2a-chip", void 0, {
|
|
32679
|
+
"tone-waiting": row.state === "waiting",
|
|
32680
|
+
"tone-replied-exact": row.state === "replied_exact",
|
|
32681
|
+
"tone-replied": row.state === "replied",
|
|
32682
|
+
"tone-replied-approx": row.state === "replied_approx",
|
|
32683
|
+
"tone-timeout": row.state === "timeout",
|
|
32684
|
+
"tone-gone": row.state === "gone"
|
|
32685
|
+
})} data-testid="a2a-chip-button"${attr("title", `${stringify(titleFor(row.toSession))} — ${stringify(labelFor(row.state))}`)}>`);
|
|
32686
|
+
if (row.state === "waiting") {
|
|
32687
|
+
$$renderer.push("<!--[0-->");
|
|
32688
|
+
Hourglass($$renderer, { size: 13 });
|
|
32689
|
+
} else if (row.state === "replied_exact" || row.state === "replied") {
|
|
32690
|
+
$$renderer.push("<!--[1-->");
|
|
32691
|
+
Check($$renderer, { size: 13 });
|
|
32692
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32693
|
+
$$renderer.push(`<!--]--> <span class="a2a-chip-label">${escape_html(labelFor(row.state))}</span></button> <button type="button" class="a2a-dismiss" data-testid="a2a-chip-dismiss" title="hide this chip (the ledger row stays)">`);
|
|
32694
|
+
X($$renderer, { size: 11 });
|
|
32695
|
+
$$renderer.push(`<!----></button></div>`);
|
|
32696
|
+
}
|
|
32697
|
+
$$renderer.push(`<!--]--> `);
|
|
32698
|
+
if (overflow() > 0) {
|
|
32699
|
+
$$renderer.push("<!--[0-->");
|
|
32700
|
+
$$renderer.push(`<div class="a2a-chip-overflow" data-testid="a2a-chip-overflow">+${escape_html(overflow())} more</div>`);
|
|
32701
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32702
|
+
$$renderer.push(`<!--]-->`);
|
|
32703
|
+
}});
|
|
32704
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32705
|
+
$$renderer.push(`<!--]-->`);
|
|
32706
|
+
});
|
|
32707
|
+
}
|
|
32708
|
+
//#endregion
|
|
32709
|
+
//#region src/lib/components/conversation/panel/ConversationStatsBar.svelte
|
|
32710
|
+
function ConversationStatsBar($$renderer, $$props) {
|
|
32711
|
+
$$renderer.component(($$renderer) => {
|
|
32712
|
+
/**
|
|
32713
|
+
* ConversationStatsBar — the panel's session baseline (ADR 2026-09-08
|
|
32714
|
+
* "The Stats Bar", D1/D3/D5): one fixed-height line under the transcript
|
|
32715
|
+
* showing what the ledger already proves — turns, steps, tool time,
|
|
32716
|
+
* token totals, cache hit. Pure presentation: the panel derives the
|
|
32717
|
+
* stats and hands them down; segments whose inputs never reached DSI
|
|
32718
|
+
* are omitted, never approximated. Renders nothing before the first
|
|
32719
|
+
* assistant message (D5 gate lives in the derive's null return).
|
|
32720
|
+
*/
|
|
32721
|
+
let { stats } = $$props;
|
|
32722
|
+
/** 85000 -> "1m25s"; 2400000 -> "40m"; 5400000 -> "1h30m"; 250 -> "250ms". */
|
|
32723
|
+
function formatDuration(ms) {
|
|
32724
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
32725
|
+
const totalSec = Math.floor(ms / 1e3);
|
|
32726
|
+
const h = Math.floor(totalSec / 3600);
|
|
32727
|
+
const m = Math.floor(totalSec % 3600 / 60);
|
|
32728
|
+
const s = totalSec % 60;
|
|
32729
|
+
if (h > 0) return `${h}h${m}m`;
|
|
32730
|
+
if (m > 0) return s > 0 ? `${m}m${s}s` : `${m}m`;
|
|
32731
|
+
return `${s}s`;
|
|
32732
|
+
}
|
|
32733
|
+
/** 15800 -> "15.8K"; 56300 -> "56.3K"; 15800000 -> "15.8M"; 108000 -> "108K"; 999 -> "999". */
|
|
32734
|
+
function formatTokens(n) {
|
|
32735
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1).replace(/\.0$/, "")}M`;
|
|
32736
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1).replace(/\.0$/, "")}K`;
|
|
32737
|
+
return String(n);
|
|
32738
|
+
}
|
|
32739
|
+
const segments = derived(() => {
|
|
32740
|
+
if (stats === null) return [];
|
|
32741
|
+
const parts = [`${stats.turns} turns · ${stats.steps} steps`];
|
|
32742
|
+
const durations = [];
|
|
32743
|
+
if (stats.llmMs !== void 0 && stats.llmMs > 0) durations.push(`LLM ${formatDuration(stats.llmMs)}`);
|
|
32744
|
+
if (stats.toolMs > 0) durations.push(`Tool ${formatDuration(stats.toolMs)}`);
|
|
32745
|
+
if (durations.length > 0) parts.push(durations.join(" · "));
|
|
32746
|
+
const speeds = [];
|
|
32747
|
+
if (stats.ttftSteps !== void 0 && stats.ttftSteps > 0 && stats.ttftMs !== void 0) speeds.push(`TTFT avg ${formatDuration(stats.ttftMs / stats.ttftSteps)}`);
|
|
32748
|
+
if (stats.decodeMs !== void 0 && stats.decodeMs > 0 && stats.decodeTokens !== void 0) speeds.push(`${Math.max(1, Math.round(stats.decodeTokens / (stats.decodeMs / 1e3)))} tok/s`);
|
|
32749
|
+
if (speeds.length > 0) parts.push(speeds.join(" · "));
|
|
32750
|
+
const inputTotal = stats.billedInputTokens ?? stats.inputTokens;
|
|
32751
|
+
if (inputTotal !== void 0) parts.push(`Input ${formatTokens(inputTotal)} tok · Output ${formatTokens(stats.outputTokens ?? 0)} tok`);
|
|
32752
|
+
if (stats.cacheHitPercent !== void 0) parts.push(`Cache hit ${stats.cacheHitPercent}%`);
|
|
32753
|
+
return parts;
|
|
32754
|
+
});
|
|
32755
|
+
if (stats !== null) {
|
|
32756
|
+
$$renderer.push("<!--[0-->");
|
|
32757
|
+
$$renderer.push(`<div data-svelte="ConversationStatsBar" class="stats-bar svelte-hnxn10" data-testid="conversation-stats-bar"${attr("title", segments().join(" | "))}><!--[-->`);
|
|
32758
|
+
const each_array = ensure_array_like(segments());
|
|
32759
|
+
for (let i = 0, $$length = each_array.length; i < $$length; i++) {
|
|
32760
|
+
let segment = each_array[i];
|
|
32761
|
+
if (i > 0) {
|
|
32762
|
+
$$renderer.push("<!--[0-->");
|
|
32763
|
+
$$renderer.push(`<span class="sep svelte-hnxn10" aria-hidden="true">|</span>`);
|
|
32764
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32765
|
+
$$renderer.push(`<!--]--> <span class="segment svelte-hnxn10" data-testid="stats-segment">${escape_html(segment)}</span>`);
|
|
32766
|
+
}
|
|
32767
|
+
$$renderer.push(`<!--]--></div>`);
|
|
32768
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32769
|
+
$$renderer.push(`<!--]-->`);
|
|
32770
|
+
});
|
|
32771
|
+
}
|
|
32772
|
+
//#endregion
|
|
32773
|
+
//#region src/lib/components/conversation/panel/submit-ladder.svelte.ts
|
|
32774
|
+
var SubmitLadder = class {
|
|
32775
|
+
deps;
|
|
32776
|
+
/** True while the plain-send rung is in flight — the footer's sending flag. */
|
|
32777
|
+
submitted = false;
|
|
32778
|
+
/** Inline command feedback (role=status, auto-dismiss 5s) — the ONLY
|
|
32779
|
+
* command UI surface; the input has already cleared by intercept time.
|
|
32780
|
+
* The wire work lives in command-executor (Prompt Macro W1 1.2): the
|
|
32781
|
+
* /new create+swap, /permission route, and mention delivery are the
|
|
32782
|
+
* SAME bytes the typed path always sent — the panel now renders
|
|
32783
|
+
* outcomes only (banner kind from result.ok). */
|
|
32784
|
+
commandNote = null;
|
|
32785
|
+
commandNoteTimer;
|
|
32786
|
+
constructor(deps) {
|
|
32787
|
+
this.deps = deps;
|
|
32788
|
+
}
|
|
32789
|
+
/** Inline command feedback — every rung banners through here. */
|
|
32790
|
+
noteCommand(kind, text) {
|
|
32791
|
+
this.commandNote = {
|
|
32792
|
+
kind,
|
|
32793
|
+
text
|
|
32794
|
+
};
|
|
32795
|
+
if (this.commandNoteTimer !== void 0) clearTimeout(this.commandNoteTimer);
|
|
32796
|
+
this.commandNoteTimer = setTimeout(() => this.commandNote = null, 5e3);
|
|
32797
|
+
}
|
|
32798
|
+
async onsubmit(text, images) {
|
|
32799
|
+
if (isTypedRun(text)) {
|
|
32800
|
+
this.deps.startMacro({
|
|
32801
|
+
text,
|
|
32802
|
+
id: -1
|
|
32803
|
+
}, false);
|
|
32804
|
+
return true;
|
|
32805
|
+
}
|
|
32806
|
+
const command = parseCommand(text);
|
|
32807
|
+
if (command !== null) {
|
|
32808
|
+
let bannered = false;
|
|
32809
|
+
const result = await executeCommand(command, this.deps.ctx(), (ok, note) => {
|
|
32810
|
+
bannered = true;
|
|
32811
|
+
this.noteCommand(ok ? "ok" : "error", note);
|
|
32812
|
+
});
|
|
32813
|
+
if (!bannered && result.note !== void 0) this.noteCommand(result.ok ? "ok" : "error", result.note);
|
|
32814
|
+
return true;
|
|
32815
|
+
}
|
|
32816
|
+
if (text.trim().length === 0 && images.length === 0) return false;
|
|
32817
|
+
const slashCatalog = this.deps.slashCatalog;
|
|
32818
|
+
if (slashCatalog?.state === "ready") {
|
|
32819
|
+
if (resolveHostCommand(text, slashCatalog.commands) !== null) return (await executeHostCommand(text, this.deps.ctx(), (ok, note) => this.noteCommand(ok ? "ok" : "error", note))).ok;
|
|
32820
|
+
}
|
|
32821
|
+
this.submitted = true;
|
|
32822
|
+
try {
|
|
32823
|
+
return (await sendPrompt(text, this.deps.ctx(), (t) => this.deps.orchestrator.submit(t, images))).ok;
|
|
32824
|
+
} finally {
|
|
32825
|
+
this.submitted = false;
|
|
32826
|
+
}
|
|
32827
|
+
}
|
|
32828
|
+
async oncancel() {
|
|
32829
|
+
await this.deps.orchestrator.cancel();
|
|
32830
|
+
}
|
|
32831
|
+
/** Menu command pick: the SAME rung the ladder uses (one execution
|
|
32832
|
+
* surface, D2), banner notes through the shared note path; the
|
|
32833
|
+
* boolean admits the composer's draft clearing (BC-A3). */
|
|
32834
|
+
async onpickcommand(line) {
|
|
32835
|
+
return (await executeHostCommand(line, this.deps.ctx(), (ok, note) => this.noteCommand(ok ? "ok" : "error", note))).ok;
|
|
32836
|
+
}
|
|
32837
|
+
};
|
|
32838
|
+
//#endregion
|
|
32839
|
+
//#region src/lib/utils/auto-open-slots.ts
|
|
32840
|
+
/** The newest reasoning entry's id (wire order), else null — the
|
|
32841
|
+
* transient think target. Empty reasoning strings do not count (the
|
|
32842
|
+
* chip renders nothing to open). */
|
|
32843
|
+
function newestReasoningId(entries) {
|
|
32844
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
32845
|
+
const e = entries[i];
|
|
32846
|
+
if (e.kind === "assistant-message" && e.reasoning !== void 0 && e.reasoning !== "") return e.id;
|
|
32847
|
+
}
|
|
32848
|
+
return null;
|
|
32849
|
+
}
|
|
32850
|
+
/** Suppression-aware view of a raw target: null while the user kept THIS
|
|
32851
|
+
* id collapsed (a newer target id simply stops matching). */
|
|
32852
|
+
function suppressed(targetId, suppressedId) {
|
|
32853
|
+
return targetId !== null && suppressedId === targetId ? null : targetId;
|
|
32854
|
+
}
|
|
32855
|
+
//#endregion
|
|
32856
|
+
//#region src/lib/components/conversation/panel/popups.svelte.ts
|
|
32857
|
+
var Popups = class {
|
|
32858
|
+
/** Chip popup state (2026-08-22, OCI pattern): ONE open chip at a time —
|
|
32859
|
+
* the id of the expanded entry; detail renders AFTER the chip row.
|
|
32860
|
+
* Per-panel by construction (moved here with the block). */
|
|
32861
|
+
openChipId = null;
|
|
32862
|
+
/** Peek popup state (ToolPeekButton port, 2026-08-22): the run key whose
|
|
32863
|
+
* chip row has its list popup open — ONE at a time, and never while a
|
|
32864
|
+
* chip detail popup is open (OCI mutual-exclusion contract). */
|
|
32865
|
+
peekOpenRunKey = null;
|
|
32866
|
+
thinkSuppressedId = null;
|
|
32867
|
+
planSuppressedId = null;
|
|
32868
|
+
/** The newest todo_write entry's id, STICKY: adopted only while
|
|
32869
|
+
* streaming AND stuck (the detection window), then kept across newer
|
|
32870
|
+
* thinks, turn end, and scroll-away — the plan stays on screen until
|
|
32871
|
+
* a newer todo_write supersedes it or the user collapses it. */
|
|
32872
|
+
autoPlanIdRaw = null;
|
|
32873
|
+
deps;
|
|
32874
|
+
stopPlanEffect;
|
|
32875
|
+
constructor(deps) {
|
|
32876
|
+
this.deps = deps;
|
|
32877
|
+
this.stopPlanEffect = () => {};
|
|
32878
|
+
}
|
|
32879
|
+
destroy() {
|
|
32880
|
+
this.stopPlanEffect();
|
|
32881
|
+
}
|
|
32882
|
+
/** The newest reasoning entry's id (wire order) while streaming AND
|
|
32883
|
+
* stuck to the live end, else null — the transient think target. */
|
|
32884
|
+
get autoThinkTargetId() {
|
|
32885
|
+
if (!this.deps.store.isStreaming || !this.deps.stick) return null;
|
|
32886
|
+
return newestReasoningId(this.deps.store.renderEntries);
|
|
32887
|
+
}
|
|
32888
|
+
/** Suppression-aware think target: null while the user kept THIS think
|
|
32889
|
+
* collapsed (a newer think id simply stops matching). */
|
|
32890
|
+
get autoThinkId() {
|
|
32891
|
+
return suppressed(this.autoThinkTargetId, this.thinkSuppressedId);
|
|
32892
|
+
}
|
|
32893
|
+
/** Suppression-aware plan target (same id-tied rule as the think). */
|
|
32894
|
+
get autoPlanId() {
|
|
32895
|
+
return suppressed(this.autoPlanIdRaw, this.planSuppressedId);
|
|
32896
|
+
}
|
|
32897
|
+
toggleChip(id, autoOpen = false) {
|
|
32898
|
+
if (autoOpen) {
|
|
32899
|
+
if (id === this.autoPlanId) this.planSuppressedId = id;
|
|
32900
|
+
else if (this.autoThinkId !== null && id === `r:${this.autoThinkId}`) this.thinkSuppressedId = this.autoThinkId;
|
|
32901
|
+
return;
|
|
32902
|
+
}
|
|
32903
|
+
this.openChipId = this.openChipId === id ? null : id;
|
|
32904
|
+
this.peekOpenRunKey = null;
|
|
32905
|
+
}
|
|
32906
|
+
togglePeek(runKey) {
|
|
32907
|
+
this.peekOpenRunKey = this.peekOpenRunKey === runKey ? null : runKey;
|
|
31787
32908
|
if (this.peekOpenRunKey !== null) this.openChipId = null;
|
|
31788
32909
|
}
|
|
31789
32910
|
};
|
|
@@ -32972,14 +34093,14 @@ function BrowserContent($$renderer, $$props) {
|
|
|
32972
34093
|
$$renderer.push(`<div class="absolute z-50 min-w-44 rounded-md border border-zinc-700 bg-white py-1 text-xs shadow-xl"${attr_style(`left:${stringify(ctxMenu.px)}px; top:${stringify(ctxMenu.py)}px`)} data-testid="browser-ctxmenu">`);
|
|
32973
34094
|
if (ctxMenu.src) {
|
|
32974
34095
|
$$renderer.push("<!--[0-->");
|
|
32975
|
-
$$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"
|
|
34096
|
+
$$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(browserctxopenimage3())}</button> <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(browserctxcopyimage3())}</button>`);
|
|
32976
34097
|
} else $$renderer.push("<!--[-1-->");
|
|
32977
34098
|
$$renderer.push(`<!--]--> `);
|
|
32978
34099
|
if (ctxMenu.href) {
|
|
32979
34100
|
$$renderer.push("<!--[0-->");
|
|
32980
|
-
$$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"
|
|
34101
|
+
$$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(browserctxopenlink3())}</button> <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(browserctxcopylink3())}</button>`);
|
|
32981
34102
|
} else $$renderer.push("<!--[-1-->");
|
|
32982
|
-
$$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"
|
|
34103
|
+
$$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>`);
|
|
32983
34104
|
} else $$renderer.push("<!--[-1-->");
|
|
32984
34105
|
$$renderer.push(`<!--]--> `);
|
|
32985
34106
|
if (status !== "live") {
|
|
@@ -32996,6 +34117,20 @@ function BrowserContent($$renderer, $$props) {
|
|
|
32996
34117
|
});
|
|
32997
34118
|
}
|
|
32998
34119
|
//#endregion
|
|
34120
|
+
//#region src/lib/components/browser/BrowserTab.svelte
|
|
34121
|
+
function BrowserTab($$renderer, $$props) {
|
|
34122
|
+
$$renderer.component(($$renderer) => {
|
|
34123
|
+
let { tab, disabled = false} = $$props;
|
|
34124
|
+
$$renderer.push(`<div data-svelte="BrowserTab" class="relative shrink-0"><button type="button"${attr_class("w-32 truncate rounded px-1.5 py-0.5 pr-4 text-left whitespace-nowrap", void 0, {
|
|
34125
|
+
"bg-blue-200": tab.active,
|
|
34126
|
+
"text-blue-900": tab.active,
|
|
34127
|
+
"text-zinc-600": !tab.active,
|
|
34128
|
+
"hover:bg-zinc-100": !tab.active,
|
|
34129
|
+
"font-medium": tab.active
|
|
34130
|
+
})}${attr("disabled", disabled || tab.active, true)} data-testid="browser-tab"${attr("data-active", tab.active)}${attr("title", tab.url)}>${escape_html(tab.title || tab.url || "tab")}</button> <button type="button" class="absolute right-0.5 top-1/2 -translate-y-1/2 rounded text-[10px] leading-none text-red-500 hover:bg-red-500 hover:text-white"${attr("title", browsertabclosetitle3())} data-testid="browser-tab-close">✕</button></div>`);
|
|
34131
|
+
});
|
|
34132
|
+
}
|
|
34133
|
+
//#endregion
|
|
32999
34134
|
//#region src/lib/components/browser/mirror-input.ts
|
|
33000
34135
|
/** The on-screen rect of the PAGE image inside its wrapper. The frame is
|
|
33001
34136
|
* drawn aspect-true (canvas object-contain): when the frame is wider or
|
|
@@ -33154,6 +34289,7 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
33154
34289
|
/** ADR-0040 D5: the tab strip — the registry's tab list mirrored here;
|
|
33155
34290
|
* the SERVER stays the authority (activeTargetId), this is a view. */
|
|
33156
34291
|
let tabs = [];
|
|
34292
|
+
let switching = false;
|
|
33157
34293
|
const moves = createMoveCoalescer((cb) => requestAnimationFrame(cb), (x, y) => void post());
|
|
33158
34294
|
async function post(input) {}
|
|
33159
34295
|
function toViewportCx(e) {
|
|
@@ -33220,16 +34356,19 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
33220
34356
|
x: p.x,
|
|
33221
34357
|
y: p.y});
|
|
33222
34358
|
}
|
|
33223
|
-
|
|
33224
|
-
|
|
33225
|
-
|
|
34359
|
+
/** ADR-0042 D3: ONE client choreography for tab creation — the context
|
|
34360
|
+
* menu's open-link/image (url present) and the strip's + chip (url
|
|
34361
|
+
* empty = BLANK, the birth state again). Empty body per D1: absence is
|
|
34362
|
+
* the blank signal, never a literal about:blank. Callers own their own
|
|
34363
|
+
* ctxClose(). */
|
|
34364
|
+
async function openTab(url) {}
|
|
33226
34365
|
function ctxAct(action) {
|
|
33227
34366
|
const m = ctxMenu;
|
|
33228
34367
|
ctxClose();
|
|
33229
34368
|
if (!m) return;
|
|
33230
|
-
if (action === "open-image" && m.src) return void
|
|
34369
|
+
if (action === "open-image" && m.src) return void openTab(m.src);
|
|
33231
34370
|
if (action === "copy-image" && m.src) return void ctxCopy(m.src);
|
|
33232
|
-
if (action === "open-link" && m.href) return void
|
|
34371
|
+
if (action === "open-link" && m.href) return void openTab(m.href);
|
|
33233
34372
|
if (action === "copy-link" && m.href) return void ctxCopy(m.href);
|
|
33234
34373
|
if (action === "reload") return void proxy();
|
|
33235
34374
|
if (action === "send-right-click") return ctxSendRightClick();
|
|
@@ -33315,15 +34454,11 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
33315
34454
|
const each_array = ensure_array_like(tabs);
|
|
33316
34455
|
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
33317
34456
|
let t = each_array[$$index];
|
|
33318
|
-
$$renderer
|
|
33319
|
-
|
|
33320
|
-
|
|
33321
|
-
"text-zinc-600": !t.active,
|
|
33322
|
-
"hover:bg-zinc-100": !t.active,
|
|
33323
|
-
"font-medium": t.active
|
|
33324
|
-
})}${attr("disabled", t.active, true)} data-testid="browser-tab"${attr("data-active", t.active)}${attr("title", t.url)}>${escape_html(t.title || t.url || "tab")}</button> <button type="button" class="absolute right-0.5 top-1/2 -translate-y-1/2 rounded text-[10px] leading-none text-red-500 hover:bg-red-500 hover:text-white" title="Close tab" data-testid="browser-tab-close">✕</button></div>`);
|
|
34457
|
+
BrowserTab($$renderer, {
|
|
34458
|
+
tab: t,
|
|
34459
|
+
disabled: switching});
|
|
33325
34460
|
}
|
|
33326
|
-
$$renderer.push(`<!--]
|
|
34461
|
+
$$renderer.push(`<!--]--> <button type="button" class="shrink-0 rounded px-1.5 leading-none text-zinc-500 hover:bg-zinc-100 disabled:opacity-40"${attr("title", t(browsernewtab2))}${attr("aria-label", t(browsernewtab2))} data-testid="browser-tab-new"${attr("disabled", true, true)}>+</button></div>`);
|
|
33327
34462
|
} else $$renderer.push("<!--[-1-->");
|
|
33328
34463
|
$$renderer.push(`<!--]--> `);
|
|
33329
34464
|
BrowserContent($$renderer, {
|
|
@@ -34209,9 +35344,13 @@ function WorkspaceFileTabGroup($$renderer, $$props) {
|
|
|
34209
35344
|
//#region src/lib/components/workspace-file/WorkspaceFileToolbar.svelte
|
|
34210
35345
|
function WorkspaceFileToolbar($$renderer, $$props) {
|
|
34211
35346
|
$$renderer.component(($$renderer) => {
|
|
35347
|
+
/** The reload icon's feedback state — the CanvasCopyButton machine
|
|
35348
|
+
* (idle → busy spinner → done check → idle), mirrored per the 2026-10-27
|
|
35349
|
+
* UX-parity operator request: a click that shows nothing happening "sucks". */
|
|
35350
|
+
let reloadState = "idle";
|
|
34212
35351
|
let columnEl = null;
|
|
34213
|
-
let { dirty, saveState = "idle", stale = false, staleNote = "", hasTabs = false, tab = "preview", view = "edit", showToggle = false, diffDisabled = false, readonly = false, onviewchange, onsave, path } = $$props;
|
|
34214
|
-
$$renderer.push(`<div data-svelte="WorkspaceFileToolbar" class="file-toolbar svelte-1vsjf39"><span class="path svelte-1vsjf39"${attr("title", path)}>${escape_html(path)}</span> `);
|
|
35352
|
+
let { dirty, saveState = "idle", stale = false, staleNote = "", hasTabs = false, tab = "preview", view = "edit", showToggle = false, diffDisabled = false, readonly = false, onviewchange, onsave, onreload, path } = $$props;
|
|
35353
|
+
$$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> `);
|
|
34215
35354
|
if (showToggle) {
|
|
34216
35355
|
$$renderer.push("<!--[0-->");
|
|
34217
35356
|
WorkspaceFileTabGroup($$renderer, {
|
|
@@ -34243,6 +35382,14 @@ function WorkspaceFileToolbar($$renderer, $$props) {
|
|
|
34243
35382
|
$$renderer.push("<!--[0-->");
|
|
34244
35383
|
$$renderer.push(`<div class="tabs svelte-1vsjf39" role="tablist"><button role="tab"${attr("aria-selected", tab === "preview")} data-testid="tab-preview"${attr_class("svelte-1vsjf39", void 0, { "active": tab === "preview" })}>${escape_html(t(workspacefilepreview2))}</button> <button role="tab"${attr("aria-selected", tab === "edit")} data-testid="tab-edit"${attr_class("svelte-1vsjf39", void 0, { "active": tab === "edit" })}>${escape_html(t(workspacefileedit2))}</button></div>`);
|
|
34245
35384
|
} else $$renderer.push("<!--[-1-->");
|
|
35385
|
+
$$renderer.push(`<!--]--> `);
|
|
35386
|
+
if (onreload) {
|
|
35387
|
+
$$renderer.push("<!--[0-->");
|
|
35388
|
+
$$renderer.push(`<button type="button" class="reload-btn svelte-1vsjf39" data-testid="file-reload"${attr("data-state", reloadState)}${attr("title", t(refresh))}${attr("aria-label", t(refresh))}>`);
|
|
35389
|
+
$$renderer.push("<!--[-1-->");
|
|
35390
|
+
Rotate_cw($$renderer, { size: 14 });
|
|
35391
|
+
$$renderer.push(`<!--]--></button>`);
|
|
35392
|
+
} else $$renderer.push("<!--[-1-->");
|
|
34246
35393
|
$$renderer.push(`<!--]--> <span class="copy-slot svelte-1vsjf39">`);
|
|
34247
35394
|
CanvasCopyButton($$renderer, {
|
|
34248
35395
|
container: columnEl,
|
|
@@ -34274,7 +35421,7 @@ function WorkspaceFile($$renderer, $$props) {
|
|
|
34274
35421
|
* old overflow:auto container made the hosts content-sized and the
|
|
34275
35422
|
* page-level scrollbar stole the height.
|
|
34276
35423
|
*/
|
|
34277
|
-
let { tab = void 0, dirty, fullPath, saveState, fileStale, staleNote, hasTabs, activeView, showToggle, diffDisabled, readonly, onViewChange, onSave, saveError, saveFailedNote, loadingNote, loadFailedNote, truncatedNote, newFileNote, phase, errorCode, title, isImage, bytesSrc, isHtml, text, isMarkdown, noHead, eof, editorHost = null, diffHost = null } = $$props;
|
|
35424
|
+
let { tab = void 0, dirty, fullPath, saveState, fileStale, staleNote, hasTabs, activeView, showToggle, diffDisabled, readonly, onViewChange, onSave, onReload, saveError, saveFailedNote, loadingNote, loadFailedNote, truncatedNote, newFileNote, phase, errorCode, title, isImage, bytesSrc, isHtml, text, isMarkdown, noHead, eof, editorHost = null, diffHost = null } = $$props;
|
|
34278
35425
|
let $$settled = true;
|
|
34279
35426
|
let $$inner_renderer;
|
|
34280
35427
|
function $$render_inner($$renderer) {
|
|
@@ -34292,6 +35439,7 @@ function WorkspaceFile($$renderer, $$props) {
|
|
|
34292
35439
|
readonly,
|
|
34293
35440
|
onviewchange: onViewChange,
|
|
34294
35441
|
onsave: onSave,
|
|
35442
|
+
onreload: onReload,
|
|
34295
35443
|
get tab() {
|
|
34296
35444
|
return tab;
|
|
34297
35445
|
},
|
|
@@ -34443,6 +35591,13 @@ function WorkspaceFilePanel($$renderer, $$props) {
|
|
|
34443
35591
|
const homeDir = marker > 0 ? dsi.slice(0, marker) : null;
|
|
34444
35592
|
return homeDir !== null && full.startsWith(homeDir + "/") ? "~" + full.slice(homeDir.length) : full;
|
|
34445
35593
|
});
|
|
35594
|
+
/** Silent external refetch (Index Pulse): when the buffer holds no
|
|
35595
|
+
* draft, the fetched text/baseline advance to the disk truth and the
|
|
35596
|
+
* editor follows; when a draft exists, the panel only raises the
|
|
35597
|
+
* visible stale note - a draft is never clobbered. */
|
|
35598
|
+
async function refreshFile() {
|
|
35599
|
+
if (isImage() || true) return;
|
|
35600
|
+
}
|
|
34446
35601
|
/** The DIRECT save (The File Eye ADR D4): POST the buffer to the
|
|
34447
35602
|
* gated write route; the written receipt advances the baseline so
|
|
34448
35603
|
* dirty clears — bytes on disk, not an agent's promise. */
|
|
@@ -34464,6 +35619,7 @@ function WorkspaceFilePanel($$renderer, $$props) {
|
|
|
34464
35619
|
readonly: false,
|
|
34465
35620
|
onViewChange: setView,
|
|
34466
35621
|
onSave: save,
|
|
35622
|
+
onReload: refreshFile,
|
|
34467
35623
|
saveError,
|
|
34468
35624
|
saveFailedNote: t(workspacefilesavefailed3),
|
|
34469
35625
|
loadingNote: t(workspaceexplorerloading2),
|
|
@@ -34707,8 +35863,10 @@ function WorkspaceExplorerPanel($$renderer, $$props) {
|
|
|
34707
35863
|
* the active file panel and cleared once it reports the highlight done. */
|
|
34708
35864
|
let lineTarget = null;
|
|
34709
35865
|
function startSplitDrag(event) {}
|
|
34710
|
-
|
|
34711
|
-
|
|
35866
|
+
/** The rendered tree lane: the settled px, or the narrow-lane default
|
|
35867
|
+
* before the first measurement. Percent lives only in treePct. */
|
|
35868
|
+
const treeBasis = derived(() => 280);
|
|
35869
|
+
$$renderer.push(`<div data-svelte="WorkspaceExplorerPanel" data-testid="workspace-explorer" class="split svelte-ldghfc"${attr_style(`--tree-basis: ${stringify(treeBasis())}px`)}>`);
|
|
34712
35870
|
WorkspaceExplorer($$renderer, {
|
|
34713
35871
|
activeFile,
|
|
34714
35872
|
root,
|
|
@@ -34860,740 +36018,218 @@ function PanelHeader($$renderer, $$props) {
|
|
|
34860
36018
|
class: "inline-flex h-[22px] w-[22px] shrink-0 items-center justify-center rounded transition-colors hover:bg-surface-hover"
|
|
34861
36019
|
});
|
|
34862
36020
|
} else $$renderer.push("<!--[-1-->");
|
|
34863
|
-
$$renderer.push(`<!--]--> `);
|
|
34864
|
-
if (onremove || lens) {
|
|
34865
|
-
$$renderer.push("<!--[0-->");
|
|
34866
|
-
PanelClose($$renderer, {
|
|
34867
|
-
sessionId,
|
|
34868
|
-
lens});
|
|
34869
|
-
} else $$renderer.push("<!--[-1-->");
|
|
34870
|
-
$$renderer.push(`<!--]--></span></div>`);
|
|
34871
|
-
});
|
|
34872
|
-
}
|
|
34873
|
-
//#endregion
|
|
34874
|
-
//#region src/lib/components/panels/PanelColumn.svelte
|
|
34875
|
-
function PanelColumn($$renderer, $$props) {
|
|
34876
|
-
$$renderer.component(($$renderer) => {
|
|
34877
|
-
/**
|
|
34878
|
-
* PanelColumn — one panel's fixed-width column shell (Panel Floor W3
|
|
34879
|
-
* task 3.2, ADR-0006): PanelHeader (floor chrome) + the conversation
|
|
34880
|
-
* body (ConversationPanel, keyed by sessionId INSIDE the route's each
|
|
34881
|
-
* — remount locality) + the 6px ResizeGutter after every panel.
|
|
34882
|
-
*
|
|
34883
|
-
* Presentational shell only: width and selection arrive as props
|
|
34884
|
-
* (bound up to the route); the body arrives as a snippet so the ROUTE
|
|
34885
|
-
* owns the {#key panel.sessionId} remount and the per-panel cold data.
|
|
34886
|
-
*
|
|
34887
|
-
* Width badge (2026-08-28): a `widthBadge` phase prop ('live' during
|
|
34888
|
-
* a gutter drag that moves this panel's width, 'fading' through the
|
|
34889
|
-
* 10s afterglow) floats the CURRENT width at the column's top right,
|
|
34890
|
-
* below the header's controls, pointer-transparent — the route owns
|
|
34891
|
-
* the membership rule (changed-from-snapshot) and the fade timer.
|
|
34892
|
-
*/
|
|
34893
|
-
let { panel, index, selected, widthBadge = null, copyValue, canMoveLeft = false, canMoveRight = false, onremove, children } = $$props;
|
|
34894
|
-
$$renderer.push(`<div data-svelte="PanelColumn"${attr_class("column svelte-1cuodug", void 0, { "selected": selected })} data-testid="panel-column"${attr("data-panel-id", panel.id)}${attr("data-session-id", panel.kind === "conversation" ? panel.sessionId : null)}${attr_style(`width: ${stringify(panel.width)}px; min-width: ${stringify(panel.width)}px; max-width: ${stringify(panel.width)}px;`)}>`);
|
|
34895
|
-
PanelHeader($$renderer, {
|
|
34896
|
-
panelId: panel.id,
|
|
34897
|
-
sessionId: panel.kind === "conversation" ? panel.sessionId : "",
|
|
34898
|
-
label: panelHeaderLabel(panel),
|
|
34899
|
-
copyValue: panel.kind === "workspace-explorer" ? panel.root : panel.kind === "workspace-file" ? copyValue : void 0,
|
|
34900
|
-
copyLabel: panel.kind === "workspace-explorer" ? t(workspaceexplorercopyworkspace3) : panel.kind === "workspace-file" ? t(workspacefilecopyfilename3) : void 0,
|
|
34901
|
-
labelTestId: panel.kind === "workspace-explorer" ? "explorer-title" : panel.kind === "workspace-file" ? "file-title" : void 0,
|
|
34902
|
-
selected,
|
|
34903
|
-
canMoveLeft,
|
|
34904
|
-
canMoveRight,
|
|
34905
|
-
onremove
|
|
34906
|
-
});
|
|
34907
|
-
$$renderer.push(`<!----> `);
|
|
34908
|
-
if (widthBadge !== null) {
|
|
34909
|
-
$$renderer.push("<!--[0-->");
|
|
34910
|
-
$$renderer.push(`<span${attr_class("width-badge svelte-1cuodug", void 0, { "fading": widthBadge === "fading" })} data-testid="panel-width-badge"${attr("data-badge-phase", widthBadge)} aria-hidden="true">${escape_html(Math.round(panel.width))}px</span>`);
|
|
34911
|
-
} else $$renderer.push("<!--[-1-->");
|
|
34912
|
-
$$renderer.push(`<!--]--> <div class="body svelte-1cuodug">`);
|
|
34913
|
-
children($$renderer);
|
|
34914
|
-
$$renderer.push(`<!----></div></div> `);
|
|
34915
|
-
ResizeGutter($$renderer, { index });
|
|
34916
|
-
$$renderer.push(`<!---->`);
|
|
34917
|
-
});
|
|
34918
|
-
}
|
|
34919
|
-
//#endregion
|
|
34920
|
-
//#region src/lib/components/panels/PanelLoupe.svelte
|
|
34921
|
-
function PanelLoupe($$renderer, $$props) {
|
|
34922
|
-
$$renderer.component(($$renderer) => {
|
|
34923
|
-
/**
|
|
34924
|
-
* PanelLoupe — the reading lens over one floor panel (The Panel Loupe
|
|
34925
|
-
* ADR D2/D5, 2026-09-04): a body-portaled modal dialog that renders
|
|
34926
|
-
* one panel's content at reading size while the floor keeps its
|
|
34927
|
-
* zoom. ANY kind lenses (The Loupe for Every Panel, 2026-09-08): the
|
|
34928
|
-
* route feeds the SAME body snippet the column renders (D7 — one
|
|
34929
|
-
* ladder, two sites) and the header rides the panel's label variant;
|
|
34930
|
-
* the loupe itself carries no conversation logic.
|
|
34931
|
-
*
|
|
34932
|
-
* Contract donor: ImageLightbox (2026-08-28) — the portal, the fixed
|
|
34933
|
-
* inset-0 z-[1000] layer, role="dialog" aria-modal, the mask's
|
|
34934
|
-
* mousedown close, Escape, the × control, focus to the × on open and
|
|
34935
|
-
* back to the opener on close. The portal is load-bearing: the floor
|
|
34936
|
-
* row carries transform: scale(), and a fixed backdrop inside a
|
|
34937
|
-
* transformed ancestor is trapped in that ancestor's box instead of
|
|
34938
|
-
* covering the viewport (ADR D2). The action is inlined here by
|
|
34939
|
-
* decision — the donor is cited, not modified or refactored.
|
|
34940
|
-
*
|
|
34941
|
-
* Lens flag (D8): setLensMode(true) during init, BEFORE children
|
|
34942
|
-
* render — every floor-verb control inside the body snippet reads the
|
|
34943
|
-
* flag at its own init and renders visible-disabled. Context follows
|
|
34944
|
-
* the component tree, so the flag reaches snippet content even after
|
|
34945
|
-
* the portal moves the DOM under document.body (asserted by the loupe
|
|
34946
|
-
* unit tests).
|
|
34947
|
-
*
|
|
34948
|
-
* The lens × and this header's copy-id are the loupe's live controls;
|
|
34949
|
-
* the header's move/close render visible-disabled (the floor verbs).
|
|
34950
|
-
* Openness is the route's session-local state — never persisted (D5).
|
|
34951
|
-
*/
|
|
34952
|
-
let { panelId, sessionId, label = void 0, children } = $$props;
|
|
34953
|
-
setLensMode(true);
|
|
34954
|
-
$$renderer.push(`<div data-svelte="PanelLoupe" class="fixed inset-0 z-[1000] grid place-items-center p-10" role="dialog" aria-modal="true"${attr("aria-label", t(panelloupe1))} data-testid="panel-loupe"${attr("data-panel-id", panelId)}${attr("data-session-id", sessionId)}><div class="absolute inset-0 bg-black/60" aria-hidden="true" data-testid="panel-loupe-mask"></div> <div class="relative" style="width: min(100vw - 4rem, 850px); height: min(95vh, calc(100vh - 5rem));" data-testid="panel-loupe-sheet"><div class="flex h-full w-full flex-col overflow-hidden rounded-xl shadow-2xl" style="background: var(--color-surface-primary, var(--color-surface-elevated));">`);
|
|
34955
|
-
PanelHeader($$renderer, {
|
|
34956
|
-
panelId,
|
|
34957
|
-
sessionId,
|
|
34958
|
-
label,
|
|
34959
|
-
lens: true
|
|
34960
|
-
});
|
|
34961
|
-
$$renderer.push(`<!----> <div class="flex min-h-0 flex-1 flex-col overflow-hidden">`);
|
|
34962
|
-
children($$renderer);
|
|
34963
|
-
$$renderer.push(`<!----></div></div> <button type="button"${attr("aria-label", t(closeloupe1))} data-testid="panel-loupe-close" class="absolute -top-3 -right-3 z-10 flex h-9 w-9 cursor-pointer items-center justify-center rounded-full border border-surface-border bg-surface-elevated text-lg leading-none text-text-primary shadow-md hover:bg-surface-hover">×</button></div></div>`);
|
|
34964
|
-
});
|
|
34965
|
-
}
|
|
34966
|
-
//#endregion
|
|
34967
|
-
//#region src/lib/components/panels/StickyColumnContainer.svelte
|
|
34968
|
-
function StickyColumnContainer($$renderer, $$props) {
|
|
34969
|
-
$$renderer.component(($$renderer) => {
|
|
34970
|
-
/**
|
|
34971
|
-
* StickyColumnContainer — a fixed-width LEADING column inside the zoom
|
|
34972
|
-
* row (OCI StickyColumnContainer port, 2026-08-26; hosts the embedded
|
|
34973
|
-
* AppSidebar the way OCI's hosts ControlRail).
|
|
34974
|
-
*
|
|
34975
|
-
* "Sticky" = the width is TRIPLE-LOCKED (width/min/max all the same
|
|
34976
|
-
* px), unlike panel columns whose widths live in [MIN, MAX]: the rail
|
|
34977
|
-
* never flexes when the row measures itself at max-content. The
|
|
34978
|
-
* column's background paints the full column height — the rail inside
|
|
34979
|
-
* fills it (align-items: stretch).
|
|
34980
|
-
*
|
|
34981
|
-
* The trailing ResizeGutter is included BY DEFAULT (OCI parity) but
|
|
34982
|
-
* only when panel columns actually follow (showGutter) — a rail alone
|
|
34983
|
-
* on the floor has nothing to resize against. The gutter is the
|
|
34984
|
-
* column's flex SIBLING (the rail's overflow must never clip its hit
|
|
34985
|
-
* area) and reports mousedown through onResizeStart — the page owns
|
|
34986
|
-
* the drag math and the single clamp (AppSidebar ownership split;
|
|
34987
|
-
* ControlBar.onresizeall precedent: layout chrome is a DIRECT child
|
|
34988
|
-
* of the route, so prop wiring here breaks no commitment).
|
|
34989
|
-
*/
|
|
34990
|
-
let { width, showGutter = true, children } = $$props;
|
|
34991
|
-
$$renderer.push(`<div data-svelte="StickyColumnContainer" class="rail-column svelte-s09nms" data-testid="sidebar-column"${attr_style(`width: ${stringify(width)}px; min-width: ${stringify(width)}px; max-width: ${stringify(width)}px;`)}>`);
|
|
34992
|
-
children($$renderer);
|
|
34993
|
-
$$renderer.push(`<!----></div> `);
|
|
34994
|
-
if (showGutter) {
|
|
34995
|
-
$$renderer.push("<!--[0-->");
|
|
34996
|
-
$$renderer.push(`<div data-svelte="StickyColumnContainer" class="rail-gutter svelte-s09nms" data-testid="sidebar-gutter" role="separator" aria-orientation="vertical"${attr("aria-label", t(resizesidebar1))}></div>`);
|
|
34997
|
-
} else $$renderer.push("<!--[-1-->");
|
|
34998
|
-
$$renderer.push(`<!--]-->`);
|
|
34999
|
-
});
|
|
35000
|
-
}
|
|
35001
|
-
//#endregion
|
|
35002
|
-
//#region src/lib/components/panels/EmptyFloor.svelte
|
|
35003
|
-
function EmptyFloor($$renderer, $$props) {
|
|
35004
|
-
$$renderer.component(($$renderer) => {
|
|
35005
|
-
$$renderer.push(`<div data-svelte="EmptyFloor" class="empty-floor svelte-z8g5d9" data-testid="workspace-empty"><p>${escape_html(t(noconversations1))}</p> <p class="hint svelte-z8g5d9">${escape_html(t(picksession1))}</p></div>`);
|
|
35006
|
-
});
|
|
35007
|
-
}
|
|
35008
|
-
//#endregion
|
|
35009
|
-
//#region src/lib/services/conversation/spine-feed.svelte.ts
|
|
35010
|
-
var spineFeed = {
|
|
35011
|
-
rows: [],
|
|
35012
|
-
presets: [],
|
|
35013
|
-
a2aRows: [],
|
|
35014
|
-
workspaces: []
|
|
35015
|
-
};
|
|
35016
|
-
//#endregion
|
|
35017
|
-
//#region src/lib/services/workspace/page-feeds.svelte.ts
|
|
35018
|
-
var PageFeeds = class {
|
|
35019
|
-
coldCache = {};
|
|
35020
|
-
coldInFlight = new SvelteSet();
|
|
35021
|
-
deadSessions = {};
|
|
35022
|
-
edgeCache = {};
|
|
35023
|
-
/** Seed-arrival prime: the seed panel mounts with full cold props on
|
|
35024
|
-
* paint one (SSR parity for the seed path). Load-time constant. */
|
|
35025
|
-
primeSeed(sessionId, cold) {
|
|
35026
|
-
this.coldCache = {
|
|
35027
|
-
...this.coldCache,
|
|
35028
|
-
[sessionId]: cold
|
|
35029
|
-
};
|
|
35030
|
-
}
|
|
35031
|
-
/** Record an ADD-time parent edge (the route's doAdd fork path). */
|
|
35032
|
-
rememberEdge(childSessionId, parentSessionId) {
|
|
35033
|
-
this.edgeCache = {
|
|
35034
|
-
...this.edgeCache,
|
|
35035
|
-
[childSessionId]: parentSessionId
|
|
35036
|
-
};
|
|
35037
|
-
}
|
|
35038
|
-
/** One dual fetch, registries kept honest (in-flight guard, dead
|
|
35039
|
-
* session card, loader clear in `finally`). The fetcher is injected:
|
|
35040
|
-
* the wire call stays the route's (`fetchCold` reads the host
|
|
35041
|
-
* config); the bookkeeping lives here. */
|
|
35042
|
-
async runCold(sessionId, fetchCold) {
|
|
35043
|
-
if (this.coldCache[sessionId] !== void 0 || this.coldInFlight.has(sessionId)) return;
|
|
35044
|
-
this.coldInFlight = new SvelteSet(this.coldInFlight).add(sessionId);
|
|
35045
|
-
try {
|
|
35046
|
-
const cold = await fetchCold(sessionId);
|
|
35047
|
-
if (cold !== null) this.coldCache = {
|
|
35048
|
-
...this.coldCache,
|
|
35049
|
-
[sessionId]: cold
|
|
35050
|
-
};
|
|
35051
|
-
else this.deadSessions = {
|
|
35052
|
-
...this.deadSessions,
|
|
35053
|
-
[sessionId]: `Session ${sessionId} not found on the DSH host. It may have been reaped.`
|
|
35054
|
-
};
|
|
35055
|
-
} finally {
|
|
35056
|
-
const next = new SvelteSet(this.coldInFlight);
|
|
35057
|
-
next.delete(sessionId);
|
|
35058
|
-
this.coldInFlight = next;
|
|
35059
|
-
}
|
|
35060
|
-
}
|
|
35061
|
-
/** The floor's two lifecycle feeds (call during component init —
|
|
35062
|
-
* `$effect` needs an owner):
|
|
35063
|
-
* - Prompt Sync hygiene (ADR "The Prompt Sync" D1/D6): a session
|
|
35064
|
-
* that left the floor holds no check and no snapshot; count 0
|
|
35065
|
-
* clears the broadcast. Conversation sessions only (D6).
|
|
35066
|
-
* - Spine feed lifecycle (W8): ref-counted single timer started on
|
|
35067
|
-
* mount, stopped on destroy; the a2a window rides the floor's
|
|
35068
|
-
* conversation senders (first sender per tick, never per panel).
|
|
35069
|
-
* Returns the spine subscription's cleanup. */
|
|
35070
|
-
installFeeds(getConversationSessionIds) {
|
|
35071
|
-
return () => {};
|
|
35072
|
-
}
|
|
35073
|
-
};
|
|
35074
|
-
var pageFeeds = new PageFeeds();
|
|
35075
|
-
/**
|
|
35076
|
-
* The open workspace explorer for a workspace ROOT — The Shared Tree ADR
|
|
35077
|
-
* (2026-09-17) D1's dedupe key: ONE explorer per ROOT across ALL sessions,
|
|
35078
|
-
* so a chip click on any session sharing the root FOCUSES instead of
|
|
35079
|
-
* adding (a duplicate is a bug, not a feature). The retired per-session
|
|
35080
|
-
* key ("two sessions sharing one workspace hold distinct explorers",
|
|
35081
|
-
* Workspace Explorer D4) produced N byte-identical trees for N sessions.
|
|
35082
|
-
*/
|
|
35083
|
-
function findWorkspaceExplorerPanel(panels, root) {
|
|
35084
|
-
return panels.find((p) => p.kind === "workspace-explorer" && p.root === root);
|
|
35085
|
-
}
|
|
35086
|
-
/**
|
|
35087
|
-
* The explorer's slot (The Shared Tree ADR 2026-09-17, D3): the FOCUSED
|
|
35088
|
-
* slot — the explorer is NOT a lineage child; a workspace tree has no
|
|
35089
|
-
* parent session, only an opener. The retired after-source rule
|
|
35090
|
-
* (Workspace Explorer D3, "Parent → explorer → file") interposed the
|
|
35091
|
-
* panel inside a conversation's family unit — the family clamp inside
|
|
35092
|
-
* focusedInsertionSlot still keeps any real family unsplit.
|
|
35093
|
-
*/
|
|
35094
|
-
function workspaceExplorerSlot(panels, selectedIndex, facts) {
|
|
35095
|
-
return focusedInsertionSlot(panels, selectedIndex, facts.parentOf);
|
|
35096
|
-
}
|
|
35097
|
-
/**
|
|
35098
|
-
* The glass FIRST slot under its opener (operator ruling 2026-10-24):
|
|
35099
|
-
* a summoned/spawned glass lands DIRECTLY below its opener - past the
|
|
35100
|
-
* opener document tail, BEFORE every adopted child - matching the
|
|
35101
|
-
* spine tree wire order -1 (the ghost always reads as the first
|
|
35102
|
-
* child). Supersedes the region-end placement for the glass only.
|
|
35103
|
-
*/
|
|
35104
|
-
function glassFirstSlot(panels, openedBy) {
|
|
35105
|
-
const openerIdx = panels.findIndex((p) => p.kind === "conversation" && p.sessionId === openedBy);
|
|
35106
|
-
if (openerIdx === -1) return panels.length;
|
|
35107
|
-
return docTailEnd(panels, openerIdx, openedBy) + 1;
|
|
35108
|
-
}
|
|
35109
|
-
/**
|
|
35110
|
-
* Insert-before-focused slot (operator spec, 2026-08-31): a fresh panel
|
|
35111
|
-
* lands at the FOCUSED panel's index — immediately before it — and takes
|
|
35112
|
-
* focus (the route selects it). 0 when nothing is focused (empty floor,
|
|
35113
|
-
* stale selection) — the old front-add stays the fallback. Math.max keeps
|
|
35114
|
-
* splice's negative-index semantics out of the no-selection case.
|
|
35115
|
-
*
|
|
35116
|
-
* Family clamp (lineage I2): a slot strictly inside a family would wedge
|
|
35117
|
-
* the newcomer between a spawner and its pinned child — unitOf/blockBounds,
|
|
35118
|
-
* the sidebar's familyRenderOrder, and the adoption slot walk all assume
|
|
35119
|
-
* families stay contiguous on the floor. When the focus is a family CHILD,
|
|
35120
|
-
* the slot climbs to the family head — the nearest non-splitting slot left
|
|
35121
|
-
* of the focus (parentOf only carries on-floor parents, so an orphan child
|
|
35122
|
-
* is a root here, its own unit). A lone panel or a family head keeps the
|
|
35123
|
-
* exact focus slot.
|
|
35124
|
-
*
|
|
35125
|
-
* Manager focus (ADR D6): no session, no family — the slot is the focus
|
|
35126
|
-
* itself.
|
|
35127
|
-
*
|
|
35128
|
-
* Workspace member focus (2026-09-10): the explorer/file pair is a family
|
|
35129
|
-
* unit in the SAME block math (blockBounds — the Loadinjected D3 walk-back
|
|
35130
|
-
* grammar), so the clamp is the SAME one: insert at the unit head — the
|
|
35131
|
-
* PARENT position, left of the block — never between explorer and file.
|
|
35132
|
-
*/
|
|
35133
|
-
function focusedInsertionSlot(panels, selectedIndex, parentOf) {
|
|
35134
|
-
const focus = Math.max(0, selectedIndex);
|
|
35135
|
-
const focused = panels[focus];
|
|
35136
|
-
if (focused === void 0) return 0;
|
|
35137
|
-
if (focused.kind === "workspace-explorer" || focused.kind === "workspace-file" || focused.kind === "browser") {
|
|
35138
|
-
const block = blockBounds(panels, focus, { parentOf });
|
|
35139
|
-
return block === null ? focus : block[0];
|
|
35140
|
-
}
|
|
35141
|
-
if (focused.kind !== "conversation") return focus;
|
|
35142
|
-
let head = focused.sessionId;
|
|
35143
|
-
for (;;) {
|
|
35144
|
-
const parent = parentOf.get(head) ?? null;
|
|
35145
|
-
if (parent === null) break;
|
|
35146
|
-
head = parent;
|
|
35147
|
-
}
|
|
35148
|
-
if (head === focused.sessionId) return focus;
|
|
35149
|
-
const headIndex = panels.findIndex((p) => p.kind === "conversation" && p.sessionId === head);
|
|
35150
|
-
return headIndex >= 0 ? Math.min(headIndex, focus) : focus;
|
|
35151
|
-
}
|
|
35152
|
-
//#endregion
|
|
35153
|
-
//#region src/lib/services/panels/floor-registry/chrome.ts
|
|
35154
|
-
/**
|
|
35155
|
-
* floor-registry/chrome — panel chrome intents + explorer + file-intent
|
|
35156
|
-
* mailbox + removal (ADR-0022 W3).
|
|
35157
|
-
*
|
|
35158
|
-
* Moved WHOLE from the state home (floor-registry.svelte.ts): the
|
|
35159
|
-
* skill-shelf / plugin-rack chrome setters, the ONE-explorer-per-workspace
|
|
35160
|
-
* open grammar, the explorer tree/tab/git intents, the file-intent
|
|
35161
|
-
* publish/consume mailbox, and family-close removal. Plain module: every
|
|
35162
|
-
* write goes through the state home's reactive `st` hub and its
|
|
35163
|
-
* primitives (ADR-0019 D2: exactly ONE writer home for floor state).
|
|
35164
|
-
* Sibling rule: factories/slots are reached through the state home's
|
|
35165
|
-
* re-export hub, never by importing another sibling directly.
|
|
35166
|
-
*/
|
|
35167
|
-
var d$4 = floorSeam;
|
|
35168
|
-
/** Chip click action: ONE explorer per WORKSPACE root across ALL
|
|
35169
|
-
* sessions — a click on any session sharing the root FOCUSES the open
|
|
35170
|
-
* explorer (dedupe key = root, D1); a fresh root lands at the focused
|
|
35171
|
-
* slot (D3, non-lineage — the explorer is not a lineage child).
|
|
35172
|
-
* sessionId rides the fresh panel as PROVENANCE (D4), never identity. */
|
|
35173
|
-
function openWorkspaceExplorer(sessionId, workspace) {
|
|
35174
|
-
const open = findWorkspaceExplorerPanel(st.panels, workspace);
|
|
35175
|
-
if (open) {
|
|
35176
|
-
st.selectedPanelId = open.id;
|
|
35177
|
-
return;
|
|
35178
|
-
}
|
|
35179
|
-
insertPanel(makeWorkspaceExplorerPanel(sessionId, workspace), workspaceExplorerSlot(st.panels, selectedIndex_(), d$4().getMoveFacts()));
|
|
35180
|
-
}
|
|
35181
|
-
/** Chip click action (The Glass Browser spec W2, ADR-0029 D4): ONE live
|
|
35182
|
-
* browser panel across the floor — the terminal singleton rule (Terminal
|
|
35183
|
-
* Desk ADR D2). A click on an open browser FOCUSES it; a miss inserts at
|
|
35184
|
-
* the focused slot. */
|
|
35185
|
-
function openBrowserPanel(index, keepSelection = false, width, openedBy, sessionId) {
|
|
35186
|
-
const open = st.panels.find((p) => p.kind === "browser" && p.openedBy === openedBy);
|
|
35187
|
-
if (open) {
|
|
35188
|
-
st.selectedPanelId = open.id;
|
|
35189
|
-
return;
|
|
35190
|
-
}
|
|
35191
|
-
const prevSelected = st.selectedPanelId;
|
|
35192
|
-
const slot = index !== void 0 ? Math.max(0, Math.min(index, st.panels.length)) : openedBy !== void 0 ? glassFirstSlot(st.panels, openedBy) : insertionSlot();
|
|
35193
|
-
insertPanel(makeBrowserPanel(width, openedBy, sessionId), slot);
|
|
35194
|
-
if (keepSelection && prevSelected !== null && prevSelected !== void 0) {
|
|
35195
|
-
if (st.panels.some((p) => p.id === prevSelected)) st.selectedPanelId = prevSelected;
|
|
35196
|
-
}
|
|
35197
|
-
}
|
|
35198
|
-
/** The open explorer for a session's workspace (The Shared Tree D1):
|
|
35199
|
-
* matched by ROOT across sessions — the panel's provenance sessionId
|
|
35200
|
-
* is not the key. */
|
|
35201
|
-
function sessionWorkspaceExplorer(sessionId) {
|
|
35202
|
-
const root = d$4().getWorkspaceFor(sessionId);
|
|
35203
|
-
return root === null ? void 0 : findWorkspaceExplorerPanel(st.panels, root);
|
|
35204
|
-
}
|
|
35205
|
-
/** Explorer tree intents: the panel emits toggle/open-file; the owner
|
|
35206
|
-
* mutates expanded (the persisted part) — the levels cache stays
|
|
35207
|
-
* component-local. */
|
|
35208
|
-
function toggleExplorerPath(panelId, path) {
|
|
35209
|
-
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
35210
|
-
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
35211
|
-
const explorer = st.panels[idx];
|
|
35212
|
-
const next = explorer.expanded.includes(path) ? explorer.expanded.filter((p) => p !== path) : [...explorer.expanded, path];
|
|
35213
|
-
st.panels = st.panels.with(idx, {
|
|
35214
|
-
...explorer,
|
|
35215
|
-
expanded: next
|
|
35216
|
-
});
|
|
35217
|
-
}
|
|
35218
|
-
/** Explorer collapse-all intent: the panel emits; the owner empties the
|
|
35219
|
-
* expanded list (the persisted part). */
|
|
35220
|
-
function collapseExplorerPaths(panelId) {
|
|
35221
|
-
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
35222
|
-
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
35223
|
-
st.panels = st.panels.with(idx, {
|
|
35224
|
-
...st.panels[idx],
|
|
35225
|
-
expanded: []
|
|
35226
|
-
});
|
|
35227
|
-
}
|
|
35228
|
-
/** Git Eye tab intent (2026-09-12): the active tab is PERSISTED on the
|
|
35229
|
-
* entry — a hard reload restores it. */
|
|
35230
|
-
function setExplorerTab(panelId, tab) {
|
|
35231
|
-
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
35232
|
-
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
35233
|
-
st.panels = st.panels.with(idx, {
|
|
35234
|
-
...st.panels[idx],
|
|
35235
|
-
tab
|
|
35236
|
-
});
|
|
35237
|
-
}
|
|
35238
|
-
/** Explorer Layout tabs (amendment 2026-09-16): the tab list and the
|
|
35239
|
-
* active tab are OWNER-PERSISTED entry facts. The file tabs die with
|
|
35240
|
-
* the panel (D5). */
|
|
35241
|
-
function openExplorerTab(panelId, path) {
|
|
35242
|
-
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
35243
|
-
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
35244
|
-
const ex = st.panels[idx];
|
|
35245
|
-
const tabs = ex.openTabs ?? [];
|
|
35246
|
-
const openTabs = tabs.includes(path) ? tabs : [...tabs, path];
|
|
35247
|
-
st.panels = st.panels.with(idx, {
|
|
35248
|
-
...ex,
|
|
35249
|
-
openTabs,
|
|
35250
|
-
activeFile: path
|
|
35251
|
-
});
|
|
35252
|
-
}
|
|
35253
|
-
function closeExplorerTab(panelId, path) {
|
|
35254
|
-
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
35255
|
-
if (idx < 0 || st.panels[idx].kind !== "workspace-explorer") return;
|
|
35256
|
-
const ex = st.panels[idx];
|
|
35257
|
-
const tabs = ex.openTabs ?? [];
|
|
35258
|
-
const closedAt = tabs.indexOf(path);
|
|
35259
|
-
if (closedAt === -1) return;
|
|
35260
|
-
const openTabs = tabs.filter((p) => p !== path);
|
|
35261
|
-
const activeFile = ex.activeFile === path ? openTabs.length === 0 ? null : openTabs[Math.max(0, closedAt - 1)] : ex.activeFile ?? null;
|
|
35262
|
-
st.panels = st.panels.with(idx, {
|
|
35263
|
-
...ex,
|
|
35264
|
-
openTabs,
|
|
35265
|
-
activeFile
|
|
36021
|
+
$$renderer.push(`<!--]--> `);
|
|
36022
|
+
if (onremove || lens) {
|
|
36023
|
+
$$renderer.push("<!--[0-->");
|
|
36024
|
+
PanelClose($$renderer, {
|
|
36025
|
+
sessionId,
|
|
36026
|
+
lens});
|
|
36027
|
+
} else $$renderer.push("<!--[-1-->");
|
|
36028
|
+
$$renderer.push(`<!--]--></span></div>`);
|
|
35266
36029
|
});
|
|
35267
36030
|
}
|
|
35268
|
-
|
|
35269
|
-
|
|
35270
|
-
|
|
35271
|
-
|
|
35272
|
-
|
|
35273
|
-
|
|
35274
|
-
|
|
35275
|
-
|
|
36031
|
+
//#endregion
|
|
36032
|
+
//#region src/lib/components/panels/PanelColumn.svelte
|
|
36033
|
+
function PanelColumn($$renderer, $$props) {
|
|
36034
|
+
$$renderer.component(($$renderer) => {
|
|
36035
|
+
/**
|
|
36036
|
+
* PanelColumn — one panel's fixed-width column shell (Panel Floor W3
|
|
36037
|
+
* task 3.2, ADR-0006): PanelHeader (floor chrome) + the conversation
|
|
36038
|
+
* body (ConversationPanel, keyed by sessionId INSIDE the route's each
|
|
36039
|
+
* — remount locality) + the 6px ResizeGutter after every panel.
|
|
36040
|
+
*
|
|
36041
|
+
* Presentational shell only: width and selection arrive as props
|
|
36042
|
+
* (bound up to the route); the body arrives as a snippet so the ROUTE
|
|
36043
|
+
* owns the {#key panel.sessionId} remount and the per-panel cold data.
|
|
36044
|
+
*
|
|
36045
|
+
* Width badge (2026-08-28): a `widthBadge` phase prop ('live' during
|
|
36046
|
+
* a gutter drag that moves this panel's width, 'fading' through the
|
|
36047
|
+
* 10s afterglow) floats the CURRENT width at the column's top right,
|
|
36048
|
+
* below the header's controls, pointer-transparent — the route owns
|
|
36049
|
+
* the membership rule (changed-from-snapshot) and the fade timer.
|
|
36050
|
+
*/
|
|
36051
|
+
let { panel, index, selected, widthBadge = null, copyValue, canMoveLeft = false, canMoveRight = false, onremove, children } = $$props;
|
|
36052
|
+
$$renderer.push(`<div data-svelte="PanelColumn"${attr_class("column svelte-1cuodug", void 0, { "selected": selected })} data-testid="panel-column"${attr("data-panel-id", panel.id)}${attr("data-session-id", panel.kind === "conversation" ? panel.sessionId : null)}${attr_style(`width: ${stringify(panel.width)}px; min-width: ${stringify(panel.width)}px; max-width: ${stringify(panel.width)}px;`)}>`);
|
|
36053
|
+
PanelHeader($$renderer, {
|
|
36054
|
+
panelId: panel.id,
|
|
36055
|
+
sessionId: panel.kind === "conversation" ? panel.sessionId : "",
|
|
36056
|
+
label: panelHeaderLabel(panel),
|
|
36057
|
+
copyValue: panel.kind === "workspace-explorer" ? panel.root : panel.kind === "workspace-file" ? copyValue : void 0,
|
|
36058
|
+
copyLabel: panel.kind === "workspace-explorer" ? t(workspaceexplorercopyworkspace3) : panel.kind === "workspace-file" ? t(workspacefilecopyfilename3) : void 0,
|
|
36059
|
+
labelTestId: panel.kind === "workspace-explorer" ? "explorer-title" : panel.kind === "workspace-file" ? "file-title" : void 0,
|
|
36060
|
+
selected,
|
|
36061
|
+
canMoveLeft,
|
|
36062
|
+
canMoveRight,
|
|
36063
|
+
onremove
|
|
36064
|
+
});
|
|
36065
|
+
$$renderer.push(`<!----> `);
|
|
36066
|
+
if (widthBadge !== null) {
|
|
36067
|
+
$$renderer.push("<!--[0-->");
|
|
36068
|
+
$$renderer.push(`<span${attr_class("width-badge svelte-1cuodug", void 0, { "fading": widthBadge === "fading" })} data-testid="panel-width-badge"${attr("data-badge-phase", widthBadge)} aria-hidden="true">${escape_html(Math.round(panel.width))}px</span>`);
|
|
36069
|
+
} else $$renderer.push("<!--[-1-->");
|
|
36070
|
+
$$renderer.push(`<!--]--> <div class="body svelte-1cuodug">`);
|
|
36071
|
+
children($$renderer);
|
|
36072
|
+
$$renderer.push(`<!----></div></div> `);
|
|
36073
|
+
ResizeGutter($$renderer, { index });
|
|
36074
|
+
$$renderer.push(`<!---->`);
|
|
35276
36075
|
});
|
|
35277
36076
|
}
|
|
35278
|
-
|
|
35279
|
-
|
|
35280
|
-
|
|
35281
|
-
|
|
35282
|
-
|
|
35283
|
-
|
|
35284
|
-
|
|
35285
|
-
*
|
|
35286
|
-
|
|
35287
|
-
|
|
35288
|
-
|
|
35289
|
-
|
|
35290
|
-
|
|
35291
|
-
|
|
35292
|
-
|
|
35293
|
-
|
|
35294
|
-
|
|
36077
|
+
//#endregion
|
|
36078
|
+
//#region src/lib/components/panels/PanelLoupe.svelte
|
|
36079
|
+
function PanelLoupe($$renderer, $$props) {
|
|
36080
|
+
$$renderer.component(($$renderer) => {
|
|
36081
|
+
/**
|
|
36082
|
+
* PanelLoupe — the reading lens over one floor panel (The Panel Loupe
|
|
36083
|
+
* ADR D2/D5, 2026-09-04): a body-portaled modal dialog that renders
|
|
36084
|
+
* one panel's content at reading size while the floor keeps its
|
|
36085
|
+
* zoom. ANY kind lenses (The Loupe for Every Panel, 2026-09-08): the
|
|
36086
|
+
* route feeds the SAME body snippet the column renders (D7 — one
|
|
36087
|
+
* ladder, two sites) and the header rides the panel's label variant;
|
|
36088
|
+
* the loupe itself carries no conversation logic.
|
|
36089
|
+
*
|
|
36090
|
+
* Contract donor: ImageLightbox (2026-08-28) — the portal, the fixed
|
|
36091
|
+
* inset-0 z-[1000] layer, role="dialog" aria-modal, the mask's
|
|
36092
|
+
* mousedown close, Escape, the × control, focus to the × on open and
|
|
36093
|
+
* back to the opener on close. The portal is load-bearing: the floor
|
|
36094
|
+
* row carries transform: scale(), and a fixed backdrop inside a
|
|
36095
|
+
* transformed ancestor is trapped in that ancestor's box instead of
|
|
36096
|
+
* covering the viewport (ADR D2). The action is inlined here by
|
|
36097
|
+
* decision — the donor is cited, not modified or refactored.
|
|
36098
|
+
*
|
|
36099
|
+
* Lens flag (D8): setLensMode(true) during init, BEFORE children
|
|
36100
|
+
* render — every floor-verb control inside the body snippet reads the
|
|
36101
|
+
* flag at its own init and renders visible-disabled. Context follows
|
|
36102
|
+
* the component tree, so the flag reaches snippet content even after
|
|
36103
|
+
* the portal moves the DOM under document.body (asserted by the loupe
|
|
36104
|
+
* unit tests).
|
|
36105
|
+
*
|
|
36106
|
+
* The lens × and this header's copy-id are the loupe's live controls;
|
|
36107
|
+
* the header's move/close render visible-disabled (the floor verbs).
|
|
36108
|
+
* Openness is the route's session-local state — never persisted (D5).
|
|
36109
|
+
*/
|
|
36110
|
+
let { panelId, sessionId, label = void 0, children } = $$props;
|
|
36111
|
+
setLensMode(true);
|
|
36112
|
+
$$renderer.push(`<div data-svelte="PanelLoupe" class="fixed inset-0 z-[1000] grid place-items-center p-10" role="dialog" aria-modal="true"${attr("aria-label", t(panelloupe1))} data-testid="panel-loupe"${attr("data-panel-id", panelId)}${attr("data-session-id", sessionId)}><div class="absolute inset-0 bg-black/60" aria-hidden="true" data-testid="panel-loupe-mask"></div> <div class="relative" style="width: min(100vw - 4rem, 850px); height: min(95vh, calc(100vh - 5rem));" data-testid="panel-loupe-sheet"><div class="flex h-full w-full flex-col overflow-hidden rounded-xl shadow-2xl" style="background: var(--color-surface-primary, var(--color-surface-elevated));">`);
|
|
36113
|
+
PanelHeader($$renderer, {
|
|
36114
|
+
panelId,
|
|
36115
|
+
sessionId,
|
|
36116
|
+
label,
|
|
36117
|
+
lens: true
|
|
36118
|
+
});
|
|
36119
|
+
$$renderer.push(`<!----> <div class="flex min-h-0 flex-1 flex-col overflow-hidden">`);
|
|
36120
|
+
children($$renderer);
|
|
36121
|
+
$$renderer.push(`<!----></div></div> <button type="button"${attr("aria-label", t(closeloupe1))} data-testid="panel-loupe-close" class="absolute -top-3 -right-3 z-10 flex h-9 w-9 cursor-pointer items-center justify-center rounded-full border border-surface-border bg-surface-elevated text-lg leading-none text-text-primary shadow-md hover:bg-surface-hover">×</button></div></div>`);
|
|
35295
36122
|
});
|
|
35296
36123
|
}
|
|
35297
|
-
|
|
35298
|
-
|
|
35299
|
-
function
|
|
35300
|
-
|
|
35301
|
-
|
|
35302
|
-
|
|
35303
|
-
|
|
35304
|
-
|
|
35305
|
-
|
|
35306
|
-
|
|
35307
|
-
|
|
36124
|
+
//#endregion
|
|
36125
|
+
//#region src/lib/components/panels/StickyColumnContainer.svelte
|
|
36126
|
+
function StickyColumnContainer($$renderer, $$props) {
|
|
36127
|
+
$$renderer.component(($$renderer) => {
|
|
36128
|
+
/**
|
|
36129
|
+
* StickyColumnContainer — a fixed-width LEADING column inside the zoom
|
|
36130
|
+
* row (OCI StickyColumnContainer port, 2026-08-26; hosts the embedded
|
|
36131
|
+
* AppSidebar the way OCI's hosts ControlRail).
|
|
36132
|
+
*
|
|
36133
|
+
* "Sticky" = the width is TRIPLE-LOCKED (width/min/max all the same
|
|
36134
|
+
* px), unlike panel columns whose widths live in [MIN, MAX]: the rail
|
|
36135
|
+
* never flexes when the row measures itself at max-content. The
|
|
36136
|
+
* column's background paints the full column height — the rail inside
|
|
36137
|
+
* fills it (align-items: stretch).
|
|
36138
|
+
*
|
|
36139
|
+
* The trailing ResizeGutter is included BY DEFAULT (OCI parity) but
|
|
36140
|
+
* only when panel columns actually follow (showGutter) — a rail alone
|
|
36141
|
+
* on the floor has nothing to resize against. The gutter is the
|
|
36142
|
+
* column's flex SIBLING (the rail's overflow must never clip its hit
|
|
36143
|
+
* area) and reports mousedown through onResizeStart — the page owns
|
|
36144
|
+
* the drag math and the single clamp (AppSidebar ownership split;
|
|
36145
|
+
* ControlBar.onresizeall precedent: layout chrome is a DIRECT child
|
|
36146
|
+
* of the route, so prop wiring here breaks no commitment).
|
|
36147
|
+
*/
|
|
36148
|
+
let { width, showGutter = true, children } = $$props;
|
|
36149
|
+
$$renderer.push(`<div data-svelte="StickyColumnContainer" class="rail-column svelte-s09nms" data-testid="sidebar-column"${attr_style(`width: ${stringify(width)}px; min-width: ${stringify(width)}px; max-width: ${stringify(width)}px;`)}>`);
|
|
36150
|
+
children($$renderer);
|
|
36151
|
+
$$renderer.push(`<!----></div> `);
|
|
36152
|
+
if (showGutter) {
|
|
36153
|
+
$$renderer.push("<!--[0-->");
|
|
36154
|
+
$$renderer.push(`<div data-svelte="StickyColumnContainer" class="rail-gutter svelte-s09nms" data-testid="sidebar-gutter" role="separator" aria-orientation="vertical"${attr("aria-label", t(resizesidebar1))}></div>`);
|
|
36155
|
+
} else $$renderer.push("<!--[-1-->");
|
|
36156
|
+
$$renderer.push(`<!--]-->`);
|
|
35308
36157
|
});
|
|
35309
36158
|
}
|
|
35310
|
-
|
|
35311
|
-
|
|
35312
|
-
function
|
|
35313
|
-
|
|
35314
|
-
|
|
35315
|
-
st.panels = st.panels.with(idx, {
|
|
35316
|
-
...st.panels[idx],
|
|
35317
|
-
view
|
|
36159
|
+
//#endregion
|
|
36160
|
+
//#region src/lib/components/panels/EmptyFloor.svelte
|
|
36161
|
+
function EmptyFloor($$renderer, $$props) {
|
|
36162
|
+
$$renderer.component(($$renderer) => {
|
|
36163
|
+
$$renderer.push(`<div data-svelte="EmptyFloor" class="empty-floor svelte-z8g5d9" data-testid="workspace-empty"><p>${escape_html(t(noconversations1))}</p> <p class="hint svelte-z8g5d9">${escape_html(t(picksession1))}</p></div>`);
|
|
35318
36164
|
});
|
|
35319
36165
|
}
|
|
35320
|
-
/** Tree file-click action (The Settings Tree ADR 2026-09-18 D1): the
|
|
35321
|
-
* intent publishes to the session's explorer, which opens/focuses a
|
|
35322
|
-
* tab. No open explorer ⇒ the intent drops. */
|
|
35323
|
-
function openWorkspaceFile(sessionId, path, lines) {
|
|
35324
|
-
const host = sessionWorkspaceExplorer(sessionId);
|
|
35325
|
-
if (host) publishFileIntent(host.id, path, lines);
|
|
35326
|
-
}
|
|
35327
|
-
/** Publish a file intent to an explorer panel and focus it. `lines` is
|
|
35328
|
-
* the optional #L anchor target — display metadata, not persisted. */
|
|
35329
|
-
function publishFileIntent(explorerId, path, lines) {
|
|
35330
|
-
st.pendingFileIntents[explorerId] = {
|
|
35331
|
-
path,
|
|
35332
|
-
nonce: ++st.fileIntentSeq,
|
|
35333
|
-
lines: lines ?? null
|
|
35334
|
-
};
|
|
35335
|
-
st.selectedPanelId = explorerId;
|
|
35336
|
-
}
|
|
35337
|
-
/** The panel consumed intent nonce N — clear exactly that publish. */
|
|
35338
|
-
function consumeFileIntent(explorerId, nonce) {
|
|
35339
|
-
if (st.pendingFileIntents[explorerId]?.nonce === nonce) st.pendingFileIntents[explorerId] = null;
|
|
35340
|
-
}
|
|
35341
|
-
/** Remove a panel; family close walks the wire lineage transitively
|
|
35342
|
-
* (every descendant sub-agent goes with it, nested included). The
|
|
35343
|
-
* Shift+Click amendment (2026-09-01): family === false opts OUT — only
|
|
35344
|
-
* THAT panel drops, the children re-root as orphan family heads.
|
|
35345
|
-
*
|
|
35346
|
-
* The session's workspace pair closes with it (2026-09-10); closing an
|
|
35347
|
-
* EXPLORER dooms its file children BY PANEL ID — the stored
|
|
35348
|
-
* explorerPanelId edge, with the legacy null-edge fallback. A
|
|
35349
|
-
* settings-home explorer (sessionId null) dies with the close. */
|
|
35350
|
-
function removePanel(panelId, opts = {}) {
|
|
35351
|
-
const idx = st.panels.findIndex((p) => p.id === panelId);
|
|
35352
|
-
if (idx < 0) return;
|
|
35353
|
-
const root = st.panels[idx];
|
|
35354
|
-
const rootSessionId = root.kind === "conversation" ? root.sessionId : null;
|
|
35355
|
-
const doomed = new SvelteSet(rootSessionId !== null ? [rootSessionId] : []);
|
|
35356
|
-
if (opts.family !== false && rootSessionId !== null) {
|
|
35357
|
-
const stack = [rootSessionId];
|
|
35358
|
-
while (stack.length > 0) for (const kid of d$4().getLineageFacts().childrenByParent.get(stack.pop()) ?? []) if (!doomed.has(kid.sessionId)) {
|
|
35359
|
-
doomed.add(kid.sessionId);
|
|
35360
|
-
stack.push(kid.sessionId);
|
|
35361
|
-
}
|
|
35362
|
-
}
|
|
35363
|
-
const doomedPanelIds = new SvelteSet();
|
|
35364
|
-
if (opts.family !== false && rootSessionId !== null) {
|
|
35365
|
-
for (const p of st.panels) if (p.kind === "browser" && p.openedBy !== void 0 && doomed.has(p.openedBy)) doomedPanelIds.add(p.id);
|
|
35366
|
-
}
|
|
35367
|
-
if (opts.family !== false && root.kind === "workspace-explorer") {
|
|
35368
|
-
for (const p of st.panels) if (p.kind === "workspace-file" && (p.explorerPanelId === root.id || p.explorerPanelId === null && p.sessionId === root.sessionId)) doomedPanelIds.add(p.id);
|
|
35369
|
-
}
|
|
35370
|
-
st.panels = st.panels.filter((p) => p.id !== root.id && !doomedPanelIds.has(p.id) && (p.kind === "conversation" ? !doomed.has(p.sessionId) : !("sessionId" in p) || p.sessionId === null || opts.family !== false && !doomed.has(p.sessionId)));
|
|
35371
|
-
if (st.selectedPanelId !== null && !st.panels.some((p) => p.id === st.selectedPanelId)) st.selectedPanelId = st.panels[Math.min(idx, st.panels.length - 1)]?.id ?? null;
|
|
35372
|
-
clearLoupeIfGone();
|
|
35373
|
-
}
|
|
35374
36166
|
//#endregion
|
|
35375
|
-
//#region src/lib/services/
|
|
35376
|
-
var
|
|
35377
|
-
|
|
35378
|
-
|
|
35379
|
-
|
|
35380
|
-
|
|
35381
|
-
|
|
35382
|
-
|
|
35383
|
-
|
|
35384
|
-
|
|
35385
|
-
|
|
35386
|
-
|
|
35387
|
-
|
|
35388
|
-
}
|
|
35389
|
-
/**
|
|
35390
|
-
*
|
|
35391
|
-
|
|
35392
|
-
|
|
35393
|
-
|
|
35394
|
-
|
|
35395
|
-
|
|
35396
|
-
async function openFileLinkFromMarkdown(sessionId, rawHref) {
|
|
35397
|
-
const { path, lines } = parseFileLinkHref(rawHref);
|
|
35398
|
-
if (path === "") return;
|
|
35399
|
-
const target = await resolveFileLinkTarget(sessionId, path, d$2().getWorkspaceFor(sessionId), void 0, workspaceRootDirs);
|
|
35400
|
-
if (target === null) return;
|
|
35401
|
-
if (!sessionWorkspaceExplorer(sessionId)) {
|
|
35402
|
-
const root = d$2().getWorkspaceFor(sessionId);
|
|
35403
|
-
if (!root) return;
|
|
35404
|
-
openWorkspaceExplorer(sessionId, root);
|
|
36167
|
+
//#region src/lib/services/conversation/spine-feed.svelte.ts
|
|
36168
|
+
var spineFeed = {
|
|
36169
|
+
rows: [],
|
|
36170
|
+
presets: [],
|
|
36171
|
+
a2aRows: [],
|
|
36172
|
+
workspaces: []
|
|
36173
|
+
};
|
|
36174
|
+
//#endregion
|
|
36175
|
+
//#region src/lib/services/workspace/page-feeds.svelte.ts
|
|
36176
|
+
var PageFeeds = class {
|
|
36177
|
+
coldCache = {};
|
|
36178
|
+
coldInFlight = new SvelteSet();
|
|
36179
|
+
deadSessions = {};
|
|
36180
|
+
edgeCache = {};
|
|
36181
|
+
/** Seed-arrival prime: the seed panel mounts with full cold props on
|
|
36182
|
+
* paint one (SSR parity for the seed path). Load-time constant. */
|
|
36183
|
+
primeSeed(sessionId, cold) {
|
|
36184
|
+
this.coldCache = {
|
|
36185
|
+
...this.coldCache,
|
|
36186
|
+
[sessionId]: cold
|
|
36187
|
+
};
|
|
35405
36188
|
}
|
|
35406
|
-
|
|
35407
|
-
|
|
35408
|
-
|
|
35409
|
-
|
|
35410
|
-
|
|
35411
|
-
|
|
35412
|
-
* from the route — a pure wire read over the global fetch. */
|
|
35413
|
-
async function fetchColdFromWire(sessionId) {
|
|
35414
|
-
const eventsRes = await fetch(`/api/dsh/session/${encodeURIComponent(sessionId)}/events?full=1`);
|
|
35415
|
-
if (!eventsRes.ok) return null;
|
|
35416
|
-
const events = await eventsRes.json();
|
|
35417
|
-
if (!events.ok) return null;
|
|
35418
|
-
const lastSeq = events.lastSeq ?? -1;
|
|
35419
|
-
let hasMore = false;
|
|
35420
|
-
const historyRes = await fetch(`/api/dsh/session/${encodeURIComponent(sessionId)}/history?beforeSeq=${lastSeq + 1}`);
|
|
35421
|
-
if (historyRes.ok) {
|
|
35422
|
-
const history = await historyRes.json();
|
|
35423
|
-
if (history.ok) hasMore = (history.entries?.length ?? 0) > 0 || history.hasMore === true;
|
|
36189
|
+
/** Record an ADD-time parent edge (the route's doAdd fork path). */
|
|
36190
|
+
rememberEdge(childSessionId, parentSessionId) {
|
|
36191
|
+
this.edgeCache = {
|
|
36192
|
+
...this.edgeCache,
|
|
36193
|
+
[childSessionId]: parentSessionId
|
|
36194
|
+
};
|
|
35424
36195
|
}
|
|
35425
|
-
|
|
35426
|
-
|
|
35427
|
-
|
|
35428
|
-
|
|
35429
|
-
|
|
35430
|
-
|
|
35431
|
-
|
|
35432
|
-
|
|
35433
|
-
|
|
35434
|
-
|
|
35435
|
-
|
|
35436
|
-
|
|
35437
|
-
|
|
35438
|
-
|
|
35439
|
-
|
|
35440
|
-
}
|
|
35441
|
-
|
|
35442
|
-
|
|
35443
|
-
|
|
35444
|
-
|
|
35445
|
-
|
|
35446
|
-
|
|
35447
|
-
* make* panel factories and the slot grammar (insertPanel, insertionSlot,
|
|
35448
|
-
* pinnedSlotIndex). Plain module: no runes here — every write goes through
|
|
35449
|
-
* the state home's reactive `st` hub and its primitives (ADR-0019 D2:
|
|
35450
|
-
* exactly ONE writer home for floor state). Sibling rule: this file never
|
|
35451
|
-
* imports another sibling; shared needs come from the state home.
|
|
35452
|
-
*/
|
|
35453
|
-
var d$1 = floorSeam;
|
|
35454
|
-
function makePanel(sessionId, agentPreset) {
|
|
35455
|
-
return {
|
|
35456
|
-
id: nextPanelId(),
|
|
35457
|
-
kind: "conversation",
|
|
35458
|
-
sessionId,
|
|
35459
|
-
agentPreset,
|
|
35460
|
-
width: clampPanelWidth(d$1().getPanelWidth())
|
|
35461
|
-
};
|
|
35462
|
-
}
|
|
35463
|
-
/** width: the reload-restored panel re-mints at the width the operator
|
|
35464
|
-
* dragged before (browser-slot persistence, RCA 2026-10-22); absent for
|
|
35465
|
-
* chip clicks and legacy slots — the honest-slider preset.
|
|
35466
|
-
* openedBy: the opener session's provenance, recorded ONCE at spawn and
|
|
35467
|
-
* never rewritten (ADR-0036 D1/D2); undefined = no conversation context. */
|
|
35468
|
-
function makeBrowserPanel(width, openedBy, sessionId) {
|
|
35469
|
-
return {
|
|
35470
|
-
id: nextPanelId(),
|
|
35471
|
-
kind: "browser",
|
|
35472
|
-
width: clampPanelWidth(width ?? d$1().getPanelWidth()),
|
|
35473
|
-
...openedBy !== void 0 ? { openedBy } : {},
|
|
35474
|
-
...sessionId !== void 0 ? { browserSessionId: sessionId } : {}
|
|
35475
|
-
};
|
|
35476
|
-
}
|
|
35477
|
-
function makeWorkspaceExplorerPanel(sessionId, root) {
|
|
35478
|
-
return {
|
|
35479
|
-
id: nextPanelId(),
|
|
35480
|
-
kind: "workspace-explorer",
|
|
35481
|
-
sessionId,
|
|
35482
|
-
root,
|
|
35483
|
-
expanded: [],
|
|
35484
|
-
width: clampPanelWidth(850, "workspace-explorer")
|
|
35485
|
-
};
|
|
35486
|
-
}
|
|
35487
|
-
function insertPanel(entry, index) {
|
|
35488
|
-
const next = [...st.panels];
|
|
35489
|
-
next.splice(Math.min(index, next.length), 0, entry);
|
|
35490
|
-
st.panels = next;
|
|
35491
|
-
st.selectedPanelId = entry.id;
|
|
35492
|
-
}
|
|
35493
|
-
function insertionSlot() {
|
|
35494
|
-
return focusedInsertionSlot(st.panels, selectedIndex_(), d$1().getMoveFacts().parentOf);
|
|
35495
|
-
}
|
|
35496
|
-
//#endregion
|
|
35497
|
-
//#region src/lib/services/panels/floor-registry.svelte.ts
|
|
35498
|
-
var deps = null;
|
|
35499
|
-
function configureFloorRegistry(d0) {
|
|
35500
|
-
deps = d0;
|
|
35501
|
-
}
|
|
35502
|
-
function d() {
|
|
35503
|
-
if (deps === null) throw new Error("floor-registry: configureFloorRegistry() was never called");
|
|
35504
|
-
return deps;
|
|
35505
|
-
}
|
|
35506
|
-
/** Sibling-module access to the dep seam (ADR-0022 W2): the ONE outside-reads
|
|
35507
|
-
* channel; siblings never open their own config channel. */
|
|
35508
|
-
function floorSeam() {
|
|
35509
|
-
return d();
|
|
35510
|
-
}
|
|
35511
|
-
var st = {
|
|
35512
|
-
panels: [],
|
|
35513
|
-
selectedPanelId: null,
|
|
35514
|
-
loupePanelId: null,
|
|
35515
|
-
focusComposerId: null,
|
|
35516
|
-
panelIdSeq: 0,
|
|
35517
|
-
terminalDeskMirrors: {},
|
|
35518
|
-
pendingFileIntents: {},
|
|
35519
|
-
fileIntentSeq: 0,
|
|
35520
|
-
drag: null,
|
|
35521
|
-
widthBadgeFading: false
|
|
35522
|
-
};
|
|
35523
|
-
/** Non-reactive gesture refs (drag start index, fade timer, badge ids) —
|
|
35524
|
-
* written by floor-registry/drag.svelte.ts; the ids set is a live
|
|
35525
|
-
* SvelteSet so badge visibility stays reactive. */
|
|
35526
|
-
var dragRefs = {
|
|
35527
|
-
ids: new SvelteSet()
|
|
35528
|
-
};
|
|
35529
|
-
var floor = {
|
|
35530
|
-
get panels() {
|
|
35531
|
-
return st.panels;
|
|
35532
|
-
},
|
|
35533
|
-
get selectedPanelId() {
|
|
35534
|
-
return st.selectedPanelId;
|
|
35535
|
-
},
|
|
35536
|
-
get loupePanelId() {
|
|
35537
|
-
return st.loupePanelId;
|
|
35538
|
-
},
|
|
35539
|
-
get focusComposerId() {
|
|
35540
|
-
return st.focusComposerId;
|
|
35541
|
-
},
|
|
35542
|
-
get terminalDeskMirrors() {
|
|
35543
|
-
return st.terminalDeskMirrors;
|
|
35544
|
-
},
|
|
35545
|
-
get pendingFileIntents() {
|
|
35546
|
-
return st.pendingFileIntents;
|
|
35547
|
-
},
|
|
35548
|
-
get drag() {
|
|
35549
|
-
return st.drag;
|
|
35550
|
-
},
|
|
35551
|
-
get widthBadgeFading() {
|
|
35552
|
-
return st.widthBadgeFading;
|
|
35553
|
-
},
|
|
35554
|
-
get widthBadgeIds() {
|
|
35555
|
-
return dragRefs.ids;
|
|
35556
|
-
},
|
|
35557
|
-
get selected() {
|
|
35558
|
-
return st.panels.find((p) => p.id === st.selectedPanelId) ?? null;
|
|
35559
|
-
},
|
|
35560
|
-
get loupePanel() {
|
|
35561
|
-
return st.panels.find((p) => p.id === st.loupePanelId) ?? null;
|
|
36196
|
+
/** One dual fetch, registries kept honest (in-flight guard, dead
|
|
36197
|
+
* session card, loader clear in `finally`). The fetcher is injected:
|
|
36198
|
+
* the wire call stays the route's (`fetchCold` reads the host
|
|
36199
|
+
* config); the bookkeeping lives here. */
|
|
36200
|
+
async runCold(sessionId, fetchCold) {
|
|
36201
|
+
if (this.coldCache[sessionId] !== void 0 || this.coldInFlight.has(sessionId)) return;
|
|
36202
|
+
this.coldInFlight = new SvelteSet(this.coldInFlight).add(sessionId);
|
|
36203
|
+
try {
|
|
36204
|
+
const cold = await fetchCold(sessionId);
|
|
36205
|
+
if (cold !== null) this.coldCache = {
|
|
36206
|
+
...this.coldCache,
|
|
36207
|
+
[sessionId]: cold
|
|
36208
|
+
};
|
|
36209
|
+
else this.deadSessions = {
|
|
36210
|
+
...this.deadSessions,
|
|
36211
|
+
[sessionId]: `Session ${sessionId} not found on the DSH host. It may have been reaped.`
|
|
36212
|
+
};
|
|
36213
|
+
} finally {
|
|
36214
|
+
const next = new SvelteSet(this.coldInFlight);
|
|
36215
|
+
next.delete(sessionId);
|
|
36216
|
+
this.coldInFlight = next;
|
|
36217
|
+
}
|
|
35562
36218
|
}
|
|
35563
|
-
|
|
35564
|
-
|
|
35565
|
-
|
|
35566
|
-
|
|
35567
|
-
|
|
35568
|
-
|
|
35569
|
-
|
|
35570
|
-
|
|
35571
|
-
|
|
36219
|
+
/** The floor's two lifecycle feeds (call during component init —
|
|
36220
|
+
* `$effect` needs an owner):
|
|
36221
|
+
* - Prompt Sync hygiene (ADR "The Prompt Sync" D1/D6): a session
|
|
36222
|
+
* that left the floor holds no check and no snapshot; count 0
|
|
36223
|
+
* clears the broadcast. Conversation sessions only (D6).
|
|
36224
|
+
* - Spine feed lifecycle (W8): ref-counted single timer started on
|
|
36225
|
+
* mount, stopped on destroy; the a2a window rides the floor's
|
|
36226
|
+
* conversation senders (first sender per tick, never per panel).
|
|
36227
|
+
* Returns the spine subscription's cleanup. */
|
|
36228
|
+
installFeeds(getConversationSessionIds) {
|
|
36229
|
+
return () => {};
|
|
35572
36230
|
}
|
|
35573
|
-
}
|
|
35574
|
-
|
|
35575
|
-
st.panels = entries;
|
|
35576
|
-
st.selectedPanelId = selectedId;
|
|
35577
|
-
syncPanelIdSeq(entries);
|
|
35578
|
-
}
|
|
35579
|
-
/** The fresh panel mounted and its composer took focus — clear the
|
|
35580
|
-
* swap-focus marker (a marker whose panel never mounts stays inert:
|
|
35581
|
-
* panel ids are unique and never remount). */
|
|
35582
|
-
function clearFocusComposer() {
|
|
35583
|
-
st.focusComposerId = null;
|
|
35584
|
-
}
|
|
35585
|
-
function selectPanel(panelId) {
|
|
35586
|
-
if (st.panels.some((p) => p.id === panelId)) st.selectedPanelId = panelId;
|
|
35587
|
-
}
|
|
35588
|
-
function closeLoupe() {
|
|
35589
|
-
st.loupePanelId = null;
|
|
35590
|
-
}
|
|
35591
|
-
function clearLoupeIfGone() {
|
|
35592
|
-
if (st.loupePanelId !== null && !st.panels.some((p) => p.id === st.loupePanelId)) st.loupePanelId = null;
|
|
35593
|
-
}
|
|
35594
|
-
function selectedIndex_() {
|
|
35595
|
-
return st.panels.findIndex((p) => p.id === st.selectedPanelId);
|
|
35596
|
-
}
|
|
36231
|
+
};
|
|
36232
|
+
var pageFeeds = new PageFeeds();
|
|
35597
36233
|
//#endregion
|
|
35598
36234
|
//#region src/lib/services/panels/glass-release.ts
|
|
35599
36235
|
/**
|
|
@@ -36117,4 +36753,4 @@ function _page($$renderer, $$props) {
|
|
|
36117
36753
|
}
|
|
36118
36754
|
|
|
36119
36755
|
export { _page as default };
|
|
36120
|
-
//# sourceMappingURL=_page.svelte.js-
|
|
36756
|
+
//# sourceMappingURL=_page.svelte.js-CY7zcWr4.js.map
|