dsh-coding-sidebar 1.0.3 → 1.0.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/README.md +27 -42
- package/lib/client-editor.js +315 -4179
- package/lib/client-registry.js +913 -1303
- package/lib/client-terminal.js +189 -261
- package/lib/client.js +911 -1301
- package/lib/index.js +13 -110
- package/lib/types/bundle-route.d.ts +1 -1
- package/lib/types/client/LiveView.d.ts +1 -0
- package/lib/types/client/SideCardSection.d.ts +3 -3
- package/lib/types/client/TextEditor.d.ts +20 -10
- package/lib/types/client/add-plugin-modal.d.ts +0 -4
- package/lib/types/client/api.d.ts +16 -11
- package/lib/types/client/builtins/index.d.ts +10 -10
- package/lib/types/client/chunk-loader.d.ts +7 -8
- package/lib/types/client/locales.d.ts +6 -26
- package/lib/types/client/native-avoid.d.ts +2 -0
- package/lib/types/client/plugins-shared.d.ts +6 -6
- package/lib/types/client/service.d.ts +13 -83
- package/lib/types/index.d.ts +1 -1
- package/lib/types/prefs-shared.d.ts +1 -24
- package/lib/types/wire.d.ts +1 -1
- package/package.json +26 -29
- package/src/bundle-route.ts +1 -1
- package/src/client/BrowserView.tsx +18 -2
- package/src/client/EditorHost.tsx +52 -122
- package/src/client/LiveView.tsx +229 -0
- package/src/client/SandboxStatusBar.tsx +12 -9
- package/src/client/SideCardSection.tsx +28 -81
- package/src/client/TextEditor.tsx +89 -266
- package/src/client/add-plugin-modal.tsx +16 -24
- package/src/client/api.ts +4 -25
- package/src/client/builtins/index.ts +10 -14
- package/src/client/chunk-loader.ts +7 -8
- package/src/client/index.tsx +12 -3
- package/src/client/locales-ar.ts +0 -6
- package/src/client/locales-de.ts +0 -6
- package/src/client/locales-fr.ts +0 -6
- package/src/client/locales-hi.ts +0 -6
- package/src/client/locales-id.ts +0 -6
- package/src/client/locales-it.ts +0 -6
- package/src/client/locales-ja.ts +0 -6
- package/src/client/locales-ko.ts +0 -6
- package/src/client/locales-nl.ts +0 -6
- package/src/client/locales-pl.ts +0 -6
- package/src/client/locales-pt.ts +0 -6
- package/src/client/locales-ru.ts +0 -6
- package/src/client/locales-sv.ts +0 -6
- package/src/client/locales-th.ts +0 -6
- package/src/client/locales-tr.ts +0 -6
- package/src/client/locales-vi.ts +0 -6
- package/src/client/locales-zh-HK.ts +0 -6
- package/src/client/locales-zh-MO.ts +0 -6
- package/src/client/locales-zh-TW.ts +0 -6
- package/src/client/locales.ts +12 -52
- package/src/client/native-avoid.ts +155 -0
- package/src/client/plugins-shared.ts +6 -6
- package/src/client/prefs.ts +0 -7
- package/src/client/service.ts +13 -150
- package/src/client/sidebar.module.css +28 -420
- package/src/config.ts +1 -4
- package/src/index.ts +17 -74
- package/src/prefs-shared.ts +1 -27
- package/src/wire.ts +1 -0
- package/lib/client-mermaid.js +0 -200776
- package/lib/types/client/MarkdownHtml.d.ts +0 -32
- package/lib/types/client/PdfView.d.ts +0 -6
- package/lib/types/client/builtins/viewers.d.ts +0 -3
- package/lib/types/client/chunks/mermaid.d.ts +0 -10
- package/lib/types/client/editor-load.d.ts +0 -66
- package/lib/types/client/image-types.d.ts +0 -3
- package/lib/types/client/markdown-html.d.ts +0 -96
- package/lib/types/client/markdown-images.d.ts +0 -45
- package/lib/types/client/md-toc.d.ts +0 -4
- package/lib/types/client/mermaid-blocks.d.ts +0 -47
- package/lib/types/client/mermaid-sanitize.d.ts +0 -2
- package/lib/types/client/mermaid.d.ts +0 -12
- package/lib/types/client/pdf-types.d.ts +0 -2
- package/lib/types/client/plugins-viewers.d.ts +0 -3
- package/lib/types/html-route.d.ts +0 -59
- package/src/client/MarkdownHtml.tsx +0 -296
- package/src/client/PdfView.tsx +0 -110
- package/src/client/builtins/viewers.tsx +0 -125
- package/src/client/chunks/mermaid.tsx +0 -10
- package/src/client/editor-load.ts +0 -92
- package/src/client/image-types.ts +0 -8
- package/src/client/markdown-html.ts +0 -331
- package/src/client/markdown-images.ts +0 -137
- package/src/client/md-toc.tsx +0 -127
- package/src/client/mermaid-blocks.ts +0 -110
- package/src/client/mermaid-sanitize.ts +0 -93
- package/src/client/mermaid.tsx +0 -406
- package/src/client/pdf-types.ts +0 -4
- package/src/client/plugins-viewers.ts +0 -30
- package/src/html-route.ts +0 -106
package/lib/client-registry.js
CHANGED
|
@@ -58,15 +58,12 @@ window.__ModuleLoader__.load({
|
|
|
58
58
|
customCss: "",
|
|
59
59
|
titleBarCompat: false,
|
|
60
60
|
titleBarStripPx: 40,
|
|
61
|
-
htmlViewerNoSandbox: false,
|
|
62
|
-
htmlViewerDefaultUnsafe: false,
|
|
63
61
|
browserNoSandbox: false,
|
|
64
62
|
browserInterceptLinks: true,
|
|
65
63
|
browserInterceptHttp: true,
|
|
66
64
|
browserInterceptHttps: false,
|
|
67
65
|
browserAllowedLoopback: "",
|
|
68
66
|
tabsEnabled: {},
|
|
69
|
-
viewersEnabled: {},
|
|
70
67
|
pluginSettings: {}
|
|
71
68
|
};
|
|
72
69
|
/** Clamp one width percent into the contract range (shared by schema and client reads). */
|
|
@@ -1302,14 +1299,139 @@ window.__ModuleLoader__.load({
|
|
|
1302
1299
|
return new SidebarStore();
|
|
1303
1300
|
}
|
|
1304
1301
|
//#endregion
|
|
1305
|
-
//#region src/client/
|
|
1306
|
-
/**
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1302
|
+
//#region src/client/native-avoid.ts
|
|
1303
|
+
/**
|
|
1304
|
+
* Native-sidebar avoidance: when the DSH shell's own sidebar expands to its
|
|
1305
|
+
* wide form, an expanded sidebar panel would crowd the page into several
|
|
1306
|
+
* columns — so the panel yields (collapses; the fact that WE collapsed it
|
|
1307
|
+
* is remembered) and restores when the native sidebar returns to its rail.
|
|
1308
|
+
*
|
|
1309
|
+
* Detection: the host exposes no programmable open/close event — the
|
|
1310
|
+
* `settings.trigger` slot's `{ wide }` owner prop is pushed only to the
|
|
1311
|
+
* slot's occupant, and that slot is single-masked (occupying it would take
|
|
1312
|
+
* over the settings button). But the shell stamps every slot outlet with
|
|
1313
|
+
* `data-slot="<key>"` (the conversation package's own CSS targets
|
|
1314
|
+
* `[data-slot=conversation\.session]`), and the native sidebar hosts the
|
|
1315
|
+
* `sidebar.*` slots — its documented collapsed form is a 56px icon rail,
|
|
1316
|
+
* the expanded form a full column. So: watch the first
|
|
1317
|
+
* `[data-slot^="sidebar."]` element with a ResizeObserver; width > 80px
|
|
1318
|
+
* means expanded. No anchor (older host, attribute renamed) → the feature
|
|
1319
|
+
* stays inert.
|
|
1320
|
+
*
|
|
1321
|
+
* The yield rides the regular `panelOpen` state (same contract as every
|
|
1322
|
+
* other collapse: the toggle button, content-open auto-expansion and the
|
|
1323
|
+
* per-session persistence all keep working). A panel transition we did not
|
|
1324
|
+
* apply — the user reopening the panel, or a content open expanding it —
|
|
1325
|
+
* hands ownership back (no restore on native close); a session switch
|
|
1326
|
+
* re-runs the rule against the newly active session.
|
|
1327
|
+
*/
|
|
1328
|
+
/** The documented rail is 56px; anything wider is an expanded sidebar. */
|
|
1329
|
+
const RAIL_MAX_WIDTH = 80;
|
|
1330
|
+
/** The native sidebar's slot outlets (sidebar.settings and siblings). */
|
|
1331
|
+
const ANCHOR_SELECTOR = "[data-slot^=\"sidebar.\"]";
|
|
1332
|
+
function installNativeSidebarAvoidance(store) {
|
|
1333
|
+
if (typeof ResizeObserver === "undefined" || typeof MutationObserver === "undefined" || typeof document === "undefined" || document.body === null) return () => {};
|
|
1334
|
+
let disposed = false;
|
|
1335
|
+
/** null until the anchor is found and measured (unknown = never act). */
|
|
1336
|
+
let nativeWide = null;
|
|
1337
|
+
/** The currently open panel was collapsed by US (restore on native close). */
|
|
1338
|
+
let yielded = false;
|
|
1339
|
+
/** Guards the store subscription: the in-flight reduce is ours. */
|
|
1340
|
+
let applying = false;
|
|
1341
|
+
let lastSeenOpen = null;
|
|
1342
|
+
let lastSessionId;
|
|
1343
|
+
const snapshotOpen = () => store.getSnapshot().state?.panelOpen === true;
|
|
1344
|
+
/** Apply the avoidance rule for the current native-sidebar state. */
|
|
1345
|
+
const reevaluate = () => {
|
|
1346
|
+
if (disposed || nativeWide === null) return;
|
|
1347
|
+
if (nativeWide && !yielded && snapshotOpen()) {
|
|
1348
|
+
yielded = true;
|
|
1349
|
+
applying = true;
|
|
1350
|
+
store.reduce(togglePanel);
|
|
1351
|
+
} else if (!nativeWide && yielded) {
|
|
1352
|
+
yielded = false;
|
|
1353
|
+
if (snapshotOpen()) return;
|
|
1354
|
+
applying = true;
|
|
1355
|
+
store.reduce(togglePanel);
|
|
1356
|
+
}
|
|
1357
|
+
};
|
|
1358
|
+
lastSeenOpen = snapshotOpen();
|
|
1359
|
+
lastSessionId = store.getSnapshot().sessionId;
|
|
1360
|
+
const unsubscribe = store.subscribe(() => {
|
|
1361
|
+
if (disposed) return;
|
|
1362
|
+
const snapshot = store.getSnapshot();
|
|
1363
|
+
const open = snapshotOpen();
|
|
1364
|
+
if (applying) {
|
|
1365
|
+
applying = false;
|
|
1366
|
+
lastSeenOpen = open;
|
|
1367
|
+
lastSessionId = snapshot.sessionId;
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1370
|
+
if (snapshot.sessionId !== lastSessionId) {
|
|
1371
|
+
lastSessionId = snapshot.sessionId;
|
|
1372
|
+
lastSeenOpen = open;
|
|
1373
|
+
reevaluate();
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
if (open !== lastSeenOpen) {
|
|
1377
|
+
lastSeenOpen = open;
|
|
1378
|
+
if (yielded && open) yielded = false;
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
1381
|
+
let resizeObserver = null;
|
|
1382
|
+
let finder = null;
|
|
1383
|
+
const applyWidth = (width) => {
|
|
1384
|
+
const wide = width > RAIL_MAX_WIDTH;
|
|
1385
|
+
if (wide !== nativeWide) {
|
|
1386
|
+
nativeWide = wide;
|
|
1387
|
+
reevaluate();
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
const watch = (element) => {
|
|
1391
|
+
resizeObserver = new ResizeObserver(() => {
|
|
1392
|
+
if (!element.isConnected) {
|
|
1393
|
+
resizeObserver?.disconnect();
|
|
1394
|
+
resizeObserver = null;
|
|
1395
|
+
nativeWide = null;
|
|
1396
|
+
startSearch();
|
|
1397
|
+
return;
|
|
1398
|
+
}
|
|
1399
|
+
applyWidth(element.getBoundingClientRect().width);
|
|
1400
|
+
});
|
|
1401
|
+
resizeObserver.observe(element);
|
|
1402
|
+
applyWidth(element.getBoundingClientRect().width);
|
|
1403
|
+
};
|
|
1404
|
+
const startSearch = () => {
|
|
1405
|
+
const found = document.querySelector(ANCHOR_SELECTOR);
|
|
1406
|
+
if (found !== null) {
|
|
1407
|
+
watch(found);
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
finder = new MutationObserver(() => {
|
|
1411
|
+
const element = document.querySelector(ANCHOR_SELECTOR);
|
|
1412
|
+
if (element !== null) {
|
|
1413
|
+
finder?.disconnect();
|
|
1414
|
+
finder = null;
|
|
1415
|
+
watch(element);
|
|
1416
|
+
}
|
|
1417
|
+
});
|
|
1418
|
+
finder.observe(document.body, {
|
|
1419
|
+
childList: true,
|
|
1420
|
+
subtree: true
|
|
1421
|
+
});
|
|
1422
|
+
};
|
|
1423
|
+
startSearch();
|
|
1424
|
+
return () => {
|
|
1425
|
+
disposed = true;
|
|
1426
|
+
unsubscribe();
|
|
1427
|
+
resizeObserver?.disconnect();
|
|
1428
|
+
resizeObserver = null;
|
|
1429
|
+
finder?.disconnect();
|
|
1430
|
+
finder = null;
|
|
1431
|
+
};
|
|
1312
1432
|
}
|
|
1433
|
+
//#endregion
|
|
1434
|
+
//#region src/client/service.ts
|
|
1313
1435
|
/** The file name of a path (both separators). */
|
|
1314
1436
|
function baseNameOf(path) {
|
|
1315
1437
|
const at = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
@@ -1340,7 +1462,7 @@ window.__ModuleLoader__.load({
|
|
|
1340
1462
|
if (claimed) return tab;
|
|
1341
1463
|
}
|
|
1342
1464
|
}
|
|
1343
|
-
const SIDEBAR_SERVICE_VERSION = "1.0.
|
|
1465
|
+
const SIDEBAR_SERVICE_VERSION = "1.0.5";
|
|
1344
1466
|
/**
|
|
1345
1467
|
* Monotonic capability list consumers use to gate new API usage (features
|
|
1346
1468
|
* are never removed). Each string names a v0.12.0+ capability:
|
|
@@ -1381,12 +1503,11 @@ window.__ModuleLoader__.load({
|
|
|
1381
1503
|
}
|
|
1382
1504
|
/**
|
|
1383
1505
|
* Create one BetterSidebar service bound to a store. The service owns the
|
|
1384
|
-
* tab
|
|
1506
|
+
* tab registry (Map + listener set) and proxies openTab/closeTab
|
|
1385
1507
|
* to the store's reducer. One instance per client plugin activation.
|
|
1386
1508
|
*/
|
|
1387
1509
|
function createBetterSidebarService(store) {
|
|
1388
1510
|
const tabs = /* @__PURE__ */ new Map();
|
|
1389
|
-
const viewers = /* @__PURE__ */ new Map();
|
|
1390
1511
|
const listeners = /* @__PURE__ */ new Set();
|
|
1391
1512
|
const notify = () => {
|
|
1392
1513
|
for (const fn of [...listeners]) fn();
|
|
@@ -1408,36 +1529,9 @@ window.__ModuleLoader__.load({
|
|
|
1408
1529
|
}
|
|
1409
1530
|
};
|
|
1410
1531
|
};
|
|
1411
|
-
const registerFileViewer = (descriptor) => {
|
|
1412
|
-
if (viewers.has(descriptor.id)) throw new Error(`[dsh-coding-sidebar] file viewer "${descriptor.id}" already registered`);
|
|
1413
|
-
viewers.set(descriptor.id, descriptor);
|
|
1414
|
-
notify();
|
|
1415
|
-
return () => {
|
|
1416
|
-
if (viewers.get(descriptor.id) === descriptor) {
|
|
1417
|
-
viewers.delete(descriptor.id);
|
|
1418
|
-
notify();
|
|
1419
|
-
}
|
|
1420
|
-
};
|
|
1421
|
-
};
|
|
1422
1532
|
const getTabs = () => Array.from(tabs.values());
|
|
1423
|
-
const getFileViewers = () => Array.from(viewers.values());
|
|
1424
1533
|
const getTab = (id) => tabs.get(id);
|
|
1425
1534
|
const isTabEnabled = (id) => store.getPrefs().tabsEnabled[id] !== false;
|
|
1426
|
-
const isViewerEnabled = (id) => store.getPrefs().viewersEnabled[id] !== false;
|
|
1427
|
-
const matchFileViewer = (path, head) => {
|
|
1428
|
-
const ext = extOfPath(path);
|
|
1429
|
-
for (const v of Array.from(viewers.values()).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))) {
|
|
1430
|
-
if (!isViewerEnabled(v.id)) continue;
|
|
1431
|
-
if (head !== void 0 && v.detect !== void 0) {
|
|
1432
|
-
if (v.detect(path, head)) return v;
|
|
1433
|
-
if (v.exts.length === 0) continue;
|
|
1434
|
-
} else if (v.exts.length === 0) {
|
|
1435
|
-
if (v.detect === void 0) return v;
|
|
1436
|
-
continue;
|
|
1437
|
-
}
|
|
1438
|
-
if (v.exts.includes(ext)) return v;
|
|
1439
|
-
}
|
|
1440
|
-
};
|
|
1441
1535
|
const openTab = (seed, scope) => {
|
|
1442
1536
|
if (!isTabEnabled(seed.type)) {
|
|
1443
1537
|
console.warn(`[dsh-coding-sidebar] tab type "${seed.type}" is disabled in the side card settings`);
|
|
@@ -1571,13 +1665,9 @@ window.__ModuleLoader__.load({
|
|
|
1571
1665
|
};
|
|
1572
1666
|
return {
|
|
1573
1667
|
registerTab,
|
|
1574
|
-
registerFileViewer,
|
|
1575
1668
|
getTabs,
|
|
1576
|
-
getFileViewers,
|
|
1577
1669
|
getTab,
|
|
1578
1670
|
isTabEnabled,
|
|
1579
|
-
isViewerEnabled,
|
|
1580
|
-
matchFileViewer,
|
|
1581
1671
|
openTab,
|
|
1582
1672
|
closeTab: closeTab$1,
|
|
1583
1673
|
subscribe,
|
|
@@ -1917,13 +2007,7 @@ window.__ModuleLoader__.load({
|
|
|
1917
2007
|
terminalDepsHint: "DSH 環境のターミナルまたは cmd で以下のコマンドを実行して修復し、再試行してください(node-pty は DSH コアと同じバージョンを維持):",
|
|
1918
2008
|
terminalDepsProfile: "(検出された profile:{profile})",
|
|
1919
2009
|
preview: "プレビュー",
|
|
1920
|
-
toc: "目次",
|
|
1921
2010
|
edit: "編集",
|
|
1922
|
-
mermaidError: "Mermaid レンダリング失敗",
|
|
1923
|
-
mermaidZoomIn: "拡大",
|
|
1924
|
-
mermaidZoomOut: "縮小",
|
|
1925
|
-
mermaidZoomReset: "リセット",
|
|
1926
|
-
mermaidZoomHint: "スクロールで拡大 ・ ドラッグで移動 ・ Esc で閉じる",
|
|
1927
2011
|
refresh: "更新",
|
|
1928
2012
|
showInFolder: "フォルダーで表示",
|
|
1929
2013
|
refreshUnsavedConfirm: "ディスク上のファイルが変更されました。更新すると未保存の編集が失われます。続行しますか?",
|
|
@@ -2276,13 +2360,7 @@ window.__ModuleLoader__.load({
|
|
|
2276
2360
|
terminalDepsHint: "Führen Sie den folgenden Befehl in einem Terminal oder in cmd auf dem DSH-System aus, um dies zu beheben, und klicken Sie dann auf „Erneut versuchen“ (node-pty bleibt mit der DSH-Core-Version synchron):",
|
|
2277
2361
|
terminalDepsProfile: " (erkanntes Profil: {profile})",
|
|
2278
2362
|
preview: "Vorschau",
|
|
2279
|
-
toc: "Inhaltsverzeichnis",
|
|
2280
2363
|
edit: "Bearbeiten",
|
|
2281
|
-
mermaidError: "Mermaid-Rendering fehlgeschlagen",
|
|
2282
|
-
mermaidZoomIn: "Vergrößern",
|
|
2283
|
-
mermaidZoomOut: "Verkleinern",
|
|
2284
|
-
mermaidZoomReset: "Zurücksetzen",
|
|
2285
|
-
mermaidZoomHint: "Scrollen zum Zoomen · Ziehen zum Verschieben · Esc zum Schließen",
|
|
2286
2364
|
refresh: "Aktualisieren",
|
|
2287
2365
|
showInFolder: "Im Ordner anzeigen",
|
|
2288
2366
|
refreshUnsavedConfirm: "Die Datei wurde geändert. Beim Aktualisieren gehen ungespeicherte Änderungen verloren. Fortfahren?",
|
|
@@ -2641,13 +2719,7 @@ window.__ModuleLoader__.load({
|
|
|
2641
2719
|
terminalDepsHint: "Exécutez la commande suivante dans un terminal ou cmd de l’environnement DSH pour réparer, puis cliquez sur Réessayer (node-pty reste à la même version que le cœur DSH) :",
|
|
2642
2720
|
terminalDepsProfile: " (profil détecté : {profile})",
|
|
2643
2721
|
preview: "Aperçu",
|
|
2644
|
-
toc: "Sommaire",
|
|
2645
2722
|
edit: "Modifier",
|
|
2646
|
-
mermaidError: "Échec du rendu Mermaid",
|
|
2647
|
-
mermaidZoomIn: "Agrandir",
|
|
2648
|
-
mermaidZoomOut: "Réduire",
|
|
2649
|
-
mermaidZoomReset: "Réinitialiser",
|
|
2650
|
-
mermaidZoomHint: "Molette pour zoomer · glisser pour déplacer · Échap pour fermer",
|
|
2651
2723
|
refresh: "Actualiser",
|
|
2652
2724
|
showInFolder: "Afficher dans le dossier",
|
|
2653
2725
|
refreshUnsavedConfirm: "Le fichier a changé sur le disque. Actualiser supprimera les modifications non enregistrées. Continuer ?",
|
|
@@ -2997,13 +3069,7 @@ window.__ModuleLoader__.load({
|
|
|
2997
3069
|
terminalDepsHint: "Execute o comando abaixo em um terminal ou cmd na máquina do DSH para reparar e tente novamente (node-pty permanece em sincronia com a versão do núcleo do DSH):",
|
|
2998
3070
|
terminalDepsProfile: " (perfil detectado: {profile})",
|
|
2999
3071
|
preview: "Pré-visualizar",
|
|
3000
|
-
toc: "Sumário",
|
|
3001
3072
|
edit: "Editar",
|
|
3002
|
-
mermaidError: "Falha ao renderizar o Mermaid",
|
|
3003
|
-
mermaidZoomIn: "Ampliar",
|
|
3004
|
-
mermaidZoomOut: "Reduzir",
|
|
3005
|
-
mermaidZoomReset: "Redefinir",
|
|
3006
|
-
mermaidZoomHint: "Rolar para ampliar · arrastar para mover · Esc para fechar",
|
|
3007
3073
|
refresh: "Atualizar",
|
|
3008
3074
|
showInFolder: "Mostrar na pasta",
|
|
3009
3075
|
refreshUnsavedConfirm: "O arquivo mudou no disco. Atualizar descartará edições não salvas. Continuar?",
|
|
@@ -3361,13 +3427,7 @@ window.__ModuleLoader__.load({
|
|
|
3361
3427
|
terminalDepsHint: "DSH가 설치된 환경의 터미널 또는 cmd에서 아래 명령을 실행하여 복구한 후 다시 시도를 클릭하세요(node-pty는 DSH 코어와 동일한 버전을 유지합니다):",
|
|
3362
3428
|
terminalDepsProfile: " (profile 감지됨: {profile})",
|
|
3363
3429
|
preview: "미리보기",
|
|
3364
|
-
toc: "목차",
|
|
3365
3430
|
edit: "편집",
|
|
3366
|
-
mermaidError: "Mermaid 렌더링 실패",
|
|
3367
|
-
mermaidZoomIn: "확대",
|
|
3368
|
-
mermaidZoomOut: "축소",
|
|
3369
|
-
mermaidZoomReset: "초기화",
|
|
3370
|
-
mermaidZoomHint: "휠로 확대/축소 · 드래그로 이동 · Esc로 닫기",
|
|
3371
3431
|
refresh: "새로고침",
|
|
3372
3432
|
showInFolder: "폴더에서 표시",
|
|
3373
3433
|
refreshUnsavedConfirm: "디스크의 파일이 변경되었습니다. 새로고침하면 저장되지 않은 편집 내용이 손실됩니다. 계속하시겠습니까?",
|
|
@@ -3734,13 +3794,7 @@ window.__ModuleLoader__.load({
|
|
|
3734
3794
|
terminalDepsHint: "شغّل الأمر التالي في طرفية أو cmd على جهاز DSH للإصلاح، ثم أعد المحاولة (يبقى node-pty متزامناً مع إصدار نواة DSH):",
|
|
3735
3795
|
terminalDepsProfile: " (الملف الشخصي المكتشف: {profile})",
|
|
3736
3796
|
preview: "معاينة",
|
|
3737
|
-
toc: "الفهرس",
|
|
3738
3797
|
edit: "تحرير",
|
|
3739
|
-
mermaidError: "فشل رسم Mermaid",
|
|
3740
|
-
mermaidZoomIn: "تكبير",
|
|
3741
|
-
mermaidZoomOut: "تصغير",
|
|
3742
|
-
mermaidZoomReset: "إعادة تعيين",
|
|
3743
|
-
mermaidZoomHint: "العجلة للتقريب · السحب للتحريك · Esc للإغلاق",
|
|
3744
3798
|
refresh: "تحديث",
|
|
3745
3799
|
showInFolder: "إظهار في المجلد",
|
|
3746
3800
|
refreshUnsavedConfirm: "تغيّر الملف على القرص. سيؤدي التحديث إلى فقدان التعديلات غير المحفوظة. متابعة؟",
|
|
@@ -4106,13 +4160,7 @@ window.__ModuleLoader__.load({
|
|
|
4106
4160
|
terminalDepsHint: "DSH मशीन पर एक टर्मिनल या cmd में नीचे दिया गया कमांड चलाएँ, फिर पुनः प्रयास करें (node-pty DSH कोर संस्करण के साथ सिंक रहता है):",
|
|
4107
4161
|
terminalDepsProfile: " (पहचाना गया प्रोफ़ाइल: {profile})",
|
|
4108
4162
|
preview: "पूर्वावलोकन",
|
|
4109
|
-
toc: "विषय-सूची",
|
|
4110
4163
|
edit: "संपादित करें",
|
|
4111
|
-
mermaidError: "Mermaid रेंडर विफल",
|
|
4112
|
-
mermaidZoomIn: "ज़ूम इन",
|
|
4113
|
-
mermaidZoomOut: "ज़ूम आउट",
|
|
4114
|
-
mermaidZoomReset: "रीसेट",
|
|
4115
|
-
mermaidZoomHint: "स्क्रॉल से ज़ूम · खींचें पैन करने · Esc से बंद",
|
|
4116
4164
|
refresh: "ताज़ा करें",
|
|
4117
4165
|
showInFolder: "फ़ोल्डर में दिखाएँ",
|
|
4118
4166
|
refreshUnsavedConfirm: "डिस्क पर फ़ाइल बदल गई है। रीफ़्रेश करने पर असहेज किए गए संपादन खो जाएँगे। जारी रखें?",
|
|
@@ -4476,13 +4524,7 @@ window.__ModuleLoader__.load({
|
|
|
4476
4524
|
terminalDepsHint: "Jalankan perintah di bawah ini di terminal atau cmd pada mesin DSH untuk memperbaikinya, lalu coba lagi (node-pty tetap sinkron dengan versi inti DSH):",
|
|
4477
4525
|
terminalDepsProfile: " (profil terdeteksi: {profile})",
|
|
4478
4526
|
preview: "Pratinjau",
|
|
4479
|
-
toc: "Daftar Isi",
|
|
4480
4527
|
edit: "Edit",
|
|
4481
|
-
mermaidError: "Render Mermaid gagal",
|
|
4482
|
-
mermaidZoomIn: "Perbesar",
|
|
4483
|
-
mermaidZoomOut: "Perkecil",
|
|
4484
|
-
mermaidZoomReset: "Reset",
|
|
4485
|
-
mermaidZoomHint: "Gulir untuk zoom · seret untuk geser · Esc untuk tutup",
|
|
4486
4528
|
refresh: "Segarkan",
|
|
4487
4529
|
showInFolder: "Tampilkan di folder",
|
|
4488
4530
|
refreshUnsavedConfirm: "File berubah di disk. Menyegarkan akan membuang edit yang belum disimpan. Lanjutkan?",
|
|
@@ -4848,13 +4890,7 @@ window.__ModuleLoader__.load({
|
|
|
4848
4890
|
terminalDepsHint: "Onarmak için DSH makinesindeki bir terminalde veya cmd’de aşağıdaki komutu çalıştırın, sonra yeniden deneyin (node-pty, DSH çekirdek sürümüyle senkron kalır):",
|
|
4849
4891
|
terminalDepsProfile: " (algılanan profil: {profile})",
|
|
4850
4892
|
preview: "Önizleme",
|
|
4851
|
-
toc: "İçindekiler",
|
|
4852
4893
|
edit: "Düzenle",
|
|
4853
|
-
mermaidError: "Mermaid oluşturma başarısız",
|
|
4854
|
-
mermaidZoomIn: "Yakınlaştır",
|
|
4855
|
-
mermaidZoomOut: "Uzaklaştır",
|
|
4856
|
-
mermaidZoomReset: "Sıfırla",
|
|
4857
|
-
mermaidZoomHint: "Yakınlaştırmak için kaydır · taşımak için sürükle · kapatmak için Esc",
|
|
4858
4894
|
refresh: "Yenile",
|
|
4859
4895
|
showInFolder: "Klasörde göster",
|
|
4860
4896
|
refreshUnsavedConfirm: "Dosya diskte değişti. Yenileme kaydedilmemiş düzenlemeleri atar. Devam edilsin mi?",
|
|
@@ -5220,13 +5256,7 @@ window.__ModuleLoader__.load({
|
|
|
5220
5256
|
terminalDepsHint: "Chạy lệnh sau trong terminal hoặc cmd trên máy DSH để sửa, rồi nhấn thử lại (node-pty đồng bộ phiên bản với lõi DSH):",
|
|
5221
5257
|
terminalDepsProfile: " (phát hiện profile: {profile})",
|
|
5222
5258
|
preview: "Xem trước",
|
|
5223
|
-
toc: "Mục lục",
|
|
5224
5259
|
edit: "Chỉnh sửa",
|
|
5225
|
-
mermaidError: "Render Mermaid thất bại",
|
|
5226
|
-
mermaidZoomIn: "Phóng to",
|
|
5227
|
-
mermaidZoomOut: "Thu nhỏ",
|
|
5228
|
-
mermaidZoomReset: "Đặt lại",
|
|
5229
|
-
mermaidZoomHint: "Cuộn để zoom · kéo để di chuyển · Esc để đóng",
|
|
5230
5260
|
refresh: "Làm mới",
|
|
5231
5261
|
showInFolder: "Hiển thị trong thư mục",
|
|
5232
5262
|
refreshUnsavedConfirm: "Tệp đã thay đổi trên đĩa. Làm mới sẽ loại bỏ các chỉnh sửa chưa lưu. Tiếp tục?",
|
|
@@ -5592,13 +5622,7 @@ window.__ModuleLoader__.load({
|
|
|
5592
5622
|
terminalDepsHint: "เรียกใช้คำสั่งด้านล่างในเทอร์มินัลหรือ cmd บนเครื่อง DSH เพื่อซ่อมแซม แล้วกดลองอีกครั้ง (node-pty ต้องซิงค์กับเวอร์ชันหลักของ DSH):",
|
|
5593
5623
|
terminalDepsProfile: " (ตรวจพบ profile: {profile})",
|
|
5594
5624
|
preview: "พรีวิว",
|
|
5595
|
-
toc: "สารบัญ",
|
|
5596
5625
|
edit: "แก้ไข",
|
|
5597
|
-
mermaidError: "เรนเดอร์ Mermaid ล้มเหลว",
|
|
5598
|
-
mermaidZoomIn: "ซูมเข้า",
|
|
5599
|
-
mermaidZoomOut: "ซูมออก",
|
|
5600
|
-
mermaidZoomReset: "รีเซ็ต",
|
|
5601
|
-
mermaidZoomHint: "เลื่อนเพื่อซูม · ลากเพื่อแพน · Esc เพื่อปิด",
|
|
5602
5626
|
refresh: "รีเฟรช",
|
|
5603
5627
|
showInFolder: "แสดงในโฟลเดอร์",
|
|
5604
5628
|
refreshUnsavedConfirm: "ไฟล์เปลี่ยนบนดิสก์ การรีเฟรชจะทิ้งการแก้ไขที่ยังไม่ได้บันทึก ดำเนินการต่อหรือไม่",
|
|
@@ -5960,13 +5984,7 @@ window.__ModuleLoader__.load({
|
|
|
5960
5984
|
terminalDepsHint: "Выполните приведённую ниже команду в терминале или cmd на машине DSH, затем нажмите «Повторить» (node-pty остаётся синхронизированным с версией ядра DSH):",
|
|
5961
5985
|
terminalDepsProfile: " (обнаружен profile: {profile})",
|
|
5962
5986
|
preview: "Предпросмотр",
|
|
5963
|
-
toc: "Оглавление",
|
|
5964
5987
|
edit: "Изменить",
|
|
5965
|
-
mermaidError: "Сбой рендеринга Mermaid",
|
|
5966
|
-
mermaidZoomIn: "Приблизить",
|
|
5967
|
-
mermaidZoomOut: "Отдалить",
|
|
5968
|
-
mermaidZoomReset: "Сбросить",
|
|
5969
|
-
mermaidZoomHint: "Колесо — масштаб · перетаскивание — панорама · Esc — закрыть",
|
|
5970
5988
|
refresh: "Обновить",
|
|
5971
5989
|
showInFolder: "Показать в папке",
|
|
5972
5990
|
refreshUnsavedConfirm: "Файл изменился на диске. Обновление отбросит несохранённые изменения. Продолжить?",
|
|
@@ -6323,13 +6341,7 @@ window.__ModuleLoader__.load({
|
|
|
6323
6341
|
terminalDepsHint: "Esegua il comando seguente in un terminale o cmd sul computer DSH per ripristinarlo, poi riprovi (node-pty resta sincronizzato con la versione del core DSH):",
|
|
6324
6342
|
terminalDepsProfile: " (rilevato profilo: {profile})",
|
|
6325
6343
|
preview: "Anteprima",
|
|
6326
|
-
toc: "Indice",
|
|
6327
6344
|
edit: "Modifica",
|
|
6328
|
-
mermaidError: "Rendering Mermaid non riuscito",
|
|
6329
|
-
mermaidZoomIn: "Ingrandisci",
|
|
6330
|
-
mermaidZoomOut: "Riduci",
|
|
6331
|
-
mermaidZoomReset: "Ripristina",
|
|
6332
|
-
mermaidZoomHint: "Scorra per zoom · trascini per panoramica · Esc per chiudere",
|
|
6333
6345
|
refresh: "Aggiorna",
|
|
6334
6346
|
showInFolder: "Mostra nella cartella",
|
|
6335
6347
|
refreshUnsavedConfirm: "Il file è cambiato su disco. Aggiornare scarterà le modifiche non salvate. Continuare?",
|
|
@@ -6694,13 +6706,7 @@ window.__ModuleLoader__.load({
|
|
|
6694
6706
|
terminalDepsHint: "Voer het onderstaande commando uit in een terminal of cmd op de DSH-machine om het te herstellen en probeer het opnieuw (node-pty blijft in sync met de DSH-coreversie):",
|
|
6695
6707
|
terminalDepsProfile: " (gedetecteerde profile: {profile})",
|
|
6696
6708
|
preview: "Voorbeeld",
|
|
6697
|
-
toc: "Inhoudsopgave",
|
|
6698
6709
|
edit: "Bewerken",
|
|
6699
|
-
mermaidError: "Mermaid-renderen mislukt",
|
|
6700
|
-
mermaidZoomIn: "Inzoomen",
|
|
6701
|
-
mermaidZoomOut: "Uitzoomen",
|
|
6702
|
-
mermaidZoomReset: "Resetten",
|
|
6703
|
-
mermaidZoomHint: "Scrollen om te zoomen · slepen om te pannen · Esc om te sluiten",
|
|
6704
6710
|
refresh: "Vernieuwen",
|
|
6705
6711
|
showInFolder: "In map tonen",
|
|
6706
6712
|
refreshUnsavedConfirm: "Het bestand is op schijf gewijzigd. Vernieuwen gooit niet-opgeslagen wijzigingen weg. Doorgaan?",
|
|
@@ -7050,13 +7056,7 @@ window.__ModuleLoader__.load({
|
|
|
7050
7056
|
terminalDepsHint: "Kör kommandot nedan i en terminal eller cmd på DSH-maskinen för att reparera det, försök sedan igen (node-pty hålls synkad med DSH-kärnversionen):",
|
|
7051
7057
|
terminalDepsProfile: " (upptäckt profil: {profile})",
|
|
7052
7058
|
preview: "Förhandsgranska",
|
|
7053
|
-
toc: "Innehållsförteckning",
|
|
7054
7059
|
edit: "Redigera",
|
|
7055
|
-
mermaidError: "Mermaid-rendering misslyckades",
|
|
7056
|
-
mermaidZoomIn: "Zooma in",
|
|
7057
|
-
mermaidZoomOut: "Zooma ut",
|
|
7058
|
-
mermaidZoomReset: "Återställ",
|
|
7059
|
-
mermaidZoomHint: "Rulla för att zooma · dra för att panorera · Esc för att stänga",
|
|
7060
7060
|
refresh: "Uppdatera",
|
|
7061
7061
|
showInFolder: "Visa i mapp",
|
|
7062
7062
|
refreshUnsavedConfirm: "Filen ändrades på disken. Uppdatering kastar osparade ändringar. Fortsätta?",
|
|
@@ -7424,13 +7424,7 @@ window.__ModuleLoader__.load({
|
|
|
7424
7424
|
terminalDepsHint: "Uruchom poniższe polecenie w terminalu lub cmd na maszynie DSH, aby to naprawić, a następnie ponów (node-pty pozostaje w synchronizacji z wersją rdzenia DSH):",
|
|
7425
7425
|
terminalDepsProfile: " (wykryty profil: {profile})",
|
|
7426
7426
|
preview: "Podgląd",
|
|
7427
|
-
toc: "Spis treści",
|
|
7428
7427
|
edit: "Edytuj",
|
|
7429
|
-
mermaidError: "Renderowanie Mermaid nie powiodło się",
|
|
7430
|
-
mermaidZoomIn: "Powiększ",
|
|
7431
|
-
mermaidZoomOut: "Pomniejsz",
|
|
7432
|
-
mermaidZoomReset: "Resetuj",
|
|
7433
|
-
mermaidZoomHint: "Kółko: powiększenie · przeciąganie: panowanie · Esc: zamknięcie",
|
|
7434
7428
|
refresh: "Odśwież",
|
|
7435
7429
|
showInFolder: "Pokaż w folderze",
|
|
7436
7430
|
refreshUnsavedConfirm: "Plik zmienił się na dysku. Odświeżenie odrzuci niezapisane zmiany. Kontynuować?",
|
|
@@ -7811,13 +7805,7 @@ window.__ModuleLoader__.load({
|
|
|
7811
7805
|
terminalDepsHint: "在 DSH 所在環境的終端或 cmd 中執行以下命令修復,然後點重試(node-pty 與 DSH 核心保持同一版本):",
|
|
7812
7806
|
terminalDepsProfile: "(偵測到 profile:{profile})",
|
|
7813
7807
|
preview: "預覽",
|
|
7814
|
-
toc: "目錄",
|
|
7815
7808
|
edit: "編輯",
|
|
7816
|
-
mermaidError: "Mermaid 渲染失敗",
|
|
7817
|
-
mermaidZoomIn: "放大",
|
|
7818
|
-
mermaidZoomOut: "縮小",
|
|
7819
|
-
mermaidZoomReset: "重設",
|
|
7820
|
-
mermaidZoomHint: "滾輪縮放 · 拖曳平移 · Esc 關閉",
|
|
7821
7809
|
refresh: "重新整理",
|
|
7822
7810
|
showInFolder: "在文件夾中顯示",
|
|
7823
7811
|
refreshUnsavedConfirm: "檔案已在磁碟上變更。重新整理會丟失尚未儲存的編輯。繼續?",
|
|
@@ -8198,13 +8186,7 @@ window.__ModuleLoader__.load({
|
|
|
8198
8186
|
terminalDepsHint: "在 DSH 所在環境的終端或 cmd 中執行以下命令修復,然後點重試(node-pty 與 DSH 核心保持同一版本):",
|
|
8199
8187
|
terminalDepsProfile: "(偵測到 profile:{profile})",
|
|
8200
8188
|
preview: "預覽",
|
|
8201
|
-
toc: "目錄",
|
|
8202
8189
|
edit: "編輯",
|
|
8203
|
-
mermaidError: "Mermaid 渲染失敗",
|
|
8204
|
-
mermaidZoomIn: "放大",
|
|
8205
|
-
mermaidZoomOut: "縮小",
|
|
8206
|
-
mermaidZoomReset: "重設",
|
|
8207
|
-
mermaidZoomHint: "滾輪縮放 · 拖曳平移 · Esc 關閉",
|
|
8208
8190
|
refresh: "重新整理",
|
|
8209
8191
|
showInFolder: "在資料夾中顯示",
|
|
8210
8192
|
refreshUnsavedConfirm: "檔案已在磁碟上變更。重新整理會丟失尚未儲存的編輯。繼續?",
|
|
@@ -8585,13 +8567,7 @@ window.__ModuleLoader__.load({
|
|
|
8585
8567
|
terminalDepsHint: "在 DSH 所在環境的終端或 cmd 中執行以下命令修復,然後點重試(node-pty 與 DSH 核心保持同一版本):",
|
|
8586
8568
|
terminalDepsProfile: "(偵測到 profile:{profile})",
|
|
8587
8569
|
preview: "預覽",
|
|
8588
|
-
toc: "目錄",
|
|
8589
8570
|
edit: "編輯",
|
|
8590
|
-
mermaidError: "Mermaid 渲染失敗",
|
|
8591
|
-
mermaidZoomIn: "放大",
|
|
8592
|
-
mermaidZoomOut: "縮小",
|
|
8593
|
-
mermaidZoomReset: "重設",
|
|
8594
|
-
mermaidZoomHint: "滾輪縮放 · 拖曳平移 · Esc 關閉",
|
|
8595
8571
|
refresh: "重新整理",
|
|
8596
8572
|
showInFolder: "在文件夾中顯示",
|
|
8597
8573
|
refreshUnsavedConfirm: "檔案已在磁碟上變更。重新整理會丟失尚未儲存的編輯。繼續?",
|
|
@@ -8963,14 +8939,6 @@ window.__ModuleLoader__.load({
|
|
|
8963
8939
|
terminalDepsFailed: "终端依赖 node-pty 加载失败",
|
|
8964
8940
|
terminalDepsHint: "在 DSH 所在环境的终端或 cmd 中执行以下命令修复,然后点重试(node-pty 与 DSH 核心保持同一版本):",
|
|
8965
8941
|
terminalDepsProfile: "(检测到 profile:{profile})",
|
|
8966
|
-
preview: "预览",
|
|
8967
|
-
toc: "目录",
|
|
8968
|
-
edit: "编辑",
|
|
8969
|
-
mermaidError: "Mermaid 渲染失败",
|
|
8970
|
-
mermaidZoomIn: "放大",
|
|
8971
|
-
mermaidZoomOut: "缩小",
|
|
8972
|
-
mermaidZoomReset: "重置",
|
|
8973
|
-
mermaidZoomHint: "滚轮缩放 · 拖拽平移 · Esc 关闭",
|
|
8974
8942
|
refresh: "刷新",
|
|
8975
8943
|
refreshUnsavedConfirm: "文件已在磁盘更新,刷新将丢弃未保存编辑。继续吗?",
|
|
8976
8944
|
save: "保存",
|
|
@@ -9113,34 +9081,27 @@ window.__ModuleLoader__.load({
|
|
|
9113
9081
|
settingsShellArgsDesc: "显式 shell 启动参数,空格分隔;非空时完全替换默认参数(与 yaml 的 shellArgs 契约一致)",
|
|
9114
9082
|
settingsShellArgsPlaceholder: "如 -l(留空用默认参数)",
|
|
9115
9083
|
settingsTabsTitle: "侧边栏内容",
|
|
9116
|
-
settingsViewersTitle: "文件预览",
|
|
9117
9084
|
settingsGeneralTitle: "常规",
|
|
9118
9085
|
settingsPopup: "功能设置",
|
|
9119
|
-
settingsViewerCatchAll: "兜底:任意文件",
|
|
9120
|
-
viewerImage: "图片",
|
|
9121
|
-
viewerPdf: "PDF",
|
|
9122
|
-
viewerMarkdown: "Markdown",
|
|
9123
|
-
viewerCode: "代码",
|
|
9124
|
-
viewerBinary: "二进制下载",
|
|
9125
|
-
viewerHtml: "HTML",
|
|
9126
9086
|
browser: "浏览器",
|
|
9127
9087
|
browserPlaceholder: "输入网址,例如 example.com",
|
|
9128
9088
|
browserGo: "前往",
|
|
9129
9089
|
browserBack: "后退",
|
|
9130
9090
|
browserForward: "前进",
|
|
9131
9091
|
browserStart: "输入网址开始浏览(沙箱模式)",
|
|
9092
|
+
browserLive: "Agent 实况",
|
|
9093
|
+
browserLiveFree: "自由浏览",
|
|
9094
|
+
browserLiveConnecting: "连接 agent 浏览器宿主…",
|
|
9095
|
+
browserLiveDown: "宿主不可达:确认 KCoder 已启动(端口 9223)",
|
|
9096
|
+
browserLiveTargetNone: "暂无打开的页面——agent 发起浏览后此处实时显示",
|
|
9097
|
+
browserLiveFollowLatest: "跟随最新页面",
|
|
9132
9098
|
browserBlockedScheme: "已阻止:仅支持 http/https 链接",
|
|
9133
9099
|
browserBlockedLoopback: "已阻止:不允许在浏览器中访问本机或内部地址",
|
|
9134
9100
|
browserInvalid: "无效的网址",
|
|
9135
9101
|
browserNoSandboxWarning: "沙箱已关闭:当前页面与界面同源,拥有完整会话权限(可在设置中恢复)",
|
|
9136
|
-
htmlNoSandboxWarning: "沙箱已关闭:此 HTML 与界面同源,可读取会话文件与内部接口(可在设置中恢复)",
|
|
9137
9102
|
sandboxStatusOn: "沙箱模式:已启用 · 页面无法访问界面数据与本地文件,登录态与第三方 Cookie 可能不可用",
|
|
9138
9103
|
sandboxUnlock: "临时解锁(不安全)",
|
|
9139
9104
|
sandboxRestore: "恢复沙箱",
|
|
9140
|
-
settingsHtmlDefaultUnsafeTitle: "HTML 预览默认以非沙箱模式打开(不安全)",
|
|
9141
|
-
settingsHtmlDefaultUnsafeDesc: "开启后,每次打开 HTML 文件时预览默认处于非沙箱状态(与界面同源,可读取会话文件与内部接口);可在状态行临时恢复沙箱",
|
|
9142
|
-
settingsHtmlSandboxTitle: "关闭 HTML 预览沙箱(不安全)",
|
|
9143
|
-
settingsHtmlSandboxDesc: "关闭后,预览的 HTML 将与界面同源运行,可读取会话文件、本地存储并调用内部接口。仅对完全可信的文件开启",
|
|
9144
9105
|
settingsBrowserSandboxTitle: "关闭浏览器沙箱(不安全)",
|
|
9145
9106
|
settingsBrowserSandboxDesc: "关闭后,访问的任何网站都将与界面同源运行,可读取会话数据并冒充你的登录状态。仅对完全可信的站点开启",
|
|
9146
9107
|
settingsBrowserLinksTitle: "聊天区外链在侧边栏打开",
|
|
@@ -9221,10 +9182,7 @@ window.__ModuleLoader__.load({
|
|
|
9221
9182
|
jobKillError: "终止失败",
|
|
9222
9183
|
addPluginsTabCard: "添加 Tab 插件",
|
|
9223
9184
|
addPluginsTabCardDesc: "注册新的侧边栏页面",
|
|
9224
|
-
addPluginsViewerCard: "添加预览插件",
|
|
9225
|
-
addPluginsViewerCardDesc: "注册新的文件类型预览",
|
|
9226
9185
|
addPluginsTabDesc: "侧边栏页面(Tab)可以由插件扩展。插件通过 ctx.betterSidebar 服务注册;点击「安装」复制安装命令,粘贴到 DSH 所在环境的终端执行。",
|
|
9227
|
-
addPluginsViewerDesc: "文件预览器可以由插件扩展。插件通过 ctx.betterSidebar 服务注册;点击「安装」复制安装命令,粘贴到 DSH 所在环境的终端执行。",
|
|
9228
9186
|
addPluginsBrowseMore: "在 GitHub 上浏览更多插件(topic: dsh-coding-sidebar)",
|
|
9229
9187
|
addPluginsSearch: "搜索插件名称 / 描述…",
|
|
9230
9188
|
addPluginsNoMatch: "没有匹配的插件",
|
|
@@ -9232,7 +9190,6 @@ window.__ModuleLoader__.load({
|
|
|
9232
9190
|
addPluginsEmpty: "暂未收录插件,欢迎在 GitHub topic 下发布你的插件",
|
|
9233
9191
|
openPlugin: "跳转",
|
|
9234
9192
|
copyInstall: "复制安装命令",
|
|
9235
|
-
pluginOfficeDesc: "为 dsh-coding-sidebar 编辑器提供 Office 三件套预览(.docx / .xlsx / .pptx),把重型 Office 渲染库拆出主包、按需安装",
|
|
9236
9193
|
pluginFlowglassDesc: "实时会话流程图:三列泳道展示用户、助手与工具调用,支持并行分组、子代理支线、逐层钻取和实时状态;安装 dsh-coding-sidebar 后注册原生「流镜」Tab,未安装时保留独立抽屉",
|
|
9237
9194
|
pluginGitForgeDesc: "dsh-coding-sidebar「Git 凭据」Tab:GitHub/Gitea 等 Forge 账号库 + 按项目授权 + push 策略硬拦;token 仅存本地 secrets,不进模型上下文;提供只读 GitForge 工具与 agent HTTPS credential helper",
|
|
9238
9195
|
pluginGitRemotesDesc: "dsh-coding-sidebar Git 远程 Tab:看分支/上游/ahead-behind,fetch(可 prune)、ff-only pull、确认后才 push。不替换内置 Git 的暂存/提交,也不提供 force-push 或模型自动推送",
|
|
@@ -9240,7 +9197,6 @@ window.__ModuleLoader__.load({
|
|
|
9240
9197
|
pluginSidebarQaDesc: "基于 dsh-coding-sidebar 的划选提问tab分页: 对话划选 → 右侧面板提问 → 同工作区独立追问会话(❓追问·主题):快速无思考模型压缩主对话上下文后与引文一起注入,不打断主对话;追问可嵌套、可继续、可归档",
|
|
9241
9198
|
pluginSshTunnelDesc: "dsh-coding-sidebar「SSH 隧道」Tab:多机主机清单 + 按项目授权 + 密钥本地保管;模型工具 SSHManager(exec/SFTP/会话策略);中央交互终端与双栏 SFTP",
|
|
9242
9199
|
pluginTurnReviewDesc: "对「刚刚这一回合」的 diff 做 Approve / Request changes 的人闸门:只审上一回合,不 fork 会话;文件按主会话/子代理/未归因分组,按文件勾选打回 + 可选评语,点文件先看回合开始快照 vs 现在的 diff。不是 /rewind",
|
|
9243
|
-
pluginVideoPreviewDesc: "在 dsh-coding-sidebar 编辑器内联预览视频文件(.mp4/.webm/.mov/.mkv/.avi 等),自带支持 HTTP Range(206)的 /video 宿主路由,可拖动进度条、不受 20MB mediaLimit 限制",
|
|
9244
9200
|
pluginDocsPanelDesc: "DSH 侧边栏里的「全局文档」:全局 Markdown 笔记,任何工作区随时可读——列表点选阅读、悬浮大纲跳转、Chrome / VS Code 外部打开、代码复制,目录可配置(默认 ~/.dsh/docs)",
|
|
9245
9201
|
pluginEgoBrowserDesc: "把 CitroLabs/ego-lite 接进 DeepSeek Harness 的 agent 浏览器:32 个 ego_* 工具驱动真实 Chromium,侧边栏原生「ego 浏览器」Tab 实时观察 agent 逛的每个页面,可直接点击/拖拽/输入接管;装 dsh-coding-sidebar 时自动注册 Tab,没装则退回浮动浮窗"
|
|
9246
9202
|
};
|
|
@@ -9318,14 +9274,6 @@ window.__ModuleLoader__.load({
|
|
|
9318
9274
|
terminalDepsFailed: "Terminal dependency node-pty failed to load",
|
|
9319
9275
|
terminalDepsHint: "Run the command below in a terminal or cmd on the DSH machine to repair it, then retry (node-pty stays in sync with the DSH core version):",
|
|
9320
9276
|
terminalDepsProfile: " (detected profile: {profile})",
|
|
9321
|
-
preview: "Preview",
|
|
9322
|
-
toc: "Table of contents",
|
|
9323
|
-
edit: "Edit",
|
|
9324
|
-
mermaidError: "Mermaid render failed",
|
|
9325
|
-
mermaidZoomIn: "Zoom in",
|
|
9326
|
-
mermaidZoomOut: "Zoom out",
|
|
9327
|
-
mermaidZoomReset: "Reset",
|
|
9328
|
-
mermaidZoomHint: "Scroll to zoom · drag to pan · Esc to close",
|
|
9329
9277
|
refresh: "Refresh",
|
|
9330
9278
|
refreshUnsavedConfirm: "The file changed on disk. Refreshing will discard unsaved edits. Continue?",
|
|
9331
9279
|
save: "Save",
|
|
@@ -9468,34 +9416,27 @@ window.__ModuleLoader__.load({
|
|
|
9468
9416
|
settingsFontSizeDesc: "Terminal font size in px (9–32, default 13)",
|
|
9469
9417
|
settingsFontSizeSuffix: "px",
|
|
9470
9418
|
settingsTabsTitle: "Sidebar content",
|
|
9471
|
-
settingsViewersTitle: "File viewers",
|
|
9472
9419
|
settingsGeneralTitle: "General",
|
|
9473
9420
|
settingsPopup: "Feature settings",
|
|
9474
|
-
settingsViewerCatchAll: "Catch-all: any file",
|
|
9475
|
-
viewerImage: "Image",
|
|
9476
|
-
viewerPdf: "PDF",
|
|
9477
|
-
viewerMarkdown: "Markdown",
|
|
9478
|
-
viewerCode: "Code",
|
|
9479
|
-
viewerBinary: "Binary download",
|
|
9480
|
-
viewerHtml: "HTML",
|
|
9481
9421
|
browser: "Browser",
|
|
9482
9422
|
browserPlaceholder: "Enter a URL, e.g. example.com",
|
|
9483
9423
|
browserGo: "Go",
|
|
9484
9424
|
browserBack: "Back",
|
|
9485
9425
|
browserForward: "Forward",
|
|
9486
9426
|
browserStart: "Enter a URL to start browsing (sandbox mode)",
|
|
9427
|
+
browserLive: "Agent live",
|
|
9428
|
+
browserLiveFree: "Free browse",
|
|
9429
|
+
browserLiveConnecting: "connecting to the agent browser host…",
|
|
9430
|
+
browserLiveDown: "host unreachable: make sure KCoder is running (port 9223)",
|
|
9431
|
+
browserLiveTargetNone: "No open pages yet — they appear here live once the agent browses",
|
|
9432
|
+
browserLiveFollowLatest: "Follow latest",
|
|
9487
9433
|
browserBlockedScheme: "Blocked: only http/https URLs are allowed",
|
|
9488
9434
|
browserBlockedLoopback: "Blocked: local and internal addresses cannot be browsed here",
|
|
9489
9435
|
browserInvalid: "Invalid URL",
|
|
9490
9436
|
browserNoSandboxWarning: "Sandbox off: the current page runs with full GUI privileges (re-enable in settings)",
|
|
9491
|
-
htmlNoSandboxWarning: "Sandbox off: this HTML runs with full GUI privileges (re-enable in settings)",
|
|
9492
9437
|
sandboxStatusOn: "Sandbox mode: on · pages cannot access the GUI's data or local files; logins and third-party cookies may not work",
|
|
9493
9438
|
sandboxUnlock: "Temporarily disable (unsafe)",
|
|
9494
9439
|
sandboxRestore: "Restore sandbox",
|
|
9495
|
-
settingsHtmlDefaultUnsafeTitle: "Open HTML previews unsandboxed by default (unsafe)",
|
|
9496
|
-
settingsHtmlDefaultUnsafeDesc: "When on, every newly opened HTML preview starts in the unsandboxed state (same origin as the GUI — it can read session files and internal APIs); the status row still offers a one-tap restore",
|
|
9497
|
-
settingsHtmlSandboxTitle: "Disable HTML preview sandbox (unsafe)",
|
|
9498
|
-
settingsHtmlSandboxDesc: "With the sandbox off, previewed HTML runs with the same origin as the GUI: it can read session files, local storage and call internal APIs. Only enable for fully trusted files",
|
|
9499
9440
|
settingsBrowserSandboxTitle: "Disable browser sandbox (unsafe)",
|
|
9500
9441
|
settingsBrowserSandboxDesc: "With the sandbox off, any visited site runs with the same origin as the GUI: it can read session data and act as your logged-in session. Only enable for fully trusted sites",
|
|
9501
9442
|
settingsBrowserLinksTitle: "Open chat external links in the sidebar",
|
|
@@ -9576,10 +9517,7 @@ window.__ModuleLoader__.load({
|
|
|
9576
9517
|
jobKillError: "Kill failed",
|
|
9577
9518
|
addPluginsTabCard: "Add tab plugins",
|
|
9578
9519
|
addPluginsTabCardDesc: "Register a new sidebar page",
|
|
9579
|
-
addPluginsViewerCard: "Add preview plugins",
|
|
9580
|
-
addPluginsViewerCardDesc: "Register a file-type preview",
|
|
9581
9520
|
addPluginsTabDesc: "Sidebar pages (tabs) can be extended by plugins. Plugins register through the ctx.betterSidebar service; clicking Install copies the install command — paste it into a terminal where your DSH profile lives and run it.",
|
|
9582
|
-
addPluginsViewerDesc: "File previewers can be extended by plugins. Plugins register through the ctx.betterSidebar service; clicking Install copies the install command — paste it into a terminal where your DSH profile lives and run it.",
|
|
9583
9521
|
addPluginsBrowseMore: "Browse more plugins on GitHub (topic: dsh-coding-sidebar)",
|
|
9584
9522
|
addPluginsSearch: "Search by plugin name or description…",
|
|
9585
9523
|
addPluginsNoMatch: "No plugins match",
|
|
@@ -9587,7 +9525,6 @@ window.__ModuleLoader__.load({
|
|
|
9587
9525
|
addPluginsEmpty: "No plugins curated yet — publish yours under the GitHub topic",
|
|
9588
9526
|
openPlugin: "Open",
|
|
9589
9527
|
copyInstall: "Copy install command",
|
|
9590
|
-
pluginOfficeDesc: "Office-suite preview (.docx / .xlsx / .pptx) for the dsh-coding-sidebar editor, keeping the heavy Office render libraries out of the core bundle",
|
|
9591
9528
|
pluginFlowglassDesc: "Live session flowgraph with three lanes for user, assistant, and tool calls, plus parallel groups, sub-agent branches, drill-down, and live status; registers a native Flowglass tab when dsh-coding-sidebar is installed and keeps its standalone drawer as a fallback",
|
|
9592
9529
|
pluginGitForgeDesc: "Git Forge tab: GitHub/Gitea (and other forge) account library + per-project grants + hard push policy; tokens stay in local secrets (never in model context); read-only GitForge tool and agent HTTPS credential helper",
|
|
9593
9530
|
pluginGitRemotesDesc: "Git Remotes tab: branch/upstream/ahead-behind, fetch (optional prune), ff-only pull, and push only after an in-tab confirm. Does not replace the built-in Git stage/commit tab, and does not offer force-push or a model auto-push tool",
|
|
@@ -9595,7 +9532,6 @@ window.__ModuleLoader__.load({
|
|
|
9595
9532
|
pluginSidebarQaDesc: "Select-and-ask: Select conversation text → ask in the right-side panel → a dedicated follow-up session (❓追问) in the same workspace; a fast no-thinking model compresses the main context and injects it with the quote, without interrupting the main conversation. Follow-ups nest, continue, and archive",
|
|
9596
9533
|
pluginSshTunnelDesc: "SSH Tunnel tab: multi-host inventory + per-project grants + local secrets; SSHManager tool (exec/SFTP/session strategies); center interactive terminal and dual-pane SFTP",
|
|
9597
9534
|
pluginTurnReviewDesc: "A human gate on the just-finished turn: Approve / Request changes per path with an optional comment; paths grouped by main session / subagent / unattributed; inline snapshot-vs-now diff before you decide. No fork, no /rewind",
|
|
9598
|
-
pluginVideoPreviewDesc: "Inline video preview (.mp4/.webm/.mov/.mkv/.avi etc.) for the dsh-coding-sidebar editor, backed by a dedicated /video host route with HTTP Range (206) support — scrubbing works and files are not capped by the 20MB mediaLimit",
|
|
9599
9535
|
pluginDocsPanelDesc: "Global docs in the DSH sidebar: read your own Markdown notes from any workspace — a file list, an outline, open in Chrome / VS Code, and copy buttons; the docs directory is configurable (default ~/.dsh/docs)",
|
|
9600
9536
|
pluginEgoBrowserDesc: "The agent browser for DeepSeek Harness: 32 ego_* tools drive a real Chromium, with a native sidebar \"ego browser\" tab giving a live view of every page the agent visits — you can click, drag, and type to take over. Registers the tab automatically when dsh-coding-sidebar is present, otherwise falls back to a floating bubble"
|
|
9601
9537
|
};
|
|
@@ -9956,7 +9892,7 @@ window.__ModuleLoader__.load({
|
|
|
9956
9892
|
}
|
|
9957
9893
|
//#endregion
|
|
9958
9894
|
//#region \0dsh-css:/Users/libing/kk_Projects/dsh-coding-sidebar/src/client/sidebar.module.css.mjs
|
|
9959
|
-
const css$4 = "[data-dsh-panel-host]{z-index:25;pointer-events:none;position:fixed;inset:0;overflow:hidden}[data-dsh-panel-host][data-dsh-panel-host-degraded]{position:absolute;top:0;left:0}.S5HVoW_toggleCluster{top:calc(3px + env(safe-area-inset-top));z-index:45;pointer-events:auto;flex-direction:row;gap:4px;display:flex;position:absolute;right:10px}.S5HVoW_panel:not(.S5HVoW_panelHidden) .S5HVoW_tabBar{padding-right:72px}.S5HVoW_toggleButton{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:background var(--ds-transition-duration-slow) var(--ds-ease-in-out), color var(--ds-transition-duration-slow) var(--ds-ease-in-out);background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;display:flex}.S5HVoW_toggleButton:hover:not(:disabled):not([aria-disabled=true]){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_toggleButton:disabled,.S5HVoW_toggleButton[aria-disabled=true]{opacity:.4;cursor:default}.S5HVoW_panel{box-sizing:border-box;z-index:40;pointer-events:auto;background:var(--dsw-alias-bg-layer-1);border-left:1px solid var(--dsw-alias-border-l2);padding-bottom:env(safe-area-inset-bottom);transition:transform var(--ds-transition-duration-slow) var(--ds-ease-in-out), width var(--ds-transition-duration-slow) var(--ds-ease-in-out);flex-direction:column;display:flex;position:absolute;top:0;bottom:0;right:0}.S5HVoW_panelHidden{pointer-events:none;visibility:hidden;transition:transform var(--ds-transition-duration-slow) var(--ds-ease-in-out), width var(--ds-transition-duration-slow) var(--ds-ease-in-out), visibility 0s linear var(--ds-transition-duration-slow);transform:translate(102%)}.S5HVoW_panel[data-dragging]{transition:none}.S5HVoW_panelResize{cursor:col-resize;z-index:2;touch-action:none;width:8px;position:absolute;top:0;bottom:0;left:-4px}.S5HVoW_panelResizeActive{background:var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_panelBody{flex:1;min-width:0;min-height:0;display:flex}.S5HVoW_panel{contain:layout style}body[data-dsh-sidebar-dragging] .S5HVoW_panel{will-change:transform}.S5HVoW_floatWindow{z-index:42;pointer-events:auto;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);box-shadow:var(--dsw-shadow-lv3);contain:layout style;border-radius:8px;flex-direction:column;display:flex;position:absolute;overflow:hidden}.S5HVoW_floatWindowDragging{will-change:left, top, width, height}.S5HVoW_floatHeader{height:34px;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;flex:none;align-items:center;gap:4px;padding:0 4px 0 10px;display:flex}.S5HVoW_floatWindowDragging .S5HVoW_floatHeader{cursor:grabbing}.S5HVoW_floatTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.S5HVoW_floatClose{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.S5HVoW_floatClose:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_floatContent{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden}.S5HVoW_floatResize{z-index:2;cursor:nwse-resize;touch-action:none;width:14px;height:14px;position:absolute;bottom:0;right:0}.S5HVoW_floatResize:hover{background:var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_pane[data-dsh-float-dock-over]{outline:2px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-2px}.S5HVoW_floatDropHint{z-index:46;pointer-events:none;border:2px dashed var(--dsw-alias-interactive-bg-hover-accent);background:color-mix(in srgb, var(--dsw-alias-interactive-bg-hover-accent) 12%, transparent);border-radius:8px;justify-content:center;align-items:center;display:flex;position:absolute}.S5HVoW_floatDropHintLabel{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:4px 12px}.S5HVoW_toggleCluster,.S5HVoW_toggleButton,.S5HVoW_tabBar,.S5HVoW_floatHeader{-webkit-app-region:no-drag}body[data-dsh-title-bar-compat] .S5HVoW_toggleCluster{top:calc(var(--dsh-title-bar-strip,40px) + 3px)}body[data-dsh-title-bar-compat] .S5HVoW_panel{padding-top:var(--dsh-title-bar-strip,40px)}.S5HVoW_iconButton{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.S5HVoW_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_iconButton:disabled{opacity:.4;cursor:default}.S5HVoW_workbench,.S5HVoW_split{flex:1;min-width:0;min-height:0;display:flex}.S5HVoW_splitRow{flex-direction:row}.S5HVoW_splitCol{flex-direction:column}.S5HVoW_splitChild{display:flex;position:relative;overflow:hidden}.S5HVoW_divider{z-index:3;touch-action:none;flex:none;position:relative}.S5HVoW_dividerRow:after,.S5HVoW_dividerCol:after{content:\"\";background:var(--dsw-alias-border-l2);transition:background var(--ds-transition-duration-slow) var(--ds-ease-in-out);position:absolute}.S5HVoW_dividerRow{cursor:col-resize;width:7px;margin:0 -2px}.S5HVoW_dividerRow:after{width:1px;top:0;bottom:0;left:50%;transform:translate(-50%)}.S5HVoW_dividerCol{cursor:row-resize;height:7px;margin:-2px 0}.S5HVoW_dividerCol:after{height:1px;top:50%;left:0;right:0;transform:translateY(-50%)}.S5HVoW_divider:hover:after,.S5HVoW_dividerActive:after{background:var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_pane{background:var(--dsw-alias-bg-base);flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;position:relative}.S5HVoW_paneDrop{outline:1px solid var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}.S5HVoW_dropOverlay{z-index:6;pointer-events:none;background:var(--dsw-alias-interactive-bg-hover-accent);opacity:.5;position:absolute}.S5HVoW_dropLeft{width:25%;top:0;bottom:0;left:0}.S5HVoW_dropRight{width:25%;top:0;bottom:0;right:0}.S5HVoW_dropUp{height:25%;top:0;left:0;right:0}.S5HVoW_dropDown{height:25%;bottom:0;left:0;right:0}.S5HVoW_dropCenter{outline:2px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-2px;background:0 0;inset:25%}.S5HVoW_paneContent{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.S5HVoW_paneTab{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_paneTabHidden{display:none}.S5HVoW_paneEmptyCards{flex:1;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));align-content:start;gap:8px;min-height:0;padding:12px;display:grid;overflow:hidden}.S5HVoW_paneCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-strong-12);cursor:pointer;text-align:center;border-radius:8px;flex-direction:column;justify-content:center;align-items:center;gap:6px;padding:12px 8px;display:flex}.S5HVoW_paneCard:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.S5HVoW_paneCard:disabled{opacity:.45;cursor:default}.S5HVoW_tabBar{border-bottom:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);flex:none;align-items:stretch;height:34px;display:flex}.S5HVoW_tabBarDrop{outline:1px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}.S5HVoW_tabList{scrollbar-width:none;flex:1;min-width:0;display:flex;overflow-x:auto}.S5HVoW_tabList::-webkit-scrollbar{display:none}.S5HVoW_tab{min-width:64px;max-width:160px;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-secondary);border-right:1px solid var(--dsw-alias-border-l1);cursor:pointer;user-select:none;background:0 0;flex:none;align-items:center;gap:4px;padding:0 4px 0 10px;display:flex}.S5HVoW_tab:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_tabActive{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-active)}.S5HVoW_tabTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.S5HVoW_tabBadge{min-width:16px;height:15px;font:var(--dsw-font-xxxs-strong-11);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-brand-primary);border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0 4px;display:inline-flex}.S5HVoW_tabClose{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.S5HVoW_tabClose:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_tabBarPlus{background:var(--dsw-alias-bg-layer-1);width:22px;height:22px;color:var(--dsw-alias-label-tertiary);cursor:pointer;border:none;border-radius:5px;flex:none;justify-content:center;align-self:center;align-items:center;margin:0 6px;padding:0;display:inline-flex;position:sticky;right:0}.S5HVoW_tabBarPlus:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_pinnedTab{color:var(--dsw-alias-label-tertiary);font-style:italic}.S5HVoW_pinnedTab:hover{color:var(--dsw-alias-label-secondary)}.S5HVoW_explorer{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_explorerHeader{flex:none;justify-content:space-between;align-items:center;gap:8px;height:36px;padding:0 8px 0 12px;display:flex}.S5HVoW_explorerRoot{font:var(--dsw-font-s-14);color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_explorerBody{flex:1;min-height:0;padding:4px 8px 8px;overflow:hidden auto}.S5HVoW_explorerRow{box-sizing:border-box;width:100%;max-width:100%;height:34px;font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;white-space:nowrap;animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);background:0 0;border:none;border-radius:8px;align-items:center;gap:6px;padding:0 8px;display:flex}.S5HVoW_explorerRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_explorerRowRevealed{background:color-mix(in srgb, var(--dsw-alias-interactive-bg-hover-accent) 18%, transparent);box-shadow:inset 2px 0 0 var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_explorerDir{font:var(--dsw-font-s-strong-14)}.S5HVoW_explorerHidden{opacity:.45}.S5HVoW_explorerSymlink{color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_explorerBroken .S5HVoW_explorerName{color:var(--dsw-alias-state-error-primary)}.S5HVoW_explorerName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.S5HVoW_explorerRef{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);height:20px;color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxxs-strong-11);cursor:pointer;border-radius:999px;flex:none;align-items:center;padding:0 8px;display:none}.S5HVoW_explorerRef:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_explorerRow:hover .S5HVoW_explorerRef,.S5HVoW_explorerRow:focus-within .S5HVoW_explorerRef{display:inline-flex}.S5HVoW_explorerCopied{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_explorerError{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);cursor:default}@keyframes S5HVoW_dsh-row-in{0%{opacity:0}}.S5HVoW_explorerEmpty{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);text-align:center;padding:16px}.S5HVoW_explorerRowDropTarget{background:var(--dsw-alias-interactive-bg-hover);outline:1px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}.S5HVoW_uploadDropZone{z-index:1001;pointer-events:none;border:2px dashed var(--dsw-alias-interactive-bg-hover-accent);box-shadow:0 0 0 200vmax var(--dsw-alias-bg-mask-drop);animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);border-radius:10px;justify-content:center;align-items:flex-start;padding:12px;display:flex;position:fixed}.S5HVoW_uploadDropHero{flex-direction:column;align-items:center;gap:10px;max-width:100%;padding-top:8px;display:flex}.S5HVoW_uploadDropZonePill{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-width:100%;box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-strong-12);border-radius:999px;align-items:center;gap:6px;padding:6px 12px;display:flex}.S5HVoW_uploadDropZoneText{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.S5HVoW_uploadDropChatHint{z-index:1002;pointer-events:none;animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;top:0;bottom:0;left:0}.S5HVoW_uploadDropChatCard{text-align:center;max-width:100%;color:var(--dsw-alias-label-primary);font:var(--dsw-font-s-strong-14);flex-direction:column;align-items:center;gap:12px;display:flex}.S5HVoW_uploadOverlay{z-index:30;background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.S5HVoW_uploadOverlayCard{border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-alias-bg-layer-2);min-width:280px;max-width:min(420px,100% - 48px);box-shadow:var(--dsw-shadow-lv3);border-radius:24px;flex-direction:column;gap:12px;padding:20px 24px;display:flex}.S5HVoW_uploadOverlayTitle{font:var(--dsw-font-s-strong-14);color:var(--dsw-alias-label-primary);align-items:center;gap:8px;display:flex}.S5HVoW_uploadOverlayTitle>svg{flex:none}.S5HVoW_uploadOverlayTitle>span{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}.S5HVoW_uploadOverlayProgress{background:var(--dsw-alias-border-l2);border-radius:3px;height:6px;overflow:hidden}.S5HVoW_uploadOverlayProgressFill{background:var(--dsw-alias-interactive-bg-hover-accent);height:100%;transition:width .15s var(--ds-ease-in-out);border-radius:3px}.S5HVoW_uploadOverlayStatus{min-height:1em;font:var(--dsw-font-xxs-12);font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.S5HVoW_uploadOverlayCancel{border:1px solid var(--dsw-alias-border-l2);height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-strong-12);cursor:pointer;background:0 0;border-radius:8px;align-self:flex-end;padding:0 14px}.S5HVoW_uploadOverlayCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l2)}.S5HVoW_uploadOverlayCancel:disabled{opacity:.4;cursor:default}.S5HVoW_editor{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_editorHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:6px;padding:6px 8px;display:flex}.S5HVoW_editorTitle{min-width:0;font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.S5HVoW_editorPathInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 10px}.S5HVoW_editorPathInput:focus{border-color:var(--dsw-alias-border-l2);outline:none}.S5HVoW_editorTreeToggleActive{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-active)}.S5HVoW_editorBody{flex:1;min-height:0;display:flex}.S5HVoW_editorMain{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.S5HVoW_editorTreeDock{border-left:1px solid var(--dsw-alias-border-l1);flex:none;min-height:0;display:flex;position:relative}.S5HVoW_editorTreeResize{cursor:col-resize;touch-action:none;z-index:3;width:6px;position:absolute;top:0;bottom:0;left:0}.S5HVoW_editorTreeResize:hover{background:var(--dsw-alias-border-l2)}.S5HVoW_editorTreePanel{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;position:relative}.S5HVoW_editorTreePanelFull{flex:1}.S5HVoW_editorTreeSearch{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:6px;padding:6px 8px;display:flex}.S5HVoW_editorSearchInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;height:26px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 10px}.S5HVoW_editorSearchInput:focus{border-color:var(--dsw-alias-border-l2);outline:none}.S5HVoW_editorSearchHint{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);padding:8px 12px}.S5HVoW_editorSearchResult{width:100%;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);text-align:left;cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:none;border-radius:6px;padding:4px 8px;display:block;overflow:hidden}.S5HVoW_editorSearchResult:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_editorStatus{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary)}.S5HVoW_editorStatusError{color:var(--dsw-alias-state-error-primary)}.S5HVoW_dirtyDot{background:var(--dsw-alias-state-warn-primary);border-radius:50%;flex:none;width:7px;height:7px}.S5HVoW_editorPlaceholder{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;padding:16px;display:flex}.S5HVoW_orphanedType{opacity:.7;overflow-wrap:anywhere;margin-top:8px;font-size:12px;display:block}.S5HVoW_editorBinary{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;padding:24px 16px;display:flex}.S5HVoW_editorBinaryNotice{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary)}.S5HVoW_editorDownloadLink{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-strong-12);cursor:pointer;transition:background var(--ds-transition-duration-slow) var(--ds-ease-in-out), border-color var(--ds-transition-duration-slow) var(--ds-ease-in-out);border-radius:6px;align-items:center;gap:6px;padding:6px 14px;text-decoration:none;display:inline-flex}.S5HVoW_editorDownloadLink:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l2)}.S5HVoW_editorError{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);padding:12px 16px}.S5HVoW_editorBanner{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex:none;padding:4px 8px}.S5HVoW_sandboxStatus{font:var(--dsw-font-xxxs-11);flex:none;align-items:center;gap:8px;padding:4px 10px;display:flex}.S5HVoW_sandboxStatusOn{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border-bottom:1px solid var(--dsw-alias-border-l1)}.S5HVoW_sandboxStatusOff{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);border-bottom:1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 45%, transparent)}.S5HVoW_sandboxDot{background:var(--dsw-alias-state-success-primary);border-radius:50%;flex:none;width:6px;height:6px}.S5HVoW_sandboxStatusOff .S5HVoW_sandboxDot{background:var(--dsw-alias-state-error-primary)}.S5HVoW_sandboxStatusText{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.S5HVoW_sandboxAction{border:1px solid var(--dsw-alias-border-l2);font:inherit;color:inherit;cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:2px 8px}.S5HVoW_sandboxAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_editorHtml{background:var(--dsw-alias-bg-base);border:none;flex:1;width:100%;min-height:0}.S5HVoW_browser{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_browserBar{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:4px;padding:6px 8px;display:flex}.S5HVoW_browserInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 10px}.S5HVoW_browserInput:focus{border-color:var(--dsw-alias-border-l2);outline:none}.S5HVoW_browserMessage{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex:none;padding:4px 12px}.S5HVoW_browserFrame{background:var(--dsw-alias-bg-base);border:none;flex:1;width:100%;min-height:0}.S5HVoW_browserStart{text-align:center;min-height:0;font:var(--dsw-font-xs-13);color:var(--dsw-alias-label-tertiary);flex:1;justify-content:center;align-items:center;padding:20px;display:flex}.S5HVoW_browserBlocked{text-align:center;min-height:0;color:var(--dsw-alias-state-warn-primary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:6px;padding:24px;display:flex}.S5HVoW_browserBlockedTitle{font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-primary)}.S5HVoW_browserBlockedDesc{max-width:280px;font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-secondary)}.S5HVoW_browserBlockedActions{gap:8px;margin-top:6px;display:flex}.S5HVoW_browserBlockedButton{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxxs-11);cursor:pointer;border-radius:6px;padding:4px 12px}.S5HVoW_browserBlockedButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_editorCm{background:0 0;flex:1;min-height:0;overflow:hidden}.S5HVoW_editorCmHidden{display:none}.S5HVoW_editorCm .cm-editor{height:100%}.S5HVoW_editorCm .cm-scroller{padding:12px 16px}.S5HVoW_editorCm .cm-editor.cm-focused{outline:none}.S5HVoW_editorModeToggle{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;flex:none;align-items:center;gap:2px;padding:2px;display:inline-flex}.S5HVoW_editorModeButton{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxxs-11);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:2px 8px}.S5HVoW_editorModeButton:hover{color:var(--dsw-alias-label-primary)}.S5HVoW_editorModeActive{background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary)}.S5HVoW_editorImageWrap{flex:1;justify-content:center;align-items:center;min-height:0;padding:12px;display:flex;overflow:auto}.S5HVoW_editorImage{object-fit:contain;max-width:100%;max-height:100%}.S5HVoW_editorMd{min-height:0;font:var(--dsw-font-xs-13);flex:1;padding:12px 16px;overflow-y:auto}.S5HVoW_mermaidWrap{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);border-radius:6px;margin:6px 0;overflow:hidden}.S5HVoW_mermaidHeader{border-bottom:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);justify-content:space-between;align-items:center;gap:6px;padding:4px 8px;display:flex}.S5HVoW_mermaidInfo{font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-label-tertiary)}.S5HVoW_mermaidCopy{height:20px;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxxs-11);cursor:pointer;background:0 0;border:none;border-radius:4px;align-items:center;gap:4px;padding:0 6px;display:inline-flex}.S5HVoW_mermaidCopy:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_mermaidBody{cursor:zoom-in;justify-content:center;padding:10px;display:flex;overflow:auto}.S5HVoW_mermaidBody svg{max-width:100%;height:auto}.S5HVoW_mermaidError{border-bottom:1px solid var(--dsw-alias-border-l1);color:var(--dsw-alias-state-error-primary);font:var(--dsw-font-xxxs-11);padding:6px 10px}.S5HVoW_mermaidCode{font:var(--dsw-font-xxxs-11);margin:0;padding:8px 10px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;overflow:auto}.S5HVoW_mermaidMarkdown .md-code-block[data-mermaid-processed]{display:contents}.S5HVoW_mermaidModal{z-index:1000;background:var(--dsw-alias-bg-mask-1);backdrop-filter:blur(2px);flex-direction:column;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.S5HVoW_mermaidModalToolbar{z-index:10;gap:8px;display:flex;position:absolute;top:16px;right:16px}.S5HVoW_mermaidModalButton{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:36px;height:36px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xs-strong-13);cursor:pointer;border-radius:8px;justify-content:center;align-items:center;display:inline-flex}.S5HVoW_mermaidModalButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_mermaidModalStage{justify-content:center;align-items:center;width:90vw;height:80vh;display:flex;position:relative;overflow:hidden}.S5HVoW_mermaidModalStage svg{cursor:grab;transform-origin:50%;user-select:none;-webkit-user-drag:none;background:var(--dsw-alias-bg-layer-1);border-radius:12px;max-width:none;max-height:none;padding:16px}.S5HVoW_mermaidModalStage svg:active{cursor:grabbing}.S5HVoW_mermaidModalHint{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxxs-11);pointer-events:none;position:absolute;bottom:16px;left:50%;transform:translate(-50%)}.S5HVoW_selectionPopup{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxxs-strong-11);white-space:nowrap;cursor:pointer;border-radius:6px;align-items:center;padding:0 10px;display:inline-flex;position:fixed;transform:translate(-50%,calc(-100% - 8px))}.S5HVoW_selectionPopup:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_editorPdf{background:var(--dsw-alias-bg-base);flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_editorPdfToolbar{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;justify-content:flex-end;padding:6px 8px;display:flex}.S5HVoW_editorPdfStage{flex:1;min-height:0;display:flex;position:relative}.S5HVoW_editorPdfFrame{background:var(--dsw-alias-bg-base);border:none;flex:1;width:100%;min-height:0}.S5HVoW_editorPdfFrameBlocked{pointer-events:none}.S5HVoW_editorPdfDragShield{z-index:4;pointer-events:none;background:0 0;position:absolute;inset:0}.S5HVoW_editorPdfDragShieldActive{pointer-events:auto}body[data-dsh-tab-dragging] .S5HVoW_editorPdfFrame{pointer-events:none!important}body[data-dsh-tab-dragging] .S5HVoW_editorPdfDragShield{pointer-events:auto!important}.S5HVoW_terminalWrap{background:var(--dsw-alias-bg-base);flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.S5HVoW_terminal{flex:1;min-height:0;padding:6px 4px 6px 8px}.S5HVoW_terminal .xterm{height:100%}.S5HVoW_terminalBanner{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex-wrap:wrap;flex:none;align-items:center;gap:8px;padding:3px 10px;display:flex}.S5HVoW_terminalBannerUrl{word-break:break-all;opacity:.85;flex-basis:100%;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.S5HVoW_boundaryError{z-index:50;background:var(--dsw-alias-bg-layer-1);border-left:1px solid var(--dsw-alias-border-l2);font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);flex-direction:column;align-items:flex-start;gap:8px;padding:16px;display:flex;position:fixed;top:0;bottom:0;right:0;overflow:auto}.S5HVoW_terminalRetry{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxxs-strong-11);cursor:pointer;border-radius:999px;flex:none;padding:1px 8px}.S5HVoW_terminalRetry:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_terminalDepsBanner{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex-direction:column;flex:none;gap:6px;padding:10px;display:flex}.S5HVoW_terminalDepsTitle{font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-state-warn-primary)}.S5HVoW_terminalDepsHint{opacity:.9}.S5HVoW_terminalDepsCommandRow{align-items:flex-start;gap:8px;display:flex}.S5HVoW_terminalRepairCommand{white-space:pre-wrap;word-break:break-all;user-select:text;min-width:0;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:4px;flex:1;max-height:160px;margin:0;padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.5;overflow:auto}.S5HVoW_terminalDepsNote{opacity:.85}.S5HVoW_terminalDepsActions{align-items:center;gap:8px;display:flex}.S5HVoW_tabBoundaryError{min-height:0;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);flex-direction:column;flex:1;align-items:flex-start;gap:8px;padding:12px 16px;display:flex;overflow:auto}.S5HVoW_git{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden auto}.S5HVoW_gitHeader{flex:none;align-items:center;gap:8px;height:36px;padding:0 8px 0 12px;display:flex}.S5HVoW_gitWorktreeRow{flex:none;align-items:center;gap:8px;padding:6px 8px 0 12px;display:flex}.S5HVoW_gitWorktreeLabel{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxxs-11);flex:none}.S5HVoW_gitBranchSelect{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);min-width:0;height:26px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 6px}.S5HVoW_gitSection{border-top:1px solid var(--dsw-alias-border-l1)}.S5HVoW_gitSectionHeader{font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-label-tertiary);text-transform:uppercase;justify-content:space-between;align-items:center;padding:6px 12px 4px;display:flex}.S5HVoW_gitLink{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:none;padding:0}.S5HVoW_gitLink:hover:not(:disabled){text-decoration:underline}.S5HVoW_gitLink:disabled{opacity:.4;cursor:default}.S5HVoW_gitRow{min-height:34px;animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);border-radius:8px;align-items:center;gap:6px;margin:0 6px;padding:0 8px;display:flex}.S5HVoW_gitRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitRowSelected{background:var(--dsw-alias-interactive-bg-active)}.S5HVoW_gitRowMain{cursor:pointer;text-align:left;background:0 0;border:none;flex:1;align-items:center;gap:8px;min-width:0;padding:3px 0;display:flex}.S5HVoW_gitBadge{width:20px;height:16px;font:var(--dsw-font-xxxs-strong-11);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;justify-content:center;align-items:center;display:inline-flex}.S5HVoW_gitName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.S5HVoW_gitEmpty{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);padding:4px 12px 8px}.S5HVoW_gitPlaceholder{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);text-align:center;padding:16px}.S5HVoW_gitError{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);white-space:pre-wrap;padding:8px 12px}.S5HVoW_gitDiff{border-top:1px solid var(--dsw-alias-border-l1);padding:8px}.S5HVoW_gitDiffTab{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden auto}.S5HVoW_gitDiffTabHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:8px;height:36px;padding:0 8px 0 12px;display:flex}.S5HVoW_gitDiffTabTitle{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.S5HVoW_gitDiffFile{width:100%;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:baseline;gap:6px;padding:8px 2px 2px;display:flex}.S5HVoW_gitDiffFile:disabled{cursor:default}.S5HVoW_gitDiffFile:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitDiffFileChevron{color:var(--dsw-alias-label-tertiary);flex:none;transform:rotate(0)}.S5HVoW_gitDiffFileChevronExpanded{transform:rotate(90deg)}.S5HVoW_gitDiffFilePath{font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_gitDiffFileOld{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:none;max-width:40%;overflow:hidden}.S5HVoW_gitDiffFileTag{border:1px solid var(--dsw-alias-border-l2);font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:0 6px}.S5HVoW_gitDiffHunk{font:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-tertiary);gap:8px;padding:3px 2px;display:flex}.S5HVoW_gitDiffHunkHeader{color:var(--dsw-alias-label-secondary);flex:none}.S5HVoW_gitDiffHunkSection{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_gitDiffLine{font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap;overflow-wrap:anywhere;align-items:stretch;min-width:0;line-height:20px;display:flex}.S5HVoW_gitDiffNum{text-align:right;width:36px;color:var(--dsw-alias-label-tertiary);user-select:none;flex:none;padding-right:8px}.S5HVoW_gitDiffCode{flex:1;min-width:0;overflow:visible}.S5HVoW_gitDiffCtx{color:var(--dsw-alias-label-primary)}.S5HVoW_gitDiffDel{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.S5HVoW_gitDiffAdd{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent)}.S5HVoW_gitDiffMeta{padding-left:2px}.S5HVoW_gitDiffMetaText{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);font-style:italic}.S5HVoW_gitDiffExpand{width:100%;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-brand-primary);cursor:pointer;text-align:center;background:0 0;border:none;margin:4px 0;display:block}.S5HVoW_gitDiffExpand:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitConfirmDesc{font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);white-space:pre-wrap;margin:0}.S5HVoW_gitCommit{border-top:1px solid var(--dsw-alias-border-l1);align-items:center;gap:6px;padding:8px 12px;display:flex}.S5HVoW_gitCommitInput{flex:1;min-width:0}.S5HVoW_gitCommitButton{background:var(--dsw-alias-button-primary-fill);height:26px;color:var(--dsw-alias-label-primary-inverted);font:var(--dsw-font-xxs-strong-12);cursor:pointer;border:none;border-radius:6px;flex:none;padding:0 12px}.S5HVoW_gitCommitButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.S5HVoW_gitCommitButton:disabled{opacity:.45;cursor:default}.S5HVoW_gitLogRow{cursor:pointer;border-radius:8px;flex-direction:column;gap:2px;padding:5px 12px;display:flex}.S5HVoW_gitLogRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitLogLine1{align-items:baseline;gap:8px;min-width:0;display:flex}.S5HVoW_gitLogHash{font:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_gitLogLine2{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;display:flex}.S5HVoW_gitLogRef{border:1px solid var(--dsw-alias-border-l2);font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-brand-primary);white-space:nowrap;border-radius:999px;flex:none;padding:0 5px}.S5HVoW_gitLogSubject{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.S5HVoW_gitLogMeta{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary)}.S5HVoW_gitLogMore{border:1px solid var(--dsw-alias-border-l2);width:calc(100% - 24px);font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:6px;margin:4px 12px 8px;padding:6px 0;display:block}.S5HVoW_gitLogMore:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_gitLogMore:disabled{opacity:.5;cursor:default}.S5HVoW_producedRow{flex-wrap:wrap;align-items:center;gap:8px;padding:4px 0;display:flex}.S5HVoW_producedLabel{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary)}.S5HVoW_producedChip{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-width:200px;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-12);cursor:pointer;border-radius:999px;align-items:center;gap:4px;padding:2px 8px;display:inline-flex;overflow:hidden}.S5HVoW_producedChip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_producedChip span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_producedMore{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary)}.S5HVoW_toggleButton:focus-visible,.S5HVoW_iconButton:focus-visible,.S5HVoW_tab:focus-visible,.S5HVoW_tabClose:focus-visible,.S5HVoW_tabBarPlus:focus-visible,.S5HVoW_paneCard:focus-visible,.S5HVoW_explorerRow:focus-visible,.S5HVoW_explorerRef:focus-visible,.S5HVoW_gitRowMain:focus-visible,.S5HVoW_gitLink:focus-visible,.S5HVoW_gitCommitButton:focus-visible,.S5HVoW_gitLogRow:focus-visible,.S5HVoW_gitLogMore:focus-visible,.S5HVoW_gitDiffFile:focus-visible,.S5HVoW_gitDiffExpand:focus-visible,.S5HVoW_terminalRetry:focus-visible,.S5HVoW_editorModeButton:focus-visible,.S5HVoW_editorDownloadLink:focus-visible,.S5HVoW_editorPptxButton:focus-visible,.S5HVoW_editorDocxZoomRange:focus-visible{outline:2px solid var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}@media (prefers-reduced-motion:reduce){.S5HVoW_panel,.S5HVoW_panelHidden,.S5HVoW_toggleCluster,.S5HVoW_toggleButton,.S5HVoW_tab,.S5HVoW_tabBarPlus,.S5HVoW_paneCard,.S5HVoW_explorerRow,.S5HVoW_gitRow,.S5HVoW_divider,.S5HVoW_dividerRow:after,.S5HVoW_dividerCol:after{transition:none;animation:none}}@media (width<=767px){.S5HVoW_panel:not(.S5HVoW_panelHidden) .S5HVoW_tabBar{padding-right:40px}.S5HVoW_tab{min-width:48px;max-width:128px}}.S5HVoW_openWithLabel{align-items:center;gap:8px;width:100%;min-width:0;display:flex}.S5HVoW_openWithName{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}.S5HVoW_openWithChevron{color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_openWithPin{width:20px;height:20px;color:var(--dsw-alias-label-tertiary);cursor:pointer;border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.S5HVoW_openWithPin:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_openWithPinActive{color:var(--dsw-alias-state-business-primary)}.S5HVoW_editorHtmlBlock{margin:8px 0}.S5HVoW_editorHtmlBlock img,.S5HVoW_editorHtmlBlock video{max-width:100%}.S5HVoW_editorHtmlBlock details{margin:4px 0;padding:4px 0}.S5HVoW_editorHtmlBlock summary{cursor:pointer}.S5HVoW_tocBar{z-index:3;pointer-events:none;justify-content:flex-end;height:0;display:flex;position:sticky;top:0}.S5HVoW_tocButton{pointer-events:auto;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);width:26px;height:26px;color:var(--dsw-alias-label-secondary);cursor:pointer;border-radius:6px;justify-content:center;align-items:center;margin:4px 2px 0 0;padding:0;display:inline-flex}.S5HVoW_tocButton:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_tocPanel{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);width:min(300px,82%);max-height:60vh;box-shadow:var(--dsw-shadow-lv2);pointer-events:auto;border-radius:8px;flex-direction:column;padding:4px;display:flex;position:absolute;top:32px;right:2px;overflow-y:auto}.S5HVoW_tocItem{min-width:0;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-12);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:6px;align-items:baseline;gap:8px;padding:4px 8px;display:flex}.S5HVoW_tocItem:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_tocItem[data-level=\"2\"]{padding-left:18px}.S5HVoW_tocItem[data-level=\"3\"]{padding-left:28px}.S5HVoW_tocItem[data-level=\"4\"]{padding-left:38px}.S5HVoW_tocItem[data-level=\"5\"]{padding-left:48px}.S5HVoW_tocItem[data-level=\"6\"]{padding-left:58px}.S5HVoW_tocItemLevel{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_tocItemText{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}@keyframes S5HVoW_dsh-toc-flash{0%,60%{background:var(--dsw-alias-interactive-bg-hover)}to{background:0 0}}.S5HVoW_tocFlash{border-radius:4px;animation:1.2s ease-out S5HVoW_dsh-toc-flash}";
|
|
9895
|
+
const css$4 = "[data-dsh-panel-host]{z-index:25;pointer-events:none;position:fixed;inset:0;overflow:hidden}[data-dsh-panel-host][data-dsh-panel-host-degraded]{position:absolute;top:0;left:0}.S5HVoW_toggleCluster{top:calc(3px + env(safe-area-inset-top));z-index:45;pointer-events:auto;flex-direction:row;gap:4px;display:flex;position:absolute;right:10px}.S5HVoW_panel:not(.S5HVoW_panelHidden) .S5HVoW_tabBar{padding-right:72px}.S5HVoW_toggleButton{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;transition:background var(--ds-transition-duration-slow) var(--ds-ease-in-out), color var(--ds-transition-duration-slow) var(--ds-ease-in-out);background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;display:flex}.S5HVoW_toggleButton:hover:not(:disabled):not([aria-disabled=true]){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_toggleButton:disabled,.S5HVoW_toggleButton[aria-disabled=true]{opacity:.4;cursor:default}.S5HVoW_panel{box-sizing:border-box;z-index:40;pointer-events:auto;background:var(--dsw-alias-bg-layer-1);border-left:1px solid var(--dsw-alias-border-l2);padding-bottom:env(safe-area-inset-bottom);transition:transform var(--ds-transition-duration-slow) var(--ds-ease-in-out), width var(--ds-transition-duration-slow) var(--ds-ease-in-out);flex-direction:column;display:flex;position:absolute;top:0;bottom:0;right:0}.S5HVoW_panelHidden{pointer-events:none;visibility:hidden;transition:transform var(--ds-transition-duration-slow) var(--ds-ease-in-out), width var(--ds-transition-duration-slow) var(--ds-ease-in-out), visibility 0s linear var(--ds-transition-duration-slow);transform:translate(102%)}.S5HVoW_panel[data-dragging]{transition:none}.S5HVoW_panelResize{cursor:col-resize;z-index:2;touch-action:none;width:8px;position:absolute;top:0;bottom:0;left:-4px}.S5HVoW_panelResizeActive{background:var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_panelBody{flex:1;min-width:0;min-height:0;display:flex}.S5HVoW_panel{contain:layout style}body[data-dsh-sidebar-dragging] .S5HVoW_panel{will-change:transform}.S5HVoW_floatWindow{z-index:42;pointer-events:auto;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);box-shadow:var(--dsw-shadow-lv3);contain:layout style;border-radius:8px;flex-direction:column;display:flex;position:absolute;overflow:hidden}.S5HVoW_floatWindowDragging{will-change:left, top, width, height}.S5HVoW_floatHeader{height:34px;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border-bottom:1px solid var(--dsw-alias-border-l1);cursor:grab;user-select:none;flex:none;align-items:center;gap:4px;padding:0 4px 0 10px;display:flex}.S5HVoW_floatWindowDragging .S5HVoW_floatHeader{cursor:grabbing}.S5HVoW_floatTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.S5HVoW_floatClose{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.S5HVoW_floatClose:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_floatContent{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden}.S5HVoW_floatResize{z-index:2;cursor:nwse-resize;touch-action:none;width:14px;height:14px;position:absolute;bottom:0;right:0}.S5HVoW_floatResize:hover{background:var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_pane[data-dsh-float-dock-over]{outline:2px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-2px}.S5HVoW_floatDropHint{z-index:46;pointer-events:none;border:2px dashed var(--dsw-alias-interactive-bg-hover-accent);background:color-mix(in srgb, var(--dsw-alias-interactive-bg-hover-accent) 12%, transparent);border-radius:8px;justify-content:center;align-items:center;display:flex;position:absolute}.S5HVoW_floatDropHintLabel{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:4px 12px}.S5HVoW_toggleCluster,.S5HVoW_toggleButton,.S5HVoW_tabBar,.S5HVoW_floatHeader{-webkit-app-region:no-drag}body[data-dsh-title-bar-compat] .S5HVoW_toggleCluster{top:calc(var(--dsh-title-bar-strip,40px) + 3px)}body[data-dsh-title-bar-compat] .S5HVoW_panel{padding-top:var(--dsh-title-bar-strip,40px)}.S5HVoW_iconButton{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;border-radius:50%;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.S5HVoW_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_iconButton:disabled{opacity:.4;cursor:default}.S5HVoW_workbench,.S5HVoW_split{flex:1;min-width:0;min-height:0;display:flex}.S5HVoW_splitRow{flex-direction:row}.S5HVoW_splitCol{flex-direction:column}.S5HVoW_splitChild{display:flex;position:relative;overflow:hidden}.S5HVoW_divider{z-index:3;touch-action:none;flex:none;position:relative}.S5HVoW_dividerRow:after,.S5HVoW_dividerCol:after{content:\"\";background:var(--dsw-alias-border-l2);transition:background var(--ds-transition-duration-slow) var(--ds-ease-in-out);position:absolute}.S5HVoW_dividerRow{cursor:col-resize;width:7px;margin:0 -2px}.S5HVoW_dividerRow:after{width:1px;top:0;bottom:0;left:50%;transform:translate(-50%)}.S5HVoW_dividerCol{cursor:row-resize;height:7px;margin:-2px 0}.S5HVoW_dividerCol:after{height:1px;top:50%;left:0;right:0;transform:translateY(-50%)}.S5HVoW_divider:hover:after,.S5HVoW_dividerActive:after{background:var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_pane{background:var(--dsw-alias-bg-base);flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;position:relative}.S5HVoW_paneDrop{outline:1px solid var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}.S5HVoW_dropOverlay{z-index:6;pointer-events:none;background:var(--dsw-alias-interactive-bg-hover-accent);opacity:.5;position:absolute}.S5HVoW_dropLeft{width:25%;top:0;bottom:0;left:0}.S5HVoW_dropRight{width:25%;top:0;bottom:0;right:0}.S5HVoW_dropUp{height:25%;top:0;left:0;right:0}.S5HVoW_dropDown{height:25%;bottom:0;left:0;right:0}.S5HVoW_dropCenter{outline:2px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-2px;background:0 0;inset:25%}.S5HVoW_paneContent{flex-direction:column;flex:1;min-height:0;display:flex;overflow:hidden}.S5HVoW_paneTab{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_paneTabHidden{display:none}.S5HVoW_paneEmptyCards{flex:1;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));align-content:start;gap:8px;min-height:0;padding:12px;display:grid;overflow:hidden}.S5HVoW_paneCard{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-strong-12);cursor:pointer;text-align:center;border-radius:8px;flex-direction:column;justify-content:center;align-items:center;gap:6px;padding:12px 8px;display:flex}.S5HVoW_paneCard:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l2)}.S5HVoW_paneCard:disabled{opacity:.45;cursor:default}.S5HVoW_tabBar{border-bottom:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);flex:none;align-items:stretch;height:34px;display:flex}.S5HVoW_tabBarDrop{outline:1px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}.S5HVoW_tabList{scrollbar-width:none;flex:1;min-width:0;display:flex;overflow-x:auto}.S5HVoW_tabList::-webkit-scrollbar{display:none}.S5HVoW_tab{min-width:64px;max-width:160px;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-secondary);border-right:1px solid var(--dsw-alias-border-l1);cursor:pointer;user-select:none;background:0 0;flex:none;align-items:center;gap:4px;padding:0 4px 0 10px;display:flex}.S5HVoW_tab:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_tabActive{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-active)}.S5HVoW_tabTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.S5HVoW_tabBadge{min-width:16px;height:15px;font:var(--dsw-font-xxxs-strong-11);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-brand-primary);border-radius:8px;flex:none;justify-content:center;align-items:center;padding:0 4px;display:inline-flex}.S5HVoW_tabClose{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:4px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.S5HVoW_tabClose:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_tabBarPlus{background:var(--dsw-alias-bg-layer-1);width:22px;height:22px;color:var(--dsw-alias-label-tertiary);cursor:pointer;border:none;border-radius:5px;flex:none;justify-content:center;align-self:center;align-items:center;margin:0 6px;padding:0;display:inline-flex;position:sticky;right:0}.S5HVoW_tabBarPlus:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_pinnedTab{color:var(--dsw-alias-label-tertiary);font-style:italic}.S5HVoW_pinnedTab:hover{color:var(--dsw-alias-label-secondary)}.S5HVoW_explorer{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_explorerHeader{flex:none;justify-content:space-between;align-items:center;gap:8px;height:36px;padding:0 8px 0 12px;display:flex}.S5HVoW_explorerRoot{font:var(--dsw-font-s-14);color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_explorerBody{flex:1;min-height:0;padding:4px 8px 8px;overflow:hidden auto}.S5HVoW_explorerRow{box-sizing:border-box;width:100%;max-width:100%;height:34px;font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;white-space:nowrap;animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);background:0 0;border:none;border-radius:8px;align-items:center;gap:6px;padding:0 8px;display:flex}.S5HVoW_explorerRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_explorerRowRevealed{background:color-mix(in srgb, var(--dsw-alias-interactive-bg-hover-accent) 18%, transparent);box-shadow:inset 2px 0 0 var(--dsw-alias-interactive-bg-hover-accent)}.S5HVoW_explorerDir{font:var(--dsw-font-s-strong-14)}.S5HVoW_explorerHidden{opacity:.45}.S5HVoW_explorerSymlink{color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_explorerBroken .S5HVoW_explorerName{color:var(--dsw-alias-state-error-primary)}.S5HVoW_explorerName{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.S5HVoW_explorerRef{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);height:20px;color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxxs-strong-11);cursor:pointer;border-radius:999px;flex:none;align-items:center;padding:0 8px;display:none}.S5HVoW_explorerRef:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_explorerRow:hover .S5HVoW_explorerRef,.S5HVoW_explorerRow:focus-within .S5HVoW_explorerRef{display:inline-flex}.S5HVoW_explorerCopied{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_explorerError{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);cursor:default}@keyframes S5HVoW_dsh-row-in{0%{opacity:0}}.S5HVoW_explorerEmpty{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);text-align:center;padding:16px}.S5HVoW_explorerRowDropTarget{background:var(--dsw-alias-interactive-bg-hover);outline:1px dashed var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}.S5HVoW_uploadDropZone{z-index:1001;pointer-events:none;border:2px dashed var(--dsw-alias-interactive-bg-hover-accent);box-shadow:0 0 0 200vmax var(--dsw-alias-bg-mask-drop);animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);border-radius:10px;justify-content:center;align-items:flex-start;padding:12px;display:flex;position:fixed}.S5HVoW_uploadDropHero{flex-direction:column;align-items:center;gap:10px;max-width:100%;padding-top:8px;display:flex}.S5HVoW_uploadDropZonePill{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-width:100%;box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-strong-12);border-radius:999px;align-items:center;gap:6px;padding:6px 12px;display:flex}.S5HVoW_uploadDropZoneText{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.S5HVoW_uploadDropChatHint{z-index:1002;pointer-events:none;animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;top:0;bottom:0;left:0}.S5HVoW_uploadDropChatCard{text-align:center;max-width:100%;color:var(--dsw-alias-label-primary);font:var(--dsw-font-s-strong-14);flex-direction:column;align-items:center;gap:12px;display:flex}.S5HVoW_uploadOverlay{z-index:30;background:var(--dsw-alias-bg-mask-1);backdrop-filter:var(--dsw-mask-blur);animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.S5HVoW_uploadOverlayCard{border:1px solid var(--dsw-alias-border-inverted);background:var(--dsw-alias-bg-layer-2);min-width:280px;max-width:min(420px,100% - 48px);box-shadow:var(--dsw-shadow-lv3);border-radius:24px;flex-direction:column;gap:12px;padding:20px 24px;display:flex}.S5HVoW_uploadOverlayTitle{font:var(--dsw-font-s-strong-14);color:var(--dsw-alias-label-primary);align-items:center;gap:8px;display:flex}.S5HVoW_uploadOverlayTitle>svg{flex:none}.S5HVoW_uploadOverlayTitle>span{white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}.S5HVoW_uploadOverlayProgress{background:var(--dsw-alias-border-l2);border-radius:3px;height:6px;overflow:hidden}.S5HVoW_uploadOverlayProgressFill{background:var(--dsw-alias-interactive-bg-hover-accent);height:100%;transition:width .15s var(--ds-ease-in-out);border-radius:3px}.S5HVoW_uploadOverlayStatus{min-height:1em;font:var(--dsw-font-xxs-12);font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-tertiary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.S5HVoW_uploadOverlayCancel{border:1px solid var(--dsw-alias-border-l2);height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-strong-12);cursor:pointer;background:0 0;border-radius:8px;align-self:flex-end;padding:0 14px}.S5HVoW_uploadOverlayCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l2)}.S5HVoW_uploadOverlayCancel:disabled{opacity:.4;cursor:default}.S5HVoW_editor{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_editorHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:6px;padding:6px 8px;display:flex}.S5HVoW_editorTitle{min-width:0;font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.S5HVoW_editorPathInput{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 10px}.S5HVoW_editorPathInput:focus{border-color:var(--dsw-alias-border-l2);outline:none}.S5HVoW_editorTreeToggleActive{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-active)}.S5HVoW_editorBody{flex:1;min-height:0;display:flex}.S5HVoW_editorMain{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex}.S5HVoW_editorTreeDock{border-left:1px solid var(--dsw-alias-border-l1);flex:none;min-height:0;display:flex;position:relative}.S5HVoW_editorTreeResize{cursor:col-resize;touch-action:none;z-index:3;width:6px;position:absolute;top:0;bottom:0;left:0}.S5HVoW_editorTreeResize:hover{background:var(--dsw-alias-border-l2)}.S5HVoW_editorTreePanel{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;position:relative}.S5HVoW_editorTreePanelFull{flex:1}.S5HVoW_editorTreeSearch{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:6px;padding:6px 8px;display:flex}.S5HVoW_editorSearchInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;height:26px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 10px}.S5HVoW_editorSearchInput:focus{border-color:var(--dsw-alias-border-l2);outline:none}.S5HVoW_editorSearchHint{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);padding:8px 12px}.S5HVoW_editorSearchResult{width:100%;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);text-align:left;cursor:pointer;text-overflow:ellipsis;white-space:nowrap;background:0 0;border:none;border-radius:6px;padding:4px 8px;display:block;overflow:hidden}.S5HVoW_editorSearchResult:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_editorStatus{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary)}.S5HVoW_editorStatusError{color:var(--dsw-alias-state-error-primary)}.S5HVoW_dirtyDot{background:var(--dsw-alias-state-warn-primary);border-radius:50%;flex:none;width:7px;height:7px}.S5HVoW_editorPlaceholder{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);text-align:center;flex:1;justify-content:center;align-items:center;padding:16px;display:flex}.S5HVoW_orphanedType{opacity:.7;overflow-wrap:anywhere;margin-top:8px;font-size:12px;display:block}.S5HVoW_editorBinary{text-align:center;flex-direction:column;flex:1;justify-content:center;align-items:center;gap:12px;padding:24px 16px;display:flex}.S5HVoW_editorBinaryNotice{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary)}.S5HVoW_editorDownloadLink{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-strong-12);cursor:pointer;transition:background var(--ds-transition-duration-slow) var(--ds-ease-in-out), border-color var(--ds-transition-duration-slow) var(--ds-ease-in-out);border-radius:6px;align-items:center;gap:6px;padding:6px 14px;text-decoration:none;display:inline-flex}.S5HVoW_editorDownloadLink:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l2)}.S5HVoW_editorError{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);padding:12px 16px}.S5HVoW_editorBanner{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex:none;padding:4px 8px}.S5HVoW_sandboxStatus{font:var(--dsw-font-xxxs-11);flex:none;align-items:center;gap:8px;padding:4px 10px;display:flex}.S5HVoW_sandboxStatusOn{color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border-bottom:1px solid var(--dsw-alias-border-l1)}.S5HVoW_sandboxStatusOff{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 10%, transparent);border-bottom:1px solid color-mix(in srgb, var(--dsw-alias-state-error-primary) 45%, transparent)}.S5HVoW_sandboxDot{background:var(--dsw-alias-state-success-primary);border-radius:50%;flex:none;width:6px;height:6px}.S5HVoW_sandboxStatusOff .S5HVoW_sandboxDot{background:var(--dsw-alias-state-error-primary)}.S5HVoW_sandboxStatusText{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.S5HVoW_sandboxAction{border:1px solid var(--dsw-alias-border-l2);font:inherit;color:inherit;cursor:pointer;background:0 0;border-radius:6px;flex:none;padding:2px 8px}.S5HVoW_sandboxAction:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_browser{flex-direction:column;flex:1;min-height:0;display:flex}.S5HVoW_browserBar{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:4px;padding:6px 8px;display:flex}.S5HVoW_browserInput{border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);min-width:0;height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 10px}.S5HVoW_browserInput:focus{border-color:var(--dsw-alias-border-l2);outline:none}.S5HVoW_browserMessage{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex:none;padding:4px 12px}.S5HVoW_browserFrame{background:var(--dsw-alias-bg-base);border:none;flex:1;width:100%;min-height:0}.S5HVoW_browserStart{text-align:center;min-height:0;font:var(--dsw-font-xs-13);color:var(--dsw-alias-label-tertiary);flex:1;justify-content:center;align-items:center;padding:20px;display:flex}.S5HVoW_browserBlocked{text-align:center;min-height:0;color:var(--dsw-alias-state-warn-primary);flex-direction:column;flex:1;justify-content:center;align-items:center;gap:6px;padding:24px;display:flex}.S5HVoW_browserBlockedTitle{font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-primary)}.S5HVoW_browserBlockedDesc{max-width:280px;font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-secondary)}.S5HVoW_browserBlockedActions{gap:8px;margin-top:6px;display:flex}.S5HVoW_browserBlockedButton{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxxs-11);cursor:pointer;border-radius:6px;padding:4px 12px}.S5HVoW_browserBlockedButton:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_editorCm{background:0 0;flex:1;min-height:0;overflow:hidden}.S5HVoW_editorCm .cm-editor{height:100%}.S5HVoW_editorCm .cm-scroller{padding:12px 16px}.S5HVoW_editorCm .cm-editor.cm-focused{outline:none}.S5HVoW_selectionPopup{z-index:60;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-2);height:28px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxxs-strong-11);white-space:nowrap;cursor:pointer;border-radius:6px;align-items:center;padding:0 10px;display:inline-flex;position:fixed;transform:translate(-50%,calc(-100% - 8px))}.S5HVoW_selectionPopup:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_terminalWrap{background:var(--dsw-alias-bg-base);flex-direction:column;flex:1;min-height:0;display:flex;position:relative}.S5HVoW_terminal{flex:1;min-height:0;padding:6px 4px 6px 8px}.S5HVoW_terminal .xterm{height:100%}.S5HVoW_terminalBanner{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex-wrap:wrap;flex:none;align-items:center;gap:8px;padding:3px 10px;display:flex}.S5HVoW_terminalBannerUrl{word-break:break-all;opacity:.85;flex-basis:100%;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.S5HVoW_boundaryError{z-index:50;background:var(--dsw-alias-bg-layer-1);border-left:1px solid var(--dsw-alias-border-l2);font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);flex-direction:column;align-items:flex-start;gap:8px;padding:16px;display:flex;position:fixed;top:0;bottom:0;right:0;overflow:auto}.S5HVoW_terminalRetry{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxxs-strong-11);cursor:pointer;border-radius:999px;flex:none;padding:1px 8px}.S5HVoW_terminalRetry:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_terminalDepsBanner{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-warn-label);background:var(--dsw-alias-state-warn-tertiary);flex-direction:column;flex:none;gap:6px;padding:10px;display:flex}.S5HVoW_terminalDepsTitle{font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-state-warn-primary)}.S5HVoW_terminalDepsHint{opacity:.9}.S5HVoW_terminalDepsCommandRow{align-items:flex-start;gap:8px;display:flex}.S5HVoW_terminalRepairCommand{white-space:pre-wrap;word-break:break-all;user-select:text;min-width:0;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:4px;flex:1;max-height:160px;margin:0;padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.5;overflow:auto}.S5HVoW_terminalDepsNote{opacity:.85}.S5HVoW_terminalDepsActions{align-items:center;gap:8px;display:flex}.S5HVoW_tabBoundaryError{min-height:0;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);flex-direction:column;flex:1;align-items:flex-start;gap:8px;padding:12px 16px;display:flex;overflow:auto}.S5HVoW_git{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden auto}.S5HVoW_gitHeader{flex:none;align-items:center;gap:8px;height:36px;padding:0 8px 0 12px;display:flex}.S5HVoW_gitWorktreeRow{flex:none;align-items:center;gap:8px;padding:6px 8px 0 12px;display:flex}.S5HVoW_gitWorktreeLabel{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-xxxs-11);flex:none}.S5HVoW_gitBranchSelect{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);min-width:0;height:26px;color:var(--dsw-alias-label-primary);font:var(--dsw-font-xxs-12);border-radius:6px;flex:1;padding:0 6px}.S5HVoW_gitSection{border-top:1px solid var(--dsw-alias-border-l1)}.S5HVoW_gitSectionHeader{font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-label-tertiary);text-transform:uppercase;justify-content:space-between;align-items:center;padding:6px 12px 4px;display:flex}.S5HVoW_gitLink{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:none;padding:0}.S5HVoW_gitLink:hover:not(:disabled){text-decoration:underline}.S5HVoW_gitLink:disabled{opacity:.4;cursor:default}.S5HVoW_gitRow{min-height:34px;animation:S5HVoW_dsh-row-in .15s var(--ds-ease-in-out);border-radius:8px;align-items:center;gap:6px;margin:0 6px;padding:0 8px;display:flex}.S5HVoW_gitRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitRowSelected{background:var(--dsw-alias-interactive-bg-active)}.S5HVoW_gitRowMain{cursor:pointer;text-align:left;background:0 0;border:none;flex:1;align-items:center;gap:8px;min-width:0;padding:3px 0;display:flex}.S5HVoW_gitBadge{width:20px;height:16px;font:var(--dsw-font-xxxs-strong-11);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;justify-content:center;align-items:center;display:inline-flex}.S5HVoW_gitName{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.S5HVoW_gitEmpty{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);padding:4px 12px 8px}.S5HVoW_gitPlaceholder{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary);text-align:center;padding:16px}.S5HVoW_gitError{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-state-error-primary);white-space:pre-wrap;padding:8px 12px}.S5HVoW_gitDiff{border-top:1px solid var(--dsw-alias-border-l1);padding:8px}.S5HVoW_gitDiffTab{flex-direction:column;flex:1;min-width:0;min-height:0;display:flex;overflow:hidden auto}.S5HVoW_gitDiffTabHeader{border-bottom:1px solid var(--dsw-alias-border-l1);flex:none;align-items:center;gap:8px;height:36px;padding:0 8px 0 12px;display:flex}.S5HVoW_gitDiffTabTitle{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.S5HVoW_gitDiffFile{width:100%;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:baseline;gap:6px;padding:8px 2px 2px;display:flex}.S5HVoW_gitDiffFile:disabled{cursor:default}.S5HVoW_gitDiffFile:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitDiffFileChevron{color:var(--dsw-alias-label-tertiary);flex:none;transform:rotate(0)}.S5HVoW_gitDiffFileChevronExpanded{transform:rotate(90deg)}.S5HVoW_gitDiffFilePath{font:var(--dsw-font-xxs-strong-12);color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_gitDiffFileOld{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);text-overflow:ellipsis;white-space:nowrap;flex:none;max-width:40%;overflow:hidden}.S5HVoW_gitDiffFileTag{border:1px solid var(--dsw-alias-border-l2);font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:0 6px}.S5HVoW_gitDiffHunk{font:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-tertiary);gap:8px;padding:3px 2px;display:flex}.S5HVoW_gitDiffHunkHeader{color:var(--dsw-alias-label-secondary);flex:none}.S5HVoW_gitDiffHunkSection{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_gitDiffLine{font:var(--dsw-font-markdown-code-block-small);white-space:pre-wrap;overflow-wrap:anywhere;align-items:stretch;min-width:0;line-height:20px;display:flex}.S5HVoW_gitDiffNum{text-align:right;width:36px;color:var(--dsw-alias-label-tertiary);user-select:none;flex:none;padding-right:8px}.S5HVoW_gitDiffCode{flex:1;min-width:0;overflow:visible}.S5HVoW_gitDiffCtx{color:var(--dsw-alias-label-primary)}.S5HVoW_gitDiffDel{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 12%, transparent)}.S5HVoW_gitDiffAdd{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb, var(--dsw-alias-state-success-primary) 12%, transparent)}.S5HVoW_gitDiffMeta{padding-left:2px}.S5HVoW_gitDiffMetaText{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary);font-style:italic}.S5HVoW_gitDiffExpand{width:100%;font:var(--dsw-font-xxs-12);color:var(--dsw-alias-brand-primary);cursor:pointer;text-align:center;background:0 0;border:none;margin:4px 0;display:block}.S5HVoW_gitDiffExpand:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitConfirmDesc{font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);white-space:pre-wrap;margin:0}.S5HVoW_gitCommit{border-top:1px solid var(--dsw-alias-border-l1);align-items:center;gap:6px;padding:8px 12px;display:flex}.S5HVoW_gitCommitInput{flex:1;min-width:0}.S5HVoW_gitCommitButton{background:var(--dsw-alias-button-primary-fill);height:26px;color:var(--dsw-alias-label-primary-inverted);font:var(--dsw-font-xxs-strong-12);cursor:pointer;border:none;border-radius:6px;flex:none;padding:0 12px}.S5HVoW_gitCommitButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.S5HVoW_gitCommitButton:disabled{opacity:.45;cursor:default}.S5HVoW_gitLogRow{cursor:pointer;border-radius:8px;flex-direction:column;gap:2px;padding:5px 12px;display:flex}.S5HVoW_gitLogRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.S5HVoW_gitLogLine1{align-items:baseline;gap:8px;min-width:0;display:flex}.S5HVoW_gitLogHash{font:var(--dsw-font-markdown-code-block-small);color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_gitLogLine2{flex-wrap:wrap;align-items:center;gap:6px;min-width:0;display:flex}.S5HVoW_gitLogRef{border:1px solid var(--dsw-alias-border-l2);font:var(--dsw-font-xxxs-strong-11);color:var(--dsw-alias-brand-primary);white-space:nowrap;border-radius:999px;flex:none;padding:0 5px}.S5HVoW_gitLogSubject{text-overflow:ellipsis;white-space:nowrap;min-width:0;font:var(--dsw-font-s-14);color:var(--dsw-alias-label-primary);flex:1;overflow:hidden}.S5HVoW_gitLogMeta{font:var(--dsw-font-xxxs-11);color:var(--dsw-alias-label-tertiary)}.S5HVoW_gitLogMore{border:1px solid var(--dsw-alias-border-l2);width:calc(100% - 24px);font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border-radius:6px;margin:4px 12px 8px;padding:6px 0;display:block}.S5HVoW_gitLogMore:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_gitLogMore:disabled{opacity:.5;cursor:default}.S5HVoW_producedRow{flex-wrap:wrap;align-items:center;gap:8px;padding:4px 0;display:flex}.S5HVoW_producedLabel{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary)}.S5HVoW_producedChip{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);max-width:200px;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-xxs-12);cursor:pointer;border-radius:999px;align-items:center;gap:4px;padding:2px 8px;display:inline-flex;overflow:hidden}.S5HVoW_producedChip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_producedChip span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.S5HVoW_producedMore{font:var(--dsw-font-xxs-12);color:var(--dsw-alias-label-tertiary)}.S5HVoW_toggleButton:focus-visible,.S5HVoW_iconButton:focus-visible,.S5HVoW_tab:focus-visible,.S5HVoW_tabClose:focus-visible,.S5HVoW_tabBarPlus:focus-visible,.S5HVoW_paneCard:focus-visible,.S5HVoW_explorerRow:focus-visible,.S5HVoW_explorerRef:focus-visible,.S5HVoW_gitRowMain:focus-visible,.S5HVoW_gitLink:focus-visible,.S5HVoW_gitCommitButton:focus-visible,.S5HVoW_gitLogRow:focus-visible,.S5HVoW_gitLogMore:focus-visible,.S5HVoW_gitDiffFile:focus-visible,.S5HVoW_gitDiffExpand:focus-visible,.S5HVoW_terminalRetry:focus-visible,.S5HVoW_editorDownloadLink:focus-visible{outline:2px solid var(--dsw-alias-interactive-bg-hover-accent);outline-offset:-1px}@media (prefers-reduced-motion:reduce){.S5HVoW_panel,.S5HVoW_panelHidden,.S5HVoW_toggleCluster,.S5HVoW_toggleButton,.S5HVoW_tab,.S5HVoW_tabBarPlus,.S5HVoW_paneCard,.S5HVoW_explorerRow,.S5HVoW_gitRow,.S5HVoW_divider,.S5HVoW_dividerRow:after,.S5HVoW_dividerCol:after{transition:none;animation:none}}@media (width<=767px){.S5HVoW_panel:not(.S5HVoW_panelHidden) .S5HVoW_tabBar{padding-right:40px}.S5HVoW_tab{min-width:48px;max-width:128px}}.S5HVoW_openWithLabel{align-items:center;gap:8px;width:100%;min-width:0;display:flex}.S5HVoW_openWithName{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}.S5HVoW_openWithChevron{color:var(--dsw-alias-label-tertiary);flex:none}.S5HVoW_openWithPin{width:20px;height:20px;color:var(--dsw-alias-label-tertiary);cursor:pointer;border-radius:6px;flex:none;justify-content:center;align-items:center;display:inline-flex}.S5HVoW_openWithPin:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.S5HVoW_openWithPinActive{color:var(--dsw-alias-state-business-primary)}@keyframes S5HVoW_dsh-toc-flash{0%,60%{background:var(--dsw-alias-interactive-bg-hover)}to{background:0 0}}.S5HVoW_browserLive{flex-direction:column;gap:6px;padding:8px 10px;display:flex;position:absolute;inset:0;overflow:hidden}.S5HVoW_browserLiveStatus{opacity:.75;align-items:center;gap:8px;font-size:12px;display:flex}.S5HVoW_browserLiveCanvas{object-fit:contain;border:1px solid var(--dsw-alias-border-l,#80808040);cursor:crosshair;background:#fff;border-radius:8px;flex:1;width:100%;min-height:0}.S5HVoW_browserLiveTarget{max-width:260px;font-size:12px}";
|
|
9960
9896
|
const tagId$4 = "dsh-external/dsh-coding-sidebar/sidebar.module.css";
|
|
9961
9897
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
9962
9898
|
const tag = document.createElement("style");
|
|
@@ -9966,241 +9902,207 @@ window.__ModuleLoader__.load({
|
|
|
9966
9902
|
document.head.appendChild(tag);
|
|
9967
9903
|
}
|
|
9968
9904
|
var sidebar_module_css_default = {
|
|
9969
|
-
"
|
|
9970
|
-
"panelResize": "S5HVoW_panelResize",
|
|
9971
|
-
"producedMore": "S5HVoW_producedMore",
|
|
9972
|
-
"divider": "S5HVoW_divider",
|
|
9973
|
-
"editorTreeDock": "S5HVoW_editorTreeDock",
|
|
9974
|
-
"editorPdfToolbar": "S5HVoW_editorPdfToolbar",
|
|
9975
|
-
"tabClose": "S5HVoW_tabClose",
|
|
9976
|
-
"panelHidden": "S5HVoW_panelHidden",
|
|
9977
|
-
"paneContent": "S5HVoW_paneContent",
|
|
9978
|
-
"explorerHidden": "S5HVoW_explorerHidden",
|
|
9979
|
-
"editorHtmlBlock": "S5HVoW_editorHtmlBlock",
|
|
9980
|
-
"editorPdf": "S5HVoW_editorPdf",
|
|
9981
|
-
"editorPdfFrameBlocked": "S5HVoW_editorPdfFrameBlocked",
|
|
9982
|
-
"gitDiffLine": "S5HVoW_gitDiffLine",
|
|
9983
|
-
"producedRow": "S5HVoW_producedRow",
|
|
9984
|
-
"explorerRowDropTarget": "S5HVoW_explorerRowDropTarget",
|
|
9985
|
-
"editorBinary": "S5HVoW_editorBinary",
|
|
9986
|
-
"floatHeader": "S5HVoW_floatHeader",
|
|
9987
|
-
"editorPdfFrame": "S5HVoW_editorPdfFrame",
|
|
9988
|
-
"gitDiffCode": "S5HVoW_gitDiffCode",
|
|
9989
|
-
"floatDropHint": "S5HVoW_floatDropHint",
|
|
9990
|
-
"dirtyDot": "S5HVoW_dirtyDot",
|
|
9991
|
-
"editor": "S5HVoW_editor",
|
|
9992
|
-
"gitLogLine2": "S5HVoW_gitLogLine2",
|
|
9993
|
-
"tab": "S5HVoW_tab",
|
|
9994
|
-
"uploadDropHero": "S5HVoW_uploadDropHero",
|
|
9995
|
-
"mermaidModalStage": "S5HVoW_mermaidModalStage",
|
|
9996
|
-
"gitLogRef": "S5HVoW_gitLogRef",
|
|
9997
|
-
"editorHtml": "S5HVoW_editorHtml",
|
|
9998
|
-
"gitBranchSelect": "S5HVoW_gitBranchSelect",
|
|
9999
|
-
"tocButton": "S5HVoW_tocButton",
|
|
10000
|
-
"floatTitle": "S5HVoW_floatTitle",
|
|
10001
|
-
"iconButton": "S5HVoW_iconButton",
|
|
9905
|
+
"toggleButton": "S5HVoW_toggleButton",
|
|
10002
9906
|
"tabBarDrop": "S5HVoW_tabBarDrop",
|
|
10003
|
-
"
|
|
10004
|
-
"
|
|
10005
|
-
"gitRowSelected": "S5HVoW_gitRowSelected",
|
|
10006
|
-
"tabTitle": "S5HVoW_tabTitle",
|
|
10007
|
-
"gitHeader": "S5HVoW_gitHeader",
|
|
10008
|
-
"splitCol": "S5HVoW_splitCol",
|
|
10009
|
-
"gitDiffMetaText": "S5HVoW_gitDiffMetaText",
|
|
10010
|
-
"gitLogRow": "S5HVoW_gitLogRow",
|
|
9907
|
+
"dropOverlay": "S5HVoW_dropOverlay",
|
|
9908
|
+
"sandboxDot": "S5HVoW_sandboxDot",
|
|
10011
9909
|
"gitDiffFileOld": "S5HVoW_gitDiffFileOld",
|
|
10012
|
-
"openWithChevron": "S5HVoW_openWithChevron",
|
|
10013
|
-
"mermaidMarkdown": "S5HVoW_mermaidMarkdown",
|
|
10014
9910
|
"gitLogHash": "S5HVoW_gitLogHash",
|
|
10015
|
-
"
|
|
9911
|
+
"floatHeader": "S5HVoW_floatHeader",
|
|
9912
|
+
"uploadDropZoneText": "S5HVoW_uploadDropZoneText",
|
|
9913
|
+
"uploadDropChatHint": "S5HVoW_uploadDropChatHint",
|
|
9914
|
+
"gitLogLine2": "S5HVoW_gitLogLine2",
|
|
9915
|
+
"dividerActive": "S5HVoW_dividerActive",
|
|
9916
|
+
"terminalWrap": "S5HVoW_terminalWrap",
|
|
9917
|
+
"explorer": "S5HVoW_explorer",
|
|
9918
|
+
"uploadOverlayProgress": "S5HVoW_uploadOverlayProgress",
|
|
9919
|
+
"uploadDropZone": "S5HVoW_uploadDropZone",
|
|
10016
9920
|
"browserBlockedActions": "S5HVoW_browserBlockedActions",
|
|
9921
|
+
"floatResize": "S5HVoW_floatResize",
|
|
9922
|
+
"panelBody": "S5HVoW_panelBody",
|
|
9923
|
+
"floatDropHintLabel": "S5HVoW_floatDropHintLabel",
|
|
9924
|
+
"explorerHeader": "S5HVoW_explorerHeader",
|
|
9925
|
+
"gitLink": "S5HVoW_gitLink",
|
|
9926
|
+
"gitDiff": "S5HVoW_gitDiff",
|
|
9927
|
+
"explorerName": "S5HVoW_explorerName",
|
|
9928
|
+
"tabBarPlus": "S5HVoW_tabBarPlus",
|
|
9929
|
+
"editorTreeSearch": "S5HVoW_editorTreeSearch",
|
|
9930
|
+
"terminalDepsBanner": "S5HVoW_terminalDepsBanner",
|
|
9931
|
+
"gitHeader": "S5HVoW_gitHeader",
|
|
9932
|
+
"tabActive": "S5HVoW_tabActive",
|
|
9933
|
+
"gitDiffFilePath": "S5HVoW_gitDiffFilePath",
|
|
9934
|
+
"dropDown": "S5HVoW_dropDown",
|
|
9935
|
+
"uploadOverlay": "S5HVoW_uploadOverlay",
|
|
9936
|
+
"openWithLabel": "S5HVoW_openWithLabel",
|
|
9937
|
+
"browserBar": "S5HVoW_browserBar",
|
|
9938
|
+
"gitConfirmDesc": "S5HVoW_gitConfirmDesc",
|
|
9939
|
+
"explorerRowDropTarget": "S5HVoW_explorerRowDropTarget",
|
|
9940
|
+
"editorPathInput": "S5HVoW_editorPathInput",
|
|
9941
|
+
"editorPlaceholder": "S5HVoW_editorPlaceholder",
|
|
10017
9942
|
"terminal": "S5HVoW_terminal",
|
|
10018
|
-
"
|
|
10019
|
-
"
|
|
10020
|
-
"
|
|
10021
|
-
"
|
|
9943
|
+
"terminalRepairCommand": "S5HVoW_terminalRepairCommand",
|
|
9944
|
+
"browserLive": "S5HVoW_browserLive",
|
|
9945
|
+
"gitDiffNum": "S5HVoW_gitDiffNum",
|
|
9946
|
+
"iconButton": "S5HVoW_iconButton",
|
|
9947
|
+
"editorHeader": "S5HVoW_editorHeader",
|
|
10022
9948
|
"uploadOverlayCard": "S5HVoW_uploadOverlayCard",
|
|
10023
|
-
"
|
|
10024
|
-
"
|
|
10025
|
-
"
|
|
10026
|
-
"
|
|
10027
|
-
"
|
|
10028
|
-
"
|
|
10029
|
-
"
|
|
9949
|
+
"uploadDropHero": "S5HVoW_uploadDropHero",
|
|
9950
|
+
"paneTab": "S5HVoW_paneTab",
|
|
9951
|
+
"dividerRow": "S5HVoW_dividerRow",
|
|
9952
|
+
"editorBanner": "S5HVoW_editorBanner",
|
|
9953
|
+
"editorBody": "S5HVoW_editorBody",
|
|
9954
|
+
"terminalBanner": "S5HVoW_terminalBanner",
|
|
9955
|
+
"floatContent": "S5HVoW_floatContent",
|
|
9956
|
+
"paneCard": "S5HVoW_paneCard",
|
|
9957
|
+
"uploadDropChatCard": "S5HVoW_uploadDropChatCard",
|
|
10030
9958
|
"editorDownloadLink": "S5HVoW_editorDownloadLink",
|
|
9959
|
+
"gitWorktreeRow": "S5HVoW_gitWorktreeRow",
|
|
9960
|
+
"gitDiffFileChevron": "S5HVoW_gitDiffFileChevron",
|
|
9961
|
+
"editorMain": "S5HVoW_editorMain",
|
|
9962
|
+
"gitDiffLine": "S5HVoW_gitDiffLine",
|
|
9963
|
+
"browserMessage": "S5HVoW_browserMessage",
|
|
9964
|
+
"gitRowMain": "S5HVoW_gitRowMain",
|
|
9965
|
+
"explorerEmpty": "S5HVoW_explorerEmpty",
|
|
9966
|
+
"terminalDepsCommandRow": "S5HVoW_terminalDepsCommandRow",
|
|
9967
|
+
"gitDiffCode": "S5HVoW_gitDiffCode",
|
|
9968
|
+
"gitDiffCtx": "S5HVoW_gitDiffCtx",
|
|
9969
|
+
"editorTreeDock": "S5HVoW_editorTreeDock",
|
|
9970
|
+
"editorSearchInput": "S5HVoW_editorSearchInput",
|
|
9971
|
+
"editorStatus": "S5HVoW_editorStatus",
|
|
9972
|
+
"producedChip": "S5HVoW_producedChip",
|
|
9973
|
+
"browserInput": "S5HVoW_browserInput",
|
|
9974
|
+
"panelResize": "S5HVoW_panelResize",
|
|
9975
|
+
"floatDropHint": "S5HVoW_floatDropHint",
|
|
9976
|
+
"editorStatusError": "S5HVoW_editorStatusError",
|
|
9977
|
+
"panel": "S5HVoW_panel",
|
|
9978
|
+
"gitDiffMeta": "S5HVoW_gitDiffMeta",
|
|
9979
|
+
"gitDiffMetaText": "S5HVoW_gitDiffMetaText",
|
|
9980
|
+
"terminalRetry": "S5HVoW_terminalRetry",
|
|
9981
|
+
"uploadOverlayTitle": "S5HVoW_uploadOverlayTitle",
|
|
9982
|
+
"gitDiffFileTag": "S5HVoW_gitDiffFileTag",
|
|
10031
9983
|
"gitCommitInput": "S5HVoW_gitCommitInput",
|
|
10032
|
-
"
|
|
10033
|
-
"explorerRef": "S5HVoW_explorerRef",
|
|
10034
|
-
"floatClose": "S5HVoW_floatClose",
|
|
10035
|
-
"explorerError": "S5HVoW_explorerError",
|
|
10036
|
-
"mermaidModal": "S5HVoW_mermaidModal",
|
|
10037
|
-
"gitPlaceholder": "S5HVoW_gitPlaceholder",
|
|
10038
|
-
"browserBlocked": "S5HVoW_browserBlocked",
|
|
10039
|
-
"editorTreePanel": "S5HVoW_editorTreePanel",
|
|
9984
|
+
"gitDiffHunkSection": "S5HVoW_gitDiffHunkSection",
|
|
10040
9985
|
"uploadOverlayStatus": "S5HVoW_uploadOverlayStatus",
|
|
10041
|
-
"
|
|
10042
|
-
"gitDiffFileChevronExpanded": "S5HVoW_gitDiffFileChevronExpanded",
|
|
10043
|
-
"editorSearchResult": "S5HVoW_editorSearchResult",
|
|
10044
|
-
"gitRow": "S5HVoW_gitRow",
|
|
10045
|
-
"gitEmpty": "S5HVoW_gitEmpty",
|
|
10046
|
-
"terminalRetry": "S5HVoW_terminalRetry",
|
|
10047
|
-
"gitDiffNum": "S5HVoW_gitDiffNum",
|
|
10048
|
-
"floatDropHintLabel": "S5HVoW_floatDropHintLabel",
|
|
10049
|
-
"gitLink": "S5HVoW_gitLink",
|
|
10050
|
-
"uploadOverlayCancel": "S5HVoW_uploadOverlayCancel",
|
|
10051
|
-
"dropOverlay": "S5HVoW_dropOverlay",
|
|
10052
|
-
"editorPdfDragShield": "S5HVoW_editorPdfDragShield",
|
|
10053
|
-
"dropUp": "S5HVoW_dropUp",
|
|
10054
|
-
"editorPptxButton": "S5HVoW_editorPptxButton",
|
|
10055
|
-
"browser": "S5HVoW_browser",
|
|
10056
|
-
"sandboxStatus": "S5HVoW_sandboxStatus",
|
|
10057
|
-
"sandboxStatusText": "S5HVoW_sandboxStatusText",
|
|
10058
|
-
"openWithName": "S5HVoW_openWithName",
|
|
10059
|
-
"terminalBannerUrl": "S5HVoW_terminalBannerUrl",
|
|
9986
|
+
"gitLogLine1": "S5HVoW_gitLogLine1",
|
|
10060
9987
|
"pinnedTab": "S5HVoW_pinnedTab",
|
|
10061
|
-
"
|
|
10062
|
-
"
|
|
10063
|
-
"
|
|
9988
|
+
"divider": "S5HVoW_divider",
|
|
9989
|
+
"dsh-toc-flash": "S5HVoW_dsh-toc-flash",
|
|
9990
|
+
"paneEmptyCards": "S5HVoW_paneEmptyCards",
|
|
9991
|
+
"orphanedType": "S5HVoW_orphanedType",
|
|
9992
|
+
"browserLiveTarget": "S5HVoW_browserLiveTarget",
|
|
9993
|
+
"dropUp": "S5HVoW_dropUp",
|
|
9994
|
+
"panelResizeActive": "S5HVoW_panelResizeActive",
|
|
9995
|
+
"gitLogMore": "S5HVoW_gitLogMore",
|
|
9996
|
+
"panelHidden": "S5HVoW_panelHidden",
|
|
9997
|
+
"terminalDepsActions": "S5HVoW_terminalDepsActions",
|
|
9998
|
+
"gitLogSubject": "S5HVoW_gitLogSubject",
|
|
9999
|
+
"openWithPin": "S5HVoW_openWithPin",
|
|
10064
10000
|
"explorerCopied": "S5HVoW_explorerCopied",
|
|
10001
|
+
"explorerDir": "S5HVoW_explorerDir",
|
|
10002
|
+
"gitDiffAdd": "S5HVoW_gitDiffAdd",
|
|
10065
10003
|
"sandboxStatusOff": "S5HVoW_sandboxStatusOff",
|
|
10066
|
-
"
|
|
10067
|
-
"
|
|
10004
|
+
"sandboxStatusText": "S5HVoW_sandboxStatusText",
|
|
10005
|
+
"producedRow": "S5HVoW_producedRow",
|
|
10006
|
+
"openWithChevron": "S5HVoW_openWithChevron",
|
|
10007
|
+
"editorBinaryNotice": "S5HVoW_editorBinaryNotice",
|
|
10068
10008
|
"gitDiffHunk": "S5HVoW_gitDiffHunk",
|
|
10069
|
-
"
|
|
10070
|
-
"
|
|
10071
|
-
"
|
|
10072
|
-
"
|
|
10073
|
-
"
|
|
10074
|
-
"explorerSymlink": "S5HVoW_explorerSymlink",
|
|
10075
|
-
"dsh-row-in": "S5HVoW_dsh-row-in",
|
|
10009
|
+
"gitLogRow": "S5HVoW_gitLogRow",
|
|
10010
|
+
"browserBlocked": "S5HVoW_browserBlocked",
|
|
10011
|
+
"producedLabel": "S5HVoW_producedLabel",
|
|
10012
|
+
"git": "S5HVoW_git",
|
|
10013
|
+
"floatWindow": "S5HVoW_floatWindow",
|
|
10076
10014
|
"explorerRowRevealed": "S5HVoW_explorerRowRevealed",
|
|
10077
|
-
"editorSearchInput": "S5HVoW_editorSearchInput",
|
|
10078
|
-
"mermaidInfo": "S5HVoW_mermaidInfo",
|
|
10079
|
-
"gitDiffFileTag": "S5HVoW_gitDiffFileTag",
|
|
10080
|
-
"explorerDir": "S5HVoW_explorerDir",
|
|
10081
|
-
"browserInput": "S5HVoW_browserInput",
|
|
10082
|
-
"editorMd": "S5HVoW_editorMd",
|
|
10083
|
-
"sandboxStatusOn": "S5HVoW_sandboxStatusOn",
|
|
10084
|
-
"mermaidWrap": "S5HVoW_mermaidWrap",
|
|
10085
|
-
"editorImage": "S5HVoW_editorImage",
|
|
10086
|
-
"sandboxDot": "S5HVoW_sandboxDot",
|
|
10087
|
-
"editorStatusError": "S5HVoW_editorStatusError",
|
|
10088
|
-
"gitLogMeta": "S5HVoW_gitLogMeta",
|
|
10089
|
-
"dropLeft": "S5HVoW_dropLeft",
|
|
10090
|
-
"browserBlockedTitle": "S5HVoW_browserBlockedTitle",
|
|
10091
|
-
"tocPanel": "S5HVoW_tocPanel",
|
|
10092
|
-
"editorCmHidden": "S5HVoW_editorCmHidden",
|
|
10093
|
-
"selectionPopup": "S5HVoW_selectionPopup",
|
|
10094
|
-
"gitDiffHunkSection": "S5HVoW_gitDiffHunkSection",
|
|
10095
|
-
"gitDiffCtx": "S5HVoW_gitDiffCtx",
|
|
10096
|
-
"editorImageWrap": "S5HVoW_editorImageWrap",
|
|
10097
|
-
"explorerRow": "S5HVoW_explorerRow",
|
|
10098
|
-
"editorModeActive": "S5HVoW_editorModeActive",
|
|
10099
|
-
"gitDiffFile": "S5HVoW_gitDiffFile",
|
|
10100
|
-
"editorStatus": "S5HVoW_editorStatus",
|
|
10101
|
-
"explorerHeader": "S5HVoW_explorerHeader",
|
|
10102
|
-
"uploadDropZoneText": "S5HVoW_uploadDropZoneText",
|
|
10103
|
-
"tabList": "S5HVoW_tabList",
|
|
10104
|
-
"explorerEmpty": "S5HVoW_explorerEmpty",
|
|
10105
|
-
"gitSection": "S5HVoW_gitSection",
|
|
10106
|
-
"tabBarPlus": "S5HVoW_tabBarPlus",
|
|
10107
|
-
"explorerBody": "S5HVoW_explorerBody",
|
|
10108
|
-
"gitDiffExpand": "S5HVoW_gitDiffExpand",
|
|
10109
|
-
"dividerRow": "S5HVoW_dividerRow",
|
|
10110
|
-
"editorPdfStage": "S5HVoW_editorPdfStage",
|
|
10111
|
-
"producedChip": "S5HVoW_producedChip",
|
|
10112
|
-
"editorError": "S5HVoW_editorError",
|
|
10113
|
-
"terminalDepsNote": "S5HVoW_terminalDepsNote",
|
|
10114
|
-
"floatResize": "S5HVoW_floatResize",
|
|
10115
|
-
"uploadDropZonePill": "S5HVoW_uploadDropZonePill",
|
|
10116
|
-
"browserBlockedDesc": "S5HVoW_browserBlockedDesc",
|
|
10117
|
-
"mermaidModalButton": "S5HVoW_mermaidModalButton",
|
|
10118
|
-
"floatContent": "S5HVoW_floatContent",
|
|
10119
10015
|
"splitChild": "S5HVoW_splitChild",
|
|
10120
|
-
"
|
|
10121
|
-
"
|
|
10122
|
-
"
|
|
10123
|
-
"
|
|
10124
|
-
"
|
|
10125
|
-
"browserBar": "S5HVoW_browserBar",
|
|
10126
|
-
"gitBadge": "S5HVoW_gitBadge",
|
|
10127
|
-
"terminalDepsHint": "S5HVoW_terminalDepsHint",
|
|
10128
|
-
"openWithPin": "S5HVoW_openWithPin",
|
|
10129
|
-
"tabBoundaryError": "S5HVoW_tabBoundaryError",
|
|
10130
|
-
"uploadOverlay": "S5HVoW_uploadOverlay",
|
|
10131
|
-
"editorPdfDragShieldActive": "S5HVoW_editorPdfDragShieldActive",
|
|
10132
|
-
"tabBar": "S5HVoW_tabBar",
|
|
10133
|
-
"sandboxAction": "S5HVoW_sandboxAction",
|
|
10134
|
-
"mermaidCopy": "S5HVoW_mermaidCopy",
|
|
10135
|
-
"tabBadge": "S5HVoW_tabBadge",
|
|
10136
|
-
"browserStart": "S5HVoW_browserStart",
|
|
10137
|
-
"git": "S5HVoW_git",
|
|
10138
|
-
"gitLogLine1": "S5HVoW_gitLogLine1",
|
|
10139
|
-
"editorMain": "S5HVoW_editorMain",
|
|
10140
|
-
"editorTreeToggleActive": "S5HVoW_editorTreeToggleActive",
|
|
10141
|
-
"producedLabel": "S5HVoW_producedLabel",
|
|
10142
|
-
"mermaidBody": "S5HVoW_mermaidBody",
|
|
10143
|
-
"editorHeader": "S5HVoW_editorHeader",
|
|
10144
|
-
"paneCard": "S5HVoW_paneCard",
|
|
10145
|
-
"openWithPinActive": "S5HVoW_openWithPinActive",
|
|
10146
|
-
"panelResizeActive": "S5HVoW_panelResizeActive",
|
|
10147
|
-
"dropDown": "S5HVoW_dropDown",
|
|
10148
|
-
"boundaryError": "S5HVoW_boundaryError",
|
|
10149
|
-
"tocBar": "S5HVoW_tocBar",
|
|
10150
|
-
"explorerName": "S5HVoW_explorerName",
|
|
10151
|
-
"gitName": "S5HVoW_gitName",
|
|
10152
|
-
"explorerRoot": "S5HVoW_explorerRoot",
|
|
10016
|
+
"terminalDepsNote": "S5HVoW_terminalDepsNote",
|
|
10017
|
+
"browserFrame": "S5HVoW_browserFrame",
|
|
10018
|
+
"gitPlaceholder": "S5HVoW_gitPlaceholder",
|
|
10019
|
+
"gitSection": "S5HVoW_gitSection",
|
|
10020
|
+
"gitDiffTabTitle": "S5HVoW_gitDiffTabTitle",
|
|
10153
10021
|
"dividerCol": "S5HVoW_dividerCol",
|
|
10154
|
-
"
|
|
10155
|
-
"
|
|
10156
|
-
"gitDiffTabHeader": "S5HVoW_gitDiffTabHeader",
|
|
10157
|
-
"terminalDepsTitle": "S5HVoW_terminalDepsTitle",
|
|
10158
|
-
"editorModeButton": "S5HVoW_editorModeButton",
|
|
10159
|
-
"panel": "S5HVoW_panel",
|
|
10160
|
-
"explorerBroken": "S5HVoW_explorerBroken",
|
|
10161
|
-
"editorTreeResize": "S5HVoW_editorTreeResize",
|
|
10162
|
-
"gitDiffFileChevron": "S5HVoW_gitDiffFileChevron",
|
|
10163
|
-
"gitConfirmDesc": "S5HVoW_gitConfirmDesc",
|
|
10164
|
-
"editorBody": "S5HVoW_editorBody",
|
|
10165
|
-
"gitWorktreeLabel": "S5HVoW_gitWorktreeLabel",
|
|
10022
|
+
"tabClose": "S5HVoW_tabClose",
|
|
10023
|
+
"gitEmpty": "S5HVoW_gitEmpty",
|
|
10166
10024
|
"editorTitle": "S5HVoW_editorTitle",
|
|
10025
|
+
"gitLogRef": "S5HVoW_gitLogRef",
|
|
10026
|
+
"editorTreeToggleActive": "S5HVoW_editorTreeToggleActive",
|
|
10167
10027
|
"editorSearchHint": "S5HVoW_editorSearchHint",
|
|
10168
|
-
"
|
|
10169
|
-
"
|
|
10170
|
-
"
|
|
10171
|
-
"
|
|
10172
|
-
"
|
|
10173
|
-
"
|
|
10174
|
-
"
|
|
10175
|
-
"
|
|
10028
|
+
"producedMore": "S5HVoW_producedMore",
|
|
10029
|
+
"gitRowSelected": "S5HVoW_gitRowSelected",
|
|
10030
|
+
"browserLiveStatus": "S5HVoW_browserLiveStatus",
|
|
10031
|
+
"splitCol": "S5HVoW_splitCol",
|
|
10032
|
+
"uploadDropZonePill": "S5HVoW_uploadDropZonePill",
|
|
10033
|
+
"terminalDepsTitle": "S5HVoW_terminalDepsTitle",
|
|
10034
|
+
"explorerHidden": "S5HVoW_explorerHidden",
|
|
10035
|
+
"workbench": "S5HVoW_workbench",
|
|
10036
|
+
"paneContent": "S5HVoW_paneContent",
|
|
10037
|
+
"explorerError": "S5HVoW_explorerError",
|
|
10038
|
+
"editorTreeResize": "S5HVoW_editorTreeResize",
|
|
10039
|
+
"gitName": "S5HVoW_gitName",
|
|
10040
|
+
"editorError": "S5HVoW_editorError",
|
|
10176
10041
|
"gitDiffHunkHeader": "S5HVoW_gitDiffHunkHeader",
|
|
10177
|
-
"
|
|
10178
|
-
"split": "S5HVoW_split",
|
|
10179
|
-
"floatWindow": "S5HVoW_floatWindow",
|
|
10042
|
+
"explorerSymlink": "S5HVoW_explorerSymlink",
|
|
10180
10043
|
"browserBlockedButton": "S5HVoW_browserBlockedButton",
|
|
10181
|
-
"
|
|
10182
|
-
"
|
|
10183
|
-
"
|
|
10184
|
-
"
|
|
10185
|
-
"
|
|
10186
|
-
"
|
|
10187
|
-
"
|
|
10188
|
-
"
|
|
10189
|
-
"
|
|
10190
|
-
"
|
|
10191
|
-
"
|
|
10044
|
+
"sandboxAction": "S5HVoW_sandboxAction",
|
|
10045
|
+
"editorBinary": "S5HVoW_editorBinary",
|
|
10046
|
+
"browserBlockedTitle": "S5HVoW_browserBlockedTitle",
|
|
10047
|
+
"gitSectionHeader": "S5HVoW_gitSectionHeader",
|
|
10048
|
+
"pane": "S5HVoW_pane",
|
|
10049
|
+
"explorerBody": "S5HVoW_explorerBody",
|
|
10050
|
+
"explorerRow": "S5HVoW_explorerRow",
|
|
10051
|
+
"editorTreePanel": "S5HVoW_editorTreePanel",
|
|
10052
|
+
"gitBadge": "S5HVoW_gitBadge",
|
|
10053
|
+
"gitDiffDel": "S5HVoW_gitDiffDel",
|
|
10054
|
+
"splitRow": "S5HVoW_splitRow",
|
|
10055
|
+
"gitWorktreeLabel": "S5HVoW_gitWorktreeLabel",
|
|
10056
|
+
"toggleCluster": "S5HVoW_toggleCluster",
|
|
10057
|
+
"explorerRef": "S5HVoW_explorerRef",
|
|
10058
|
+
"dsh-row-in": "S5HVoW_dsh-row-in",
|
|
10059
|
+
"editor": "S5HVoW_editor",
|
|
10060
|
+
"browserLiveCanvas": "S5HVoW_browserLiveCanvas",
|
|
10061
|
+
"selectionPopup": "S5HVoW_selectionPopup",
|
|
10192
10062
|
"dropRight": "S5HVoW_dropRight",
|
|
10193
|
-
"
|
|
10063
|
+
"explorerBroken": "S5HVoW_explorerBroken",
|
|
10064
|
+
"boundaryError": "S5HVoW_boundaryError",
|
|
10065
|
+
"paneTabHidden": "S5HVoW_paneTabHidden",
|
|
10066
|
+
"floatClose": "S5HVoW_floatClose",
|
|
10067
|
+
"browserStart": "S5HVoW_browserStart",
|
|
10068
|
+
"gitBranchSelect": "S5HVoW_gitBranchSelect",
|
|
10069
|
+
"gitDiffExpand": "S5HVoW_gitDiffExpand",
|
|
10070
|
+
"floatWindowDragging": "S5HVoW_floatWindowDragging",
|
|
10071
|
+
"gitCommitButton": "S5HVoW_gitCommitButton",
|
|
10072
|
+
"editorSearchResult": "S5HVoW_editorSearchResult",
|
|
10073
|
+
"browserBlockedDesc": "S5HVoW_browserBlockedDesc",
|
|
10074
|
+
"gitLogMeta": "S5HVoW_gitLogMeta",
|
|
10075
|
+
"openWithPinActive": "S5HVoW_openWithPinActive",
|
|
10076
|
+
"terminalDepsHint": "S5HVoW_terminalDepsHint",
|
|
10194
10077
|
"dropCenter": "S5HVoW_dropCenter",
|
|
10195
|
-
"
|
|
10196
|
-
"
|
|
10197
|
-
"
|
|
10198
|
-
"
|
|
10199
|
-
"
|
|
10200
|
-
"
|
|
10201
|
-
"
|
|
10202
|
-
"
|
|
10203
|
-
"
|
|
10078
|
+
"dirtyDot": "S5HVoW_dirtyDot",
|
|
10079
|
+
"sandboxStatusOn": "S5HVoW_sandboxStatusOn",
|
|
10080
|
+
"terminalBannerUrl": "S5HVoW_terminalBannerUrl",
|
|
10081
|
+
"dropLeft": "S5HVoW_dropLeft",
|
|
10082
|
+
"uploadOverlayCancel": "S5HVoW_uploadOverlayCancel",
|
|
10083
|
+
"browser": "S5HVoW_browser",
|
|
10084
|
+
"tabList": "S5HVoW_tabList",
|
|
10085
|
+
"split": "S5HVoW_split",
|
|
10086
|
+
"tabBoundaryError": "S5HVoW_tabBoundaryError",
|
|
10087
|
+
"tab": "S5HVoW_tab",
|
|
10088
|
+
"editorTreePanelFull": "S5HVoW_editorTreePanelFull",
|
|
10089
|
+
"explorerRoot": "S5HVoW_explorerRoot",
|
|
10090
|
+
"gitDiffFile": "S5HVoW_gitDiffFile",
|
|
10091
|
+
"gitDiffTab": "S5HVoW_gitDiffTab",
|
|
10092
|
+
"gitDiffTabHeader": "S5HVoW_gitDiffTabHeader",
|
|
10093
|
+
"gitCommit": "S5HVoW_gitCommit",
|
|
10094
|
+
"gitRow": "S5HVoW_gitRow",
|
|
10095
|
+
"openWithName": "S5HVoW_openWithName",
|
|
10096
|
+
"gitError": "S5HVoW_gitError",
|
|
10097
|
+
"uploadOverlayProgressFill": "S5HVoW_uploadOverlayProgressFill",
|
|
10098
|
+
"tabBadge": "S5HVoW_tabBadge",
|
|
10099
|
+
"editorCm": "S5HVoW_editorCm",
|
|
10100
|
+
"floatTitle": "S5HVoW_floatTitle",
|
|
10101
|
+
"tabBar": "S5HVoW_tabBar",
|
|
10102
|
+
"paneDrop": "S5HVoW_paneDrop",
|
|
10103
|
+
"tabTitle": "S5HVoW_tabTitle",
|
|
10104
|
+
"sandboxStatus": "S5HVoW_sandboxStatus",
|
|
10105
|
+
"gitDiffFileChevronExpanded": "S5HVoW_gitDiffFileChevronExpanded"
|
|
10204
10106
|
};
|
|
10205
10107
|
//#endregion
|
|
10206
10108
|
//#region src/client/intercept.tsx
|
|
@@ -10547,29 +10449,23 @@ window.__ModuleLoader__.load({
|
|
|
10547
10449
|
/** Probe a URL's response headers (the sidebar browser's embeddability
|
|
10548
10450
|
* check; see the host's browser.probe route). */
|
|
10549
10451
|
browserProbe: (url, signal) => call("browser.probe", { url }, signal),
|
|
10452
|
+
/** Agent 浏览器宿主的 page target 列表(host 代理 CDP /json/list)。 */
|
|
10453
|
+
cdpTargets: (signal) => call("cdp.targets", {}, signal),
|
|
10550
10454
|
/** External open for the file tree's "open with" menu: reveal a path in
|
|
10551
10455
|
* the OS file manager, or hand a custom-scheme URL (vscode://, cursor://,
|
|
10552
10456
|
* zed://, custom editors) to its registered handler. The host launches
|
|
10553
10457
|
* the platform opener (argv, no shell). */
|
|
10554
10458
|
openExternal: (payload) => call("open.external", payload)
|
|
10555
10459
|
};
|
|
10556
|
-
/** Absolute URL of the media route for one path (images only). */
|
|
10557
|
-
function mediaUrl(scope, path) {
|
|
10558
|
-
return fileUrl(scope, path, false);
|
|
10559
|
-
}
|
|
10560
10460
|
/** Absolute URL of the download route: serves raw bytes (binary-safe) with
|
|
10561
10461
|
* `Content-Disposition: attachment`, so the browser saves the file. */
|
|
10562
10462
|
function downloadUrl(scope, path) {
|
|
10563
|
-
return fileUrl(scope, path, true);
|
|
10564
|
-
}
|
|
10565
|
-
/** Shared URL builder for the /sidebar/file route (media vs download). */
|
|
10566
|
-
function fileUrl(scope, path, download) {
|
|
10567
10463
|
const params = new URLSearchParams({
|
|
10568
10464
|
sessionId: scope.sessionId,
|
|
10569
|
-
path
|
|
10465
|
+
path,
|
|
10466
|
+
download: "1"
|
|
10570
10467
|
});
|
|
10571
10468
|
if (scope.cwd !== void 0 && scope.cwd !== "") params.set("cwd", scope.cwd);
|
|
10572
|
-
if (download) params.set("download", "1");
|
|
10573
10469
|
return `/sidebar/file?${params.toString()}`;
|
|
10574
10470
|
}
|
|
10575
10471
|
//#endregion
|
|
@@ -10590,67 +10486,6 @@ window.__ModuleLoader__.load({
|
|
|
10590
10486
|
});
|
|
10591
10487
|
}
|
|
10592
10488
|
//#endregion
|
|
10593
|
-
//#region src/client/editor-load.ts
|
|
10594
|
-
/** Decode the host's base64 head bytes into the sniffing buffer. */
|
|
10595
|
-
function decodeHead(headBase64) {
|
|
10596
|
-
const binary = atob(headBase64);
|
|
10597
|
-
const bytes = new Uint8Array(binary.length);
|
|
10598
|
-
for (let i = 0; i < binary.length; i += 1) bytes[i] = binary.charCodeAt(i);
|
|
10599
|
-
return bytes;
|
|
10600
|
-
}
|
|
10601
|
-
/**
|
|
10602
|
-
* Dispatch one matched viewer's fetchStrategy. A missing viewer or a
|
|
10603
|
-
* `binary-download` strategy both mean "no client-side renderer" → the
|
|
10604
|
-
* download UI. `mediaUrlOf` builds the media URL for `mediaUrl`/`none`
|
|
10605
|
-
* strategies (pure, but scope-bound — injected by the host).
|
|
10606
|
-
*/
|
|
10607
|
-
function planFirstMatch(viewer, mediaUrlOf) {
|
|
10608
|
-
if (viewer === void 0 || viewer.fetchStrategy === "binary-download") return { kind: "binary" };
|
|
10609
|
-
switch (viewer.fetchStrategy) {
|
|
10610
|
-
case "mediaUrl":
|
|
10611
|
-
case "none": return {
|
|
10612
|
-
kind: "render",
|
|
10613
|
-
viewer,
|
|
10614
|
-
mediaUrl: mediaUrlOf()
|
|
10615
|
-
};
|
|
10616
|
-
case "custom": return {
|
|
10617
|
-
kind: "customLoad",
|
|
10618
|
-
viewer
|
|
10619
|
-
};
|
|
10620
|
-
case "fsRead": return {
|
|
10621
|
-
kind: "fetchFsRead",
|
|
10622
|
-
viewer
|
|
10623
|
-
};
|
|
10624
|
-
}
|
|
10625
|
-
}
|
|
10626
|
-
/**
|
|
10627
|
-
* Decide what an fsRead result means for the editor.
|
|
10628
|
-
* - Text: the first match stands (content is valid for any fsRead viewer).
|
|
10629
|
-
* - Binary: the host head bytes enable a re-match — a `detect` viewer (e.g.
|
|
10630
|
-
* a plugin sniffing a binary format) may claim the file. `custom` viewers
|
|
10631
|
-
* load their own bytes; `mediaUrl`/`none` viewers render the media route;
|
|
10632
|
-
* an fsRead viewer or nothing cannot render binary → download UI.
|
|
10633
|
-
*/
|
|
10634
|
-
function planFsReadOutcome(viewer, result, rematch, mediaUrlOf) {
|
|
10635
|
-
if (!result.binary) return {
|
|
10636
|
-
kind: "render",
|
|
10637
|
-
viewer,
|
|
10638
|
-
content: result.content,
|
|
10639
|
-
truncated: result.truncated
|
|
10640
|
-
};
|
|
10641
|
-
const claimed = result.head === void 0 ? void 0 : rematch(decodeHead(result.head));
|
|
10642
|
-
if (claimed !== void 0 && claimed.fetchStrategy === "custom") return {
|
|
10643
|
-
kind: "customLoad",
|
|
10644
|
-
viewer: claimed
|
|
10645
|
-
};
|
|
10646
|
-
if (claimed !== void 0 && (claimed.fetchStrategy === "mediaUrl" || claimed.fetchStrategy === "none")) return {
|
|
10647
|
-
kind: "render",
|
|
10648
|
-
viewer: claimed,
|
|
10649
|
-
mediaUrl: mediaUrlOf()
|
|
10650
|
-
};
|
|
10651
|
-
return { kind: "binary" };
|
|
10652
|
-
}
|
|
10653
|
-
//#endregion
|
|
10654
10489
|
//#region node_modules/.pnpm/react-icons@5.7.0_react@18.3.1/node_modules/react-icons/lib/iconContext.mjs
|
|
10655
10490
|
var DefaultContext = {
|
|
10656
10491
|
color: void 0,
|
|
@@ -10796,6 +10631,24 @@ window.__ModuleLoader__.load({
|
|
|
10796
10631
|
}
|
|
10797
10632
|
//#endregion
|
|
10798
10633
|
//#region node_modules/.pnpm/react-icons@5.7.0_react@18.3.1/node_modules/react-icons/vsc/index.mjs
|
|
10634
|
+
function VscRemoteExplorer(props) {
|
|
10635
|
+
return GenIcon({
|
|
10636
|
+
"tag": "svg",
|
|
10637
|
+
"attr": {
|
|
10638
|
+
"viewBox": "0 0 24 25",
|
|
10639
|
+
"fill": "currentColor"
|
|
10640
|
+
},
|
|
10641
|
+
"child": [{
|
|
10642
|
+
"tag": "path",
|
|
10643
|
+
"attr": {
|
|
10644
|
+
"fillRule": "evenodd",
|
|
10645
|
+
"clipRule": "evenodd",
|
|
10646
|
+
"d": "M9.32 20.0677C9.469 20.5907 9.667 21.0917 9.911 21.5677H3.759C3.345 21.5677 3.009 21.2317 3.009 20.8177C3.009 20.4037 3.345 20.0677 3.759 20.0677H6.008V18.5517H3C1.343 18.5517 0 17.2087 0 15.5517V5.06775C0 3.41075 1.343 2.06775 3 2.06775H16.5C18.157 2.06775 19.5 3.41075 19.5 5.06775V9.88775C19.016 9.74975 18.516 9.65275 18 9.60575V5.06775C18 4.23975 17.328 3.56775 16.5 3.56775H3C2.172 3.56775 1.5 4.23975 1.5 5.06775V15.5517C1.5 16.3797 2.172 17.0517 3 17.0517H9.039C9.016 17.3047 9 17.5587 9 17.8177C9 18.0657 9.016 18.3097 9.037 18.5517H7.507V20.0677H9.32ZM24 17.8177C24 21.5457 20.978 24.5677 17.25 24.5677C13.522 24.5677 10.5 21.5457 10.5 17.8177C10.5 14.0897 13.522 11.0677 17.25 11.0677C20.978 11.0677 24 14.0897 24 17.8177ZM17.251 19.3177C17.251 19.2187 17.231 19.1217 17.194 19.0307C17.156 18.9397 17.101 18.8567 17.031 18.7867L14.781 16.5367C14.64 16.3957 14.449 16.3167 14.25 16.3167C14.051 16.3167 13.86 16.3957 13.719 16.5367C13.578 16.6777 13.499 16.8687 13.499 17.0677C13.499 17.2667 13.578 17.4577 13.719 17.5987L15.44 19.3177L13.719 21.0367C13.578 21.1777 13.499 21.3687 13.499 21.5677C13.499 21.7667 13.578 21.9577 13.719 22.0987C13.86 22.2397 14.051 22.3187 14.25 22.3187C14.449 22.3187 14.64 22.2397 14.781 22.0987L17.031 19.8487C17.101 19.7787 17.156 19.6967 17.194 19.6057C17.232 19.5147 17.251 19.4167 17.251 19.3177ZM19.06 16.3177L20.78 14.5987C20.921 14.4577 21 14.2667 21 14.0677C21 13.8687 20.921 13.6777 20.78 13.5367C20.639 13.3957 20.448 13.3167 20.249 13.3167C20.05 13.3167 19.859 13.3957 19.718 13.5367L17.468 15.7867C17.398 15.8567 17.343 15.9387 17.305 16.0307C17.267 16.1217 17.248 16.2197 17.248 16.3177C17.248 16.4157 17.268 16.5137 17.305 16.6057C17.343 16.6967 17.398 16.7797 17.468 16.8487L19.718 19.0987C19.859 19.2397 20.05 19.3187 20.249 19.3187C20.448 19.3187 20.639 19.2397 20.78 19.0987C20.921 18.9577 21 18.7667 21 18.5677C21 18.3687 20.921 18.1777 20.78 18.0367L19.06 16.3177Z"
|
|
10647
|
+
},
|
|
10648
|
+
"child": []
|
|
10649
|
+
}]
|
|
10650
|
+
})(props);
|
|
10651
|
+
}
|
|
10799
10652
|
function VscPinned(props) {
|
|
10800
10653
|
return GenIcon({
|
|
10801
10654
|
"tag": "svg",
|
|
@@ -11042,137 +10895,6 @@ window.__ModuleLoader__.load({
|
|
|
11042
10895
|
strokeLinejoin: "round"
|
|
11043
10896
|
})
|
|
11044
10897
|
});
|
|
11045
|
-
/** Image viewer glyph: a picture frame with a sun and a mountain. */
|
|
11046
|
-
const IconImageOutline16 = ({ size = 16, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
11047
|
-
width: size,
|
|
11048
|
-
height: size,
|
|
11049
|
-
className,
|
|
11050
|
-
viewBox: "0 0 16 16",
|
|
11051
|
-
fill: "none",
|
|
11052
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
11053
|
-
children: [
|
|
11054
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
11055
|
-
x: "1.5",
|
|
11056
|
-
y: "2.5",
|
|
11057
|
-
width: "13",
|
|
11058
|
-
height: "11",
|
|
11059
|
-
rx: "2",
|
|
11060
|
-
stroke: "currentColor",
|
|
11061
|
-
strokeWidth: "1.5"
|
|
11062
|
-
}),
|
|
11063
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
11064
|
-
cx: "5.5",
|
|
11065
|
-
cy: "6",
|
|
11066
|
-
r: "1.2",
|
|
11067
|
-
stroke: "currentColor",
|
|
11068
|
-
strokeWidth: "1.5"
|
|
11069
|
-
}),
|
|
11070
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11071
|
-
d: "m3.5 12 3-3 2.25 2.25L11.5 8.5 13 10.5",
|
|
11072
|
-
stroke: "currentColor",
|
|
11073
|
-
strokeWidth: "1.5",
|
|
11074
|
-
strokeLinecap: "round",
|
|
11075
|
-
strokeLinejoin: "round"
|
|
11076
|
-
})
|
|
11077
|
-
]
|
|
11078
|
-
});
|
|
11079
|
-
/** PDF viewer glyph: a document frame with the "PDF" label. */
|
|
11080
|
-
const IconPdfOutline16 = ({ size = 16, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
11081
|
-
width: size,
|
|
11082
|
-
height: size,
|
|
11083
|
-
className,
|
|
11084
|
-
viewBox: "0 0 16 16",
|
|
11085
|
-
fill: "none",
|
|
11086
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
11087
|
-
children: [
|
|
11088
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11089
|
-
d: "M3.5 1.5h6.5L13.5 5v9.5h-10z",
|
|
11090
|
-
stroke: "currentColor",
|
|
11091
|
-
strokeWidth: "1.5",
|
|
11092
|
-
strokeLinejoin: "round"
|
|
11093
|
-
}),
|
|
11094
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11095
|
-
d: "M9.5 1.5V5h4",
|
|
11096
|
-
stroke: "currentColor",
|
|
11097
|
-
strokeWidth: "1.5",
|
|
11098
|
-
strokeLinejoin: "round"
|
|
11099
|
-
}),
|
|
11100
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11101
|
-
d: "M5 13.5v-3h1.4c.75 0 1.1.32 1.1.85 0 .54-.35.85-1.1.85H5.3",
|
|
11102
|
-
stroke: "currentColor",
|
|
11103
|
-
strokeWidth: "1.25",
|
|
11104
|
-
strokeLinecap: "round",
|
|
11105
|
-
strokeLinejoin: "round"
|
|
11106
|
-
}),
|
|
11107
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11108
|
-
d: "M8.3 13.5v-3h1.05c.8 0 1.35.5 1.35 1.5s-.55 1.5-1.35 1.5z",
|
|
11109
|
-
stroke: "currentColor",
|
|
11110
|
-
strokeWidth: "1.25",
|
|
11111
|
-
strokeLinecap: "round",
|
|
11112
|
-
strokeLinejoin: "round"
|
|
11113
|
-
}),
|
|
11114
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11115
|
-
d: "M11.6 13.5v-3h1.3",
|
|
11116
|
-
stroke: "currentColor",
|
|
11117
|
-
strokeWidth: "1.25",
|
|
11118
|
-
strokeLinecap: "round"
|
|
11119
|
-
})
|
|
11120
|
-
]
|
|
11121
|
-
});
|
|
11122
|
-
/** Markdown viewer glyph: the classic "M with a down arrow" badge. */
|
|
11123
|
-
const IconMarkdownOutline16 = ({ size = 16, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
11124
|
-
width: size,
|
|
11125
|
-
height: size,
|
|
11126
|
-
className,
|
|
11127
|
-
viewBox: "0 0 16 16",
|
|
11128
|
-
fill: "none",
|
|
11129
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
11130
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
11131
|
-
x: "1.5",
|
|
11132
|
-
y: "2.5",
|
|
11133
|
-
width: "13",
|
|
11134
|
-
height: "11",
|
|
11135
|
-
rx: "2",
|
|
11136
|
-
stroke: "currentColor",
|
|
11137
|
-
strokeWidth: "1.5"
|
|
11138
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11139
|
-
d: "M4 10.5V5.5l2 2.5 2-2.5v5M9.5 10.5v-5l2 2.5 2-2.5v5",
|
|
11140
|
-
stroke: "currentColor",
|
|
11141
|
-
strokeWidth: "1.5",
|
|
11142
|
-
strokeLinecap: "round",
|
|
11143
|
-
strokeLinejoin: "round"
|
|
11144
|
-
})]
|
|
11145
|
-
});
|
|
11146
|
-
/** HTML viewer glyph: a document frame with a "‹/›" tag pair. */
|
|
11147
|
-
const IconHtmlOutline16 = ({ size = 16, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
11148
|
-
width: size,
|
|
11149
|
-
height: size,
|
|
11150
|
-
className,
|
|
11151
|
-
viewBox: "0 0 16 16",
|
|
11152
|
-
fill: "none",
|
|
11153
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
11154
|
-
children: [
|
|
11155
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11156
|
-
d: "M3.5 1.5h6.5L13.5 5v9.5h-10z",
|
|
11157
|
-
stroke: "currentColor",
|
|
11158
|
-
strokeWidth: "1.5",
|
|
11159
|
-
strokeLinejoin: "round"
|
|
11160
|
-
}),
|
|
11161
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11162
|
-
d: "M9.5 1.5V5h4",
|
|
11163
|
-
stroke: "currentColor",
|
|
11164
|
-
strokeWidth: "1.5",
|
|
11165
|
-
strokeLinejoin: "round"
|
|
11166
|
-
}),
|
|
11167
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
11168
|
-
d: "M5.6 13.2 4.2 10l1.4-3.2M7.4 6.8 8.8 10l-1.4 3.2",
|
|
11169
|
-
stroke: "currentColor",
|
|
11170
|
-
strokeWidth: "1.25",
|
|
11171
|
-
strokeLinecap: "round",
|
|
11172
|
-
strokeLinejoin: "round"
|
|
11173
|
-
})
|
|
11174
|
-
]
|
|
11175
|
-
});
|
|
11176
10898
|
/** Browser tab glyph: a globe with meridians. */
|
|
11177
10899
|
const IconGlobeOutline16 = ({ size = 16, className }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
11178
10900
|
width: size,
|
|
@@ -12296,15 +12018,12 @@ window.__ModuleLoader__.load({
|
|
|
12296
12018
|
customCss: typeof record.customCss === "string" ? record.customCss : SIDEBAR_PREFS_DEFAULTS.customCss,
|
|
12297
12019
|
titleBarCompat: typeof record.titleBarCompat === "boolean" ? record.titleBarCompat : SIDEBAR_PREFS_DEFAULTS.titleBarCompat,
|
|
12298
12020
|
titleBarStripPx: typeof record.titleBarStripPx === "number" && Number.isFinite(record.titleBarStripPx) ? clampTitleBarStrip(record.titleBarStripPx) : SIDEBAR_PREFS_DEFAULTS.titleBarStripPx,
|
|
12299
|
-
htmlViewerNoSandbox: typeof record.htmlViewerNoSandbox === "boolean" ? record.htmlViewerNoSandbox : SIDEBAR_PREFS_DEFAULTS.htmlViewerNoSandbox,
|
|
12300
|
-
htmlViewerDefaultUnsafe: typeof record.htmlViewerDefaultUnsafe === "boolean" ? record.htmlViewerDefaultUnsafe : SIDEBAR_PREFS_DEFAULTS.htmlViewerDefaultUnsafe,
|
|
12301
12021
|
browserNoSandbox: typeof record.browserNoSandbox === "boolean" ? record.browserNoSandbox : SIDEBAR_PREFS_DEFAULTS.browserNoSandbox,
|
|
12302
12022
|
browserInterceptLinks: typeof record.browserInterceptLinks === "boolean" ? record.browserInterceptLinks : SIDEBAR_PREFS_DEFAULTS.browserInterceptLinks,
|
|
12303
12023
|
browserInterceptHttp: typeof record.browserInterceptHttp === "boolean" ? record.browserInterceptHttp : SIDEBAR_PREFS_DEFAULTS.browserInterceptHttp,
|
|
12304
12024
|
browserInterceptHttps: typeof record.browserInterceptHttps === "boolean" ? record.browserInterceptHttps : SIDEBAR_PREFS_DEFAULTS.browserInterceptHttps,
|
|
12305
12025
|
browserAllowedLoopback: typeof record.browserAllowedLoopback === "string" ? record.browserAllowedLoopback : SIDEBAR_PREFS_DEFAULTS.browserAllowedLoopback,
|
|
12306
12026
|
tabsEnabled: booleanMapOf(record.tabsEnabled),
|
|
12307
|
-
viewersEnabled: booleanMapOf(record.viewersEnabled),
|
|
12308
12027
|
pluginSettings: pluginSettingsMapOf(record.pluginSettings)
|
|
12309
12028
|
};
|
|
12310
12029
|
}
|
|
@@ -12728,14 +12447,98 @@ window.__ModuleLoader__.load({
|
|
|
12728
12447
|
});
|
|
12729
12448
|
}
|
|
12730
12449
|
//#endregion
|
|
12450
|
+
//#region src/client/lazy-chunk.tsx
|
|
12451
|
+
/**
|
|
12452
|
+
* Lazy chunk view wrapper: mounts a component that lives in a lazy chunk,
|
|
12453
|
+
* showing a loading placeholder while the chunk script loads and an error +
|
|
12454
|
+
* retry affordance on failure. Used by the built-in tab/viewer descriptors.
|
|
12455
|
+
*
|
|
12456
|
+
* Contract note: {@link lazyChunkComponent} returns a plain render-prop
|
|
12457
|
+
* function — the descriptor contract is `component: (props) => ReactNode`,
|
|
12458
|
+
* and the repo renders descriptors BOTH ways: Sidebar calls
|
|
12459
|
+
* `descriptor.component(props)` directly, EditorHost renders it via
|
|
12460
|
+
* `createElement`. The wrapper function body therefore contains no hooks;
|
|
12461
|
+
* all state lives in the inner {@link LazyChunkView} component.
|
|
12462
|
+
*/
|
|
12463
|
+
function LazyChunkView({ chunk, pick, props }) {
|
|
12464
|
+
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
12465
|
+
const [state, setState] = (0, react.useState)({ status: "loading" });
|
|
12466
|
+
(0, react.useEffect)(() => {
|
|
12467
|
+
let cancelled = false;
|
|
12468
|
+
setState({ status: "loading" });
|
|
12469
|
+
loadChunk(chunk).then((mod) => {
|
|
12470
|
+
if (cancelled) return;
|
|
12471
|
+
const Comp = pick(mod);
|
|
12472
|
+
if (Comp === void 0) {
|
|
12473
|
+
setState({
|
|
12474
|
+
status: "error",
|
|
12475
|
+
message: `[dsh-coding-sidebar] chunk "${chunk}" is missing its component`
|
|
12476
|
+
});
|
|
12477
|
+
return;
|
|
12478
|
+
}
|
|
12479
|
+
setState({
|
|
12480
|
+
status: "ready",
|
|
12481
|
+
Comp
|
|
12482
|
+
});
|
|
12483
|
+
}).catch((error) => {
|
|
12484
|
+
if (cancelled) return;
|
|
12485
|
+
setState({
|
|
12486
|
+
status: "error",
|
|
12487
|
+
message: error instanceof Error ? error.message : String(error)
|
|
12488
|
+
});
|
|
12489
|
+
});
|
|
12490
|
+
return () => {
|
|
12491
|
+
cancelled = true;
|
|
12492
|
+
};
|
|
12493
|
+
}, [
|
|
12494
|
+
chunk,
|
|
12495
|
+
pick,
|
|
12496
|
+
attempt
|
|
12497
|
+
]);
|
|
12498
|
+
if (state.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
12499
|
+
className: sidebar_module_css_default.editorPlaceholder,
|
|
12500
|
+
children: t("loading")
|
|
12501
|
+
});
|
|
12502
|
+
if (state.status === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
12503
|
+
className: sidebar_module_css_default.editorError,
|
|
12504
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: state.message }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
12505
|
+
type: "button",
|
|
12506
|
+
className: sidebar_module_css_default.terminalRetry,
|
|
12507
|
+
onClick: () => {
|
|
12508
|
+
setAttempt((current) => current + 1);
|
|
12509
|
+
},
|
|
12510
|
+
children: t("terminalRetry")
|
|
12511
|
+
})]
|
|
12512
|
+
});
|
|
12513
|
+
return (0, react.createElement)(state.Comp, props);
|
|
12514
|
+
}
|
|
12515
|
+
/**
|
|
12516
|
+
* Build a descriptor-compatible lazy wrapper for a chunk-resident component.
|
|
12517
|
+
* The returned function is the descriptor `component` itself: it returns an
|
|
12518
|
+
* element and never calls hooks, so both invocation styles (plain function
|
|
12519
|
+
* call and createElement/JSX render) work. `pick` must be a module-level
|
|
12520
|
+
* function (stable identity) — an inline lambda would re-trigger the load
|
|
12521
|
+
* effect on every render.
|
|
12522
|
+
* @param chunk - the chunk name (see chunk-loader.ts).
|
|
12523
|
+
* @param pick - select the component from the chunk's exports.
|
|
12524
|
+
*/
|
|
12525
|
+
function lazyChunkComponent(chunk, pick) {
|
|
12526
|
+
return (props) => (0, react.createElement)(LazyChunkView, {
|
|
12527
|
+
chunk,
|
|
12528
|
+
pick,
|
|
12529
|
+
props
|
|
12530
|
+
});
|
|
12531
|
+
}
|
|
12532
|
+
//#endregion
|
|
12731
12533
|
//#region src/client/EditorHost.tsx
|
|
12732
12534
|
/**
|
|
12733
|
-
* The editor tab host: the single FILES WINDOW. It
|
|
12734
|
-
*
|
|
12735
|
-
*
|
|
12736
|
-
*
|
|
12737
|
-
*
|
|
12738
|
-
*
|
|
12535
|
+
* The editor tab host: the single FILES WINDOW. It fetches a file's text
|
|
12536
|
+
* through the host fs.read — text renders in the (chunk-lazy) sidebar text
|
|
12537
|
+
* editor, a binary file renders the shared download pane. (v1.0.4: the
|
|
12538
|
+
* file-viewer registry/matching was retired — file preview is the host's
|
|
12539
|
+
* job now, the sidebar edits text only.) A tab without a path (the seeded
|
|
12540
|
+
* "Files" home) renders an empty-state hint instead of the loading flow;
|
|
12541
|
+
* that path-less window IS the file explorer.
|
|
12739
12542
|
*
|
|
12740
12543
|
* The chrome depends on the `editorExplorer` mode (read reactively so
|
|
12741
12544
|
* toggling it re-renders without a reload):
|
|
@@ -12749,10 +12552,15 @@ window.__ModuleLoader__.load({
|
|
|
12749
12552
|
* The tree's context menu offers the explicit escapes in both modes: open
|
|
12750
12553
|
* in a new tab (per-path dedupe) or to the side (a fresh tab in a fresh
|
|
12751
12554
|
* rightward split of the current pane).
|
|
12752
|
-
*
|
|
12753
|
-
* The strategy dispatch is pure (planFirstMatch / planFsReadOutcome in
|
|
12754
|
-
* editor-load.ts); this component only wires it to the host APIs.
|
|
12755
12555
|
*/
|
|
12556
|
+
/**
|
|
12557
|
+
* Lazy wrapper over the chunk-resident text editor: CodeMirror and the
|
|
12558
|
+
* language packs are fetched only when a file tab first renders (see
|
|
12559
|
+
* chunk-loader.ts). The `pick` function is module-level (stable identity —
|
|
12560
|
+
* the wrapper effect depends on it); the cast bridges the chunk exports
|
|
12561
|
+
* record to the prop shape.
|
|
12562
|
+
*/
|
|
12563
|
+
const LazyTextEditor = lazyChunkComponent("editor", (mod) => mod.TextEditor);
|
|
12756
12564
|
/** The docked tree panel's width bounds (drag-resize clamps into them). */
|
|
12757
12565
|
const TREE_WIDTH_DEFAULT = 240;
|
|
12758
12566
|
const TREE_WIDTH_MIN = 160;
|
|
@@ -12790,7 +12598,6 @@ window.__ModuleLoader__.load({
|
|
|
12790
12598
|
function EditorHost(props) {
|
|
12791
12599
|
const { ctx, store, scope, tab, expanded, revealed, onToggleDir, onReferenceFile } = props;
|
|
12792
12600
|
const path = tab.path ?? "";
|
|
12793
|
-
const title = tab.title;
|
|
12794
12601
|
const isDir = metaOf(tab).dir === true;
|
|
12795
12602
|
const [load, setLoad] = (0, react.useState)({ status: "loading" });
|
|
12796
12603
|
const [reloadSeq, setReloadSeq] = (0, react.useState)(0);
|
|
@@ -12929,81 +12736,36 @@ window.__ModuleLoader__.load({
|
|
|
12929
12736
|
setToolbar(null);
|
|
12930
12737
|
if (showEmpty || isDir) return;
|
|
12931
12738
|
let cancelled = false;
|
|
12932
|
-
const controller = new AbortController();
|
|
12933
12739
|
setLoad({ status: "loading" });
|
|
12934
|
-
|
|
12935
|
-
const apply = (action) => {
|
|
12740
|
+
api.fsRead(scope, path).then((result) => {
|
|
12936
12741
|
if (cancelled) return;
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
return;
|
|
12941
|
-
case "render":
|
|
12942
|
-
setLoad({
|
|
12943
|
-
status: "ready",
|
|
12944
|
-
viewer: action.viewer,
|
|
12945
|
-
content: action.content,
|
|
12946
|
-
truncated: action.truncated,
|
|
12947
|
-
mediaUrl: action.mediaUrl,
|
|
12948
|
-
customData: action.customData
|
|
12949
|
-
});
|
|
12950
|
-
return;
|
|
12951
|
-
case "customLoad":
|
|
12952
|
-
action.viewer.load?.(path, scope, controller.signal).then((data) => {
|
|
12953
|
-
if (cancelled) return;
|
|
12954
|
-
setLoad({
|
|
12955
|
-
status: "ready",
|
|
12956
|
-
viewer: action.viewer,
|
|
12957
|
-
customData: data
|
|
12958
|
-
});
|
|
12959
|
-
}).catch((error) => {
|
|
12960
|
-
if (cancelled) return;
|
|
12961
|
-
setLoad({
|
|
12962
|
-
status: "error",
|
|
12963
|
-
message: error instanceof Error ? error.message : String(error)
|
|
12964
|
-
});
|
|
12965
|
-
});
|
|
12966
|
-
return;
|
|
12967
|
-
case "fetchFsRead":
|
|
12968
|
-
api.fsRead(scope, path).then((result) => {
|
|
12969
|
-
if (cancelled) return;
|
|
12970
|
-
const outcome = planFsReadOutcome(action.viewer, {
|
|
12971
|
-
binary: result.kind === "binary",
|
|
12972
|
-
content: result.kind === "text" ? result.content : "",
|
|
12973
|
-
truncated: result.truncated,
|
|
12974
|
-
head: result.kind === "binary" ? result.head : void 0
|
|
12975
|
-
}, (head) => ctx.get("betterSidebar")?.matchFileViewer(path, head), mediaUrlOf);
|
|
12976
|
-
apply(outcome);
|
|
12977
|
-
}).catch((error) => {
|
|
12978
|
-
if (cancelled) return;
|
|
12979
|
-
setLoad({
|
|
12980
|
-
status: "error",
|
|
12981
|
-
message: error instanceof Error ? error.message : String(error)
|
|
12982
|
-
});
|
|
12983
|
-
});
|
|
12984
|
-
return;
|
|
12742
|
+
if (result.kind === "binary") {
|
|
12743
|
+
setLoad({ status: "binary" });
|
|
12744
|
+
return;
|
|
12985
12745
|
}
|
|
12986
|
-
|
|
12987
|
-
|
|
12746
|
+
setLoad({
|
|
12747
|
+
status: "ready",
|
|
12748
|
+
content: result.content,
|
|
12749
|
+
truncated: result.truncated
|
|
12750
|
+
});
|
|
12751
|
+
}).catch((error) => {
|
|
12752
|
+
if (cancelled) return;
|
|
12753
|
+
setLoad({
|
|
12754
|
+
status: "error",
|
|
12755
|
+
message: error instanceof Error ? error.message : String(error)
|
|
12756
|
+
});
|
|
12757
|
+
});
|
|
12988
12758
|
return () => {
|
|
12989
12759
|
cancelled = true;
|
|
12990
|
-
controller.abort();
|
|
12991
12760
|
};
|
|
12992
12761
|
}, [
|
|
12993
12762
|
scope.sessionId,
|
|
12994
12763
|
scope.cwd,
|
|
12995
12764
|
path,
|
|
12996
|
-
ctx,
|
|
12997
12765
|
showEmpty,
|
|
12998
12766
|
isDir,
|
|
12999
12767
|
reloadSeq
|
|
13000
12768
|
]);
|
|
13001
|
-
const prevSaveState = (0, react.useRef)(void 0);
|
|
13002
|
-
(0, react.useEffect)(() => {
|
|
13003
|
-
const current = toolbar?.saveState;
|
|
13004
|
-
if (prevSaveState.current !== "saved" && current === "saved" && toolbar?.mode === "preview") setReloadSeq((sequence) => sequence + 1);
|
|
13005
|
-
prevSaveState.current = current;
|
|
13006
|
-
}, [toolbar?.saveState, toolbar?.mode]);
|
|
13007
12769
|
const treeOpen = treeOpenOf(tab);
|
|
13008
12770
|
/** Persist the panel flag on the tab (survives reloads with the layout). */
|
|
13009
12771
|
const toggleTree = () => {
|
|
@@ -13040,25 +12802,6 @@ window.__ModuleLoader__.load({
|
|
|
13040
12802
|
cwd: scope.cwd,
|
|
13041
12803
|
onOpen: openFile
|
|
13042
12804
|
}, path),
|
|
13043
|
-
toolbar?.modes === true && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13044
|
-
className: sidebar_module_css_default.editorModeToggle,
|
|
13045
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13046
|
-
type: "button",
|
|
13047
|
-
className: clsx(sidebar_module_css_default.editorModeButton, toolbar.mode === "preview" && sidebar_module_css_default.editorModeActive),
|
|
13048
|
-
onClick: () => {
|
|
13049
|
-
if (toolbar.mode === "edit" && toolbar.dirty !== true && toolbar.saveState !== "failed") setReloadSeq((sequence) => sequence + 1);
|
|
13050
|
-
controlsRef.current?.setMode("preview");
|
|
13051
|
-
},
|
|
13052
|
-
children: t("preview")
|
|
13053
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13054
|
-
type: "button",
|
|
13055
|
-
className: clsx(sidebar_module_css_default.editorModeButton, toolbar.mode === "edit" && sidebar_module_css_default.editorModeActive),
|
|
13056
|
-
onClick: () => {
|
|
13057
|
-
controlsRef.current?.setMode("edit");
|
|
13058
|
-
},
|
|
13059
|
-
children: t("edit")
|
|
13060
|
-
})]
|
|
13061
|
-
}),
|
|
13062
12805
|
toolbar?.dirty === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
13063
12806
|
className: sidebar_module_css_default.dirtyDot,
|
|
13064
12807
|
title: t("unsaved")
|
|
@@ -13116,17 +12859,13 @@ window.__ModuleLoader__.load({
|
|
|
13116
12859
|
scope,
|
|
13117
12860
|
path
|
|
13118
12861
|
}),
|
|
13119
|
-
!showEmpty && load.status === "ready" && (0,
|
|
12862
|
+
!showEmpty && load.status === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyTextEditor, {
|
|
13120
12863
|
ctx,
|
|
13121
12864
|
store,
|
|
13122
12865
|
scope,
|
|
13123
12866
|
path,
|
|
13124
|
-
title,
|
|
13125
|
-
viewerId: load.viewer.id,
|
|
13126
12867
|
content: load.content,
|
|
13127
12868
|
truncated: load.truncated,
|
|
13128
|
-
mediaUrl: load.mediaUrl,
|
|
13129
|
-
customData: load.customData,
|
|
13130
12869
|
toolbar: "host",
|
|
13131
12870
|
onToolbarState,
|
|
13132
12871
|
onToolbarControls
|
|
@@ -13217,75 +12956,75 @@ window.__ModuleLoader__.load({
|
|
|
13217
12956
|
document.head.appendChild(tag);
|
|
13218
12957
|
}
|
|
13219
12958
|
var SideCardSection_module_css_default = {
|
|
13220
|
-
"
|
|
13221
|
-
"
|
|
13222
|
-
"
|
|
12959
|
+
"typedInputNumber": "AC9POW_typedInputNumber",
|
|
12960
|
+
"cssTextArea": "AC9POW_cssTextArea",
|
|
12961
|
+
"pluginGroupHeading": "AC9POW_pluginGroupHeading",
|
|
12962
|
+
"switchTrack": "AC9POW_switchTrack",
|
|
12963
|
+
"rowText": "AC9POW_rowText",
|
|
12964
|
+
"desc": "AC9POW_desc",
|
|
12965
|
+
"percentInput": "AC9POW_percentInput",
|
|
12966
|
+
"openWithFamily": "AC9POW_openWithFamily",
|
|
12967
|
+
"suffix": "AC9POW_suffix",
|
|
13223
12968
|
"openWithEditorInput": "AC9POW_openWithEditorInput",
|
|
13224
|
-
"
|
|
12969
|
+
"pluginName": "AC9POW_pluginName",
|
|
12970
|
+
"cardSwitchThumb": "AC9POW_cardSwitchThumb",
|
|
12971
|
+
"openWithHint": "AC9POW_openWithHint",
|
|
12972
|
+
"cardSettings": "AC9POW_cardSettings",
|
|
13225
12973
|
"pluginInstall": "AC9POW_pluginInstall",
|
|
12974
|
+
"cardIconChip": "AC9POW_cardIconChip",
|
|
12975
|
+
"selectAnchor": "AC9POW_selectAnchor",
|
|
12976
|
+
"pluginModal": "AC9POW_pluginModal",
|
|
13226
12977
|
"pluginEntryHead": "AC9POW_pluginEntryHead",
|
|
12978
|
+
"cardTitle": "AC9POW_cardTitle",
|
|
12979
|
+
"popupRows": "AC9POW_popupRows",
|
|
12980
|
+
"cardTop": "AC9POW_cardTop",
|
|
12981
|
+
"popupRow": "AC9POW_popupRow",
|
|
12982
|
+
"group": "AC9POW_group",
|
|
12983
|
+
"row": "AC9POW_row",
|
|
12984
|
+
"pluginJumpBtn": "AC9POW_pluginJumpBtn",
|
|
12985
|
+
"grid": "AC9POW_grid",
|
|
12986
|
+
"versionBadgeTag": "AC9POW_versionBadgeTag",
|
|
12987
|
+
"pluginEntryActions": "AC9POW_pluginEntryActions",
|
|
12988
|
+
"selectOption": "AC9POW_selectOption",
|
|
12989
|
+
"cardDesc": "AC9POW_cardDesc",
|
|
12990
|
+
"pluginDesc": "AC9POW_pluginDesc",
|
|
12991
|
+
"section": "AC9POW_section",
|
|
13227
12992
|
"openWithEditorTemplate": "AC9POW_openWithEditorTemplate",
|
|
13228
12993
|
"versionBadge": "AC9POW_versionBadge",
|
|
13229
|
-
"cardDesc": "AC9POW_cardDesc",
|
|
13230
|
-
"percentInput": "AC9POW_percentInput",
|
|
13231
|
-
"pluginGroup": "AC9POW_pluginGroup",
|
|
13232
12994
|
"switch": "AC9POW_switch",
|
|
13233
|
-
"
|
|
13234
|
-
"
|
|
13235
|
-
"
|
|
13236
|
-
"
|
|
13237
|
-
"cardIconChip": "AC9POW_cardIconChip",
|
|
13238
|
-
"versionBadgeTag": "AC9POW_versionBadgeTag",
|
|
12995
|
+
"pluginList": "AC9POW_pluginList",
|
|
12996
|
+
"versionBadgeName": "AC9POW_versionBadgeName",
|
|
12997
|
+
"openWithEditorRow": "AC9POW_openWithEditorRow",
|
|
12998
|
+
"selectAnchorText": "AC9POW_selectAnchorText",
|
|
13239
12999
|
"pluginCopyBtn": "AC9POW_pluginCopyBtn",
|
|
13000
|
+
"card": "AC9POW_card",
|
|
13240
13001
|
"selectOptionText": "AC9POW_selectOptionText",
|
|
13241
|
-
"
|
|
13242
|
-
"popupRow": "AC9POW_popupRow",
|
|
13243
|
-
"pluginSearch": "AC9POW_pluginSearch",
|
|
13244
|
-
"typedInputNumber": "AC9POW_typedInputNumber",
|
|
13245
|
-
"rowGear": "AC9POW_rowGear",
|
|
13246
|
-
"pluginJumpBtn": "AC9POW_pluginJumpBtn",
|
|
13247
|
-
"switchThumb": "AC9POW_switchThumb",
|
|
13248
|
-
"section": "AC9POW_section",
|
|
13249
|
-
"suffix": "AC9POW_suffix",
|
|
13250
|
-
"grid": "AC9POW_grid",
|
|
13251
|
-
"pluginDesc": "AC9POW_pluginDesc",
|
|
13252
|
-
"cardSwitchThumb": "AC9POW_cardSwitchThumb",
|
|
13253
|
-
"cardSettings": "AC9POW_cardSettings",
|
|
13254
|
-
"openWithFamily": "AC9POW_openWithFamily",
|
|
13255
|
-
"row": "AC9POW_row",
|
|
13256
|
-
"cardMain": "AC9POW_cardMain",
|
|
13257
|
-
"groupHeading": "AC9POW_groupHeading",
|
|
13002
|
+
"intro": "AC9POW_intro",
|
|
13258
13003
|
"popupDialog": "AC9POW_popupDialog",
|
|
13259
|
-
"count": "AC9POW_count",
|
|
13260
|
-
"openWithHint": "AC9POW_openWithHint",
|
|
13261
|
-
"cardTitle": "AC9POW_cardTitle",
|
|
13262
|
-
"selectAnchorText": "AC9POW_selectAnchorText",
|
|
13263
|
-
"selectOption": "AC9POW_selectOption",
|
|
13264
13004
|
"typedInput": "AC9POW_typedInput",
|
|
13265
|
-
"error": "AC9POW_error",
|
|
13266
|
-
"cardOn": "AC9POW_cardOn",
|
|
13267
|
-
"pluginEmpty": "AC9POW_pluginEmpty",
|
|
13268
|
-
"popupRows": "AC9POW_popupRows",
|
|
13269
|
-
"control": "AC9POW_control",
|
|
13270
|
-
"card": "AC9POW_card",
|
|
13271
|
-
"cssTextArea": "AC9POW_cssTextArea",
|
|
13272
|
-
"done": "AC9POW_done",
|
|
13273
|
-
"pluginGroupHeading": "AC9POW_pluginGroupHeading",
|
|
13274
|
-
"desc": "AC9POW_desc",
|
|
13275
|
-
"selectAnchorIcon": "AC9POW_selectAnchorIcon",
|
|
13276
13005
|
"pluginEntry": "AC9POW_pluginEntry",
|
|
13277
|
-
"
|
|
13278
|
-
"versionBadgeName": "AC9POW_versionBadgeName",
|
|
13006
|
+
"pluginEntries": "AC9POW_pluginEntries",
|
|
13279
13007
|
"title": "AC9POW_title",
|
|
13280
|
-
"
|
|
13281
|
-
"
|
|
13282
|
-
"
|
|
13283
|
-
"
|
|
13008
|
+
"pluginGroup": "AC9POW_pluginGroup",
|
|
13009
|
+
"openWithRemove": "AC9POW_openWithRemove",
|
|
13010
|
+
"cardOn": "AC9POW_cardOn",
|
|
13011
|
+
"switchThumb": "AC9POW_switchThumb",
|
|
13012
|
+
"control": "AC9POW_control",
|
|
13013
|
+
"pluginSearch": "AC9POW_pluginSearch",
|
|
13014
|
+
"rowGear": "AC9POW_rowGear",
|
|
13015
|
+
"switchInput": "AC9POW_switchInput",
|
|
13016
|
+
"selectOptionIcon": "AC9POW_selectOptionIcon",
|
|
13017
|
+
"groupHeading": "AC9POW_groupHeading",
|
|
13284
13018
|
"cardSwitchTrack": "AC9POW_cardSwitchTrack",
|
|
13019
|
+
"selectAnchorIcon": "AC9POW_selectAnchorIcon",
|
|
13020
|
+
"done": "AC9POW_done",
|
|
13021
|
+
"pluginTopicBtn": "AC9POW_pluginTopicBtn",
|
|
13285
13022
|
"addCard": "AC9POW_addCard",
|
|
13286
|
-
"
|
|
13287
|
-
"
|
|
13288
|
-
"
|
|
13023
|
+
"cardMain": "AC9POW_cardMain",
|
|
13024
|
+
"cardSwitch": "AC9POW_cardSwitch",
|
|
13025
|
+
"error": "AC9POW_error",
|
|
13026
|
+
"pluginEmpty": "AC9POW_pluginEmpty",
|
|
13027
|
+
"count": "AC9POW_count"
|
|
13289
13028
|
};
|
|
13290
13029
|
//#endregion
|
|
13291
13030
|
//#region src/client/open-with-settings.tsx
|
|
@@ -13437,89 +13176,6 @@ window.__ModuleLoader__.load({
|
|
|
13437
13176
|
});
|
|
13438
13177
|
}
|
|
13439
13178
|
//#endregion
|
|
13440
|
-
//#region src/client/lazy-chunk.tsx
|
|
13441
|
-
/**
|
|
13442
|
-
* Lazy chunk view wrapper: mounts a component that lives in a lazy chunk,
|
|
13443
|
-
* showing a loading placeholder while the chunk script loads and an error +
|
|
13444
|
-
* retry affordance on failure. Used by the built-in tab/viewer descriptors.
|
|
13445
|
-
*
|
|
13446
|
-
* Contract note: {@link lazyChunkComponent} returns a plain render-prop
|
|
13447
|
-
* function — the descriptor contract is `component: (props) => ReactNode`,
|
|
13448
|
-
* and the repo renders descriptors BOTH ways: Sidebar calls
|
|
13449
|
-
* `descriptor.component(props)` directly, EditorHost renders it via
|
|
13450
|
-
* `createElement`. The wrapper function body therefore contains no hooks;
|
|
13451
|
-
* all state lives in the inner {@link LazyChunkView} component.
|
|
13452
|
-
*/
|
|
13453
|
-
function LazyChunkView({ chunk, pick, props }) {
|
|
13454
|
-
const [attempt, setAttempt] = (0, react.useState)(0);
|
|
13455
|
-
const [state, setState] = (0, react.useState)({ status: "loading" });
|
|
13456
|
-
(0, react.useEffect)(() => {
|
|
13457
|
-
let cancelled = false;
|
|
13458
|
-
setState({ status: "loading" });
|
|
13459
|
-
loadChunk(chunk).then((mod) => {
|
|
13460
|
-
if (cancelled) return;
|
|
13461
|
-
const Comp = pick(mod);
|
|
13462
|
-
if (Comp === void 0) {
|
|
13463
|
-
setState({
|
|
13464
|
-
status: "error",
|
|
13465
|
-
message: `[dsh-coding-sidebar] chunk "${chunk}" is missing its component`
|
|
13466
|
-
});
|
|
13467
|
-
return;
|
|
13468
|
-
}
|
|
13469
|
-
setState({
|
|
13470
|
-
status: "ready",
|
|
13471
|
-
Comp
|
|
13472
|
-
});
|
|
13473
|
-
}).catch((error) => {
|
|
13474
|
-
if (cancelled) return;
|
|
13475
|
-
setState({
|
|
13476
|
-
status: "error",
|
|
13477
|
-
message: error instanceof Error ? error.message : String(error)
|
|
13478
|
-
});
|
|
13479
|
-
});
|
|
13480
|
-
return () => {
|
|
13481
|
-
cancelled = true;
|
|
13482
|
-
};
|
|
13483
|
-
}, [
|
|
13484
|
-
chunk,
|
|
13485
|
-
pick,
|
|
13486
|
-
attempt
|
|
13487
|
-
]);
|
|
13488
|
-
if (state.status === "loading") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
13489
|
-
className: sidebar_module_css_default.editorPlaceholder,
|
|
13490
|
-
children: t("loading")
|
|
13491
|
-
});
|
|
13492
|
-
if (state.status === "error") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
13493
|
-
className: sidebar_module_css_default.editorError,
|
|
13494
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: state.message }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
13495
|
-
type: "button",
|
|
13496
|
-
className: sidebar_module_css_default.terminalRetry,
|
|
13497
|
-
onClick: () => {
|
|
13498
|
-
setAttempt((current) => current + 1);
|
|
13499
|
-
},
|
|
13500
|
-
children: t("terminalRetry")
|
|
13501
|
-
})]
|
|
13502
|
-
});
|
|
13503
|
-
return (0, react.createElement)(state.Comp, props);
|
|
13504
|
-
}
|
|
13505
|
-
/**
|
|
13506
|
-
* Build a descriptor-compatible lazy wrapper for a chunk-resident component.
|
|
13507
|
-
* The returned function is the descriptor `component` itself: it returns an
|
|
13508
|
-
* element and never calls hooks, so both invocation styles (plain function
|
|
13509
|
-
* call and createElement/JSX render) work. `pick` must be a module-level
|
|
13510
|
-
* function (stable identity) — an inline lambda would re-trigger the load
|
|
13511
|
-
* effect on every render.
|
|
13512
|
-
* @param chunk - the chunk name (see chunk-loader.ts).
|
|
13513
|
-
* @param pick - select the component from the chunk's exports.
|
|
13514
|
-
*/
|
|
13515
|
-
function lazyChunkComponent(chunk, pick) {
|
|
13516
|
-
return (props) => (0, react.createElement)(LazyChunkView, {
|
|
13517
|
-
chunk,
|
|
13518
|
-
pick,
|
|
13519
|
-
props
|
|
13520
|
-
});
|
|
13521
|
-
}
|
|
13522
|
-
//#endregion
|
|
13523
13179
|
//#region src/client/GitView.tsx
|
|
13524
13180
|
/**
|
|
13525
13181
|
* The source-control panel: status list (staged vs unstaged), stage/unstage,
|
|
@@ -15086,58 +14742,58 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
15086
14742
|
document.head.appendChild(tag);
|
|
15087
14743
|
}
|
|
15088
14744
|
var SubagentView_module_css_default = {
|
|
15089
|
-
"
|
|
15090
|
-
"
|
|
15091
|
-
"
|
|
15092
|
-
"subagentContent": "F2T6aa_subagentContent",
|
|
15093
|
-
"jobsSecondary": "F2T6aa_jobsSecondary",
|
|
15094
|
-
"jobsRowSelected": "F2T6aa_jobsRowSelected",
|
|
14745
|
+
"jobsPaneDot": "F2T6aa_jobsPaneDot",
|
|
14746
|
+
"subagentLiveText": "F2T6aa_subagentLiveText",
|
|
14747
|
+
"jobsContent": "F2T6aa_jobsContent",
|
|
15095
14748
|
"jobsPaneHeader": "F2T6aa_jobsPaneHeader",
|
|
15096
|
-
"jobsPaneHint": "F2T6aa_jobsPaneHint",
|
|
15097
14749
|
"jobsKind": "F2T6aa_jobsKind",
|
|
14750
|
+
"jobsCount": "F2T6aa_jobsCount",
|
|
14751
|
+
"subagentLiveArgs": "F2T6aa_subagentLiveArgs",
|
|
14752
|
+
"subagentLive": "F2T6aa_subagentLive",
|
|
14753
|
+
"jobsList": "F2T6aa_jobsList",
|
|
14754
|
+
"subagentContent": "F2T6aa_subagentContent",
|
|
14755
|
+
"jobs": "F2T6aa_jobs",
|
|
15098
14756
|
"jobsRowSettled": "F2T6aa_jobsRowSettled",
|
|
14757
|
+
"historyToggle": "F2T6aa_historyToggle",
|
|
14758
|
+
"subagent": "F2T6aa_subagent",
|
|
15099
14759
|
"subagentEmptyHint": "F2T6aa_subagentEmptyHint",
|
|
15100
|
-
"
|
|
14760
|
+
"jobsLabelLine": "F2T6aa_jobsLabelLine",
|
|
15101
14761
|
"jobsLabel": "F2T6aa_jobsLabel",
|
|
15102
|
-
"subagentLiveText": "F2T6aa_subagentLiveText",
|
|
15103
|
-
"jobsPaneDot": "F2T6aa_jobsPaneDot",
|
|
15104
|
-
"jobsPaneClose": "F2T6aa_jobsPaneClose",
|
|
15105
14762
|
"jobsKill": "F2T6aa_jobsKill",
|
|
15106
|
-
"
|
|
15107
|
-
"subagent": "F2T6aa_subagent",
|
|
15108
|
-
"subagentRowDisabled": "F2T6aa_subagentRowDisabled",
|
|
15109
|
-
"jobsKillArmed": "F2T6aa_jobsKillArmed",
|
|
15110
|
-
"subagentDot": "F2T6aa_subagentDot",
|
|
15111
|
-
"subagentSecondary": "F2T6aa_subagentSecondary",
|
|
15112
|
-
"jobs": "F2T6aa_jobs",
|
|
15113
|
-
"subagentTitle": "F2T6aa_subagentTitle",
|
|
15114
|
-
"subagentRowLoading": "F2T6aa_subagentRowLoading",
|
|
15115
|
-
"subagentLabel": "F2T6aa_subagentLabel",
|
|
15116
|
-
"subagentRow": "F2T6aa_subagentRow",
|
|
14763
|
+
"jobsKillError": "F2T6aa_jobsKillError",
|
|
15117
14764
|
"subagentCount": "F2T6aa_subagentCount",
|
|
15118
|
-
"
|
|
15119
|
-
"
|
|
15120
|
-
"
|
|
14765
|
+
"jobsPaneClose": "F2T6aa_jobsPaneClose",
|
|
14766
|
+
"jobsPanePre": "F2T6aa_jobsPanePre",
|
|
14767
|
+
"jobsPaneHint": "F2T6aa_jobsPaneHint",
|
|
14768
|
+
"jobsDot": "F2T6aa_jobsDot",
|
|
14769
|
+
"subagentDot": "F2T6aa_subagentDot",
|
|
14770
|
+
"jobsPaneLabel": "F2T6aa_jobsPaneLabel",
|
|
14771
|
+
"jobsTitle": "F2T6aa_jobsTitle",
|
|
15121
14772
|
"jobsRow": "F2T6aa_jobsRow",
|
|
15122
|
-
"
|
|
15123
|
-
"subagentRowActive": "F2T6aa_subagentRowActive",
|
|
15124
|
-
"jobsKillError": "F2T6aa_jobsKillError",
|
|
14773
|
+
"jobsRowSelected": "F2T6aa_jobsRowSelected",
|
|
15125
14774
|
"jobsPane": "F2T6aa_jobsPane",
|
|
15126
|
-
"
|
|
15127
|
-
"jobsPaneLabel": "F2T6aa_jobsPaneLabel",
|
|
15128
|
-
"subagentNode": "F2T6aa_subagentNode",
|
|
14775
|
+
"subagentChildren": "F2T6aa_subagentChildren",
|
|
15129
14776
|
"jobsHeader": "F2T6aa_jobsHeader",
|
|
15130
|
-
"
|
|
15131
|
-
"
|
|
15132
|
-
"jobsLabelLine": "F2T6aa_jobsLabelLine",
|
|
14777
|
+
"subagentLiveTool": "F2T6aa_subagentLiveTool",
|
|
14778
|
+
"jobsKillArmed": "F2T6aa_jobsKillArmed",
|
|
15133
14779
|
"subagentHeader": "F2T6aa_subagentHeader",
|
|
15134
|
-
"historyToggle": "F2T6aa_historyToggle",
|
|
15135
14780
|
"subagentErrorRetry": "F2T6aa_subagentErrorRetry",
|
|
15136
|
-
"
|
|
15137
|
-
"
|
|
15138
|
-
"
|
|
15139
|
-
"
|
|
15140
|
-
"
|
|
14781
|
+
"subagentRowLoading": "F2T6aa_subagentRowLoading",
|
|
14782
|
+
"subagentNode": "F2T6aa_subagentNode",
|
|
14783
|
+
"jobsRowMain": "F2T6aa_jobsRowMain",
|
|
14784
|
+
"subagentError": "F2T6aa_subagentError",
|
|
14785
|
+
"jobsPaneError": "F2T6aa_jobsPaneError",
|
|
14786
|
+
"jobsSecondary": "F2T6aa_jobsSecondary",
|
|
14787
|
+
"subagentRowActive": "F2T6aa_subagentRowActive",
|
|
14788
|
+
"subagentLabel": "F2T6aa_subagentLabel",
|
|
14789
|
+
"subagentRow": "F2T6aa_subagentRow",
|
|
14790
|
+
"subagentTitle": "F2T6aa_subagentTitle",
|
|
14791
|
+
"subagentEmpty": "F2T6aa_subagentEmpty",
|
|
14792
|
+
"subagentSecondary": "F2T6aa_subagentSecondary",
|
|
14793
|
+
"subagentRefresh": "F2T6aa_subagentRefresh",
|
|
14794
|
+
"jobsPaneStatus": "F2T6aa_jobsPaneStatus",
|
|
14795
|
+
"subagentRowDisabled": "F2T6aa_subagentRowDisabled",
|
|
14796
|
+
"subagentBody": "F2T6aa_subagentBody"
|
|
15141
14797
|
};
|
|
15142
14798
|
//#endregion
|
|
15143
14799
|
//#region src/client/SubagentView.tsx
|
|
@@ -16244,45 +15900,45 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
16244
15900
|
document.head.appendChild(tag);
|
|
16245
15901
|
}
|
|
16246
15902
|
var SideChatView_module_css_default = {
|
|
16247
|
-
"
|
|
16248
|
-
"
|
|
16249
|
-
"
|
|
15903
|
+
"sidechatRowMeta": "_64UoUa_sidechatRowMeta",
|
|
15904
|
+
"sidechatHeroDesc": "_64UoUa_sidechatHeroDesc",
|
|
15905
|
+
"sidechatRowBody": "_64UoUa_sidechatRowBody",
|
|
15906
|
+
"sidechatComposer": "_64UoUa_sidechatComposer",
|
|
15907
|
+
"sidechatDetailHeader": "_64UoUa_sidechatDetailHeader",
|
|
16250
15908
|
"sidechatRowSummary": "_64UoUa_sidechatRowSummary",
|
|
16251
|
-
"sidechatBtnIn": "_64UoUa_sidechatBtnIn",
|
|
16252
|
-
"sidechatRow": "_64UoUa_sidechatRow",
|
|
16253
|
-
"sidechatRowMono": "_64UoUa_sidechatRowMono",
|
|
16254
|
-
"sidechatComposerBar": "_64UoUa_sidechatComposerBar",
|
|
16255
|
-
"sidechatSweep": "_64UoUa_sidechatSweep",
|
|
16256
|
-
"sidechatStatusText": "_64UoUa_sidechatStatusText",
|
|
16257
|
-
"sidechatIconBtn": "_64UoUa_sidechatIconBtn",
|
|
16258
|
-
"sidechatHeroTitle": "_64UoUa_sidechatHeroTitle",
|
|
16259
|
-
"sidechatRowIn": "_64UoUa_sidechatRowIn",
|
|
16260
|
-
"sidechatRowProse": "_64UoUa_sidechatRowProse",
|
|
16261
15909
|
"sidechatAgentBadge": "_64UoUa_sidechatAgentBadge",
|
|
16262
|
-
"
|
|
16263
|
-
"
|
|
15910
|
+
"sidechatRowIn": "_64UoUa_sidechatRowIn",
|
|
15911
|
+
"sidechatRowLine": "_64UoUa_sidechatRowLine",
|
|
15912
|
+
"sidechatShimmerText": "_64UoUa_sidechatShimmerText",
|
|
16264
15913
|
"sidechatSendBtn": "_64UoUa_sidechatSendBtn",
|
|
16265
|
-
"
|
|
15914
|
+
"sidechatRowFailed": "_64UoUa_sidechatRowFailed",
|
|
15915
|
+
"sidechat": "_64UoUa_sidechat",
|
|
15916
|
+
"sidechatError": "_64UoUa_sidechatError",
|
|
15917
|
+
"sidechatUser": "_64UoUa_sidechatUser",
|
|
15918
|
+
"sidechatHint": "_64UoUa_sidechatHint",
|
|
15919
|
+
"sidechatRow": "_64UoUa_sidechatRow",
|
|
15920
|
+
"sidechatHeaderSpacer": "_64UoUa_sidechatHeaderSpacer",
|
|
15921
|
+
"sidechatHeroTitle": "_64UoUa_sidechatHeroTitle",
|
|
15922
|
+
"sidechatStatus": "_64UoUa_sidechatStatus",
|
|
16266
15923
|
"sidechatHero": "_64UoUa_sidechatHero",
|
|
16267
15924
|
"sidechatFadeIn": "_64UoUa_sidechatFadeIn",
|
|
16268
|
-
"
|
|
16269
|
-
"
|
|
16270
|
-
"
|
|
15925
|
+
"sidechatPrimaryBtn": "_64UoUa_sidechatPrimaryBtn",
|
|
15926
|
+
"sidechatHeaderDot": "_64UoUa_sidechatHeaderDot",
|
|
15927
|
+
"sidechatSweep": "_64UoUa_sidechatSweep",
|
|
15928
|
+
"sidechatIconBtn": "_64UoUa_sidechatIconBtn",
|
|
15929
|
+
"sidechatRowStatic": "_64UoUa_sidechatRowStatic",
|
|
15930
|
+
"sidechatComposerMeta": "_64UoUa_sidechatComposerMeta",
|
|
16271
15931
|
"sidechatScroll": "_64UoUa_sidechatScroll",
|
|
16272
|
-
"sidechatHint": "_64UoUa_sidechatHint",
|
|
16273
|
-
"sidechatError": "_64UoUa_sidechatError",
|
|
16274
|
-
"sidechat": "_64UoUa_sidechat",
|
|
16275
|
-
"sidechatRowLabel": "_64UoUa_sidechatRowLabel",
|
|
16276
|
-
"sidechatRowFailed": "_64UoUa_sidechatRowFailed",
|
|
16277
|
-
"sidechatRowCode": "_64UoUa_sidechatRowCode",
|
|
16278
15932
|
"sidechatComposerInput": "_64UoUa_sidechatComposerInput",
|
|
16279
|
-
"sidechatComposerMeta": "_64UoUa_sidechatComposerMeta",
|
|
16280
|
-
"sidechatRowStatic": "_64UoUa_sidechatRowStatic",
|
|
16281
|
-
"sidechatHeaderSpacer": "_64UoUa_sidechatHeaderSpacer",
|
|
16282
15933
|
"sidechatRowChevron": "_64UoUa_sidechatRowChevron",
|
|
16283
|
-
"
|
|
16284
|
-
"
|
|
16285
|
-
"
|
|
15934
|
+
"sidechatRowProse": "_64UoUa_sidechatRowProse",
|
|
15935
|
+
"sidechatRowMono": "_64UoUa_sidechatRowMono",
|
|
15936
|
+
"sidechatStatusText": "_64UoUa_sidechatStatusText",
|
|
15937
|
+
"sidechatAssistant": "_64UoUa_sidechatAssistant",
|
|
15938
|
+
"sidechatRowCode": "_64UoUa_sidechatRowCode",
|
|
15939
|
+
"sidechatRowLabel": "_64UoUa_sidechatRowLabel",
|
|
15940
|
+
"sidechatComposerBar": "_64UoUa_sidechatComposerBar",
|
|
15941
|
+
"sidechatBtnIn": "_64UoUa_sidechatBtnIn"
|
|
16286
15942
|
};
|
|
16287
15943
|
//#endregion
|
|
16288
15944
|
//#region src/client/SideChatView.tsx
|
|
@@ -16975,17 +16631,20 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
16975
16631
|
//#endregion
|
|
16976
16632
|
//#region src/client/SandboxStatusBar.tsx
|
|
16977
16633
|
/**
|
|
16978
|
-
* The live sandbox status row of the
|
|
16979
|
-
*
|
|
16980
|
-
*
|
|
16981
|
-
*
|
|
16634
|
+
* The live sandbox status row of the built-in browser tab: a green
|
|
16635
|
+
* "sandbox on" state with a one-tap TEMPORARY unlock, or a RED "sandbox
|
|
16636
|
+
* off" state (global setting or the temporary unlock) with a restore
|
|
16637
|
+
* action.
|
|
16982
16638
|
*
|
|
16983
16639
|
* The temporary unlock is component state only — it never writes the
|
|
16984
|
-
* global side card setting (`
|
|
16985
|
-
*
|
|
16986
|
-
*
|
|
16987
|
-
*
|
|
16988
|
-
*
|
|
16640
|
+
* global side card setting (`browserNoSandbox`); it lasts until the
|
|
16641
|
+
* surface unmounts (tab switch) or the user restores the sandbox from the
|
|
16642
|
+
* row. When the global setting already drops the sandbox, no
|
|
16643
|
+
* unlock/restore action is offered (changing the global setting is the
|
|
16644
|
+
* settings page's job) — the red warning stands.
|
|
16645
|
+
*
|
|
16646
|
+
* (v1.0.4: the HTML preview surface was retired with the file-viewer line;
|
|
16647
|
+
* this row now serves the browser tab only.)
|
|
16989
16648
|
*/
|
|
16990
16649
|
function SandboxStatusBar(props) {
|
|
16991
16650
|
const { sandboxed, local, dangerCopy, onUnlock, onRestore } = props;
|
|
@@ -17028,6 +16687,268 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
17028
16687
|
});
|
|
17029
16688
|
}
|
|
17030
16689
|
//#endregion
|
|
16690
|
+
//#region src/client/LiveView.tsx
|
|
16691
|
+
/**
|
|
16692
|
+
* Agent 浏览器实况(CDP screencast + 输入回传,2026-09-12 方案 2)。
|
|
16693
|
+
*
|
|
16694
|
+
* 数据面:KCoder 桌面端 browser-host 维护一个无头 Chromium(固定 CDP
|
|
16695
|
+
* 转发地址 127.0.0.1:9223,与 playwright MCP `--cdp-endpoint` 共用)。
|
|
16696
|
+
* 本组件作为第二个 CDP 客户端:
|
|
16697
|
+
* - target 列表经宿主代理 `/sidebar/api`(CDP HTTP 无 CORS 头);
|
|
16698
|
+
* - screencast/输入走 renderer 直连 `ws://127.0.0.1:9223/devtools/page/<id>`
|
|
16699
|
+
* (WebSocket 不受 CORS 约束,宿主未设 CSP)。
|
|
16700
|
+
*
|
|
16701
|
+
* 连接模型:`attachedId`(用户显式选择)优先,否则自动跟随「最新创建的
|
|
16702
|
+
* page target」;连接按 effectiveId 建立与重建,列表仅在内容变化时更新
|
|
16703
|
+
* state(JSON 比对),避免轮询引起重连抖动。
|
|
16704
|
+
*
|
|
16705
|
+
* 交互:screencast 帧绘到 canvas;指针/滚轮按 canvas→viewport 比例回传
|
|
16706
|
+
* (Input.dispatchMouseEvent);可打印字符经 Input.insertText,控制键走
|
|
16707
|
+
* rawKeyDown/keyUp。视口统一 1280×800(Emulation.setDeviceMetricsOverride),
|
|
16708
|
+
* canvas 等比缩放显示。
|
|
16709
|
+
*/
|
|
16710
|
+
/** 与 KCoder desktop/main/browser-host.ts 的 BROWSER_HOST_PORT 一致。 */
|
|
16711
|
+
const CDP_WS = "ws://127.0.0.1:9223";
|
|
16712
|
+
/** 实况视口(CDP 侧强制,帧与输入坐标以此为基准)。 */
|
|
16713
|
+
const VIEW_W = 1280;
|
|
16714
|
+
const VIEW_H = 800;
|
|
16715
|
+
function LiveView() {
|
|
16716
|
+
const canvasRef = (0, react.useRef)(null);
|
|
16717
|
+
const wsRef = (0, react.useRef)(null);
|
|
16718
|
+
const [status, setStatus] = (0, react.useState)("connecting");
|
|
16719
|
+
const [targets, setTargets] = (0, react.useState)([]);
|
|
16720
|
+
const [hostDown, setHostDown] = (0, react.useState)(false);
|
|
16721
|
+
/** 用户显式钉住的 target(null = 自动跟随最新)。 */
|
|
16722
|
+
const [pinnedId, setPinnedId] = (0, react.useState)(null);
|
|
16723
|
+
/** 连接代数:手动重连/换 target 时 +1。 */
|
|
16724
|
+
const [epoch, setEpoch] = (0, react.useState)(0);
|
|
16725
|
+
(0, react.useEffect)(() => {
|
|
16726
|
+
let alive = true;
|
|
16727
|
+
const poll = async () => {
|
|
16728
|
+
try {
|
|
16729
|
+
const { targets: list } = await api.cdpTargets();
|
|
16730
|
+
if (!alive) return;
|
|
16731
|
+
setHostDown(false);
|
|
16732
|
+
setTargets((prev) => JSON.stringify(prev) === JSON.stringify(list) ? prev : list);
|
|
16733
|
+
} catch {
|
|
16734
|
+
if (alive) setHostDown(true);
|
|
16735
|
+
}
|
|
16736
|
+
};
|
|
16737
|
+
poll();
|
|
16738
|
+
const timer = setInterval(() => {
|
|
16739
|
+
poll();
|
|
16740
|
+
}, 3e3);
|
|
16741
|
+
return () => {
|
|
16742
|
+
alive = false;
|
|
16743
|
+
clearInterval(timer);
|
|
16744
|
+
};
|
|
16745
|
+
}, []);
|
|
16746
|
+
/** 实际附加的 target:id 钉住且存活 → 它;否则自动跟随最新页。 */
|
|
16747
|
+
const effectiveId = (0, react.useMemo)(() => {
|
|
16748
|
+
if (pinnedId !== null && targets.some((tg) => tg.id === pinnedId)) return pinnedId;
|
|
16749
|
+
return targets.length > 0 ? targets[targets.length - 1].id : null;
|
|
16750
|
+
}, [pinnedId, targets]);
|
|
16751
|
+
(0, react.useEffect)(() => {
|
|
16752
|
+
if (effectiveId === null) {
|
|
16753
|
+
setStatus("idle");
|
|
16754
|
+
return;
|
|
16755
|
+
}
|
|
16756
|
+
let cancelled = false;
|
|
16757
|
+
let socket = null;
|
|
16758
|
+
let msgId = 0;
|
|
16759
|
+
setStatus("connecting");
|
|
16760
|
+
socket = new WebSocket(`${CDP_WS}/devtools/page/${effectiveId}`);
|
|
16761
|
+
wsRef.current = socket;
|
|
16762
|
+
const send = (method, params) => {
|
|
16763
|
+
if (socket !== null && socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify({
|
|
16764
|
+
id: ++msgId,
|
|
16765
|
+
method,
|
|
16766
|
+
params: params ?? {}
|
|
16767
|
+
}));
|
|
16768
|
+
};
|
|
16769
|
+
const draw = (data) => {
|
|
16770
|
+
const el = canvasRef.current;
|
|
16771
|
+
if (el === null || cancelled) return;
|
|
16772
|
+
const img = new Image();
|
|
16773
|
+
img.onload = () => {
|
|
16774
|
+
if (cancelled) return;
|
|
16775
|
+
el.width = img.naturalWidth;
|
|
16776
|
+
el.height = img.naturalHeight;
|
|
16777
|
+
el.getContext("2d")?.drawImage(img, 0, 0);
|
|
16778
|
+
};
|
|
16779
|
+
img.src = `data:image/jpeg;base64,${data}`;
|
|
16780
|
+
};
|
|
16781
|
+
socket.onopen = () => {
|
|
16782
|
+
if (cancelled) return;
|
|
16783
|
+
setStatus("live");
|
|
16784
|
+
send("Page.enable");
|
|
16785
|
+
send("Runtime.enable");
|
|
16786
|
+
send("Emulation.setDeviceMetricsOverride", {
|
|
16787
|
+
width: VIEW_W,
|
|
16788
|
+
height: VIEW_H,
|
|
16789
|
+
deviceScaleFactor: 1,
|
|
16790
|
+
mobile: false
|
|
16791
|
+
});
|
|
16792
|
+
send("Page.startScreencast", {
|
|
16793
|
+
format: "jpeg",
|
|
16794
|
+
quality: 62,
|
|
16795
|
+
maxWidth: VIEW_W,
|
|
16796
|
+
maxHeight: VIEW_H,
|
|
16797
|
+
everyNthFrame: 1
|
|
16798
|
+
});
|
|
16799
|
+
};
|
|
16800
|
+
socket.onmessage = (event) => {
|
|
16801
|
+
const msg = JSON.parse(event.data);
|
|
16802
|
+
if (msg.method === "Page.screencastFrame") {
|
|
16803
|
+
const p = msg.params ?? {};
|
|
16804
|
+
if (typeof p.data === "string") draw(p.data);
|
|
16805
|
+
if (typeof p.screencastFrameId === "string") send("Page.screencastFrameAck", { screencastFrameId: p.screencastFrameId });
|
|
16806
|
+
}
|
|
16807
|
+
};
|
|
16808
|
+
socket.onclose = () => {
|
|
16809
|
+
if (!cancelled) setStatus("connecting");
|
|
16810
|
+
};
|
|
16811
|
+
socket.onerror = () => {
|
|
16812
|
+
if (!cancelled) setStatus("down");
|
|
16813
|
+
};
|
|
16814
|
+
return () => {
|
|
16815
|
+
cancelled = true;
|
|
16816
|
+
socket?.close();
|
|
16817
|
+
wsRef.current = null;
|
|
16818
|
+
};
|
|
16819
|
+
}, [effectiveId]);
|
|
16820
|
+
const sendInput = (method, params) => {
|
|
16821
|
+
wsRef.current?.send(JSON.stringify({
|
|
16822
|
+
id: Math.floor(Math.random() * 1e9),
|
|
16823
|
+
method,
|
|
16824
|
+
params
|
|
16825
|
+
}));
|
|
16826
|
+
};
|
|
16827
|
+
const scaleOf = (el) => {
|
|
16828
|
+
const shown = el.getBoundingClientRect().width;
|
|
16829
|
+
return shown > 0 ? VIEW_W / shown : 1;
|
|
16830
|
+
};
|
|
16831
|
+
const posOf = (e) => {
|
|
16832
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
16833
|
+
const k = scaleOf(e.currentTarget);
|
|
16834
|
+
return {
|
|
16835
|
+
x: (e.clientX - rect.left) * k,
|
|
16836
|
+
y: (e.clientY - rect.top) * k
|
|
16837
|
+
};
|
|
16838
|
+
};
|
|
16839
|
+
const onPointerDown = (e) => {
|
|
16840
|
+
const p = posOf(e);
|
|
16841
|
+
sendInput("Input.dispatchMouseEvent", {
|
|
16842
|
+
type: "mousePressed",
|
|
16843
|
+
x: p.x,
|
|
16844
|
+
y: p.y,
|
|
16845
|
+
button: "left",
|
|
16846
|
+
clickCount: 1
|
|
16847
|
+
});
|
|
16848
|
+
};
|
|
16849
|
+
const onPointerUp = (e) => {
|
|
16850
|
+
const p = posOf(e);
|
|
16851
|
+
sendInput("Input.dispatchMouseEvent", {
|
|
16852
|
+
type: "mouseReleased",
|
|
16853
|
+
x: p.x,
|
|
16854
|
+
y: p.y,
|
|
16855
|
+
button: "left",
|
|
16856
|
+
clickCount: 1
|
|
16857
|
+
});
|
|
16858
|
+
};
|
|
16859
|
+
const onPointerMove = (e) => {
|
|
16860
|
+
if (e.buttons === 0) return;
|
|
16861
|
+
const p = posOf(e);
|
|
16862
|
+
sendInput("Input.dispatchMouseEvent", {
|
|
16863
|
+
type: "mouseMoved",
|
|
16864
|
+
x: p.x,
|
|
16865
|
+
y: p.y,
|
|
16866
|
+
button: "left"
|
|
16867
|
+
});
|
|
16868
|
+
};
|
|
16869
|
+
const onWheel = (e) => {
|
|
16870
|
+
const p = posOf(e);
|
|
16871
|
+
sendInput("Input.dispatchMouseEvent", {
|
|
16872
|
+
type: "mouseWheel",
|
|
16873
|
+
x: p.x,
|
|
16874
|
+
y: p.y,
|
|
16875
|
+
deltaX: e.deltaX,
|
|
16876
|
+
deltaY: e.deltaY
|
|
16877
|
+
});
|
|
16878
|
+
};
|
|
16879
|
+
const onKeyDown = (e) => {
|
|
16880
|
+
const code = {
|
|
16881
|
+
Enter: 13,
|
|
16882
|
+
Backspace: 8,
|
|
16883
|
+
Tab: 9,
|
|
16884
|
+
Escape: 27,
|
|
16885
|
+
ArrowUp: 38,
|
|
16886
|
+
ArrowDown: 40,
|
|
16887
|
+
ArrowLeft: 37,
|
|
16888
|
+
ArrowRight: 39
|
|
16889
|
+
}[e.key];
|
|
16890
|
+
if (code !== void 0) {
|
|
16891
|
+
sendInput("Input.dispatchKeyEvent", {
|
|
16892
|
+
type: "rawKeyDown",
|
|
16893
|
+
windowsVirtualKeyCode: code,
|
|
16894
|
+
key: e.key
|
|
16895
|
+
});
|
|
16896
|
+
sendInput("Input.dispatchKeyEvent", {
|
|
16897
|
+
type: "keyUp",
|
|
16898
|
+
windowsVirtualKeyCode: code,
|
|
16899
|
+
key: e.key
|
|
16900
|
+
});
|
|
16901
|
+
return;
|
|
16902
|
+
}
|
|
16903
|
+
if (e.key.length === 1) sendInput("Input.insertText", { text: e.key });
|
|
16904
|
+
};
|
|
16905
|
+
const statusText = hostDown || status === "down" ? t("browserLiveDown") : status === "live" ? targets.find((tg) => tg.id === effectiveId)?.url ?? t("browserLiveTargetNone") : effectiveId === null ? t("browserLiveTargetNone") : t("browserLiveConnecting");
|
|
16906
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
16907
|
+
className: "browserLive",
|
|
16908
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
16909
|
+
className: "browserLiveStatus",
|
|
16910
|
+
children: [
|
|
16911
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
16912
|
+
type: "button",
|
|
16913
|
+
onClick: () => {
|
|
16914
|
+
setEpoch((e) => e + 1);
|
|
16915
|
+
},
|
|
16916
|
+
children: t("refresh")
|
|
16917
|
+
}),
|
|
16918
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
16919
|
+
className: "browserLiveTarget",
|
|
16920
|
+
value: effectiveId ?? "",
|
|
16921
|
+
onChange: (e) => {
|
|
16922
|
+
setPinnedId(e.target.value === "" ? null : e.target.value);
|
|
16923
|
+
},
|
|
16924
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
16925
|
+
value: "",
|
|
16926
|
+
children: t("browserLiveFollowLatest")
|
|
16927
|
+
}), targets.map((tg) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
16928
|
+
value: tg.id,
|
|
16929
|
+
children: tg.title || tg.url
|
|
16930
|
+
}, tg.id))]
|
|
16931
|
+
}),
|
|
16932
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: statusText })
|
|
16933
|
+
]
|
|
16934
|
+
}), effectiveId !== null && status !== "idle" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("canvas", {
|
|
16935
|
+
ref: canvasRef,
|
|
16936
|
+
className: "browserLiveCanvas",
|
|
16937
|
+
width: VIEW_W,
|
|
16938
|
+
height: VIEW_H,
|
|
16939
|
+
tabIndex: 0,
|
|
16940
|
+
onPointerDown,
|
|
16941
|
+
onPointerUp,
|
|
16942
|
+
onPointerMove,
|
|
16943
|
+
onWheel,
|
|
16944
|
+
onKeyDown
|
|
16945
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
16946
|
+
className: "browserStart",
|
|
16947
|
+
children: hostDown ? t("browserLiveDown") : t("browserLiveTargetNone")
|
|
16948
|
+
})]
|
|
16949
|
+
});
|
|
16950
|
+
}
|
|
16951
|
+
//#endregion
|
|
17031
16952
|
//#region src/client/BrowserView.tsx
|
|
17032
16953
|
/**
|
|
17033
16954
|
* The built-in browser tab: an address bar plus a sandboxed iframe.
|
|
@@ -17106,6 +17027,9 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
17106
17027
|
const [embedBlocked, setEmbedBlocked] = (0, react.useState)(null);
|
|
17107
17028
|
/** The user asked to load the refused site anyway (keeps the plain iframe). */
|
|
17108
17029
|
const [forceEmbed, setForceEmbed] = (0, react.useState)(false);
|
|
17030
|
+
/** Agent 实况模式(CDP screencast):开启后本 tab 只显示 agent 无头
|
|
17031
|
+
* 浏览器的实况画面,地址栏/iframe 暂停。会话态开关,不持久化。 */
|
|
17032
|
+
const [live, setLive] = (0, react.useState)(false);
|
|
17109
17033
|
(0, react.useEffect)(() => {
|
|
17110
17034
|
if (url === void 0) return;
|
|
17111
17035
|
let cancelled = false;
|
|
@@ -17215,6 +17139,17 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
17215
17139
|
},
|
|
17216
17140
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLinkOutline14, {})
|
|
17217
17141
|
}),
|
|
17142
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
17143
|
+
type: "button",
|
|
17144
|
+
className: sidebar_module_css_default.iconButton,
|
|
17145
|
+
"aria-label": t("browserLive"),
|
|
17146
|
+
title: t("browserLive"),
|
|
17147
|
+
"aria-pressed": live,
|
|
17148
|
+
onClick: () => {
|
|
17149
|
+
setLive((value) => !value);
|
|
17150
|
+
},
|
|
17151
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VscRemoteExplorer, { size: 15 })
|
|
17152
|
+
}),
|
|
17218
17153
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
17219
17154
|
type: "button",
|
|
17220
17155
|
className: sidebar_module_css_default.iconButton,
|
|
@@ -17243,7 +17178,7 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
17243
17178
|
setLocalUnlock(false);
|
|
17244
17179
|
}
|
|
17245
17180
|
}),
|
|
17246
|
-
url === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17181
|
+
live ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LiveView, {}) : url === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17247
17182
|
className: sidebar_module_css_default.browserStart,
|
|
17248
17183
|
children: t("browserStart")
|
|
17249
17184
|
}) : embedBlocked !== null && !forceEmbed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BrowserEmbedBlocked, {
|
|
@@ -17575,252 +17510,14 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
17575
17510
|
];
|
|
17576
17511
|
}
|
|
17577
17512
|
//#endregion
|
|
17578
|
-
//#region src/client/PdfView.tsx
|
|
17579
|
-
/** Browser-native PDF preview with an always-available download fallback. */
|
|
17580
|
-
function PdfView(props) {
|
|
17581
|
-
const { scope, path, title } = props;
|
|
17582
|
-
const [load, setLoad] = (0, react.useState)({ status: "loading" });
|
|
17583
|
-
const [interactionBlocked, setInteractionBlocked] = (0, react.useState)(false);
|
|
17584
|
-
const frameRef = (0, react.useRef)(null);
|
|
17585
|
-
const shieldRef = (0, react.useRef)(null);
|
|
17586
|
-
(0, react.useEffect)(() => {
|
|
17587
|
-
const controller = new AbortController();
|
|
17588
|
-
let objectUrl;
|
|
17589
|
-
setLoad({ status: "loading" });
|
|
17590
|
-
(async () => {
|
|
17591
|
-
try {
|
|
17592
|
-
const response = await fetch(mediaUrl(scope, path), { signal: controller.signal });
|
|
17593
|
-
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
17594
|
-
const bytes = await response.arrayBuffer();
|
|
17595
|
-
if (controller.signal.aborted) return;
|
|
17596
|
-
objectUrl = URL.createObjectURL(new Blob([bytes], { type: "application/pdf" }));
|
|
17597
|
-
setLoad({
|
|
17598
|
-
status: "ready",
|
|
17599
|
-
url: objectUrl
|
|
17600
|
-
});
|
|
17601
|
-
} catch (error) {
|
|
17602
|
-
if (controller.signal.aborted) return;
|
|
17603
|
-
setLoad({
|
|
17604
|
-
status: "error",
|
|
17605
|
-
message: error instanceof Error ? error.message : String(error)
|
|
17606
|
-
});
|
|
17607
|
-
}
|
|
17608
|
-
})();
|
|
17609
|
-
return () => {
|
|
17610
|
-
controller.abort();
|
|
17611
|
-
if (objectUrl !== void 0) URL.revokeObjectURL(objectUrl);
|
|
17612
|
-
};
|
|
17613
|
-
}, [
|
|
17614
|
-
scope.sessionId,
|
|
17615
|
-
scope.cwd,
|
|
17616
|
-
path
|
|
17617
|
-
]);
|
|
17618
|
-
(0, react.useEffect)(() => {
|
|
17619
|
-
const block = () => {
|
|
17620
|
-
setInteractionBlocked(true);
|
|
17621
|
-
if (frameRef.current !== null) frameRef.current.style.pointerEvents = "none";
|
|
17622
|
-
if (shieldRef.current !== null) shieldRef.current.style.pointerEvents = "auto";
|
|
17623
|
-
};
|
|
17624
|
-
const unblock = () => {
|
|
17625
|
-
setInteractionBlocked(false);
|
|
17626
|
-
if (frameRef.current !== null) frameRef.current.style.pointerEvents = "";
|
|
17627
|
-
if (shieldRef.current !== null) shieldRef.current.style.pointerEvents = "none";
|
|
17628
|
-
};
|
|
17629
|
-
const blockForResize = (event) => {
|
|
17630
|
-
const target = event.target;
|
|
17631
|
-
if (target instanceof Element && target.closest(`.${sidebar_module_css_default.panelResize}, .${sidebar_module_css_default.divider}`) !== null) block();
|
|
17632
|
-
};
|
|
17633
|
-
document.addEventListener("dragstart", block, true);
|
|
17634
|
-
document.addEventListener("dragend", unblock, true);
|
|
17635
|
-
document.addEventListener("drop", unblock, true);
|
|
17636
|
-
window.addEventListener("pointerdown", blockForResize, true);
|
|
17637
|
-
window.addEventListener("pointerup", unblock, true);
|
|
17638
|
-
window.addEventListener("pointercancel", unblock, true);
|
|
17639
|
-
window.addEventListener("blur", unblock);
|
|
17640
|
-
return () => {
|
|
17641
|
-
document.removeEventListener("dragstart", block, true);
|
|
17642
|
-
document.removeEventListener("dragend", unblock, true);
|
|
17643
|
-
document.removeEventListener("drop", unblock, true);
|
|
17644
|
-
window.removeEventListener("pointerdown", blockForResize, true);
|
|
17645
|
-
window.removeEventListener("pointerup", unblock, true);
|
|
17646
|
-
window.removeEventListener("pointercancel", unblock, true);
|
|
17647
|
-
window.removeEventListener("blur", unblock);
|
|
17648
|
-
};
|
|
17649
|
-
}, []);
|
|
17650
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17651
|
-
className: sidebar_module_css_default.editorPdf,
|
|
17652
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17653
|
-
className: sidebar_module_css_default.editorPdfToolbar,
|
|
17654
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
17655
|
-
className: sidebar_module_css_default.editorDownloadLink,
|
|
17656
|
-
href: downloadUrl(scope, path),
|
|
17657
|
-
download: true,
|
|
17658
|
-
children: t("downloadToView")
|
|
17659
|
-
})
|
|
17660
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
17661
|
-
className: sidebar_module_css_default.editorPdfStage,
|
|
17662
|
-
children: [
|
|
17663
|
-
load.status === "loading" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17664
|
-
className: sidebar_module_css_default.editorPlaceholder,
|
|
17665
|
-
children: t("loading")
|
|
17666
|
-
}),
|
|
17667
|
-
load.status === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17668
|
-
className: sidebar_module_css_default.editorError,
|
|
17669
|
-
children: load.message
|
|
17670
|
-
}),
|
|
17671
|
-
load.status === "ready" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("iframe", {
|
|
17672
|
-
ref: frameRef,
|
|
17673
|
-
className: clsx(sidebar_module_css_default.editorPdfFrame, interactionBlocked && sidebar_module_css_default.editorPdfFrameBlocked),
|
|
17674
|
-
src: load.url,
|
|
17675
|
-
title
|
|
17676
|
-
}),
|
|
17677
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17678
|
-
ref: shieldRef,
|
|
17679
|
-
className: clsx(sidebar_module_css_default.editorPdfDragShield, interactionBlocked && sidebar_module_css_default.editorPdfDragShieldActive),
|
|
17680
|
-
"aria-hidden": "true"
|
|
17681
|
-
})
|
|
17682
|
-
]
|
|
17683
|
-
})]
|
|
17684
|
-
});
|
|
17685
|
-
}
|
|
17686
|
-
//#endregion
|
|
17687
|
-
//#region src/client/builtins/viewers.tsx
|
|
17688
|
-
/**
|
|
17689
|
-
* The 6 built-in file viewer descriptors: every preview surface is a
|
|
17690
|
-
* registered viewer (image / pdf / markdown / html / code /
|
|
17691
|
-
* binary-download), exactly like external plugins register theirs. Office
|
|
17692
|
-
* previews (.docx / .xlsx / .pptx) are NOT built in anymore — they moved to
|
|
17693
|
-
* the recommended office plugin (see plugins-viewers.ts), which registers
|
|
17694
|
-
* the same ids through this service.
|
|
17695
|
-
*
|
|
17696
|
-
* The `binary-download` viewer sniffs NUL bytes via `detect` for unknown
|
|
17697
|
-
* binaries and serves legacy doc/xls/ppt by extension; `code` is the
|
|
17698
|
-
* catch-all (`exts: []`, lowest priority) that claims any file no other
|
|
17699
|
-
* viewer did.
|
|
17700
|
-
*
|
|
17701
|
-
* The heavy viewers (the CodeMirror-backed markdown/html/code) render
|
|
17702
|
-
* through {@link lazyChunkComponent} wrappers — their libraries are fetched
|
|
17703
|
-
* only when such a file is first opened (see chunk-loader.ts). The
|
|
17704
|
-
* descriptor metadata (id/exts/priority/detect) is identical either way,
|
|
17705
|
-
* so matching semantics and external-plugin overrides are unaffected; the
|
|
17706
|
-
* `component` wrapper keeps the descriptor contract `(props) => ReactNode`.
|
|
17707
|
-
*
|
|
17708
|
-
* Every viewer carries the declarative settings-surface fields — `title`
|
|
17709
|
-
* and `icon` — so the Side card settings page can render the enable/disable
|
|
17710
|
-
* inventory without hardcoding (eating our own dogfood).
|
|
17711
|
-
*/
|
|
17712
|
-
/**
|
|
17713
|
-
* Lazy wrapper over the chunk-resident viewer component. The `pick`
|
|
17714
|
-
* function is module-level (stable identity — the wrapper effect depends
|
|
17715
|
-
* on it); the cast bridges the chunk exports record to the descriptor prop
|
|
17716
|
-
* shape (the view reads only its own subset of FileViewerProps).
|
|
17717
|
-
*/
|
|
17718
|
-
const LazyTextEditor = lazyChunkComponent("editor", (mod) => mod.TextEditor);
|
|
17719
|
-
/** The 6 built-in file viewer descriptors. */
|
|
17720
|
-
function builtinViewers() {
|
|
17721
|
-
return [
|
|
17722
|
-
{
|
|
17723
|
-
id: "image",
|
|
17724
|
-
title: () => t("viewerImage"),
|
|
17725
|
-
icon: (size) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconImageOutline16, { size }),
|
|
17726
|
-
exts: [
|
|
17727
|
-
"png",
|
|
17728
|
-
"jpg",
|
|
17729
|
-
"jpeg",
|
|
17730
|
-
"gif",
|
|
17731
|
-
"webp",
|
|
17732
|
-
"svg",
|
|
17733
|
-
"bmp",
|
|
17734
|
-
"ico",
|
|
17735
|
-
"avif"
|
|
17736
|
-
],
|
|
17737
|
-
fetchStrategy: "mediaUrl",
|
|
17738
|
-
component: ({ mediaUrl: url, title }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
17739
|
-
className: sidebar_module_css_default.editorImageWrap,
|
|
17740
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
17741
|
-
className: sidebar_module_css_default.editorImage,
|
|
17742
|
-
src: url,
|
|
17743
|
-
alt: title
|
|
17744
|
-
})
|
|
17745
|
-
})
|
|
17746
|
-
},
|
|
17747
|
-
{
|
|
17748
|
-
id: "pdf",
|
|
17749
|
-
title: () => t("viewerPdf"),
|
|
17750
|
-
icon: (size) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconPdfOutline16, { size }),
|
|
17751
|
-
exts: ["pdf"],
|
|
17752
|
-
fetchStrategy: "mediaUrl",
|
|
17753
|
-
component: ({ scope, path, title }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PdfView, {
|
|
17754
|
-
scope,
|
|
17755
|
-
path,
|
|
17756
|
-
title
|
|
17757
|
-
})
|
|
17758
|
-
},
|
|
17759
|
-
{
|
|
17760
|
-
id: "markdown",
|
|
17761
|
-
title: () => t("viewerMarkdown"),
|
|
17762
|
-
icon: (size) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconMarkdownOutline16, { size }),
|
|
17763
|
-
exts: ["md", "markdown"],
|
|
17764
|
-
fetchStrategy: "fsRead",
|
|
17765
|
-
component: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyTextEditor, { ...props })
|
|
17766
|
-
},
|
|
17767
|
-
{
|
|
17768
|
-
id: "html",
|
|
17769
|
-
title: () => t("viewerHtml"),
|
|
17770
|
-
icon: (size) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IconHtmlOutline16, { size }),
|
|
17771
|
-
exts: ["html", "htm"],
|
|
17772
|
-
fetchStrategy: "fsRead",
|
|
17773
|
-
settings: { toggles: [{
|
|
17774
|
-
key: "htmlViewerNoSandbox",
|
|
17775
|
-
title: () => t("settingsHtmlSandboxTitle"),
|
|
17776
|
-
desc: () => t("settingsHtmlSandboxDesc")
|
|
17777
|
-
}, {
|
|
17778
|
-
key: "htmlViewerDefaultUnsafe",
|
|
17779
|
-
title: () => t("settingsHtmlDefaultUnsafeTitle"),
|
|
17780
|
-
desc: () => t("settingsHtmlDefaultUnsafeDesc")
|
|
17781
|
-
}] },
|
|
17782
|
-
component: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyTextEditor, { ...props })
|
|
17783
|
-
},
|
|
17784
|
-
{
|
|
17785
|
-
id: "code",
|
|
17786
|
-
title: () => t("viewerCode"),
|
|
17787
|
-
icon: (size) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCodeOutline16, { size }),
|
|
17788
|
-
exts: [],
|
|
17789
|
-
priority: -100,
|
|
17790
|
-
fetchStrategy: "fsRead",
|
|
17791
|
-
component: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LazyTextEditor, { ...props })
|
|
17792
|
-
},
|
|
17793
|
-
{
|
|
17794
|
-
id: "binary-download",
|
|
17795
|
-
title: () => t("viewerBinary"),
|
|
17796
|
-
icon: (size) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutline16, { size }),
|
|
17797
|
-
exts: [
|
|
17798
|
-
"doc",
|
|
17799
|
-
"xls",
|
|
17800
|
-
"ppt"
|
|
17801
|
-
],
|
|
17802
|
-
priority: -50,
|
|
17803
|
-
fetchStrategy: "binary-download",
|
|
17804
|
-
detect: (_path, head) => head.includes(0),
|
|
17805
|
-
component: ({ scope, path }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BinaryDownload, {
|
|
17806
|
-
scope,
|
|
17807
|
-
path
|
|
17808
|
-
})
|
|
17809
|
-
}
|
|
17810
|
-
];
|
|
17811
|
-
}
|
|
17812
|
-
//#endregion
|
|
17813
17513
|
//#region src/client/builtins/index.ts
|
|
17814
17514
|
/**
|
|
17815
|
-
* Register all built-in tabs
|
|
17816
|
-
*
|
|
17817
|
-
* disposal). The `ctx` is threaded into tab descriptors that need it
|
|
17818
|
-
* (EditorHost reads `ctx.betterSidebar` for file-viewer matching).
|
|
17515
|
+
* Register all built-in tabs with the service. Returns a disposer that
|
|
17516
|
+
* unregisters everything (cordis auto-invokes it on fiber disposal).
|
|
17819
17517
|
*/
|
|
17820
17518
|
function registerBuiltins(ctx, service, options = {}) {
|
|
17821
17519
|
const disposers = [];
|
|
17822
17520
|
for (const tab of builtinTabs(ctx, options)) disposers.push(service.registerTab(tab));
|
|
17823
|
-
for (const viewer of builtinViewers()) disposers.push(service.registerFileViewer(viewer));
|
|
17824
17521
|
return () => {
|
|
17825
17522
|
for (const d of disposers) try {
|
|
17826
17523
|
d();
|
|
@@ -20343,12 +20040,12 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20343
20040
|
//#endregion
|
|
20344
20041
|
//#region src/client/plugins-shared.ts
|
|
20345
20042
|
/**
|
|
20346
|
-
* Shared vocabulary of the recommended plugin
|
|
20347
|
-
* the GitHub topic URL. The
|
|
20348
|
-
* `plugins-tabs.ts` (tab registrations) and
|
|
20349
|
-
*
|
|
20350
|
-
* (
|
|
20351
|
-
*
|
|
20043
|
+
* Shared vocabulary of the recommended plugin catalog: the entry shape and
|
|
20044
|
+
* the GitHub topic URL. The catalog lives in the sibling module
|
|
20045
|
+
* `plugins-tabs.ts` (tab registrations) and is shown in the "add plugin"
|
|
20046
|
+
* modal (Side card settings → the dashed card at the end of the 侧边栏内容
|
|
20047
|
+
* grid). (v1.0.4: the file-previewer catalog was retired with the
|
|
20048
|
+
* file-viewer registry.)
|
|
20352
20049
|
*/
|
|
20353
20050
|
/** The GitHub topic page listing every repo tagged `dsh-coding-sidebar`. */
|
|
20354
20051
|
const PLUGIN_TOPIC_URL = "https://github.com/topics/dsh-coding-sidebar";
|
|
@@ -20431,40 +20128,16 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20431
20128
|
}
|
|
20432
20129
|
];
|
|
20433
20130
|
//#endregion
|
|
20434
|
-
//#region src/client/plugins-viewers.ts
|
|
20435
|
-
/**
|
|
20436
|
-
* The built-in catalog of FILE-PREVIEWER plugins (file-type previewers),
|
|
20437
|
-
* shown in the "add preview plugin" modal (Side card settings → 文件预览
|
|
20438
|
-
* grid → the dashed card). Adding an entry: append one object here (unique
|
|
20439
|
-
* `id` = npm package name, `url` = GitHub repo, `description` =
|
|
20440
|
-
* i18n-friendly, `install` = the full shell command pre-filled into the
|
|
20441
|
-
* install terminal — it starts with `cd ~/.dsh` so the install runs with
|
|
20442
|
-
* the DSH home as the working directory). Data integrity is guarded by
|
|
20443
|
-
* `tests/plugin-list.spec.ts`.
|
|
20444
|
-
*/
|
|
20445
|
-
/** File-previewer plugins (alphabetical order). */
|
|
20446
|
-
const builtinViewerPlugins = [{
|
|
20447
|
-
id: "@huanlin/dsh-plugin-better-sidebar-plugin-office",
|
|
20448
|
-
name: "Office 预览插件",
|
|
20449
|
-
url: "https://github.com/HuanLinOTO/dsh-plugin-better-sidebar-plugin-office",
|
|
20450
|
-
description: () => t("pluginOfficeDesc"),
|
|
20451
|
-
install: "cd ~/.dsh && dsh plugin --profile web add @huanlin/dsh-plugin-better-sidebar-plugin-office"
|
|
20452
|
-
}, {
|
|
20453
|
-
id: "dsh-video-preview",
|
|
20454
|
-
name: "视频预览插件",
|
|
20455
|
-
url: "https://github.com/zemul/dsh-video-preview",
|
|
20456
|
-
description: () => t("pluginVideoPreviewDesc"),
|
|
20457
|
-
install: "cd ~/.dsh && dsh plugin --profile web add dsh-video-preview"
|
|
20458
|
-
}];
|
|
20459
|
-
//#endregion
|
|
20460
20131
|
//#region src/client/add-plugin-modal.tsx
|
|
20461
20132
|
/**
|
|
20462
|
-
* The "add plugin"
|
|
20463
|
-
*
|
|
20464
|
-
*
|
|
20465
|
-
*
|
|
20466
|
-
*
|
|
20467
|
-
*
|
|
20133
|
+
* The "add plugin" modal (Side card settings → the dashed card at the end
|
|
20134
|
+
* of the 侧边栏内容 grid): declares that the sidebar's tab extension point
|
|
20135
|
+
* is open to plugins (registered through `ctx.betterSidebar`), points at
|
|
20136
|
+
* the GitHub topic page for discovery, and shows the repo's recommended
|
|
20137
|
+
* plugin catalog (name / url / description / install script).
|
|
20138
|
+
*
|
|
20139
|
+
* (v1.0.4: the file-viewer extension point was retired with the file-viewer
|
|
20140
|
+
* registry — this modal now catalogs tab plugins only.)
|
|
20468
20141
|
*
|
|
20469
20142
|
* Per entry there are two actions:
|
|
20470
20143
|
* - 「跳转」opens the plugin's repo in a REAL new browser tab (window.open
|
|
@@ -20479,20 +20152,15 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20479
20152
|
* Modal must never be renderToString'd (same rule as the settingsFor popup
|
|
20480
20153
|
* in SideCardSection); the modal itself mounts only while open.
|
|
20481
20154
|
*/
|
|
20482
|
-
/** The catalog of one kind (kept in two repo files: plugins-tabs.ts /
|
|
20483
|
-
* plugins-viewers.ts). */
|
|
20484
|
-
function catalogOf(kind) {
|
|
20485
|
-
return kind === "tab" ? builtinTabPlugins : builtinViewerPlugins;
|
|
20486
|
-
}
|
|
20487
20155
|
/** How long the "已复制" feedback stays on the copy button. */
|
|
20488
20156
|
const COPIED_FEEDBACK_MS = 1500;
|
|
20489
20157
|
/** The modal body: the GitHub topic button + the recommended plugin list
|
|
20490
20158
|
* with per-entry jump/copy buttons (extracted for direct testing). */
|
|
20491
20159
|
function PluginListBody(props) {
|
|
20492
|
-
const { service
|
|
20160
|
+
const { service } = props;
|
|
20493
20161
|
const [copiedId, setCopiedId] = (0, react.useState)(null);
|
|
20494
20162
|
const [query, setQuery] = (0, react.useState)("");
|
|
20495
|
-
const catalog =
|
|
20163
|
+
const catalog = builtinTabPlugins;
|
|
20496
20164
|
const needle = query.trim().toLowerCase();
|
|
20497
20165
|
const matches = (entry) => {
|
|
20498
20166
|
if (needle === "") return true;
|
|
@@ -20619,12 +20287,12 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20619
20287
|
}
|
|
20620
20288
|
/** The modal itself (mounted only while open — see the module comment). */
|
|
20621
20289
|
function AddPluginModal(props) {
|
|
20622
|
-
const { service, onClose
|
|
20290
|
+
const { service, onClose } = props;
|
|
20623
20291
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
20624
20292
|
open: true,
|
|
20625
20293
|
onClose,
|
|
20626
|
-
title:
|
|
20627
|
-
description:
|
|
20294
|
+
title: t("addPluginsTabCard"),
|
|
20295
|
+
description: t("addPluginsTabDesc"),
|
|
20628
20296
|
closeLabel: t("close"),
|
|
20629
20297
|
className: SideCardSection_module_css_default.pluginModal,
|
|
20630
20298
|
footer: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -20633,10 +20301,7 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20633
20301
|
onClick: onClose,
|
|
20634
20302
|
children: t("settingsDone")
|
|
20635
20303
|
}),
|
|
20636
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PluginListBody, {
|
|
20637
|
-
service,
|
|
20638
|
-
kind
|
|
20639
|
-
})
|
|
20304
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PluginListBody, { service })
|
|
20640
20305
|
});
|
|
20641
20306
|
}
|
|
20642
20307
|
//#endregion
|
|
@@ -20655,8 +20320,9 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20655
20320
|
* external plugins alike), laid out in a responsive grid that wraps
|
|
20656
20321
|
* several cards per row — icon chip + title + type id, clicked to toggle
|
|
20657
20322
|
* the switch persisted in `prefs.tabsEnabled[id]`.
|
|
20658
|
-
*
|
|
20659
|
-
*
|
|
20323
|
+
*
|
|
20324
|
+
* (v1.0.4: the 文件预览 viewer inventory was retired with the file-viewer
|
|
20325
|
+
* registry — file preview is the host's job now.)
|
|
20660
20326
|
*
|
|
20661
20327
|
* Every group lives in a container card (the DSH PluginCard recipe: l2
|
|
20662
20328
|
* hairline, 16px radius, layer-3 fill) with a heading and an inventory count
|
|
@@ -20713,18 +20379,14 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
20713
20379
|
const preset = getShellPreset(prefs.titleBarPresetId);
|
|
20714
20380
|
return preset !== void 0 ? `preset:${preset.id}` : "auto";
|
|
20715
20381
|
}
|
|
20716
|
-
/** Viewer inventory order: priority desc (the catch-all `code` comes last). */
|
|
20717
|
-
function viewerOrder(a, b) {
|
|
20718
|
-
return (b.priority ?? 0) - (a.priority ?? 0);
|
|
20719
|
-
}
|
|
20720
20382
|
/** Whether a feature declares any secondary settings (gear button shows). */
|
|
20721
20383
|
function hasSettings(feature) {
|
|
20722
20384
|
const settings = feature.settings;
|
|
20723
20385
|
return settings !== void 0 && ((settings.toggles?.length ?? 0) > 0 || (settings.pluginToggles?.length ?? 0) > 0 || settings.render !== void 0);
|
|
20724
20386
|
}
|
|
20725
|
-
/** A feature's display name
|
|
20387
|
+
/** A feature's display name. */
|
|
20726
20388
|
function featureNameOf(feature) {
|
|
20727
|
-
return textOf(
|
|
20389
|
+
return textOf(feature.title) || feature.id;
|
|
20728
20390
|
}
|
|
20729
20391
|
/**
|
|
20730
20392
|
* Merge one plugin-owned setting into a pluginSettings map (pure, v0.12.0+).
|
|
@@ -21034,7 +20696,7 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21034
20696
|
});
|
|
21035
20697
|
}
|
|
21036
20698
|
/**
|
|
21037
|
-
* The secondary settings popup body of one
|
|
20699
|
+
* The secondary settings popup body of one registered tab:
|
|
21038
20700
|
* - the host-prefs `toggles` rows, then the plugin-owned `pluginToggles`
|
|
21039
20701
|
* rows (their values live in `pluginSettings[feature.id]`, projected onto
|
|
21040
20702
|
* the prefs face so the shared row renderer reads them);
|
|
@@ -21090,16 +20752,14 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21090
20752
|
const [settingsFor, setSettingsFor] = (0, react.useState)(null);
|
|
21091
20753
|
const [stripSettingsOpen, setStripSettingsOpen] = (0, react.useState)(false);
|
|
21092
20754
|
const detectedEnv = (0, react.useMemo)(() => parseDesktopEnv(), []);
|
|
21093
|
-
const [addPluginsOpen, setAddPluginsOpen] = (0, react.useState)(
|
|
20755
|
+
const [addPluginsOpen, setAddPluginsOpen] = (0, react.useState)(false);
|
|
21094
20756
|
const optimisticRef = (0, react.useRef)(prefs);
|
|
21095
20757
|
(0, react.useEffect)(() => {
|
|
21096
20758
|
optimisticRef.current = prefs;
|
|
21097
20759
|
}, [prefs]);
|
|
21098
20760
|
const [tabs, setTabs] = (0, react.useState)(() => [...service.getTabs()].sort(tabOrder));
|
|
21099
|
-
const [viewers, setViewers] = (0, react.useState)(() => [...service.getFileViewers()].sort(viewerOrder));
|
|
21100
20761
|
(0, react.useEffect)(() => service.subscribe(() => {
|
|
21101
20762
|
setTabs([...service.getTabs()].sort(tabOrder));
|
|
21102
|
-
setViewers([...service.getFileViewers()].sort(viewerOrder));
|
|
21103
20763
|
}), [service]);
|
|
21104
20764
|
const revisionRef = (0, react.useRef)(void 0);
|
|
21105
20765
|
const dirtyRef = (0, react.useRef)(false);
|
|
@@ -21168,13 +20828,6 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21168
20828
|
[id]: next
|
|
21169
20829
|
} });
|
|
21170
20830
|
};
|
|
21171
|
-
/** Flip one per-viewer enable switch (merge into the viewersEnabled map). */
|
|
21172
|
-
const onToggleViewer = (id, next) => {
|
|
21173
|
-
applyPref({ viewersEnabled: {
|
|
21174
|
-
...optimisticRef.current.viewersEnabled,
|
|
21175
|
-
[id]: next
|
|
21176
|
-
} });
|
|
21177
|
-
};
|
|
21178
20831
|
/** Flip one declaratively-declared toggle (a SidebarPrefs boolean field). */
|
|
21179
20832
|
const onToggleSetting = (toggle, next) => {
|
|
21180
20833
|
applyPref({ [toggle.key]: next });
|
|
@@ -21520,7 +21173,7 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21520
21173
|
type: "button",
|
|
21521
21174
|
className: clsx(SideCardSection_module_css_default.card, SideCardSection_module_css_default.addCard),
|
|
21522
21175
|
onClick: () => {
|
|
21523
|
-
setAddPluginsOpen(
|
|
21176
|
+
setAddPluginsOpen(true);
|
|
21524
21177
|
},
|
|
21525
21178
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
21526
21179
|
className: SideCardSection_module_css_default.cardTop,
|
|
@@ -21538,49 +21191,6 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21538
21191
|
})]
|
|
21539
21192
|
})]
|
|
21540
21193
|
}),
|
|
21541
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21542
|
-
className: SideCardSection_module_css_default.group,
|
|
21543
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21544
|
-
className: SideCardSection_module_css_default.groupHeading,
|
|
21545
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("settingsViewersTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21546
|
-
className: SideCardSection_module_css_default.count,
|
|
21547
|
-
children: viewers.length
|
|
21548
|
-
})]
|
|
21549
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
21550
|
-
className: SideCardSection_module_css_default.grid,
|
|
21551
|
-
children: [viewers.map((viewer) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderCard({
|
|
21552
|
-
title: textOf(viewer.title) || viewer.id,
|
|
21553
|
-
desc: viewer.exts.length === 0 ? t("settingsViewerCatchAll") : viewer.exts.join(" · "),
|
|
21554
|
-
icon: iconOf(viewer.icon, 16),
|
|
21555
|
-
enabled: prefs.viewersEnabled[viewer.id] !== false,
|
|
21556
|
-
onToggle: (next) => {
|
|
21557
|
-
onToggleViewer(viewer.id, next);
|
|
21558
|
-
},
|
|
21559
|
-
onOpenSettings: prefs.viewersEnabled[viewer.id] !== false && hasSettings(viewer) ? () => {
|
|
21560
|
-
setSettingsFor(viewer);
|
|
21561
|
-
} : void 0
|
|
21562
|
-
}) }, viewer.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
21563
|
-
type: "button",
|
|
21564
|
-
className: clsx(SideCardSection_module_css_default.card, SideCardSection_module_css_default.addCard),
|
|
21565
|
-
onClick: () => {
|
|
21566
|
-
setAddPluginsOpen("viewer");
|
|
21567
|
-
},
|
|
21568
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
21569
|
-
className: SideCardSection_module_css_default.cardTop,
|
|
21570
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21571
|
-
className: SideCardSection_module_css_default.cardIconChip,
|
|
21572
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 16 })
|
|
21573
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21574
|
-
className: SideCardSection_module_css_default.cardTitle,
|
|
21575
|
-
children: t("addPluginsViewerCard")
|
|
21576
|
-
})]
|
|
21577
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
21578
|
-
className: SideCardSection_module_css_default.cardDesc,
|
|
21579
|
-
children: t("addPluginsViewerCardDesc")
|
|
21580
|
-
})]
|
|
21581
|
-
})]
|
|
21582
|
-
})]
|
|
21583
|
-
}),
|
|
21584
21194
|
settingsFor !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
21585
21195
|
open: true,
|
|
21586
21196
|
onClose: () => {
|
|
@@ -21661,12 +21271,11 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21661
21271
|
}, prefs.customCss)]
|
|
21662
21272
|
})
|
|
21663
21273
|
}),
|
|
21664
|
-
addPluginsOpen
|
|
21274
|
+
addPluginsOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AddPluginModal, {
|
|
21665
21275
|
service,
|
|
21666
21276
|
onClose: () => {
|
|
21667
|
-
setAddPluginsOpen(
|
|
21668
|
-
}
|
|
21669
|
-
kind: addPluginsOpen
|
|
21277
|
+
setAddPluginsOpen(false);
|
|
21278
|
+
}
|
|
21670
21279
|
}),
|
|
21671
21280
|
error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
21672
21281
|
className: SideCardSection_module_css_default.error,
|
|
@@ -21780,6 +21389,7 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21780
21389
|
const sidebarStore = createSidebarStore();
|
|
21781
21390
|
const service = createBetterSidebarService(sidebarStore);
|
|
21782
21391
|
ctx.provide("betterSidebar", service);
|
|
21392
|
+
ctx.effect(() => installNativeSidebarAvoidance(sidebarStore), "dsh-coding-sidebar: native-sidebar avoidance");
|
|
21783
21393
|
const fallbackTitle = t("terminal");
|
|
21784
21394
|
let terminalTitle = fallbackTitle;
|
|
21785
21395
|
api.shellGet().then(({ name }) => {
|
|
@@ -21789,7 +21399,7 @@ Mode: this is a continuable side conversation. Your answers stay in this side th
|
|
|
21789
21399
|
const tabs = allLeaves(snapshot.state.splits).flatMap((leaf) => leaf.tabs);
|
|
21790
21400
|
for (const tab of tabs) if (tab.type === "terminal" && !isAgentTabId(tab.id) && tab.title === fallbackTitle) service.updateTab(tab.id, { title: name });
|
|
21791
21401
|
}).catch(() => {});
|
|
21792
|
-
ctx.effect(() => registerBuiltins(ctx, service, { terminalTitle: () => terminalTitle }), "dsh-coding-sidebar: register built-in tabs
|
|
21402
|
+
ctx.effect(() => registerBuiltins(ctx, service, { terminalTitle: () => terminalTitle }), "dsh-coding-sidebar: register built-in tabs");
|
|
21793
21403
|
const fail = (phase, error) => {
|
|
21794
21404
|
console.error(`[dsh-coding-sidebar] ${phase} error:`, error);
|
|
21795
21405
|
try {
|