@deepseek-insight/dsi 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/client/_app/immutable/assets/0.DyOAkKS-.css +2 -0
- package/build/client/_app/immutable/assets/2.BPprd30B.css +1 -0
- package/build/client/_app/immutable/chunks/{CJ1fzlPC.js → BoHeiMOU.js} +1 -1
- package/build/client/_app/immutable/chunks/C9QAOGL1.js +2 -0
- package/build/client/_app/immutable/chunks/QJuSx3RG.js +1 -0
- package/build/client/_app/immutable/chunks/sC_8Ss7w.js +1 -0
- package/build/client/_app/immutable/entry/{app.DP0oSUf-.js → app.S_mxIoOg.js} +2 -2
- package/build/client/_app/immutable/entry/start.BPQAB3iV.js +1 -0
- package/build/client/_app/immutable/nodes/{1.UuScj-IS.js → 1.D20V6eTe.js} +1 -1
- package/build/client/_app/immutable/nodes/{2.CJRPZhbe.js → 2.BHcBdFqH.js} +223 -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/{db.js-B8BUpxGM.js → db.js-DQm6CZ_r.js} +2 -2
- package/build/server/chunks/chunks/{db2.js-CNe3I_g2.js → db2.js-DUhFxA3a.js} +2 -2
- package/build/server/chunks/chunks/{dsh-connection.js-xltcocWy.js → dsh-connection.js-BgeraFA2.js} +2 -2
- package/build/server/chunks/chunks/{dsh-events.js-CGuF_had.js → dsh-events.js-BUkLR6ZV.js} +13 -1
- package/build/server/chunks/chunks/{git-probe.js-CUsTmhmV.js → git-probe.js-CLF37SRh.js} +3 -3
- package/build/server/chunks/chunks/{insight-config.js-CaHHJpFK.js → insight-config.js-Dp_2gB5J.js} +5 -3
- package/build/server/chunks/chunks/{internal2.js-Pv5iygVN.js → internal2.js-Ba5p8uFM.js} +2 -2
- package/build/server/chunks/chunks/registry.js-C2MdrfNv.js +954 -0
- package/build/server/chunks/chunks/{state.js-BCaKzPy6.js → state.js-BSiAgink.js} +2 -2
- package/build/server/chunks/chunks/{watcher.js-DcT3cS4v.js → watcher.js-BVKnoQUw.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/a2a/_id_/{_server.ts.js-19pFOjH8.js → _server.ts.js-BjzdVwdY.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/a2a/{_server.ts.js-BcUn6axe.js → _server.ts.js-3kQCQuHT.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/a2a/register/{_server.ts.js-oMpzLZoy.js → _server.ts.js-BUBTCLFn.js} +6 -6
- package/build/server/chunks/entries/endpoints/api/browser/_id_/activate/_server.ts.js-CogDOHKu.js +45 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/close/{_server.ts.js-DC3qPMQS.js → _server.ts.js-xOt7LnS1.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/browser/_id_/closetab/_server.ts.js-CSmVPvSM.js +44 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/element/_server.ts.js-BA40oCDW.js +43 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/input/{_server.ts.js-CHNcK7BH.js → _server.ts.js-EX7eVzjp.js} +6 -5
- package/build/server/chunks/entries/endpoints/api/browser/_id_/mcp/{_server.ts.js-CYkOJL2O.js → _server.ts.js-B_EcmyFt.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/browser/_id_/navigate/{_server.ts.js-DHTDi8KR.js → _server.ts.js-C3dYbyS3.js} +12 -8
- package/build/server/chunks/entries/endpoints/api/browser/_id_/opentab/_server.ts.js-CMhJJO25.js +45 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/page/{_server.ts.js-Y5khEC2l.js → _server.ts.js-DIW4uI2S.js} +5 -4
- package/build/server/chunks/entries/endpoints/api/browser/_id_/stream/{_server.ts.js-BmjgfZD2.js → _server.ts.js-CIPIlq5X.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/browser/_id_/tabs/_server.ts.js-CoEdOiml.js +34 -0
- package/build/server/chunks/entries/endpoints/api/browser/_id_/viewport/{_server.ts.js-IxS-goi1.js → _server.ts.js-CdELUoGT.js} +7 -5
- package/build/server/chunks/entries/endpoints/api/browser/{_server.ts.js-6STmJ7FD.js → _server.ts.js-ea6HpNGh.js} +15 -5
- package/build/server/chunks/entries/endpoints/api/config/{_server.ts.js-BVyx8gPc.js → _server.ts.js-C8XDnDwe.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/directory/{_server.ts.js-CNJbv6CC.js → _server.ts.js-BFmWshpv.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/{_server.ts.js-CDWmXDJX.js → _server.ts.js-DATWy5mQ.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/jobs/follow/{_server.ts.js-BDXQcQSL.js → _server.ts.js-CugOD1Zd.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/pick-directory/{_server.ts.js-CgedtzOg.js → _server.ts.js-DCupM4da.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/presets/{_server.ts.js-ut2pK15B.js → _server.ts.js-Bh1btvr9.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/attachment/{_server.ts.js-Ct2W7g4c.js → _server.ts.js-Cb8SBWVw.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/cancel/{_server.ts.js-Rke3V_qh.js → _server.ts.js-WI9yH2iG.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/catalog/{_server.ts.js-BYHm5WBA.js → _server.ts.js-bN9adUqz.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/changes/{_server.ts.js-B_bEUKkt.js → _server.ts.js-Bxlm966G.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/command/{_server.ts.js-D78fGUQk.js → _server.ts.js-CM-raN_Q.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/events/{_server.ts.js-CgB_c7zG.js → _server.ts.js-BzP30TXW.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/fork/{_server.ts.js-dVaW22_K.js → _server.ts.js-DvNkrTaY.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/goal/{_server.ts.js-Dl8SBXdH.js → _server.ts.js-DXbCrefw.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/history/{_server.ts.js-BKDiwMIE.js → _server.ts.js-B7YRQhuJ.js} +4 -4
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/models/{_server.ts.js-D3FY2Wxt.js → _server.ts.js-C_AEaLLJ.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/path/{_server.ts.js-BWuIEdjl.js → _server.ts.js-Dj-pF5ik.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/permission/{_server.ts.js-CeiQFOGP.js → _server.ts.js-BX9FWJ6g.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/prompt/{_server.ts.js-lMofZOns.js → _server.ts.js-CQ2Bmtu4.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/rename/{_server.ts.js-CNalVHrK.js → _server.ts.js-Ha7xjnKW.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/respond/{_server.ts.js-I2s8qvcV.js → _server.ts.js-BOg6llHk.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/session/_sessionId_/select-model/{_server.ts.js-DTKELD7v.js → _server.ts.js-DBqGALzZ.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/sessions/{_server.ts.js-BXSD__Gg.js → _server.ts.js-CvA8WDDb.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-file/{_server.ts.js-C9IZl2Qh.js → _server.ts.js-BfjNH40j.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspace-tree/{_server.ts.js-BRXu3UtL.js → _server.ts.js-De_qumyr.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/{_server.ts.js-DmnpiaD2.js → _server.ts.js-tFpJJHCb.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/delete/{_server.ts.js-C5qCdsdm.js → _server.ts.js-DVx5GGA_.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/dsh/workspaces/_workspaceId_/rename/{_server.ts.js-BVUn49yf.js → _server.ts.js-DuKT-aZp.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/prompts/_id_/{_server.ts.js-DuCOsoF0.js → _server.ts.js-DsWFidFY.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/prompts/{_server.ts.js-2mcRY7IP.js → _server.ts.js-C6j0adQs.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/prompts/use/{_server.ts.js-DZjaHZxU.js → _server.ts.js-BChAg4hm.js} +3 -3
- package/build/server/chunks/entries/endpoints/api/settings/{_server.ts.js-DTVmsohJ.js → _server.ts.js-BPSHqbZN.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/terminal/{_server.ts.js-DZXTArj7.js → _server.ts.js-D5CbUe5k.js} +2 -2
- package/build/server/chunks/entries/endpoints/api/workspace/file-write/{_server.ts.js-LSc5EKH7.js → _server.ts.js-B-5YihUA.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-events/{_server.ts.js-DNjiScBe.js → _server.ts.js-DT5jRZFE.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-file-head/{_server.ts.js-CHMbLoSn.js → _server.ts.js-DtW-utrd.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-map/{_server.ts.js-BgM4JEAm.js → _server.ts.js-8AIAo9jX.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/git-status/{_server.ts.js-BH0cLS8o.js → _server.ts.js-CMw96vjY.js} +5 -5
- package/build/server/chunks/entries/endpoints/api/workspace/write-gate/{_server.ts.js-BzlV3cVT.js → _server.ts.js-DKufa14_.js} +5 -5
- package/build/server/chunks/entries/pages/{_error.svelte.js-BRyCyR0c.js → _error.svelte.js-D8-G0evO.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.server.ts.js-DttLUwdf.js → _page.server.ts.js-7x6ZfGoB.js} +3 -3
- package/build/server/chunks/entries/pages/{_page.svelte.js-CKY8hz9T.js → _page.svelte.js-7xWLRsiZ.js} +333 -158
- package/build/server/chunks/{handler-D1oqmwyy.js → handler-BedQ0jP-.js} +3 -3
- package/build/server/chunks/{index.js-BZ8zP9wS.js → index.js-BF6tPPQs.js} +2 -2
- package/build/server/chunks/{manifest.js-CA6PuZTD.js → manifest.js-3c0p7QAl.js} +90 -55
- package/build/server/chunks/nodes/{0.js-DtkNHIFx.js → 0.js-B3i7sGR_.js} +3 -3
- package/build/server/chunks/nodes/1.js-eUf50uxI.js +9 -0
- package/build/server/chunks/nodes/{2.js-P1boc94A.js → 2.js-CgnRGwm6.js} +8 -8
- package/package.json +2 -7
- package/skills/dsi-kb-scenario/SKILL.md +67 -0
- package/template/.dsi/prompts.sqlite-shm +0 -0
- package/template/.dsi/prompts.sqlite-wal +0 -0
- package/template/.dsi/settings.yaml +8 -1
- package/build/client/_app/immutable/assets/0.DBVVEjy9.css +0 -2
- package/build/client/_app/immutable/assets/2.BhBfHqja.css +0 -1
- package/build/client/_app/immutable/chunks/C0tWPpc3.js +0 -2
- package/build/client/_app/immutable/chunks/gZFoJ-NI.js +0 -1
- package/build/client/_app/immutable/chunks/xkjLeSzJ.js +0 -1
- package/build/client/_app/immutable/entry/start.mBp3LB6J.js +0 -1
- package/build/server/chunks/chunks/registry.js-BTiJ1Kaj.js +0 -577
- package/build/server/chunks/nodes/1.js-Q6zZupRG.js +0 -9
- /package/build/client/_app/immutable/nodes/{0.Dm_ry-Pr.js → 0.6dTmg1Xv.js} +0 -0
|
@@ -9,7 +9,7 @@ import { D as DEFAULT_IMAGE_LIMITS } from '../../chunks/image-limits.js-CUdJ0f7r
|
|
|
9
9
|
import { s as sanitizeWorkspaceProfile, d as dsiKey, t as themePrefs } from '../../chunks/theme-prefs.svelte.js-8CaWz46g.js';
|
|
10
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-BM4WbMFB.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-BSiAgink.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-Ba5p8uFM.js';
|
|
25
25
|
import '../../chunks/utils.js-CAdNO8Tu.js';
|
|
26
26
|
|
|
27
27
|
//#region src/lib/paraglide/messages/abort.js
|
|
@@ -952,6 +952,38 @@ var browserchiplabel2 = ((inputs = {}, options = {}) => {
|
|
|
952
952
|
return en_browserchiplabel2();
|
|
953
953
|
});
|
|
954
954
|
//#endregion
|
|
955
|
+
//#region src/lib/paraglide/messages/browserclosedelete2.js
|
|
956
|
+
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
957
|
+
/** @typedef {{}} Browserclosedelete2Inputs */
|
|
958
|
+
var en_browserclosedelete2 = () => {
|
|
959
|
+
return `Delete the glass browser — kills the session and removes the panel`;
|
|
960
|
+
};
|
|
961
|
+
var zh_browserclosedelete2 = () => {
|
|
962
|
+
return `删除玻璃浏览器 — 终止会话并移除面板`;
|
|
963
|
+
};
|
|
964
|
+
var id_browserclosedelete2 = () => {
|
|
965
|
+
return `Hapus browser kaca — matikan sesi dan hapus panel`;
|
|
966
|
+
};
|
|
967
|
+
var es_browserclosedelete2 = () => {
|
|
968
|
+
return `Eliminar el navegador de vidrio — mata la sesión y quita el panel`;
|
|
969
|
+
};
|
|
970
|
+
/**
|
|
971
|
+
* | output |
|
|
972
|
+
* | --- |
|
|
973
|
+
* | "Delete the glass browser — kills the session and removes the panel" |
|
|
974
|
+
*
|
|
975
|
+
* @param {Browserclosedelete2Inputs} inputs
|
|
976
|
+
* @param {{ locale?: "en" | "zh" | "id" | "es" }} options
|
|
977
|
+
* @returns {LocalizedString}
|
|
978
|
+
*/
|
|
979
|
+
var browserclosedelete2 = ((inputs = {}, options = {}) => {
|
|
980
|
+
const locale = options.locale ?? getLocale();
|
|
981
|
+
if (locale === "zh") return zh_browserclosedelete2();
|
|
982
|
+
if (locale === "id") return id_browserclosedelete2();
|
|
983
|
+
if (locale === "es") return es_browserclosedelete2();
|
|
984
|
+
return en_browserclosedelete2();
|
|
985
|
+
});
|
|
986
|
+
//#endregion
|
|
955
987
|
//#region src/lib/paraglide/messages/browserforward1.js
|
|
956
988
|
/** @typedef {import('../runtime.js').LocalizedString} LocalizedString */
|
|
957
989
|
/** @typedef {{}} Browserforward1Inputs */
|
|
@@ -14840,6 +14872,7 @@ var _index_exports = /* @__PURE__ */ __exportAll({
|
|
|
14840
14872
|
broadcastSyncedTo: () => broadcastsyncedto2,
|
|
14841
14873
|
browserBack: () => browserback1,
|
|
14842
14874
|
browserChipLabel: () => browserchiplabel2,
|
|
14875
|
+
browserCloseDelete: () => browserclosedelete2,
|
|
14843
14876
|
browserForward: () => browserforward1,
|
|
14844
14877
|
browserLaunching: () => browserlaunching1,
|
|
14845
14878
|
browserOpenTitle: () => browseropentitle2,
|
|
@@ -15311,6 +15344,7 @@ var messages_exports = /* @__PURE__ */ __exportAll({
|
|
|
15311
15344
|
broadcastSyncedTo: () => broadcastsyncedto2,
|
|
15312
15345
|
browserBack: () => browserback1,
|
|
15313
15346
|
browserChipLabel: () => browserchiplabel2,
|
|
15347
|
+
browserCloseDelete: () => browserclosedelete2,
|
|
15314
15348
|
browserForward: () => browserforward1,
|
|
15315
15349
|
browserLaunching: () => browserlaunching1,
|
|
15316
15350
|
browserOpenTitle: () => browseropentitle2,
|
|
@@ -17585,8 +17619,8 @@ function ThemeToggle($$renderer, $$props) {
|
|
|
17585
17619
|
}
|
|
17586
17620
|
//#endregion
|
|
17587
17621
|
//#region package.json
|
|
17588
|
-
var version = "0.8.
|
|
17589
|
-
var dsh = { "webVersion": "0.2.1-rc.
|
|
17622
|
+
var version = "0.8.3";
|
|
17623
|
+
var dsh = { "webVersion": "0.2.1-rc.3" };
|
|
17590
17624
|
//#endregion
|
|
17591
17625
|
//#region src/lib/version.ts
|
|
17592
17626
|
/**
|
|
@@ -23324,6 +23358,32 @@ function panelRowsFor(input) {
|
|
|
23324
23358
|
function rowFactsByPanelId(rows) {
|
|
23325
23359
|
return new Map(rows.map((r) => [r.panel.id, r]));
|
|
23326
23360
|
}
|
|
23361
|
+
/**
|
|
23362
|
+
* The folded-glass ghost rows (ADR-0037 D4, extracted 2026-10-24 — the
|
|
23363
|
+
* Glass Close Ladder task 2.2): the ONE derivation the route renders.
|
|
23364
|
+
* Pure over the slot mirror — a removeBrowserSlot prune drops the ghost
|
|
23365
|
+
* (roster) and the spine nest in the same stroke (Ladder ADR D4).
|
|
23366
|
+
*/
|
|
23367
|
+
function foldedGlassRowsFor(slots, depthOf, titleFor) {
|
|
23368
|
+
return slots.filter((s) => s.folded && s.sessionId && s.openedBy).map((s) => ({
|
|
23369
|
+
panel: {
|
|
23370
|
+
id: "glass-" + s.sessionId,
|
|
23371
|
+
kind: "conversation",
|
|
23372
|
+
sessionId: s.sessionId,
|
|
23373
|
+
agentPreset: null,
|
|
23374
|
+
width: 0
|
|
23375
|
+
},
|
|
23376
|
+
title: "Browser — " + (titleFor(s.openedBy) ?? s.openedBy),
|
|
23377
|
+
workspace: null,
|
|
23378
|
+
dead: false,
|
|
23379
|
+
running: true,
|
|
23380
|
+
depth: depthOf(s.openedBy) + 1,
|
|
23381
|
+
runningDescendants: 0,
|
|
23382
|
+
kind: "ghost",
|
|
23383
|
+
parentSessionId: s.openedBy,
|
|
23384
|
+
siblingIndex: -1
|
|
23385
|
+
}));
|
|
23386
|
+
}
|
|
23327
23387
|
//#endregion
|
|
23328
23388
|
//#region src/lib/components/prompt-manager/PromptsManagerDialogHeader.svelte
|
|
23329
23389
|
function PromptsManagerDialogHeader($$renderer, $$props) {
|
|
@@ -26369,6 +26429,14 @@ function groupTurns(entries) {
|
|
|
26369
26429
|
continue;
|
|
26370
26430
|
}
|
|
26371
26431
|
if (entry.kind === "turn-lifecycle") continue;
|
|
26432
|
+
if (entry.kind === "developer-message") {
|
|
26433
|
+
groups.push({
|
|
26434
|
+
kind: "developer",
|
|
26435
|
+
key: entry.id,
|
|
26436
|
+
entry
|
|
26437
|
+
});
|
|
26438
|
+
continue;
|
|
26439
|
+
}
|
|
26372
26440
|
const side = entry;
|
|
26373
26441
|
const last = groups[groups.length - 1];
|
|
26374
26442
|
if (last?.kind === "assistant-turn") last.entries.push(side);
|
|
@@ -30398,8 +30466,11 @@ function ConversationScrollArea($$renderer, $$props) {
|
|
|
30398
30466
|
open: openChipId === group.entry.id});
|
|
30399
30467
|
$$renderer.push(`<!----></div>`);
|
|
30400
30468
|
}});
|
|
30401
|
-
} else if (group.kind === "
|
|
30469
|
+
} else if (group.kind === "developer") {
|
|
30402
30470
|
$$renderer.push("<!--[1-->");
|
|
30471
|
+
$$renderer.push(`<div data-testid="developer-message-row"${attr("data-seq", group.entry.seq)} class="mx-auto max-w-2xl rounded-md border border-text-muted/20 bg-surface0/5 px-3 py-1.5 text-xs text-text-muted"><span class="mr-1.5 font-medium uppercase tracking-wide opacity-70">developer</span> <span data-testid="developer-message-text">${escape_html(group.entry.text)}</span></div>`);
|
|
30472
|
+
} else if (group.kind === "prompt" || group.kind === "context") {
|
|
30473
|
+
$$renderer.push("<!--[2-->");
|
|
30403
30474
|
PromptBubble($$renderer, {
|
|
30404
30475
|
text: group.kind === "prompt" ? group.entry.text : void 0,
|
|
30405
30476
|
time: group.kind === "prompt" ? group.entry.time : group.entries[0]?.time,
|
|
@@ -32836,6 +32907,19 @@ function persistBrowserSlots(slots, storage = defaultStorage()) {
|
|
|
32836
32907
|
* plain .ts module stays rune-free). Rows and the route derive the
|
|
32837
32908
|
* folded set from it; persistBrowserSlots is the only writer. */
|
|
32838
32909
|
var browserSlotStore = writable([]);
|
|
32910
|
+
/**
|
|
32911
|
+
* Drop the slot entry whose glass session died (The Glass Close Ladder
|
|
32912
|
+
* ADR 2026-10-24 D4): the live prune — a dead glass's entry is REMOVED,
|
|
32913
|
+
* never folded, so the roster ghost and the spine nest drop with it in
|
|
32914
|
+
* the same mirror stroke, no reload. Unknown id = quiet no-op (false).
|
|
32915
|
+
*/
|
|
32916
|
+
function removeBrowserSlot(sessionId, storage = defaultStorage()) {
|
|
32917
|
+
const slots = readBrowserSlots(storage);
|
|
32918
|
+
const next = slots.filter((s) => s.sessionId !== sessionId);
|
|
32919
|
+
if (next.length === slots.length) return false;
|
|
32920
|
+
persistBrowserSlots(next, storage);
|
|
32921
|
+
return true;
|
|
32922
|
+
}
|
|
32839
32923
|
/** Seed the mirror from storage (boot). */
|
|
32840
32924
|
function primeBrowserSlotStore(storage = defaultStorage()) {
|
|
32841
32925
|
browserSlotStore.set(readBrowserSlots(storage));
|
|
@@ -32845,7 +32929,7 @@ function primeBrowserSlotStore(storage = defaultStorage()) {
|
|
|
32845
32929
|
function BrowserClosed($$renderer, $$props) {
|
|
32846
32930
|
$$renderer.component(($$renderer) => {
|
|
32847
32931
|
let { closing = false} = $$props;
|
|
32848
|
-
$$renderer.push(`<button data-svelte="BrowserClosed" class="rounded
|
|
32932
|
+
$$renderer.push(`<button data-svelte="BrowserClosed" class="rounded hover:bg-surface-active svelte-18cg1lj" data-testid="browse-close"${attr("aria-label", browserclosedelete2())}${attr("title", browserclosedelete2())}${attr("disabled", closing, true)}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="red" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h18"></path><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"></path><path d="M10 11v6"></path><path d="M14 11v6"></path></svg></button>`);
|
|
32849
32933
|
});
|
|
32850
32934
|
}
|
|
32851
32935
|
//#endregion
|
|
@@ -32876,13 +32960,28 @@ function BrowserHeader($$renderer, $$props) {
|
|
|
32876
32960
|
//#region src/lib/components/browser/BrowserContent.svelte
|
|
32877
32961
|
function BrowserContent($$renderer, $$props) {
|
|
32878
32962
|
$$renderer.component(($$renderer) => {
|
|
32879
|
-
let { status, failReason = null, wrap = null, canvas = null, ondown, onup, onmove, onwheel, onkey } = $$props;
|
|
32963
|
+
let { status, failReason = null, wrap = null, canvas = null, ondown, onup, onmove, onwheel, onkey, oncontextmenu, ctxMenu = null, onctxaction, onctxclose } = $$props;
|
|
32880
32964
|
if (status === "failed") {
|
|
32881
32965
|
$$renderer.push("<!--[0-->");
|
|
32882
32966
|
$$renderer.push(`<div data-svelte="BrowserContent" class="p-3 text-xs text-red-500" data-testid="browser-failed">${escape_html(browsersessionfailed2({ reason: failReason ?? "" }))}</div>`);
|
|
32883
32967
|
} else {
|
|
32884
32968
|
$$renderer.push("<!--[-1-->");
|
|
32885
32969
|
$$renderer.push(`<div data-svelte="BrowserContent" class="relative min-h-0 flex-1 overflow-hidden" data-testid="browser-glass"><canvas class="h-full w-full object-contain" tabindex="0"></canvas> `);
|
|
32970
|
+
if (ctxMenu) {
|
|
32971
|
+
$$renderer.push("<!--[0-->");
|
|
32972
|
+
$$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
|
+
if (ctxMenu.src) {
|
|
32974
|
+
$$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">Open image in new tab</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">Copy image address</button>`);
|
|
32976
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32977
|
+
$$renderer.push(`<!--]--> `);
|
|
32978
|
+
if (ctxMenu.href) {
|
|
32979
|
+
$$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">Open link in new tab</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">Copy link address</button>`);
|
|
32981
|
+
} 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">Reload</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">Send right-click to the page</button></div>`);
|
|
32983
|
+
} else $$renderer.push("<!--[-1-->");
|
|
32984
|
+
$$renderer.push(`<!--]--> `);
|
|
32886
32985
|
if (status !== "live") {
|
|
32887
32986
|
$$renderer.push("<!--[0-->");
|
|
32888
32987
|
$$renderer.push(`<div class="absolute inset-0 grid place-items-center text-xs opacity-60" data-testid="browser-placeholder">${escape_html(status === "opening" ? browserlaunching1() : browserwaitingframes2())}</div>`);
|
|
@@ -32940,6 +33039,99 @@ function createMoveCoalescer(raf, fire) {
|
|
|
32940
33039
|
} };
|
|
32941
33040
|
}
|
|
32942
33041
|
//#endregion
|
|
33042
|
+
//#region src/lib/utils/sidebar-prefs.ts
|
|
33043
|
+
/**
|
|
33044
|
+
* Sidebar preferences — persisted layout state for the conversation page's
|
|
33045
|
+
* app sidebar (OCI ControlRail pattern, 2026-08-23).
|
|
33046
|
+
*
|
|
33047
|
+
* Pure localStorage round-trip: SSR-safe (no localStorage → defaults), junk
|
|
33048
|
+
* payloads and out-of-range widths fall back instead of throwing into the
|
|
33049
|
+
* page, and writes are best-effort (a full or blocked store must not break
|
|
33050
|
+
* the layout — it only loses persistence for that session).
|
|
33051
|
+
*
|
|
33052
|
+
* Workspace profiles (storage-profile.ts): `?profile=widi` moves the key
|
|
33053
|
+
* to `dsi-sidebar_widi` — each desk remembers its own rail layout.
|
|
33054
|
+
*/
|
|
33055
|
+
/** localStorage base key — one JSON blob `{ collapsed, width }`. */
|
|
33056
|
+
var STORAGE_KEY = "dsi-sidebar";
|
|
33057
|
+
/** The single width bound site — load-side sanitizing and drag clamping
|
|
33058
|
+
* both route through here so the bounds exist in exactly one place.
|
|
33059
|
+
* Bounds read the config store (layout load has landed them before any
|
|
33060
|
+
* mount; constants are the fallback defaults). */
|
|
33061
|
+
function clampSidebarWidth(width) {
|
|
33062
|
+
const { minWidth, maxWidth } = appConfig().sidebar;
|
|
33063
|
+
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
33064
|
+
}
|
|
33065
|
+
/** Config-driven default width (clamped through the single bound site). */
|
|
33066
|
+
function defaultSidebarWidth() {
|
|
33067
|
+
return clampSidebarWidth(appConfig().sidebar.defaultWidth);
|
|
33068
|
+
}
|
|
33069
|
+
/** Persisted defaults when nothing (usable) is stored. */
|
|
33070
|
+
function defaultSidebarPrefs() {
|
|
33071
|
+
return {
|
|
33072
|
+
collapsed: false,
|
|
33073
|
+
width: defaultSidebarWidth()
|
|
33074
|
+
};
|
|
33075
|
+
}
|
|
33076
|
+
/**
|
|
33077
|
+
* Read prefs from localStorage.
|
|
33078
|
+
* @param profile sanitized workspace profile (null/omitted = default desk).
|
|
33079
|
+
* @returns stored prefs when parseable, defaults when absent, junk, or SSR.
|
|
33080
|
+
*/
|
|
33081
|
+
function loadSidebarPrefs(profile) {
|
|
33082
|
+
if (typeof localStorage === "undefined") return defaultSidebarPrefs();
|
|
33083
|
+
try {
|
|
33084
|
+
const raw = localStorage.getItem(dsiKey(STORAGE_KEY, profile));
|
|
33085
|
+
if (!raw) return defaultSidebarPrefs();
|
|
33086
|
+
const parsed = JSON.parse(raw);
|
|
33087
|
+
if (parsed === null || typeof parsed !== "object") return defaultSidebarPrefs();
|
|
33088
|
+
return {
|
|
33089
|
+
collapsed: parsed.collapsed === true,
|
|
33090
|
+
width: clampSidebarWidth(typeof parsed.width === "number" && Number.isFinite(parsed.width) ? parsed.width : defaultSidebarWidth())
|
|
33091
|
+
};
|
|
33092
|
+
} catch {
|
|
33093
|
+
return defaultSidebarPrefs();
|
|
33094
|
+
}
|
|
33095
|
+
}
|
|
33096
|
+
//#endregion
|
|
33097
|
+
//#region src/lib/services/workspace/page-prefs.svelte.ts
|
|
33098
|
+
var PagePrefs = class {
|
|
33099
|
+
/** Width preset for the next conversation panel (clamped). */
|
|
33100
|
+
panelWidth = 0;
|
|
33101
|
+
/** Floor zoom (clamped). */
|
|
33102
|
+
zoom = 1;
|
|
33103
|
+
/** Explorer Layout split (clamped). */
|
|
33104
|
+
treePct = 0;
|
|
33105
|
+
/** Sidebar rail state (OCI ControlRail port). */
|
|
33106
|
+
sidebarCollapsed = false;
|
|
33107
|
+
sidebarWidth = 0;
|
|
33108
|
+
#profile = null;
|
|
33109
|
+
#initialised = false;
|
|
33110
|
+
/** Seed every field from the persisted blobs — exactly once, BEFORE
|
|
33111
|
+
* the route reads any field (makePanel reads panelWidth during the
|
|
33112
|
+
* seed reset). Intentional initial capture per the route's old
|
|
33113
|
+
* "svelte-ignore state_referenced_locally" comments: prefs seed the
|
|
33114
|
+
* layout once; later writes go through the save effects. */
|
|
33115
|
+
init(profile) {
|
|
33116
|
+
this.#initialised = true;
|
|
33117
|
+
this.#profile = profile;
|
|
33118
|
+
const floor = loadPanelPrefs(profile);
|
|
33119
|
+
this.panelWidth = clampPanelWidth(floor.panelWidth);
|
|
33120
|
+
this.zoom = clampPanelZoom(floor.zoom);
|
|
33121
|
+
this.treePct = clampTreePct(floor.treePct);
|
|
33122
|
+
const sidebar = loadSidebarPrefs(profile);
|
|
33123
|
+
this.sidebarCollapsed = sidebar.collapsed;
|
|
33124
|
+
this.sidebarWidth = sidebar.width;
|
|
33125
|
+
}
|
|
33126
|
+
get profile() {
|
|
33127
|
+
return this.#profile;
|
|
33128
|
+
}
|
|
33129
|
+
/** Sidebar persistence (the route's old sidebar save effect). Call
|
|
33130
|
+
* during component initialisation — `$effect` needs an owner. */
|
|
33131
|
+
installSidebarAutoSave() {}
|
|
33132
|
+
};
|
|
33133
|
+
var pagePrefs = new PagePrefs();
|
|
33134
|
+
//#endregion
|
|
32943
33135
|
//#region src/lib/components/browser/BrowserPanel.svelte
|
|
32944
33136
|
function BrowserPanel($$renderer, $$props) {
|
|
32945
33137
|
$$renderer.component(($$renderer) => {
|
|
@@ -32959,6 +33151,9 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
32959
33151
|
let proxyBusy = false;
|
|
32960
33152
|
let canBack = false;
|
|
32961
33153
|
let canForward = false;
|
|
33154
|
+
/** ADR-0040 D5: the tab strip — the registry's tab list mirrored here;
|
|
33155
|
+
* the SERVER stays the authority (activeTargetId), this is a view. */
|
|
33156
|
+
let tabs = [];
|
|
32962
33157
|
const moves = createMoveCoalescer((cb) => requestAnimationFrame(cb), (x, y) => void post());
|
|
32963
33158
|
async function post(input) {}
|
|
32964
33159
|
function toViewportCx(e) {
|
|
@@ -32984,6 +33179,67 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
32984
33179
|
const p = toViewportCx(e);
|
|
32985
33180
|
if (p) moves.push(p.x, p.y);
|
|
32986
33181
|
}
|
|
33182
|
+
/** BUGFIX 2026-10-25 (operator: YouTube's right-click menu never appears
|
|
33183
|
+
* in the glass): only the LEFT button was dispatched. Right-click must
|
|
33184
|
+
* reach the page as a right mousePressed/Released pair — Chrome paints
|
|
33185
|
+
* its OWN context menu and the screencast mirrors it. preventDefault
|
|
33186
|
+
* stops the DSI page's menu from covering the glass. */
|
|
33187
|
+
/** BUGFIX 2026-10-25 round 2: Chrome's NATIVE right-click menu is browser
|
|
33188
|
+
* UI — it never renders in the page, so the screencast can never show it
|
|
33189
|
+
* (only in-page custom menus like YouTube's player menu can mirror). So
|
|
33190
|
+
* DSI supplies its OWN menu: what the right-click landed on comes from
|
|
33191
|
+
* the /element data pass; actions ride the wire (opentab/clipboard/the
|
|
33192
|
+
* page's own menu via a dispatched right-click). */
|
|
33193
|
+
let ctxMenu = null;
|
|
33194
|
+
let ctxPoint = null;
|
|
33195
|
+
function onContextMenu(e) {
|
|
33196
|
+
e.preventDefault();
|
|
33197
|
+
ctxPoint = toViewportCx(e);
|
|
33198
|
+
const rect = wrap?.getBoundingClientRect();
|
|
33199
|
+
const menuW = 190, menuH = 210;
|
|
33200
|
+
const px = rect ? Math.min(e.clientX - rect.left, rect.width - menuW - 6) : e.clientX;
|
|
33201
|
+
const py = rect ? Math.min(e.clientY - rect.top, rect.height - menuH - 6) : e.clientY;
|
|
33202
|
+
ctxMenu = {
|
|
33203
|
+
px: Math.max(6, px),
|
|
33204
|
+
py: Math.max(6, py),
|
|
33205
|
+
href: null,
|
|
33206
|
+
src: null
|
|
33207
|
+
};
|
|
33208
|
+
}
|
|
33209
|
+
function ctxClose() {
|
|
33210
|
+
ctxMenu = null;
|
|
33211
|
+
}
|
|
33212
|
+
function ctxSendRightClick() {
|
|
33213
|
+
const p = ctxPoint;
|
|
33214
|
+
ctxClose();
|
|
33215
|
+
if (!p) return;
|
|
33216
|
+
post({
|
|
33217
|
+
x: p.x,
|
|
33218
|
+
y: p.y});
|
|
33219
|
+
post({
|
|
33220
|
+
x: p.x,
|
|
33221
|
+
y: p.y});
|
|
33222
|
+
}
|
|
33223
|
+
async function ctxOpenTab(url) {
|
|
33224
|
+
ctxClose();
|
|
33225
|
+
}
|
|
33226
|
+
function ctxAct(action) {
|
|
33227
|
+
const m = ctxMenu;
|
|
33228
|
+
ctxClose();
|
|
33229
|
+
if (!m) return;
|
|
33230
|
+
if (action === "open-image" && m.src) return void ctxOpenTab(m.src);
|
|
33231
|
+
if (action === "copy-image" && m.src) return void ctxCopy(m.src);
|
|
33232
|
+
if (action === "open-link" && m.href) return void ctxOpenTab(m.href);
|
|
33233
|
+
if (action === "copy-link" && m.href) return void ctxCopy(m.href);
|
|
33234
|
+
if (action === "reload") return void proxy();
|
|
33235
|
+
if (action === "send-right-click") return ctxSendRightClick();
|
|
33236
|
+
}
|
|
33237
|
+
async function ctxCopy(text) {
|
|
33238
|
+
ctxClose();
|
|
33239
|
+
try {
|
|
33240
|
+
await navigator.clipboard.writeText(text);
|
|
33241
|
+
} catch {}
|
|
33242
|
+
}
|
|
32987
33243
|
function onWheel(e) {
|
|
32988
33244
|
const p = toViewportCx(e);
|
|
32989
33245
|
if (!p) return;
|
|
@@ -33028,7 +33284,7 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
33028
33284
|
let $$settled = true;
|
|
33029
33285
|
let $$inner_renderer;
|
|
33030
33286
|
function $$render_inner($$renderer) {
|
|
33031
|
-
$$renderer.push(`<div data-svelte="BrowserPanel" class="flex h-full flex-col bg-surface-elevated" data-testid="panel-browser">`);
|
|
33287
|
+
$$renderer.push(`<div data-svelte="BrowserPanel" class="relative flex h-full flex-col bg-surface-elevated" data-testid="panel-browser">`);
|
|
33032
33288
|
BrowserHeader($$renderer, {
|
|
33033
33289
|
status,
|
|
33034
33290
|
reBound,
|
|
@@ -33053,6 +33309,23 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
33053
33309
|
$$renderer.push(`<!--]--></div>`);
|
|
33054
33310
|
} else $$renderer.push("<!--[-1-->");
|
|
33055
33311
|
$$renderer.push(`<!--]--> `);
|
|
33312
|
+
if (tabs.length >= 1) {
|
|
33313
|
+
$$renderer.push("<!--[0-->");
|
|
33314
|
+
$$renderer.push(`<div class="flex items-center gap-1 overflow-x-auto border-b border-surface-border px-1 py-0.5 text-[11px]" data-testid="browser-tab-strip"><!--[-->`);
|
|
33315
|
+
const each_array = ensure_array_like(tabs);
|
|
33316
|
+
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
|
|
33317
|
+
let t = each_array[$$index];
|
|
33318
|
+
$$renderer.push(`<div 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, {
|
|
33319
|
+
"bg-blue-200": t.active,
|
|
33320
|
+
"text-blue-900": t.active,
|
|
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>`);
|
|
33325
|
+
}
|
|
33326
|
+
$$renderer.push(`<!--]--></div>`);
|
|
33327
|
+
} else $$renderer.push("<!--[-1-->");
|
|
33328
|
+
$$renderer.push(`<!--]--> `);
|
|
33056
33329
|
BrowserContent($$renderer, {
|
|
33057
33330
|
status,
|
|
33058
33331
|
failReason,
|
|
@@ -33061,6 +33334,10 @@ function BrowserPanel($$renderer, $$props) {
|
|
|
33061
33334
|
onmove: onPointerMove,
|
|
33062
33335
|
onwheel: onWheel,
|
|
33063
33336
|
onkey: onKey,
|
|
33337
|
+
ctxMenu,
|
|
33338
|
+
onctxaction: ctxAct,
|
|
33339
|
+
onctxclose: ctxClose,
|
|
33340
|
+
oncontextmenu: onContextMenu,
|
|
33064
33341
|
get wrap() {
|
|
33065
33342
|
return wrap;
|
|
33066
33343
|
},
|
|
@@ -34729,99 +35006,6 @@ function EmptyFloor($$renderer, $$props) {
|
|
|
34729
35006
|
});
|
|
34730
35007
|
}
|
|
34731
35008
|
//#endregion
|
|
34732
|
-
//#region src/lib/utils/sidebar-prefs.ts
|
|
34733
|
-
/**
|
|
34734
|
-
* Sidebar preferences — persisted layout state for the conversation page's
|
|
34735
|
-
* app sidebar (OCI ControlRail pattern, 2026-08-23).
|
|
34736
|
-
*
|
|
34737
|
-
* Pure localStorage round-trip: SSR-safe (no localStorage → defaults), junk
|
|
34738
|
-
* payloads and out-of-range widths fall back instead of throwing into the
|
|
34739
|
-
* page, and writes are best-effort (a full or blocked store must not break
|
|
34740
|
-
* the layout — it only loses persistence for that session).
|
|
34741
|
-
*
|
|
34742
|
-
* Workspace profiles (storage-profile.ts): `?profile=widi` moves the key
|
|
34743
|
-
* to `dsi-sidebar_widi` — each desk remembers its own rail layout.
|
|
34744
|
-
*/
|
|
34745
|
-
/** localStorage base key — one JSON blob `{ collapsed, width }`. */
|
|
34746
|
-
var STORAGE_KEY = "dsi-sidebar";
|
|
34747
|
-
/** The single width bound site — load-side sanitizing and drag clamping
|
|
34748
|
-
* both route through here so the bounds exist in exactly one place.
|
|
34749
|
-
* Bounds read the config store (layout load has landed them before any
|
|
34750
|
-
* mount; constants are the fallback defaults). */
|
|
34751
|
-
function clampSidebarWidth(width) {
|
|
34752
|
-
const { minWidth, maxWidth } = appConfig().sidebar;
|
|
34753
|
-
return Math.max(minWidth, Math.min(maxWidth, width));
|
|
34754
|
-
}
|
|
34755
|
-
/** Config-driven default width (clamped through the single bound site). */
|
|
34756
|
-
function defaultSidebarWidth() {
|
|
34757
|
-
return clampSidebarWidth(appConfig().sidebar.defaultWidth);
|
|
34758
|
-
}
|
|
34759
|
-
/** Persisted defaults when nothing (usable) is stored. */
|
|
34760
|
-
function defaultSidebarPrefs() {
|
|
34761
|
-
return {
|
|
34762
|
-
collapsed: false,
|
|
34763
|
-
width: defaultSidebarWidth()
|
|
34764
|
-
};
|
|
34765
|
-
}
|
|
34766
|
-
/**
|
|
34767
|
-
* Read prefs from localStorage.
|
|
34768
|
-
* @param profile sanitized workspace profile (null/omitted = default desk).
|
|
34769
|
-
* @returns stored prefs when parseable, defaults when absent, junk, or SSR.
|
|
34770
|
-
*/
|
|
34771
|
-
function loadSidebarPrefs(profile) {
|
|
34772
|
-
if (typeof localStorage === "undefined") return defaultSidebarPrefs();
|
|
34773
|
-
try {
|
|
34774
|
-
const raw = localStorage.getItem(dsiKey(STORAGE_KEY, profile));
|
|
34775
|
-
if (!raw) return defaultSidebarPrefs();
|
|
34776
|
-
const parsed = JSON.parse(raw);
|
|
34777
|
-
if (parsed === null || typeof parsed !== "object") return defaultSidebarPrefs();
|
|
34778
|
-
return {
|
|
34779
|
-
collapsed: parsed.collapsed === true,
|
|
34780
|
-
width: clampSidebarWidth(typeof parsed.width === "number" && Number.isFinite(parsed.width) ? parsed.width : defaultSidebarWidth())
|
|
34781
|
-
};
|
|
34782
|
-
} catch {
|
|
34783
|
-
return defaultSidebarPrefs();
|
|
34784
|
-
}
|
|
34785
|
-
}
|
|
34786
|
-
//#endregion
|
|
34787
|
-
//#region src/lib/services/workspace/page-prefs.svelte.ts
|
|
34788
|
-
var PagePrefs = class {
|
|
34789
|
-
/** Width preset for the next conversation panel (clamped). */
|
|
34790
|
-
panelWidth = 0;
|
|
34791
|
-
/** Floor zoom (clamped). */
|
|
34792
|
-
zoom = 1;
|
|
34793
|
-
/** Explorer Layout split (clamped). */
|
|
34794
|
-
treePct = 0;
|
|
34795
|
-
/** Sidebar rail state (OCI ControlRail port). */
|
|
34796
|
-
sidebarCollapsed = false;
|
|
34797
|
-
sidebarWidth = 0;
|
|
34798
|
-
#profile = null;
|
|
34799
|
-
#initialised = false;
|
|
34800
|
-
/** Seed every field from the persisted blobs — exactly once, BEFORE
|
|
34801
|
-
* the route reads any field (makePanel reads panelWidth during the
|
|
34802
|
-
* seed reset). Intentional initial capture per the route's old
|
|
34803
|
-
* "svelte-ignore state_referenced_locally" comments: prefs seed the
|
|
34804
|
-
* layout once; later writes go through the save effects. */
|
|
34805
|
-
init(profile) {
|
|
34806
|
-
this.#initialised = true;
|
|
34807
|
-
this.#profile = profile;
|
|
34808
|
-
const floor = loadPanelPrefs(profile);
|
|
34809
|
-
this.panelWidth = clampPanelWidth(floor.panelWidth);
|
|
34810
|
-
this.zoom = clampPanelZoom(floor.zoom);
|
|
34811
|
-
this.treePct = clampTreePct(floor.treePct);
|
|
34812
|
-
const sidebar = loadSidebarPrefs(profile);
|
|
34813
|
-
this.sidebarCollapsed = sidebar.collapsed;
|
|
34814
|
-
this.sidebarWidth = sidebar.width;
|
|
34815
|
-
}
|
|
34816
|
-
get profile() {
|
|
34817
|
-
return this.#profile;
|
|
34818
|
-
}
|
|
34819
|
-
/** Sidebar persistence (the route's old sidebar save effect). Call
|
|
34820
|
-
* during component initialisation — `$effect` needs an owner. */
|
|
34821
|
-
installSidebarAutoSave() {}
|
|
34822
|
-
};
|
|
34823
|
-
var pagePrefs = new PagePrefs();
|
|
34824
|
-
//#endregion
|
|
34825
35009
|
//#region src/lib/services/conversation/spine-feed.svelte.ts
|
|
34826
35010
|
var spineFeed = {
|
|
34827
35011
|
rows: [],
|
|
@@ -34911,6 +35095,18 @@ function workspaceExplorerSlot(panels, selectedIndex, facts) {
|
|
|
34911
35095
|
return focusedInsertionSlot(panels, selectedIndex, facts.parentOf);
|
|
34912
35096
|
}
|
|
34913
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
|
+
/**
|
|
34914
35110
|
* Insert-before-focused slot (operator spec, 2026-08-31): a fresh panel
|
|
34915
35111
|
* lands at the FOCUSED panel's index — immediately before it — and takes
|
|
34916
35112
|
* focus (the route selects it). 0 when nothing is focused (empty floor,
|
|
@@ -34938,7 +35134,7 @@ function focusedInsertionSlot(panels, selectedIndex, parentOf) {
|
|
|
34938
35134
|
const focus = Math.max(0, selectedIndex);
|
|
34939
35135
|
const focused = panels[focus];
|
|
34940
35136
|
if (focused === void 0) return 0;
|
|
34941
|
-
if (focused.kind === "workspace-explorer" || focused.kind === "workspace-file") {
|
|
35137
|
+
if (focused.kind === "workspace-explorer" || focused.kind === "workspace-file" || focused.kind === "browser") {
|
|
34942
35138
|
const block = blockBounds(panels, focus, { parentOf });
|
|
34943
35139
|
return block === null ? focus : block[0];
|
|
34944
35140
|
}
|
|
@@ -34953,34 +35149,6 @@ function focusedInsertionSlot(panels, selectedIndex, parentOf) {
|
|
|
34953
35149
|
const headIndex = panels.findIndex((p) => p.kind === "conversation" && p.sessionId === head);
|
|
34954
35150
|
return headIndex >= 0 ? Math.min(headIndex, focus) : focus;
|
|
34955
35151
|
}
|
|
34956
|
-
/**
|
|
34957
|
-
* Lineage-order slot below an OPEN spawner (operator spec, 2026-08-28):
|
|
34958
|
-
* after the spawner AND after every already-adopted sibling that PRECEDES
|
|
34959
|
-
* the child in wire order — plus those siblings' own panels (an adopted
|
|
34960
|
-
* subtree travels whole). Ghost clicks and sub-agent replacements keep the
|
|
34961
|
-
* family region in the ghost list's order regardless of arrival sequence:
|
|
34962
|
-
* adopting sub2 then sub3 lands |A|sub2|sub3|, a late sub1 slots back to
|
|
34963
|
-
* |A|sub1|sub2|sub3|.
|
|
34964
|
-
*/
|
|
34965
|
-
function lineagePinnedSlot(panels, childrenByParent, parentSessionId, childSessionId) {
|
|
34966
|
-
let base = panels.findIndex((p) => p.kind === "conversation" && p.sessionId === parentSessionId) + 1;
|
|
34967
|
-
base = docTailEnd(panels, base - 1, parentSessionId) + 1;
|
|
34968
|
-
const siblings = childrenByParent.get(parentSessionId) ?? [];
|
|
34969
|
-
const mine = siblings.findIndex((s) => s.sessionId === childSessionId);
|
|
34970
|
-
const closure = new Set(siblings.slice(0, mine < 0 ? siblings.length : mine).map((s) => s.sessionId));
|
|
34971
|
-
const stack = [...closure];
|
|
34972
|
-
while (stack.length > 0) for (const k of childrenByParent.get(stack.pop()) ?? []) if (!closure.has(k.sessionId)) {
|
|
34973
|
-
closure.add(k.sessionId);
|
|
34974
|
-
stack.push(k.sessionId);
|
|
34975
|
-
}
|
|
34976
|
-
let index = base;
|
|
34977
|
-
while (index < panels.length) {
|
|
34978
|
-
const at = panels[index];
|
|
34979
|
-
if (at.kind !== "conversation" || !closure.has(at.sessionId)) break;
|
|
34980
|
-
index++;
|
|
34981
|
-
}
|
|
34982
|
-
return index;
|
|
34983
|
-
}
|
|
34984
35152
|
//#endregion
|
|
34985
35153
|
//#region src/lib/services/panels/floor-registry/chrome.ts
|
|
34986
35154
|
/**
|
|
@@ -35021,7 +35189,7 @@ function openBrowserPanel(index, keepSelection = false, width, openedBy, session
|
|
|
35021
35189
|
return;
|
|
35022
35190
|
}
|
|
35023
35191
|
const prevSelected = st.selectedPanelId;
|
|
35024
|
-
const slot = index !== void 0 ? Math.max(0, Math.min(index, st.panels.length)) : openedBy !== void 0
|
|
35192
|
+
const slot = index !== void 0 ? Math.max(0, Math.min(index, st.panels.length)) : openedBy !== void 0 ? glassFirstSlot(st.panels, openedBy) : insertionSlot();
|
|
35025
35193
|
insertPanel(makeBrowserPanel(width, openedBy, sessionId), slot);
|
|
35026
35194
|
if (keepSelection && prevSelected !== null && prevSelected !== void 0) {
|
|
35027
35195
|
if (st.panels.some((p) => p.id === prevSelected)) st.selectedPanelId = prevSelected;
|
|
@@ -35325,9 +35493,6 @@ function insertPanel(entry, index) {
|
|
|
35325
35493
|
function insertionSlot() {
|
|
35326
35494
|
return focusedInsertionSlot(st.panels, selectedIndex_(), d$1().getMoveFacts().parentOf);
|
|
35327
35495
|
}
|
|
35328
|
-
function pinnedSlotIndex(parentSessionId, childSessionId) {
|
|
35329
|
-
return lineagePinnedSlot(st.panels, d$1().getLineageFacts().childrenByParent, parentSessionId, childSessionId);
|
|
35330
|
-
}
|
|
35331
35496
|
//#endregion
|
|
35332
35497
|
//#region src/lib/services/panels/floor-registry.svelte.ts
|
|
35333
35498
|
var deps = null;
|
|
@@ -35430,6 +35595,27 @@ function selectedIndex_() {
|
|
|
35430
35595
|
return st.panels.findIndex((p) => p.id === st.selectedPanelId);
|
|
35431
35596
|
}
|
|
35432
35597
|
//#endregion
|
|
35598
|
+
//#region src/lib/services/panels/glass-release.ts
|
|
35599
|
+
/**
|
|
35600
|
+
* glass-release — the Glass Close Ladder executor (ADR 2026-10-24 D1/D3):
|
|
35601
|
+
* the ONE wire-kill caller. The registry stays the only teardown authority;
|
|
35602
|
+
* this module merely knocks on its door — fire-and-forget POST close per
|
|
35603
|
+
* doomed glass id, an ok answer pruning the slot entry LIVE (D4). A network
|
|
35604
|
+
* failure swallows (the reaper stays the net); a refusal never prunes.
|
|
35605
|
+
* Pure seam shape: fetch and the prune are injectable for tests.
|
|
35606
|
+
*/
|
|
35607
|
+
async function releaseGlasses(sessionIds, deps = {}) {
|
|
35608
|
+
if (sessionIds.length === 0) return;
|
|
35609
|
+
const doFetch = deps.fetchImpl ?? fetch;
|
|
35610
|
+
const apiBase = deps.apiBase ?? "";
|
|
35611
|
+
await Promise.all(sessionIds.map(async (id) => {
|
|
35612
|
+
try {
|
|
35613
|
+
if (!(await doFetch(apiBase + "/api/browser/" + id + "/close", { method: "POST" })).ok) return;
|
|
35614
|
+
(deps.prune ?? ((sid) => removeBrowserSlot(sid)))(id);
|
|
35615
|
+
} catch {}
|
|
35616
|
+
}));
|
|
35617
|
+
}
|
|
35618
|
+
//#endregion
|
|
35433
35619
|
//#region src/lib/services/panels/floor-reads.svelte.ts
|
|
35434
35620
|
var floorReads = {
|
|
35435
35621
|
get spineRows() {
|
|
@@ -35573,7 +35759,8 @@ function _page($$renderer, $$props) {
|
|
|
35573
35759
|
setPanelWidthPreset: (w) => pagePrefs.panelWidth = w,
|
|
35574
35760
|
setTreePct: (pct) => pagePrefs.treePct = pct,
|
|
35575
35761
|
getSettingsHomes: () => appConfig().settingsHomes,
|
|
35576
|
-
applyTerminalDeskAction: (a) => void 0
|
|
35762
|
+
applyTerminalDeskAction: (a) => void 0,
|
|
35763
|
+
releaseGlasses: (ids) => void releaseGlasses(ids)
|
|
35577
35764
|
});
|
|
35578
35765
|
initFloor(seededInitially ? [makePanel(seedSessionId(), seedCold?.agentPreset ?? null)] : initialPrefs.panels, seededInitially ? null : initialPrefs.selectedPanelId);
|
|
35579
35766
|
if (seededInitially) selectPanel(floor.panels[0]?.id ?? null);
|
|
@@ -35596,9 +35783,11 @@ function _page($$renderer, $$props) {
|
|
|
35596
35783
|
} catch {}
|
|
35597
35784
|
}
|
|
35598
35785
|
/** Bring ONE folded glass back (the summon; the replace verb is the
|
|
35599
|
-
* same re-bind — the glass owns its slot identity, D4).
|
|
35600
|
-
|
|
35601
|
-
|
|
35786
|
+
* same re-bind — the glass owns its slot identity, D4). keepSelection:
|
|
35787
|
+
* boot restore keeps the operator's focus (true, the default); the
|
|
35788
|
+
* ghost-click summon focuses the GLASS (false, Ladder focus contract). */
|
|
35789
|
+
function summonGlass(glass, opts = {}) {
|
|
35790
|
+
openBrowserPanel(glass.index, opts.keepSelection ?? true, glass.width, glass.openedBy, glass.sessionId);
|
|
35602
35791
|
}
|
|
35603
35792
|
primeBrowserSlotStore();
|
|
35604
35793
|
restoreBrowserGlasses();
|
|
@@ -35614,24 +35803,7 @@ function _page($$renderer, $$props) {
|
|
|
35614
35803
|
const spineWorkspaces = derived(() => floorReads.spineWorkspaces);
|
|
35615
35804
|
const lineageFacts = derived(() => floorReads.lineageFacts);
|
|
35616
35805
|
const conversationPanels = derived(() => floorReads.conversationPanels);
|
|
35617
|
-
const allFoldedGlassRows = derived(() => store_get($$store_subs ??= {}, "$browserSlotStore", browserSlotStore)
|
|
35618
|
-
panel: {
|
|
35619
|
-
id: "glass-" + s.sessionId,
|
|
35620
|
-
kind: "conversation",
|
|
35621
|
-
sessionId: s.sessionId,
|
|
35622
|
-
agentPreset: null,
|
|
35623
|
-
width: 0
|
|
35624
|
-
},
|
|
35625
|
-
title: "Browser — " + (panelTitleFor(s.openedBy) ?? s.openedBy),
|
|
35626
|
-
workspace: null,
|
|
35627
|
-
dead: false,
|
|
35628
|
-
running: true,
|
|
35629
|
-
depth: (lineageFacts().depthById.get(s.openedBy) ?? 0) + 1,
|
|
35630
|
-
runningDescendants: 0,
|
|
35631
|
-
kind: "ghost",
|
|
35632
|
-
parentSessionId: s.openedBy,
|
|
35633
|
-
siblingIndex: -1
|
|
35634
|
-
})));
|
|
35806
|
+
const allFoldedGlassRows = derived(() => foldedGlassRowsFor(store_get($$store_subs ??= {}, "$browserSlotStore", browserSlotStore), (id) => lineageFacts().depthById.get(id) ?? 0, (id) => panelTitleFor(id)));
|
|
35635
35807
|
const spineGlassRows = derived(() => allFoldedGlassRows().filter((g) => !conversationPanels().some((p) => p.sessionId === g.parentSessionId)).map((g) => ({
|
|
35636
35808
|
sessionId: g.panel.sessionId,
|
|
35637
35809
|
openedBy: g.parentSessionId,
|
|
@@ -35704,7 +35876,10 @@ function _page($$renderer, $$props) {
|
|
|
35704
35876
|
$$renderer.push("<!--[1-->");
|
|
35705
35877
|
BrowserManager($$renderer, {
|
|
35706
35878
|
browserSessionId: "browserSessionId" in panel ? panel.browserSessionId : void 0,
|
|
35707
|
-
onclose: () =>
|
|
35879
|
+
onclose: () => {
|
|
35880
|
+
if ("browserSessionId" in panel && panel.browserSessionId) releaseGlasses([panel.browserSessionId]);
|
|
35881
|
+
removePanel(panel.id);
|
|
35882
|
+
},
|
|
35708
35883
|
openedBy: panel.openedBy,
|
|
35709
35884
|
parentTitle: panel.openedBy ? panelTitleFor(panel.openedBy) ?? panel.openedBy : null,
|
|
35710
35885
|
depth: panel.openedBy ? lineageFacts().depthById.get(panel.openedBy) ?? 0 : 0});
|
|
@@ -35942,4 +36117,4 @@ function _page($$renderer, $$props) {
|
|
|
35942
36117
|
}
|
|
35943
36118
|
|
|
35944
36119
|
export { _page as default };
|
|
35945
|
-
//# sourceMappingURL=_page.svelte.js-
|
|
36120
|
+
//# sourceMappingURL=_page.svelte.js-7xWLRsiZ.js.map
|