dsh-sessions-manager 3.2.1 → 3.2.2

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.en.md CHANGED
@@ -14,6 +14,12 @@
14
14
 
15
15
  A persistent DSH plugin (host + browser halves). Starting with v3.0.0, it covers both the **settings panel** and the **main sidebar**, so frequent session actions don't require opening Settings.
16
16
 
17
+ ## Changelog
18
+
19
+ - **v3.2.2**: engineering hardening, no behavior change. Sidebar decision logic extracted to `src/client/logic.js` (dot semantics / drop validation / fiber row detection) with 13 new regression tests; CI now smoke-tests each runtime version against real cordis and tracks runtime drift.
20
+ - **v3.2.1**: zstd session-log safety fix (frame-boundary scan mismatching zstd magic inside compressed data).
21
+ - **v3.2.0**: sidebar cross-workspace drag & drop + full session management workbench.
22
+
17
23
  ## What's new in v3.2
18
24
 
19
25
  - **Cross-workspace sidebar drag-and-drop**: drop a session on a workspace heading to move it. It coexists with DSH's native same-group sorting and provides target highlighting, same-workspace protection, failure feedback, and a keyboard-accessible menu fallback.
package/README.md CHANGED
@@ -14,6 +14,12 @@
14
14
 
15
15
  一个 DSH 持久化插件(host + browser 双半)。v3.0.0 起同时覆盖「设置面板」与「主页侧边栏」两个入口,无需打开设置即可完成高频会话操作。
16
16
 
17
+ ## 更新日志
18
+
19
+ - **v3.2.2**:工程加固版,无功能变化。侧栏判定纯逻辑抽取到 `src/client/logic.js`(状态点语义 / 拖拽校验 / fiber 行识别),新增 13 个回归测试;CI 新增 runtime 版本冒烟(真实 cordis DI 契约校验 + 版本漂移追踪)。
20
+ - **v3.2.1**:zstd 会话日志安全修复(帧边界定位误匹配压缩数据内的 magic)。
21
+ - **v3.2.0**:侧栏跨工作区拖拽 + 完整会话管理工作台。
22
+
17
23
  ## v3.2 亮点
18
24
 
19
25
  - **侧栏跨工作区拖拽**:把会话拖到目标工作区标题即可完成迁移;与 DSH 原生同组排序兼容,提供目标高亮、同工作区拦截、失败反馈,并保留键盘可达的菜单入口。
package/lib/client.js CHANGED
@@ -35,6 +35,48 @@ __export(index_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
37
  var import_react = __toESM(require("react"), 1);
38
+
39
+ // src/client/logic.js
40
+ function dotStateFor({ manualUnread = false, dataState = "", isActive = false } = {}) {
41
+ if (manualUnread) return "manual";
42
+ switch (dataState) {
43
+ case "running":
44
+ return "running";
45
+ case "warning":
46
+ return "feedback";
47
+ case "error":
48
+ return "error";
49
+ case "done":
50
+ return isActive ? null : "done";
51
+ default:
52
+ return null;
53
+ }
54
+ }
55
+ function canDropOnWorkspace(item, target) {
56
+ if (!item || !target) return false;
57
+ if (item.workspacePath && target.path === item.workspacePath) return false;
58
+ return true;
59
+ }
60
+ function sessionForNodes(nodes, knownSessions) {
61
+ for (const node of nodes || []) {
62
+ const id = node && node.id != null ? String(node.id) : "";
63
+ if (knownSessions.has(id)) return knownSessions.get(id);
64
+ if (id && node.workspaceId == null && (node.title != null || node.updatedAt != null || node.blank != null)) {
65
+ return { sessionId: id, title: node.title || "", workspacePath: null };
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ function workspaceForNodes(nodes) {
71
+ for (const group of nodes || []) {
72
+ if (group && group.workspaceId != null && typeof group.cwd === "string" && group.cwd) {
73
+ return { workspaceId: String(group.workspaceId), path: group.cwd, title: group.label || group.cwd };
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+
79
+ // src/client/index.jsx
38
80
  var import_jsx_runtime = require("react/jsx-runtime");
39
81
  var inject = ["slots"];
40
82
  var PANEL_PREFS_KEY = "dsm-panel-prefs-v1";
@@ -1377,15 +1419,8 @@ function installSidebarStatusDots() {
1377
1419
  const sd = row.querySelector("[data-state]");
1378
1420
  if (sd) sd.style.display = "none";
1379
1421
  let dot = row.querySelector("[" + DOT + "]");
1380
- let color = null;
1381
- if (manualUnread.has(id)) color = COLOR.manual;
1382
- else if (sd) {
1383
- const st = sd.getAttribute("data-state");
1384
- if (st === "running") color = COLOR.running;
1385
- else if (st === "warning") color = COLOR.feedback;
1386
- else if (st === "error") color = COLOR.error;
1387
- else if (st === "done") color = activeId === id ? null : COLOR.done;
1388
- }
1422
+ const state = dotStateFor({ manualUnread: manualUnread.has(id), dataState: sd ? sd.getAttribute("data-state") : "", isActive: activeId === id });
1423
+ const color = state ? COLOR[state] : null;
1389
1424
  if (!color) {
1390
1425
  if (dot) dot.remove();
1391
1426
  return;
@@ -1449,24 +1484,10 @@ function installSidebarWorkspaceDrag() {
1449
1484
  }
1450
1485
  return out;
1451
1486
  };
1452
- const sessionForRow = (row) => {
1453
- for (const node of fiberNodes(row)) {
1454
- const id = node && node.id != null ? String(node.id) : "";
1455
- if (sessions.has(id)) return sessions.get(id);
1456
- if (id && node.workspaceId == null && (node.title != null || node.updatedAt != null || node.blank != null)) {
1457
- return { sessionId: id, title: node.title || "", workspacePath: null };
1458
- }
1459
- }
1460
- return null;
1461
- };
1487
+ const sessionForRow = (row) => sessionForNodes(fiberNodes(row), sessions);
1462
1488
  const workspaceForRow = (row) => {
1463
1489
  if (sessionForRow(row)) return null;
1464
- for (const group of fiberNodes(row)) {
1465
- if (group.workspaceId != null && typeof group.cwd === "string" && group.cwd) {
1466
- return { workspaceId: String(group.workspaceId), path: group.cwd, title: group.label || group.cwd };
1467
- }
1468
- }
1469
- return null;
1490
+ return workspaceForNodes(fiberNodes(row));
1470
1491
  };
1471
1492
  const eventRow = (event) => {
1472
1493
  for (const item of event.composedPath ? event.composedPath() : []) {
@@ -1514,7 +1535,7 @@ function installSidebarWorkspaceDrag() {
1514
1535
  const row = eventRow(event);
1515
1536
  const target = row && workspaceForRow(row);
1516
1537
  if (!dragging || !target || moving) return;
1517
- if (dragging.workspacePath && target.path === dragging.workspacePath) return;
1538
+ if (!canDropOnWorkspace(dragging, target)) return;
1518
1539
  event.preventDefault();
1519
1540
  event.stopPropagation();
1520
1541
  if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
@@ -1527,7 +1548,7 @@ function installSidebarWorkspaceDrag() {
1527
1548
  const row = eventRow(event);
1528
1549
  const item = dragging;
1529
1550
  const target = row && workspaceForRow(row);
1530
- if (!item || !target || moving || item.workspacePath && target.path === item.workspacePath) return;
1551
+ if (!item || !target || moving || !canDropOnWorkspace(item, target)) return;
1531
1552
  event.preventDefault();
1532
1553
  event.stopPropagation();
1533
1554
  moving = true;
package/lib/client.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/client/index.jsx"],
4
- "sourcesContent": ["/**\n * dsh-sessions-manager \u2014 browser half: renders a single \"\u4F1A\u8BDD\u7BA1\u7406\" settings\n * section (settings.section list slot) that unifies archived-session\n * management and cross-workspace moving. It talks to the host half's\n * /archived-sessions/* JSON routes by fetch, showing every conversation with\n * its archive state and offering archive / restore / delete / move (and batch)\n * actions. All DOM/runtime wiring failures are logged, never thrown \u2014 a thrown\n * plugin apply takes down the whole web-shell boot.\n *\n * @module dsh-sessions-manager/client\n */\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\n\nexport const inject = ['slots']\n\nconst PANEL_PREFS_KEY = 'dsm-panel-prefs-v1'\nfunction loadPanelPrefs() {\n try { return JSON.parse(localStorage.getItem(PANEL_PREFS_KEY) || '{}') || {} } catch (e) { return {} }\n}\n\nconst CSS = `\n.archv{--dsm-radius-tag:4px;display:flex;flex-direction:column;gap:4px;max-width:800px;padding:8px 2px 28px}\n.archv-head{display:flex;align-items:center;gap:10px;margin:0 0 2px}\n.archv-title{font-size:16px;font-weight:650;color:var(--dsw-alias-label-primary);letter-spacing:-0.01em;margin:0}\n.archv-count{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:1px 8px;flex:none}\n.archv-sub{font-size:12px;line-height:1.55;color:var(--dsw-alias-label-tertiary);margin:0 0 12px;max-width:64ch}\n.archv-err{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);border-radius:10px;color:var(--dsw-alias-state-error-primary);font-size:12px;margin-bottom:10px}\n.archv-errretry{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent);background:transparent;color:inherit;border-radius:8px;padding:4px 10px;font-size:11px;cursor:pointer;flex:none}\n.sess-filter{display:flex;align-items:center;gap:6px;margin:0 0 12px}\n.sess-fbtn{appearance:none;min-height:30px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:999px;font-size:12px;font-weight:500;cursor:pointer}\n.sess-fbtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.sess-fbtn-on{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l3)}\n.sess-tools{display:grid;grid-template-columns:minmax(180px,1fr) minmax(140px,.7fr) minmax(130px,.55fr);gap:8px;margin:0 0 8px}\n.sess-field{display:flex;flex-direction:column;gap:5px;min-width:0}\n.sess-field label{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary)}\n.sess-field input,.sess-field select{box-sizing:border-box;width:100%;min-height:36px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);font:inherit;font-size:12px}\n.sess-results{font-size:11px;color:var(--dsw-alias-label-tertiary);margin:0 0 4px}\n.archv button:focus-visible,.archv input:focus-visible,.archv select:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}\n.sess-batch{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 2px 4px;margin-bottom:4px}\n.sess-btntext{font-size:12px;color:var(--dsw-alias-label-tertiary);flex:none}\n.archv-list{display:flex;flex-direction:column;gap:8px}\n.archv-card{display:flex;flex-direction:column;align-items:stretch;gap:0;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-elevated);transition:border-color .15s ease,background-color .15s ease}\n.archv-card:hover{border-color:var(--dsw-alias-border-l4)}\n.archv-card-exp{border-color:var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-1)}\n.archv-row{display:flex;align-items:center;gap:14px;width:100%;min-width:0}\n.archv-main{min-width:0;display:flex;flex-direction:column;gap:4px}\n.archv-name{font-size:13px;font-weight:550;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0}\n.archv-wtag{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;font-weight:500;line-height:1;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsm-radius-tag);padding:3px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-wgone{border-style:dashed;color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 7%,transparent)}\n.archv-active{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 45%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent)}\n.archv-date{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none}\n.archv-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dsw-alias-label-tertiary);flex:none}\n.archv-dot{color:var(--dsw-alias-border-l3);flex:none}\n.archv-check{width:15px;height:15px;accent-color:var(--dsw-alias-state-business-primary);flex:none;cursor:pointer}\n.archv-body{flex:1;min-width:0;display:flex;align-items:center;gap:12px}\n.archv-actions{display:flex;gap:8px;flex:none;flex-wrap:nowrap;justify-content:flex-end}\n.archv-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;gap:6px;text-align:center;transition:background-color .15s ease,border-color .15s ease,color .15s ease}\n.archv-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.archv-btn:disabled{opacity:.5;cursor:default}\n.archv-del{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent)}\n.archv-del:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.archv-go{color:var(--dsw-alias-state-business-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent)}\n.archv-go:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent);color:var(--dsw-alias-state-business-primary)}\n.archv-empty{display:flex;align-items:center;gap:10px;padding:20px 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.archv-skel{display:flex;flex-direction:column;gap:8px}\n.archv-skel-card{height:58px;border-radius:12px;background:var(--dsw-alias-fill-subtle);position:relative;overflow:hidden}\n.archv-skel-card::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dsw-alias-fill-elevated) 75%,transparent),transparent);animation:archv-shimmer 1.4s infinite}\n.archv-status{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:60;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);display:flex;align-items:center;gap:8px;animation:archv-pop .18s ease-out;max-width:min(90vw,420px)}\n.archv-spin{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dsw-alias-label-secondary) 35%,transparent);border-top-color:var(--dsw-alias-label-secondary);border-radius:50%;animation:archv-rot .8s linear infinite;flex:none}\n@keyframes archv-shimmer{100%{transform:translateX(100%)}}\n@keyframes archv-rot{to{transform:rotate(360deg)}}\n@keyframes archv-pop{from{opacity:0;transform:translateX(-50%) translateY(10px)}}\n@media (prefers-reduced-motion:reduce){.archv-skel-card::after{animation:none}.archv-card,.archv-btn{transition:none}.archv-status,.archv-spin{animation:none}}\n@media (max-width:640px){.archv-card{flex-direction:column;align-items:stretch;gap:10px}.archv-actions{justify-content:flex-end}.sess-tools{grid-template-columns:1fr}.sess-fbtn,.archv-btn{min-height:40px}}\n.mv-sheet{width:100%;box-sizing:border-box;display:flex;flex-direction:column;gap:12px;margin-top:12px;padding:14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-fill-subtle)}\n.mv-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:10px}\n.mv-sheet-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin:0}\n.mv-sheet-close{appearance:none;width:26px;height:26px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:7px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1}\n.mv-sheet-close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.mv-seg{display:flex;gap:2px;padding:2px;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;width:100%}\n.mv-segbtn{appearance:none;flex:1;min-height:30px;padding:0 12px;border:none;background:transparent;color:var(--dsw-alias-label-secondary);border-radius:8px;font-size:12px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:6px}\n.mv-segbtn:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.mv-segbtn-on{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);box-shadow:0 1px 2px rgb(0 0 0/.08)}\n.mv-field{display:flex;flex-direction:column;gap:6px}\n.mv-field label.mv-field-label{font-size:12px;font-weight:500;color:var(--dsw-alias-label-secondary)}\n.mv-field select,.mv-field input[type=text]{box-sizing:border-box;appearance:none;width:100%;min-height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);font-size:12px;font-family:inherit}\n.mv-field select:focus-visible,.mv-field input[type=text]:focus-visible,.mv-sheet-close:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.mv-browse-row{display:flex;align-items:center;gap:8px}\n.mv-browse-row input[type=text]{flex:1;min-width:0}\n.mv-foot{display:flex;justify-content:flex-end;align-items:center;gap:8px;margin-top:2px}\n@media (max-width:640px){.archv-row{flex-wrap:wrap}.mv-sheet{padding:12px}}\n.dtl-sheet{margin-top:12px;padding:14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-fill-subtle)}\n.dtl-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:10px}\n.dtl-sheet-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin:0}\n.dtl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:8px;margin-top:10px}\n.dtl-cell{display:flex;flex-direction:column;gap:2px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-fill-elevated);min-width:0}\n.dtl-k{font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dtl-v{font-size:12px;color:var(--dsw-alias-label-primary);word-break:break-all}\n.dtl-sec{margin-top:12px}\n.dtl-sec-t{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.03em;margin-bottom:6px}\n.dtl-tags{display:flex;flex-wrap:wrap;gap:6px}\n.dtl-tag{display:inline-flex;font-size:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsm-radius-tag);padding:2px 8px}\n.dtl-list{margin:0;padding-left:18px;display:flex;flex-direction:column;gap:3px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}\n.dtl-list code,.dtl-paths code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:var(--dsw-alias-label-primary);word-break:break-all}\n.dtl-filetool{color:var(--dsw-alias-label-tertiary)}\n.dtl-paths{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--dsw-alias-label-secondary);word-break:break-all}\n.more-wrap{position:relative;flex:none}\n.more-btn{appearance:none;width:28px;height:28px;border:none;border-radius:8px;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;line-height:1}\n.more-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.more-menu{position:absolute;top:calc(100% + 4px);right:0;z-index:60;min-width:160px;padding:5px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);border-radius:10px;box-shadow:0 10px 32px rgb(0 0 0/.24);display:flex;flex-direction:column;gap:1px}\n.more-item{appearance:none;display:flex;align-items:center;gap:8px;width:100%;padding:7px 10px;border:none;background:transparent;color:var(--dsw-alias-label-primary);border-radius:7px;font-size:12.5px;cursor:pointer;white-space:nowrap;text-align:left}\n.more-item:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.more-item-danger{color:var(--dsw-alias-state-error-primary)}\n.more-item-danger:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.dlg-backdrop{position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.dlg{width:min(420px,92vw);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);border-radius:14px;padding:18px;box-shadow:0 16px 48px rgb(0 0 0/.28);display:flex;flex-direction:column;gap:12px}\n.dlg-title{font-size:15px;font-weight:650;color:var(--dsw-alias-label-primary);margin:0}\n.dlg-text{font-size:13px;line-height:1.6;color:var(--dsw-alias-label-secondary);margin:0;word-break:break-all}\n.dlg-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:2px}\n`\n\nfunction fmtDate(iso) {\n if (!iso) return null\n const d = new Date(iso)\n if (isNaN(d.getTime())) return null\n try {\n return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }).format(d)\n } catch {\n return String(iso)\n }\n}\n\nfunction fmtBytes(n) {\n if (!n && n !== 0) return null\n if (n < 1024) return `${n} B`\n const units = ['KB', 'MB', 'GB', 'TB']\n let v = n\n let u = -1\n do { v /= 1024; u++ } while (v >= 1024 && u < units.length - 1)\n return `${v >= 100 ? v.toFixed(0) : v.toFixed(1)} ${units[u]}`\n}\n\nfunction pathName(p) {\n if (!p) return null\n const parts = String(p).replace(/\\\\+$/, '').split(/[/\\\\]/)\n return parts[parts.length - 1] || p\n}\n\nasync function postJSON(path, body) {\n const res = await fetch(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: JSON.stringify(body || {}),\n })\n const data = await res.json().catch(() => null)\n if (!res.ok || !data) throw new Error((data && (data.error || data.message)) || `request failed (${res.status})`)\n return data\n}\n\n// Left-nav icon swap: DSH's settings shell renders a shared fallback gear for\n// every custom section and settings.section has no per-section icon field.\n// Like dsh-better-sidebar, we mark our own row by matching its visible label\n// text, then CSS swaps the gear for an archive-box glyph. The marker owns no\n// shell structure and is removed on fiber disposal (HMR-safe, ships with the\n// plugin).\nconst NAV_CSS = `\n[data-dsh-nav-sessions] > svg:first-child { display: none; }\n[data-dsh-nav-sessions]::before {\n content: ''; flex: none; width: 16px; height: 16px; background: currentColor;\n -webkit-mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E\") center / contain no-repeat;\n mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E\") center / contain no-repeat;\n}\n`\n\nfunction markSettingsNav() {\n const LABEL = '\u4F1A\u8BDD\u7BA1\u7406'\n let disposed = false\n const sync = () => {\n if (disposed) return\n const buttons = document.querySelectorAll('[role=\"dialog\"] nav button')\n for (const b of buttons) {\n const t = (b.textContent || '').trim()\n if (t === LABEL) b.setAttribute('data-dsh-nav-sessions', '')\n else b.removeAttribute('data-dsh-nav-sessions')\n }\n }\n sync()\n const obs = new MutationObserver(sync)\n obs.observe(document.body, { childList: true, subtree: true, characterData: true })\n return () => {\n disposed = true\n obs.disconnect()\n document.querySelectorAll('[data-dsh-nav-sessions]').forEach((e) => e.removeAttribute('data-dsh-nav-sessions'))\n }\n}\n\nfunction installSettingsNavIcons(ctx) {\n const styleEl = document.createElement('style')\n styleEl.textContent = NAV_CSS\n document.head.appendChild(styleEl)\n const dispose = markSettingsNav()\n ctx.effect(() => () => {\n dispose()\n if (styleEl.parentNode) styleEl.parentNode.removeChild(styleEl)\n })\n}\n\nfunction SessionPanel({ workspacesSvc }) {\n const [sessions, setSessions] = useState(null)\n const [workspaces, setWorkspaces] = useState([])\n const initialPrefs = useRef(loadPanelPrefs()).current\n const [filter, setFilter] = useState(() => ['all', 'active', 'archived', 'trash'].includes(initialPrefs.filter) ? initialPrefs.filter : 'all')\n const [query, setQuery] = useState('')\n const [workspaceFilter, setWorkspaceFilter] = useState(() => initialPrefs.workspaceFilter || 'all')\n const [sortBy, setSortBy] = useState(() => ['newest', 'oldest', 'title'].includes(initialPrefs.sortBy) ? initialPrefs.sortBy : 'newest')\n const [selected, setSelected] = useState({})\n const [delTarget, setDelTarget] = useState(null)\n const [confirmBatch, setConfirmBatch] = useState(false)\n const [busy, setBusy] = useState(null)\n const [openMove, setOpenMove] = useState(null)\n const [moveMode, setMoveMode] = useState('existing')\n const [targetWs, setTargetWs] = useState('')\n const [newPath, setNewPath] = useState('')\n const [error, setError] = useState(null)\n const [toast, setToast] = useState(null)\n const [picking, setPicking] = useState(false)\n const [trash, setTrash] = useState([])\n const [trashBusy, setTrashBusy] = useState(null)\n const [trashSettings, setTrashSettings] = useState({ retentionDays: 0 })\n const [trashCheck, setTrashCheck] = useState(null)\n const [purgeTarget, setPurgeTarget] = useState(null)\n const [details, setDetails] = useState({})\n const [openDetails, setOpenDetails] = useState(null)\n const [detailsLoading, setDetailsLoading] = useState(null)\n const [openMenu, setOpenMenu] = useState(null)\n const timer = useRef(null)\n const menuRef = useRef(null)\n const dialogRef = useRef(null)\n\n const showToast = (msg) => {\n if (timer.current) clearTimeout(timer.current)\n setToast(msg)\n timer.current = setTimeout(() => setToast(null), 2400)\n }\n\n const refresh = () => {\n setError(null)\n Promise.all([\n postJSON('/archived-sessions/sessions', {}),\n postJSON('/archived-sessions/workspaces', {}),\n ])\n .then(([s, works]) => {\n // Permanently-purged sessions must never re-appear here, even if DSH's\n // in-memory session index still lists them after the file was unlinked.\n const purged = dsmLoadPurged()\n const visible = (s.items || []).filter((x) => !purged.has(String(x.sessionId)))\n setSessions(visible)\n setWorkspaces(works.items || [])\n setSelected({})\n setDelTarget(null)\n setConfirmBatch(false)\n if (!targetWs && works.items && works.items.length) setTargetWs(works.items[0].workspaceId)\n loadTrash()\n })\n .catch((e) => setError(String((e && e.message) || e)))\n }\n\n useEffect(() => {\n refresh()\n return () => { if (timer.current) clearTimeout(timer.current) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n try { localStorage.setItem(PANEL_PREFS_KEY, JSON.stringify({ filter, workspaceFilter, sortBy })) } catch (e) {}\n }, [filter, workspaceFilter, sortBy])\n\n // Close the \u22EF menu on outside click / Escape (no full-screen backdrop).\n useEffect(() => {\n if (openMenu === null) return\n const onDown = (e) => {\n if (menuRef.current && !menuRef.current.contains(e.target)) setOpenMenu(null)\n }\n const onKey = (e) => { if (e.key === 'Escape') setOpenMenu(null) }\n document.addEventListener('mousedown', onDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [openMenu])\n\n useEffect(() => {\n if (!delTarget && !purgeTarget) return\n const previous = document.activeElement\n const onKey = (e) => {\n if (e.key === 'Escape') { setDelTarget(null); setPurgeTarget(null) }\n }\n document.addEventListener('keydown', onKey)\n requestAnimationFrame(() => dialogRef.current && dialogRef.current.querySelector('button')?.focus())\n return () => {\n document.removeEventListener('keydown', onKey)\n if (previous && typeof previous.focus === 'function') previous.focus()\n }\n }, [delTarget, purgeTarget])\n\n const wsPath = (id) => {\n const w = workspaces.find((x) => x.workspaceId === id)\n return w ? w.path : ''\n }\n\n const archivedList = sessions ? sessions.filter((x) => x.archived) : []\n const activeList = sessions ? sessions.filter((x) => !x.archived) : []\n const list = useMemo(() => {\n if (filter === 'trash') return []\n const base = filter === 'archived' ? archivedList : filter === 'active' ? activeList : sessions || []\n const needle = query.trim().toLocaleLowerCase()\n const filtered = base.filter((item) => {\n if (workspaceFilter !== 'all' && (item.workspacePath || '') !== workspaceFilter) return false\n if (!needle) return true\n return [item.title, item.sessionId, item.workspaceTitle, item.workspacePath].some((value) => String(value || '').toLocaleLowerCase().includes(needle))\n })\n return [...filtered].sort((a, b) => {\n if (sortBy === 'oldest') return Number(a.createdAt || 0) - Number(b.createdAt || 0)\n if (sortBy === 'title') return String(a.title || '').localeCompare(String(b.title || ''), 'zh-CN')\n return Number(b.createdAt || 0) - Number(a.createdAt || 0)\n })\n }, [sessions, filter, query, workspaceFilter, sortBy])\n const selIds = Object.keys(selected).filter((k) => selected[k])\n\n const toggle = (id) => setSelected((s) => ({ ...s, [id]: !s[id] }))\n const clearSel = () => setSelected({})\n const selectAll = () => {\n const o = {}\n list.forEach((x) => { o[x.sessionId] = true })\n setSelected(o)\n }\n\n const act = (action, it) => {\n if (busy) return\n setBusy(it.sessionId)\n postJSON('/archived-sessions/' + action, { sessionId: it.sessionId })\n .then(() => {\n setBusy(null)\n const n = it.title || it.sessionId\n showToast(action === 'archive' ? `\u5DF2\u5F52\u6863\u300C${n}\u300D` : `\u5DF2\u6062\u590D\u300C${n}\u300D`)\n refresh()\n })\n .catch((e) => { setBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const doDeleteConfirmed = () => {\n if (!delTarget || busy) return\n setBusy(delTarget.sessionId)\n postJSON('/archived-sessions/delete', { sessionId: delTarget.sessionId })\n .then(() => {\n setBusy(null)\n const n = delTarget.title || delTarget.sessionId\n showToast(`\u5DF2\u5220\u9664 ${n}\uFF08\u5DF2\u79FB\u5165\u56DE\u6536\u7AD9\uFF09`)\n setDelTarget(null)\n refresh()\n })\n .catch((e) => { setBusy(null); setDelTarget(null); setError(String((e && e.message) || e)) })\n }\n\n const loadTrash = () => {\n postJSON('/archived-sessions/trash/list', {})\n .then((r) => { setTrash(r.items || []); setTrashSettings(r.settings || { retentionDays: 0 }) })\n .catch(() => {})\n }\n\n const updateRetention = (days) => {\n setTrashBusy('__settings')\n postJSON('/archived-sessions/trash/settings', { retentionDays: Number(days) })\n .then((r) => { setTrashBusy(null); setTrashSettings(r.settings); showToast('\u5DF2\u66F4\u65B0\u81EA\u52A8\u6E05\u7406\u7B56\u7565') })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const verifyTrash = () => {\n setTrashBusy('__verify')\n postJSON('/archived-sessions/trash/verify', {})\n .then((r) => { setTrashBusy(null); setTrashCheck(r); showToast(r.missing ? `\u53D1\u73B0 ${r.missing} \u6761\u65E5\u5FD7\u7F3A\u5931` : '\u56DE\u6536\u7AD9\u6821\u9A8C\u901A\u8FC7') })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const restoreTrash = (sid) => {\n if (trashBusy) return\n setTrashBusy(sid)\n postJSON('/archived-sessions/trash/restore', { sessionId: sid })\n .then(() => { setTrashBusy(null); showToast('\u5DF2\u6062\u590D\u4F1A\u8BDD'); loadTrash(); refresh() })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n const purgeTrash = (sid) => {\n if (trashBusy) return\n setTrashBusy(sid)\n postJSON('/archived-sessions/trash/purge', { sessionId: sid })\n .then(() => { setTrashBusy(null); showToast('\u5DF2\u5F7B\u5E95\u5220\u9664'); dsmMarkPurged([sid]); dsmLoadTrashIds(); loadTrash() })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n const purgeAllTrash = () => {\n if (trashBusy || !trash.length) return\n setTrashBusy('__all')\n const all = trash.map((t) => t.sessionId)\n postJSON('/archived-sessions/trash/purge-many', { sessionIds: all })\n .then((result) => {\n setTrashBusy(null)\n const rows = result.results || []\n const succeeded = rows.filter((item) => item.ok).map((item) => item.sessionId)\n const failed = rows.filter((item) => !item.ok)\n if (succeeded.length) dsmMarkPurged(succeeded)\n dsmLoadTrashIds()\n loadTrash()\n if (failed.length) {\n const first = failed[0]\n setError(`\u6E05\u7406\u5B8C\u6210 ${succeeded.length} \u6761\uFF0C\u5931\u8D25 ${failed.length} \u6761\uFF1A${first.error || first.sessionId}`)\n } else showToast('\u5DF2\u6E05\u7A7A\u56DE\u6536\u7AD9')\n })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const doMove = (it) => {\n const targetPath = moveMode === 'new' ? newPath.trim() : wsPath(targetWs)\n if (!targetPath) { setError('\u8BF7\u9009\u62E9\u5DF2\u6709\u5DE5\u4F5C\u533A\u6216\u8F93\u5165\u65B0\u7684\u76EE\u6807\u76EE\u5F55\u8DEF\u5F84'); return }\n setBusy(it.sessionId)\n setError(null)\n postJSON('/archived-sessions/move', { sessionId: it.sessionId, targetPath })\n .then((r) => {\n setBusy(null)\n setOpenMove(null)\n setMoveMode('existing')\n setNewPath('')\n showToast(`\u5DF2\u628A\u300C${it.title || it.sessionId}\u300D\u79FB\u5230 ${r.workspaceTitle || targetPath}`)\n refresh()\n })\n .catch((e) => { setBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const doBatch = (action) => {\n if (!selIds.length || busy) return\n if (action === 'delete-many') {\n if (!confirmBatch) { setConfirmBatch(true); return }\n setConfirmBatch(false)\n }\n setBusy('__batch__')\n postJSON('/archived-sessions/' + action, { sessionIds: selIds })\n .then((r) => {\n setBusy(null)\n const n = (r && (r.archived || r.restored || r.deleted)) || selIds.length\n showToast(`\u5DF2\u5904\u7406 ${n} \u4E2A\u4F1A\u8BDD`)\n refresh()\n })\n .catch((e) => { setBusy(null); setConfirmBatch(false); setError(String((e && e.message) || e)) })\n }\n\n const openMoveFor = (it) => {\n if (openMove === it.sessionId) { setOpenMove(null); return }\n setTargetWs(workspaces.length ? (targetWs || workspaces[0].workspaceId) : '')\n setMoveMode('existing')\n setNewPath('')\n setOpenMove(it.sessionId)\n }\n\n const pickDirectory = async () => {\n if (!workspacesSvc || picking) return\n setPicking(true)\n try {\n const p = await workspacesSvc.pickDirectory()\n if (p) { setNewPath(p); setMoveMode('new') }\n } catch (e) {\n setError(String((e && e.message) || e))\n } finally {\n setPicking(false)\n }\n }\n\n const toggleDetails = (it) => {\n if (openDetails === it.sessionId) { setOpenDetails(null); return }\n if (details[it.sessionId]) { setOpenDetails(it.sessionId); return }\n setDetailsLoading(it.sessionId)\n postJSON('/archived-sessions/details', { sessionId: it.sessionId })\n .then((d) => {\n setDetails((m) => ({ ...m, [it.sessionId]: d }))\n setDetailsLoading(null)\n setOpenDetails(it.sessionId)\n })\n .catch((e) => { setDetailsLoading(null); setError(String((e && e.message) || e)) })\n }\n\n const workspaceTag = (it) => {\n if (it.hasWorkspace && it.workspaceGone) {\n return <span className=\"archv-wtag archv-wgone\" title={(it.workspacePath || '') + '\uFF08\u539F\u5DE5\u4F5C\u533A\u5DF2\u5220\u9664\uFF09'}>\u5DE5\u4F5C\u533A\u5DF2\u5220 \u00B7 {pathName(it.workspacePath) || '?'}</span>\n }\n const wName = it.workspaceTitle || pathName(it.workspacePath)\n if (wName) return <span className=\"archv-wtag\" title={it.workspacePath || ''}>{wName}</span>\n return <span className=\"archv-wtag\">\u672A\u5206\u7EC4</span>\n }\n\n const runMenu = (id, it) => {\n setOpenMenu(null)\n if (id === 'restore') act('restore', it)\n else if (id === 'archive') act('archive', it)\n else if (id === 'delete') setDelTarget(it)\n else if (id === 'move') openMoveFor(it)\n else if (id === 'details') toggleDetails(it)\n }\n\n const rowMenu = (it) => {\n const items = it.archived\n ? [\n ['restore', '\u6062\u590D'],\n ['move', openMove === it.sessionId ? '\u6536\u8D77\u79FB\u52A8' : '\u79FB\u52A8'],\n ['details', openDetails === it.sessionId ? '\u6536\u8D77\u8BE6\u60C5' : '\u8BE6\u60C5'],\n ['delete', '\u5220\u9664'],\n ]\n : [['archive', '\u5F52\u6863'], ['move', '\u79FB\u52A8'], ['details', '\u8BE6\u60C5'], ['delete', '\u5220\u9664']]\n return (\n <div ref={openMenu === it.sessionId ? menuRef : null} className=\"more-wrap\">\n <button\n type=\"button\"\n className=\"more-btn\"\n aria-label=\"\u66F4\u591A\u64CD\u4F5C\"\n aria-haspopup=\"true\"\n aria-expanded={openMenu === it.sessionId}\n onClick={(e) => { e.stopPropagation(); setOpenMenu(openMenu === it.sessionId ? null : it.sessionId) }}\n >\u22EF</button>\n {openMenu === it.sessionId && (\n <div className=\"more-menu\" role=\"menu\">\n {items.map(([id, label]) => (\n <button\n key={id}\n type=\"button\"\n role=\"menuitem\"\n className={'more-item' + (id === 'delete' ? ' more-item-danger' : '')}\n onClick={() => runMenu(id, it)}\n >{label}</button>\n ))}\n </div>\n )}\n </div>\n )\n }\n\n return (\n <div className=\"archv\" role=\"region\" aria-label=\"\u4F1A\u8BDD\u7BA1\u7406\">\n <style>{CSS}</style>\n <div className=\"archv-head\">\n <h2 className=\"archv-title\">\u4F1A\u8BDD\u7BA1\u7406</h2>\n {sessions !== null && <span className=\"archv-count\" aria-label={`${sessions.length} \u4E2A\u4F1A\u8BDD`}>{sessions.length}</span>}\n </div>\n <p className=\"archv-sub\">\n \u7EDF\u4E00\u7BA1\u7406\u5168\u90E8\u4F1A\u8BDD\uFF1A\u5F52\u6863 / \u6062\u590D / \u79FB\u52A8\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A / \u4F1A\u8BDD\u8BE6\u60C5 / \u6279\u91CF\u64CD\u4F5C\uFF0C\u5220\u9664\u4F1A\u5148\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u53EF\u5728\u56DE\u6536\u7AD9\u5185\u6062\u590D\u6216\u5F7B\u5E95\u6E05\u7406\u3002\n </p>\n {error && (\n <div className=\"archv-err\" role=\"alert\">\n <span>{error}</span>\n <button type=\"button\" className=\"archv-errretry\" onClick={refresh}>\u91CD\u8BD5</button>\n </div>\n )}\n {sessions === null ? (\n <div className=\"archv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">\n {[0, 1, 2].map((i) => <div key={i} className=\"archv-skel-card\" />)}\n </div>\n ) : (\n <>\n <div className=\"sess-filter\" role=\"tablist\" aria-label=\"\u4F1A\u8BDD\u7B5B\u9009\">\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'all'} className={'sess-fbtn' + (filter === 'all' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('all'); clearSel(); setConfirmBatch(false) }}>\u5168\u90E8 ({sessions.length})</button>\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'active'} className={'sess-fbtn' + (filter === 'active' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('active'); clearSel(); setConfirmBatch(false) }}>\u6D3B\u52A8 ({activeList.length})</button>\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'archived'} className={'sess-fbtn' + (filter === 'archived' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('archived'); clearSel(); setConfirmBatch(false) }}>\u5DF2\u5F52\u6863 ({archivedList.length})</button>\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'trash'} className={'sess-fbtn' + (filter === 'trash' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('trash'); clearSel(); setConfirmBatch(false) }}>\u56DE\u6536\u7AD9 ({trash.length})</button>\n </div>\n\n {filter !== 'trash' && (\n <>\n <div className=\"sess-tools\" aria-label=\"\u67E5\u627E\u548C\u6574\u7406\u4F1A\u8BDD\">\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-search\">\u641C\u7D22\u4F1A\u8BDD</label>\n <input id=\"dsm-search\" type=\"search\" value={query} onChange={(e) => setQuery(e.target.value)} placeholder=\"\u6807\u9898\u3001\u4F1A\u8BDD ID \u6216\u5DE5\u4F5C\u533A\" />\n </div>\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-workspace-filter\">\u5DE5\u4F5C\u533A</label>\n <select id=\"dsm-workspace-filter\" value={workspaceFilter} onChange={(e) => setWorkspaceFilter(e.target.value)}>\n <option value=\"all\">\u5168\u90E8\u5DE5\u4F5C\u533A</option>\n {workspaces.map((w) => <option key={w.workspaceId} value={w.path}>{w.title}</option>)}\n </select>\n </div>\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-sort\">\u6392\u5E8F</label>\n <select id=\"dsm-sort\" value={sortBy} onChange={(e) => setSortBy(e.target.value)}>\n <option value=\"newest\">\u6700\u65B0\u521B\u5EFA</option><option value=\"oldest\">\u6700\u65E9\u521B\u5EFA</option><option value=\"title\">\u6807\u9898 A\u2013Z</option>\n </select>\n </div>\n </div>\n <div className=\"sess-results\" role=\"status\">\u663E\u793A {list.length} \u4E2A\u4F1A\u8BDD{query || workspaceFilter !== 'all' ? `\uFF0C\u5171 ${filter === 'archived' ? archivedList.length : filter === 'active' ? activeList.length : sessions.length} \u4E2A` : ''}</div>\n </>\n )}\n\n {filter !== 'trash' && list.length > 0 && (\n <div className=\"sess-batch\">\n <span className=\"sess-btntext\">{selIds.length ? `\u5DF2\u9009 ${selIds.length} \u9879` : (filter === 'archived' ? `\u5171 ${archivedList.length} \u4E2A\u5F52\u6863\u4F1A\u8BDD` : `\u5171 ${sessions.length} \u4E2A\u4F1A\u8BDD\uFF08\u6D3B\u52A8 ${activeList.length} / \u5DF2\u5F52\u6863 ${archivedList.length}\uFF09`)}</span>\n <button type=\"button\" className=\"archv-btn\" disabled={list.length === 0} onClick={selectAll}>\u5168\u9009</button>\n {selIds.length > 0 && (\n <>\n {filter === 'archived' && (\n <>\n <button type=\"button\" className=\"archv-btn\" disabled={busy !== null} onClick={() => doBatch('restore-many')}>\u6062\u590D\u6240\u9009</button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={busy !== null} onClick={() => doBatch('delete-many')}>{confirmBatch ? '\u786E\u8BA4\u5220\u9664\u6240\u9009?' : '\u5220\u9664\u6240\u9009'}</button>\n </>\n )}\n {filter !== 'archived' && (\n <button type=\"button\" className=\"archv-btn\" disabled={busy !== null} onClick={() => doBatch('archive-many')}>\u5F52\u6863\u6240\u9009</button>\n )}\n <button type=\"button\" className=\"archv-btn\" onClick={clearSel}>\u53D6\u6D88\u9009\u62E9</button>\n </>\n )}\n </div>\n )}\n\n {filter !== 'trash' && list.length === 0 ? (\n <div className=\"archv-empty\">{query || workspaceFilter !== 'all' ? '\u6CA1\u6709\u5339\u914D\u7684\u4F1A\u8BDD\u3002\u8BF7\u8C03\u6574\u641C\u7D22\u8BCD\u6216\u5DE5\u4F5C\u533A\u7B5B\u9009\u3002' : filter === 'archived' ? '\u76EE\u524D\u6CA1\u6709\u5F52\u6863\u4F1A\u8BDD\u3002\u5728\u201C\u5168\u90E8\u201D\u91CC\u9009\u4E2D\u4F1A\u8BDD\u70B9\u201C\u5F52\u6863\u201D\u5373\u53EF\u6536\u7EB3\u8FDB\u6765\u3002' : filter === 'active' ? '\u76EE\u524D\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD\u3002' : '\u6682\u65E0\u53EF\u7BA1\u7406\u7684\u4F1A\u8BDD\u3002'}</div>\n ) : filter !== 'trash' ? (\n <div className=\"archv-list\" role=\"list\">\n {list.map((it) => {\n const date = fmtDate(it.createdAt)\n const expanded = openMove === it.sessionId\n return (\n <div key={it.sessionId} className={'archv-card' + (expanded ? ' archv-card-exp' : '')} role=\"listitem\">\n <div className=\"archv-row\">\n <input\n type=\"checkbox\"\n className=\"archv-check\"\n checked={!!selected[it.sessionId]}\n onChange={() => toggle(it.sessionId)}\n aria-label={'\u9009\u62E9 ' + (it.title || it.sessionId)}\n />\n <div className=\"archv-body\">\n <div className=\"archv-main\">\n <div className=\"archv-name\" title={it.title || ''}>{it.title || '(\u65E0\u6807\u9898)'}</div>\n <div className=\"archv-meta\">\n {it.archived ? <span className=\"archv-wtag archv-wgone\">\u5DF2\u5F52\u6863</span> : <span className=\"archv-wtag archv-active\">\u6D3B\u52A8</span>}\n {workspaceTag(it)}\n {date && <><span className=\"archv-dot\">\u00B7</span><span className=\"archv-date\">{date}</span></>}\n <span className=\"archv-id\">{it.sessionId}</span>\n </div>\n </div>\n {rowMenu(it)}\n </div>\n </div>\n {expanded && (\n <div className=\"mv-sheet\" role=\"region\" aria-label=\"\u79FB\u52A8\u5230\u5DE5\u4F5C\u533A\">\n <div className=\"mv-sheet-head\">\n <h3 className=\"mv-sheet-title\">\u79FB\u52A8\u5230\u5DE5\u4F5C\u533A</h3>\n <button type=\"button\" className=\"mv-sheet-close\" aria-label=\"\u5173\u95ED\" onClick={() => setOpenMove(null)}>\u00D7</button>\n </div>\n <div className=\"mv-seg\" role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={moveMode === 'existing'} className={'mv-segbtn' + (moveMode === 'existing' ? ' mv-segbtn-on' : '')} onClick={() => setMoveMode('existing')}>\u5DF2\u6709\u5DE5\u4F5C\u533A</button>\n <button type=\"button\" role=\"tab\" aria-selected={moveMode === 'new'} className={'mv-segbtn' + (moveMode === 'new' ? ' mv-segbtn-on' : '')} onClick={() => setMoveMode('new')}>\u65B0\u5EFA\u76EE\u5F55</button>\n </div>\n {moveMode === 'existing' ? (\n <div className=\"mv-field\">\n <label className=\"mv-field-label\" htmlFor=\"mv-target-ws\">\u76EE\u6807\u5DE5\u4F5C\u533A</label>\n <select id=\"mv-target-ws\" value={targetWs} onChange={(e) => setTargetWs(e.target.value)}>\n {workspaces.length === 0 && <option value=\"\">\uFF08\u6682\u65E0\u5DE5\u4F5C\u533A\uFF09</option>}\n {workspaces.map((w) => (\n <option key={w.workspaceId} value={w.workspaceId}>{w.title} \u00B7 {w.path}</option>\n ))}\n </select>\n </div>\n ) : (\n <div className=\"mv-field\">\n <label className=\"mv-field-label\" htmlFor=\"mv-new-path\">\u65B0\u5DE5\u4F5C\u533A\u76EE\u5F55\u8DEF\u5F84</label>\n <div className=\"mv-browse-row\">\n <input\n id=\"mv-new-path\"\n type=\"text\"\n value={newPath}\n onChange={(e) => setNewPath(e.target.value)}\n placeholder=\"\u4F8B\u5982 /Users/you/Projects/demo \u6216 ~/demo\"\n />\n <button\n type=\"button\"\n className=\"archv-btn\"\n onClick={pickDirectory}\n disabled={busy !== null || picking || !workspacesSvc}\n title={!workspacesSvc ? '\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u4E0D\u652F\u6301\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9' : '\u6253\u5F00\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9\u7A97\u53E3'}\n >\n {picking ? '\u9009\u62E9\u4E2D\u2026' : '\u6D4F\u89C8\u2026'}\n </button>\n </div>\n </div>\n )}\n <div className=\"mv-foot\">\n <button type=\"button\" className=\"archv-btn\" onClick={() => setOpenMove(null)}>\u53D6\u6D88</button>\n <button type=\"button\" className=\"archv-btn archv-go\" disabled={busy !== null} onClick={() => doMove(it)}>\n {busy === it.sessionId && <span className=\"archv-spin\" aria-hidden=\"true\" />}\u786E\u8BA4\u79FB\u52A8\n </button>\n </div>\n </div>\n )}\n {openDetails === it.sessionId && (\n <div className=\"dtl-sheet\" role=\"region\" aria-label=\"\u4F1A\u8BDD\u8BE6\u60C5\">\n <div className=\"dtl-sheet-head\">\n <h3 className=\"dtl-sheet-title\">\u4F1A\u8BDD\u8BE6\u60C5</h3>\n <button type=\"button\" className=\"mv-sheet-close\" aria-label=\"\u5173\u95ED\u8BE6\u60C5\" onClick={() => setOpenDetails(null)}>\u00D7</button>\n </div>\n {detailsLoading === it.sessionId ? (\n <div className=\"archv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">{[0, 1].map((i) => <div key={i} className=\"archv-skel-card\" />)}</div>\n ) : (() => {\n const d = details[it.sessionId]\n if (!d) return <div className=\"dtl-paths\">\u6682\u65E0\u8BE6\u60C5</div>\n const st = d.stats || {}\n const tools = st.toolCounts ? Object.entries(st.toolCounts).sort((a, b) => b[1] - a[1]).slice(0, 10) : []\n return (\n <div>\n <div className=\"dtl-grid\">\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u78C1\u76D8\u5360\u7528</span><span className=\"dtl-v\">{fmtBytes(d.sizeBytes) || '\u2014'}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u8F6E\u6B21 / \u6B65\u9AA4</span><span className=\"dtl-v\">{st.turns ?? 0} / {st.steps ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u7528\u6237 / \u52A9\u624B</span><span className=\"dtl-v\">{st.userMessages ?? 0} / {st.assistantMessages ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u5DE5\u5177\u8C03\u7528</span><span className=\"dtl-v\">{st.toolCalls ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u56FE\u7247\u9644\u4EF6</span><span className=\"dtl-v\">{st.attachments ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u521B\u5EFA / \u66F4\u65B0</span><span className=\"dtl-v\">{fmtDate(d.createdAt) || '\u2014'} \u00B7 {fmtDate(d.updatedAt) || '\u2014'}</span></div>\n </div>\n {tools.length > 0 && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u5DE5\u5177\u4F7F\u7528</div>\n <div className=\"dtl-tags\">{tools.map(([t, c]) => <span className=\"dtl-tag\" key={t}>{t} \u00D7{c}</span>)}</div>\n </div>\n )}\n {st.fetches && st.fetches.length > 0 && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u641C\u7D22 / \u6293\u53D6</div>\n <ul className=\"dtl-list\">{st.fetches.map((f, i) => <li key={i}>{f.tool}{f.query ? ` \u300C${f.query}\u300D` : ''}</li>)}</ul>\n </div>\n )}\n {d.files && d.files.length > 0 && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u5199\u8FC7\u7684\u6587\u4EF6\uFF08{d.files.length}\uFF09</div>\n <ul className=\"dtl-list\">{d.files.map((f, i) => <li key={i}><code>{f.path}</code> <span className=\"dtl-filetool\">({f.tool})</span></li>)}</ul>\n </div>\n )}\n {d.lineage && (d.lineage.parentSessionId || (d.lineage.children && d.lineage.children.length > 0) || (d.lineage.subagents && d.lineage.subagents.length > 0)) && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u8840\u7EDF</div>\n <div className=\"dtl-paths\">\n {d.lineage.parentSessionId && <div>\u7236\u4F1A\u8BDD: <code>{d.lineage.parentSessionId}</code></div>}\n {d.lineage.children && d.lineage.children.length > 0 && <div>\u5B50\u4F1A\u8BDD ({d.lineage.children.length}): <code>{d.lineage.children.join(', ')}</code></div>}\n {d.lineage.subagents && d.lineage.subagents.length > 0 && <div>\u5B50\u4EE3\u7406 ({d.lineage.subagents.length}): <code>{d.lineage.subagents.join(', ')}</code></div>}\n </div>\n </div>\n )}\n </div>\n )\n })()}\n </div>\n )}\n </div>\n )\n })}\n </div>\n ) : null}\n </>\n )}\n {toast && <div className=\"archv-status\" role=\"status\">{toast}</div>}\n {delTarget && (\n <div className=\"dlg-backdrop\" onClick={() => setDelTarget(null)}>\n <div ref={dialogRef} className=\"dlg\" role=\"alertdialog\" aria-modal=\"true\" aria-label=\"\u5220\u9664\u4F1A\u8BDD\" onClick={(e) => e.stopPropagation()}>\n <h3 className=\"dlg-title\">\u5220\u9664\u4F1A\u8BDD</h3>\n <p className=\"dlg-text\">\u786E\u8BA4\u5220\u9664\u300C{delTarget.title || delTarget.sessionId}\u300D\uFF1F\u5C06\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u53EF\u5728\u672C\u9875\u5E95\u90E8\u300C\u56DE\u6536\u7AD9\u300D\u4E2D\u6062\u590D\u6216\u5F7B\u5E95\u5220\u9664\u3002</p>\n <div className=\"dlg-actions\">\n <button type=\"button\" className=\"archv-btn\" disabled={busy !== null} onClick={() => setDelTarget(null)}>\u53D6\u6D88</button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={busy !== null} onClick={doDeleteConfirmed}>\u79FB\u5165\u56DE\u6536\u7AD9</button>\n </div>\n </div>\n </div>\n )}\n {filter === 'trash' && <section className=\"dsm-trash\" aria-label=\"\u56DE\u6536\u7AD9\">\n <div className=\"dsm-trash-h\">\n <h3>\u56DE\u6536\u7AD9</h3>\n <span className=\"dsm-trash-count\">{trash.length ? `\uFF08${trash.length} \u4E2A\u5F85\u6E05\u7406\uFF09` : '\uFF08\u7A7A\uFF09'}</span>\n </div>\n <div className=\"sess-tools\">\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-retention\">\u81EA\u52A8\u6E05\u7406</label>\n <select id=\"dsm-retention\" value={trashSettings.retentionDays || 0} disabled={trashBusy !== null} onChange={(e) => updateRetention(e.target.value)}>\n <option value=\"0\">\u4E0D\u81EA\u52A8\u6E05\u7406</option><option value=\"7\">\u4FDD\u7559 7 \u5929</option><option value=\"30\">\u4FDD\u7559 30 \u5929</option><option value=\"90\">\u4FDD\u7559 90 \u5929</option>\n </select>\n </div>\n <div className=\"sess-field\"><label>\u6570\u636E\u68C0\u67E5</label><button type=\"button\" className=\"archv-btn\" disabled={trashBusy !== null} onClick={verifyTrash}>{trashBusy === '__verify' ? '\u6821\u9A8C\u4E2D\u2026' : '\u6821\u9A8C\u65E5\u5FD7\u5B8C\u6574\u6027'}</button></div>\n <div className=\"sess-field\"><label>\u6C38\u4E45\u6E05\u7406</label><button type=\"button\" className=\"archv-btn archv-del\" disabled={trashBusy !== null || !trash.length} onClick={() => setPurgeTarget('__all')}>\u6E05\u7A7A\u56DE\u6536\u7AD9</button></div>\n </div>\n {trashCheck && <div className={trashCheck.missing ? 'archv-err' : 'archv-empty'} role=\"status\">\u6821\u9A8C\u5B8C\u6210\uFF1A{trashCheck.healthy} \u6761\u6B63\u5E38\uFF0C{trashCheck.missing} \u6761\u65E5\u5FD7\u7F3A\u5931\u3002</div>}\n {trash.length === 0 ? (\n <div className=\"dsm-trash-empty\">\u56DE\u6536\u7AD9\u4E3A\u7A7A\u3002\u5220\u9664\u7684\u4F1A\u8BDD\u4F1A\u5148\u8FDB\u5165\u8FD9\u91CC\uFF0C\u53EF\u6062\u590D\u6216\u5F7B\u5E95\u5220\u9664\u3002</div>\n ) : (\n <div className=\"dsm-trash-list\">\n {trash.map((t) => (\n <div key={t.sessionId} className=\"dsm-trash-row\">\n <span className=\"dsm-trash-name\" title={t.sessionId}>{t.title || t.sessionId}</span>\n <span className=\"dsm-trash-date\">{fmtDate(t.deletedAt)}</span>\n <span className=\"dsm-trash-actions\">\n <button type=\"button\" className=\"archv-btn\" disabled={trashBusy !== null} onClick={() => restoreTrash(t.sessionId)}>\u6062\u590D</button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={trashBusy !== null} onClick={() => setPurgeTarget(t.sessionId)}>\u5F7B\u5E95\u5220\u9664</button>\n </span>\n </div>\n ))}\n </div>\n )}\n </section>}\n {purgeTarget && (\n <div className=\"dlg-backdrop\" onClick={() => setPurgeTarget(null)}>\n <div ref={dialogRef} className=\"dlg\" role=\"alertdialog\" aria-modal=\"true\" aria-labelledby=\"dsm-purge-title\" onClick={(e) => e.stopPropagation()}>\n <h3 id=\"dsm-purge-title\" className=\"dlg-title\">\u6C38\u4E45\u5220\u9664{purgeTarget === '__all' ? '\u5168\u90E8\u56DE\u6536\u7AD9\u4F1A\u8BDD' : '\u8FD9\u4E2A\u4F1A\u8BDD'}\uFF1F</h3>\n <p className=\"dlg-text\">\u6B64\u64CD\u4F5C\u4F1A\u7269\u7406\u5220\u9664\u65E5\u5FD7\uFF0C\u65E0\u6CD5\u6062\u590D\u3002\u5F52\u6863\u3001\u7B5B\u9009\u548C\u91CD\u65B0\u5B89\u88C5\u63D2\u4EF6\u90FD\u4E0D\u80FD\u627E\u56DE\u8FD9\u4E9B\u6570\u636E\u3002</p>\n <div className=\"dlg-actions\">\n <button type=\"button\" className=\"archv-btn\" onClick={() => setPurgeTarget(null)}>\u53D6\u6D88</button>\n <button type=\"button\" className=\"archv-btn archv-del\" onClick={() => { const target = purgeTarget; setPurgeTarget(null); target === '__all' ? purgeAllTrash() : purgeTrash(target) }}>\u786E\u8BA4\u6C38\u4E45\u5220\u9664</button>\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n\n// ---- Main-page sidebar session \"\u22EF\" menu augmentation (DOM shim) -----------\n// DSH core renders the sidebar session list (dsh-client-ui-workspace) with a\n// per-row \"\u22EF\" Menu whose items (rename / fork / archive) are hardcoded \u2014 there\n// is NO plugin slot for adding per-session menu items, and the row DOM carries\n// no sessionId. To honor the request we augment the already-opened portalled\n// menu via DOM: we watch for a [role=\"menu\"] portalled to document.body whose\n// React fiber chain reaches a SessionNodeItem (i.e. it is a session menu), read\n// the session id (and current cwd) off that fiber, then clone an existing menu\n// item to append \"\u79FB\u52A8\u4F1A\u8BDD\" / \"\u5220\u9664\u4F1A\u8BDD\". This is intentionally a DOM shim and is\n// fragile against DSH UI updates (class names / fiber shape / menu markup).\nconst SIDEBAR_AUG_CSS = `\n.dsm-backdrop{position:fixed;inset:0;z-index:2147483600;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.dsm-dlg{width:min(420px,92vw);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);border-radius:14px;padding:18px;box-shadow:0 16px 48px rgb(0 0 0/.28);display:flex;flex-direction:column;gap:12px}\n.dsm-title{font-size:15px;font-weight:650;color:var(--dsw-alias-label-primary);margin:0}\n.dsm-text{font-size:13px;line-height:1.6;color:var(--dsw-alias-label-secondary);margin:0;word-break:break-all}\n.dsm-body{display:flex;flex-direction:column;gap:4px;max-height:280px;overflow:auto}\n.dsm-loading,.dsm-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:4px 2px}\n.dsm-err{font-size:12px;color:var(--dsw-alias-state-error-primary);padding:4px 2px}\n.dsm-opt{appearance:none;display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;padding:9px 11px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);border-radius:9px;font-size:12.5px;cursor:pointer;text-align:left}\n.dsm-opt:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l4)}\n.dsm-opt:disabled{opacity:.55;cursor:default}\n.dsm-opt-cur{border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent);color:var(--dsw-alias-state-business-primary)}\n.dsm-opt-name{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}\n.dsm-opt-sub{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;margin-left:8px}\n.dsm-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:2px}\n.dsm-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer}\n.dsm-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.dsm-del{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent)}\n.dsm-del:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.dsm-toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:2147483601;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);max-width:min(90vw,420px)}\n.dsm-sub{position:fixed;z-index:1100;box-sizing:border-box;min-width:190px;max-width:320px;padding:4px;display:flex;flex-direction:column;gap:0;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;box-shadow:var(--dsw-shadow-lv3)}\n.dsm-sub-loading,.dsm-sub-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:6px 10px}\n.dsm-sub-err{font-size:12px;color:var(--dsw-alias-state-error-primary);padding:6px 10px}\n.dsm-sub-item{display:flex;align-items:center;gap:8px;width:100%;min-height:36px;padding:6px 10px;border:none;border-radius:8px;background:transparent;cursor:pointer;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);text-align:left}\n.dsm-sub-item:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsm-sub-item:disabled{opacity:.5;cursor:default}\n.dsm-sub-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsm-sub-cur{font-size:11px;color:var(--dsw-alias-state-business-primary);flex:none;margin-left:8px}\n.dsm-dot{position:absolute;left:6px;top:50%;transform:translateY(-50%);width:8px;height:8px;border-radius:50%;box-sizing:border-box;cursor:pointer;pointer-events:auto;z-index:1}\n.dsm-dot-unread-manual{background:var(--dsw-alias-state-business-primary)}\n.dsm-dot-waiting{background:var(--dsw-alias-state-warning-primary)}\n.dsm-dot-unread{background:var(--dsw-alias-state-success-primary)}\n.dsm-drag-source{opacity:.48}\n.dsm-drop-target{position:relative;background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent)!important;outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px;border-radius:8px}\n.dsm-drop-target::after{content:'\u79FB\u52A8\u5230\u8FD9\u91CC';position:absolute;right:8px;top:50%;transform:translateY(-50%);padding:1px 6px;border-radius:4px;background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-inverted);font-size:10px;font-weight:600;line-height:16px;pointer-events:none}\n.dsm-drag-busy{cursor:progress!important}\n.dsm-trash{margin-top:18px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:14px}\n.dsm-trash-h{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px}\n.dsm-trash-h h3{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin:0}\n.dsm-trash-count{font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dsm-trash-list{display:flex;flex-direction:column;gap:6px;max-height:260px;overflow:auto}\n.dsm-trash-row{display:flex;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated)}\n.dsm-trash-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;color:var(--dsw-alias-label-primary)}\n.dsm-trash-date{font-size:11px;color:var(--dsw-alias-label-tertiary);flex:none;white-space:nowrap}\n.dsm-trash-actions{display:flex;gap:6px;flex:none}.dsm-trash-actions .archv-btn{min-width:72px}\n.dsm-trash-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:6px 2px}\n`\n\n// Shared status-dot state so the \u22EF-menu \"\u6807\u8BB0\u672A\u8BFB\" action can toggle the\n// manual flag and trigger a repaint without coupling the two installers.\nconst DSM_KEY_MANUAL = 'dsm-manual-unread-v1'\nlet dsmManualUnread = null\nlet dsmRepaintDots = null\nfunction dsmLoadManual() {\n if (dsmManualUnread) return dsmManualUnread\n try { dsmManualUnread = new Set(JSON.parse(localStorage.getItem(DSM_KEY_MANUAL) || '[]')) } catch (e) { dsmManualUnread = new Set() }\n return dsmManualUnread\n}\nfunction dsmSaveManual() { try { localStorage.setItem(DSM_KEY_MANUAL, JSON.stringify([...dsmLoadManual()])) } catch (e) {} }\nfunction dsmToggleManual(id) {\n const s = dsmLoadManual()\n if (s.has(id)) s.delete(id); else s.add(id)\n dsmSaveManual()\n if (dsmRepaintDots) dsmRepaintDots()\n}\n\n// Recycle-bin membership (session ids currently in \u56DE\u6536\u7AD9). The sidebar\n// status-dot installer uses this to hide trashed sessions so they don't show\n// up under DSH's \"\u672A\u5206\u7EC4\" group. Loaded from the backend on a throttle and\n// updated optimistically when our own \u22EF-menu deletes a session.\nlet dsmTrashIds = null\nlet dsmServerPurgedIds = new Set()\nlet dsmAuthoritativeTitles = new Map()\nlet dsmTrashTick = 0\nasync function dsmLoadTrashIds() {\n try {\n const r = await postJSON('/archived-sessions/sidebar-state', {})\n dsmTrashIds = new Set(((r && r.trashedSessionIds) || []).map(String))\n dsmServerPurgedIds = new Set(((r && r.purgedSessionIds) || []).map(String))\n dsmAuthoritativeTitles = new Map(Object.entries((r && r.titles) || {}).map(([id, title]) => [String(id), String(title)]))\n if (dsmRepaintDots) dsmRepaintDots()\n } catch (e) { /* keep last known set */ }\n return dsmTrashIds\n}\n\n// Permanently-hidden set: sessions the user hard-purged from the \u56DE\u6536\u7AD9. Unlike\n// dsmTrashIds (which the backend poll refreshes and can drop), these are GONE for\n// good, so we keep them hidden forever \u2014 otherwise DSH re-surfaces the orphan\n// under a \"\u672A\u5206\u7EC4\" group after the trash poll drops it from dsmTrashIds.\nconst DSM_KEY_PURGED = 'dsm-purged-v1'\nlet dsmPurgedIds = null\nfunction dsmLoadPurged() {\n if (!dsmPurgedIds) {\n try { dsmPurgedIds = new Set(JSON.parse(localStorage.getItem(DSM_KEY_PURGED) || '[]')) } catch (e) { dsmPurgedIds = new Set() }\n }\n dsmServerPurgedIds.forEach((id) => dsmPurgedIds.add(id))\n return dsmPurgedIds\n}\nfunction dsmSavePurged() { try { localStorage.setItem(DSM_KEY_PURGED, JSON.stringify([...dsmLoadPurged()])) } catch (e) {} }\nfunction dsmMarkPurged(ids) {\n const s = dsmLoadPurged()\n ids.forEach((id) => s.add(String(id)))\n dsmSavePurged()\n if (dsmRepaintDots) dsmRepaintDots()\n}\n\nfunction installSidebarSessionMenuAug() {\n if (typeof document === 'undefined') return\n const AUG = 'data-dsm-aug'\n let styleInjected = false\n let activeSubClose = null\n let hoverTimer = null\n\n const findFiber = (el) => {\n const k = Object.keys(el).find((kk) => kk.startsWith('__reactFiber') || kk.startsWith('__reactInternalInstance'))\n return k ? el[k] : null\n }\n // Walk the React fiber chain from the portalled menu element up to the\n // SessionNodeItem component, which carries `node.id` (the session id).\n const sessionInfoFromMenu = (menuEl) => {\n let f = findFiber(menuEl)\n let guard = 0\n while (f && guard++ < 300) {\n const p = f.memoizedProps\n if (p && p.node && typeof p.node.id === 'string' && p.node.id) {\n return { id: p.node.id, cwd: p.node.cwd || p.node.workspacePath || null }\n }\n f = f.return\n }\n return null\n }\n const closeMenu = () => {\n try { document.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })) } catch (e) {}\n try { document.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true })) } catch (e) {}\n }\n const escapeHtml = (s) => {\n const d = document.createElement('div')\n d.textContent = s == null ? '' : String(s)\n return d.innerHTML\n }\n const toast = (msg) => {\n const t = document.createElement('div')\n t.className = 'dsm-toast'\n t.textContent = msg\n document.body.appendChild(t)\n setTimeout(() => t.remove(), 2600)\n }\n const ensureStyle = () => {\n if (styleInjected) return\n const s = document.createElement('style')\n s.dataset.dsm = 'aug'\n s.textContent = SIDEBAR_AUG_CSS\n document.head.appendChild(s)\n styleInjected = true\n }\n const closeMoveSubmenu = () => {\n if (activeSubClose) { const f = activeSubClose; activeSubClose = null; f() }\n }\n const openMoveSubmenu = (moveBtn, info) => {\n ensureStyle()\n closeMoveSubmenu()\n const sub = document.createElement('div')\n sub.className = 'dsm-sub'\n sub.setAttribute('role', 'menu')\n sub.setAttribute('data-dsm-sub', '')\n sub.innerHTML = '<div class=\"dsm-sub-loading\">\u52A0\u8F7D\u5DE5\u4F5C\u533A\u2026</div>'\n const r = moveBtn.getBoundingClientRect()\n sub.style.top = Math.max(8, Math.round(r.top - 4)) + 'px'\n sub.style.left = Math.round(r.right + 10) + 'px'\n document.body.appendChild(sub)\n const closeSub = () => {\n activeSubClose = null\n if (sub.parentNode) sub.remove()\n document.removeEventListener('mousedown', onDocDown, true)\n window.removeEventListener('blur', closeSub)\n }\n const onDocDown = (e) => {\n if (sub.contains(e.target) || moveBtn.contains(e.target)) return\n closeSub()\n }\n // Keep DSH's own outside-click handler from closing the parent menu while\n // the pointer is over our submenu (it lives outside the portalled card).\n sub.addEventListener('mousedown', (e) => e.stopPropagation())\n // Hover bridging: moving from the trigger button across the 10px gap to\n // the submenu must not dismiss it; entering the submenu cancels the\n // pending close timer set on the button's mouseleave.\n sub.addEventListener('mouseenter', () => { if (hoverTimer) { clearTimeout(hoverTimer); hoverTimer = null } })\n sub.addEventListener('mouseleave', () => { hoverTimer = setTimeout(() => closeSub(), 160) })\n setTimeout(() => document.addEventListener('mousedown', onDocDown, true), 0)\n window.addEventListener('blur', closeSub)\n activeSubClose = closeSub\n Promise.all([\n postJSON('/archived-sessions/workspaces', {}),\n postJSON('/archived-sessions/sessions', {}),\n ]).then(([ws, sess]) => {\n const items = ws.items || []\n const cur = (sess.items || []).find((x) => x.sessionId === info.id)\n const curPath = cur ? cur.workspacePath : (info.cwd || null)\n if (!items.length) { sub.innerHTML = '<div class=\"dsm-sub-empty\">\uFF08\u6682\u65E0\u53EF\u7528\u5DE5\u4F5C\u533A\uFF09</div>'; return }\n sub.innerHTML = ''\n items.forEach((w) => {\n const isCur = !!curPath && w.path === curPath\n const b = document.createElement('button')\n b.type = 'button'\n b.className = 'dsm-sub-item'\n b.setAttribute('role', 'menuitem')\n b.disabled = isCur\n const name = document.createElement('span')\n name.className = 'dsm-sub-name'\n name.textContent = w.title || pathName(w.path) || w.workspaceId\n b.appendChild(name)\n if (isCur) {\n const c = document.createElement('span')\n c.className = 'dsm-sub-cur'\n c.textContent = '\u5F53\u524D'\n b.appendChild(c)\n }\n b.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n closeSub()\n closeMenu()\n postJSON('/archived-sessions/move', { sessionId: info.id, targetPath: w.path })\n .then(() => toast('\u79FB\u52A8\u6210\u529F'))\n .catch((ee) => toast('\u79FB\u52A8\u5931\u8D25\uFF1A' + String((ee && ee.message) || ee)))\n })\n sub.appendChild(b)\n })\n }).catch((e) => {\n sub.innerHTML = '<div class=\"dsm-sub-err\">' + escapeHtml(String((e && e.message) || e)) + '</div>'\n })\n }\n const openDeleteConfirm = (id) => {\n ensureStyle()\n const backdrop = document.createElement('div')\n backdrop.className = 'dsm-backdrop'\n const dlg = document.createElement('div')\n dlg.className = 'dsm-dlg'\n dlg.innerHTML = '<h3 class=\"dsm-title\">\u5220\u9664\u4F1A\u8BDD</h3><p class=\"dsm-text\">\u786E\u8BA4\u5C06\u8BE5\u4F1A\u8BDD\u79FB\u5165\u56DE\u6536\u7AD9\uFF1F\u53EF\u5728\u300C\u8BBE\u7F6E \u2192 \u4F1A\u8BDD\u7BA1\u7406 \u2192 \u56DE\u6536\u7AD9\u300D\u4E2D\u6062\u590D\u6216\u5F7B\u5E95\u5220\u9664\u3002</p><div class=\"dsm-actions\"><button type=\"button\" class=\"dsm-btn\" data-role=\"cancel\">\u53D6\u6D88</button><button type=\"button\" class=\"dsm-btn dsm-del\" data-role=\"ok\">\u79FB\u5165\u56DE\u6536\u7AD9</button></div>'\n backdrop.appendChild(dlg)\n document.body.appendChild(backdrop)\n const close = () => backdrop.remove()\n backdrop.addEventListener('click', (e) => { if (e.target === backdrop) close() })\n dlg.querySelector('[data-role=cancel]').addEventListener('click', close)\n dlg.querySelector('[data-role=ok]').addEventListener('click', () => {\n close()\n postJSON('/archived-sessions/delete', { sessionId: id })\n .then(() => {\n if (dsmTrashIds) dsmTrashIds.add(String(id))\n if (dsmRepaintDots) dsmRepaintDots()\n toast('\u5DF2\u79FB\u5165\u56DE\u6536\u7AD9')\n })\n .catch((e) => toast('\u5220\u9664\u5931\u8D25\uFF1A' + String((e && e.message) || e)))\n })\n }\n const augmentMenu = (menuEl, info) => {\n if (menuEl.querySelector('[' + AUG + ']')) return\n const viewport = menuEl.querySelector('[role=\"presentation\"]') || menuEl.firstElementChild\n if (!viewport) return\n const proto = menuEl.querySelector('[role=\"menuitem\"]')\n if (!proto) return\n const protoWrap = proto.parentElement\n const protoCls = proto.className\n const protoWrapCls = protoWrap ? protoWrap.className : ''\n const ICON_MOVE = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/><path d=\"M12 11v4\"/><path d=\"M10 13l2 2 2-2\"/></svg>'\n const ICON_DEL = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7h16\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/><path d=\"M6 7l1 13a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1l1-13\"/><path d=\"M9 7V4h6v3\"/></svg>'\n const ICON_UNREAD = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"8\"/><circle cx=\"12\" cy=\"12\" r=\"3\" fill=\"currentColor\" stroke=\"none\"/></svg>'\n const mk = (label, svg, danger) => {\n const wrap = protoWrap ? protoWrap.cloneNode(false) : document.createElement('div')\n if (protoWrapCls) wrap.className = protoWrapCls\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.setAttribute('role', 'menuitem')\n btn.className = protoCls // same `.item` class DSH uses \u2192 identical layout/alignment\n const icon = document.createElement('span')\n icon.style.cssText = 'display:inline-flex;flex:none;width:16px;height:16px;align-items:center;justify-content:center;color:' + (danger ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-tertiary)')\n icon.innerHTML = svg\n const lab = document.createElement('span')\n lab.style.cssText = 'flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap'\n lab.textContent = label\n btn.appendChild(icon)\n btn.appendChild(lab)\n if (danger) btn.style.color = 'var(--dsw-alias-state-error-primary)'\n btn.setAttribute(AUG, '')\n wrap.appendChild(btn)\n return { wrap, btn }\n }\n const move = mk('\u79FB\u52A8\u4F1A\u8BDD', ICON_MOVE, false)\n const del = mk('\u5220\u9664\u4F1A\u8BDD', ICON_DEL, true)\n const mark = mk(dsmLoadManual().has(info.id) ? '\u6807\u8BB0\u5DF2\u8BFB' : '\u6807\u8BB0\u672A\u8BFB', ICON_UNREAD, false)\n if (mark.btn.firstChild) mark.btn.firstChild.style.color = 'var(--dsw-alias-state-business-primary)'\n const chev = document.createElement('span')\n chev.style.cssText = 'margin-left:auto;flex:none;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:1'\n chev.textContent = '\u203A'\n move.btn.appendChild(chev)\n move.btn.addEventListener('mouseenter', () => {\n if (!document.querySelector('[data-dsm-sub]')) openMoveSubmenu(move.btn, info)\n })\n move.btn.addEventListener('mouseleave', () => {\n hoverTimer = setTimeout(() => closeMoveSubmenu(), 160)\n })\n move.btn.addEventListener('click', (e) => { e.stopPropagation(); e.preventDefault() })\n del.btn.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n closeMoveSubmenu()\n openDeleteConfirm(info.id)\n })\n mark.btn.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n closeMoveSubmenu()\n dsmToggleManual(info.id)\n closeMenu()\n })\n viewport.appendChild(move.wrap)\n viewport.appendChild(del.wrap)\n // \u6807\u8BB0\u672A\u8BFB goes to the very top of the menu (above DSH's native items).\n viewport.insertBefore(mark.wrap, viewport.firstElementChild)\n }\n\n const seen = new WeakSet()\n const obs = new MutationObserver(() => {\n const menus = document.querySelectorAll('body > [role=\"menu\"]')\n menus.forEach((menuEl) => {\n if (seen.has(menuEl)) return\n const info = sessionInfoFromMenu(menuEl)\n if (!info) return // not a session menu (e.g. settings / header dropdown)\n seen.add(menuEl)\n try { augmentMenu(menuEl, info) } catch (e) { /* best-effort DOM shim */ }\n })\n })\n obs.observe(document.body, { childList: true, subtree: false })\n}\n\n// Left-side per-session status dot (DOM shim). The color is driven by DSH's\n// REAL session status, read from the row's own StateDot ([data-state]):\n// \u624B\u52A8\u6807\u8BB0\u672A\u8BFB\uFF08\u84DD\uFF09 = \u7528\u6237\u5728 \u22EF \u83DC\u5355\u6216\u70B9\u51FB\u5706\u70B9\u624B\u52A8\u6807\u8BB0\uFF0ClocalStorage \u6301\u4E45\u5316\uFF08\u6700\u9AD8\u4F18\u5148\u7EA7\uFF09\n// \u5DE5\u4F5C\u4E2D\uFF08\u9EC4\uFF09 = DSH state 'running'\n// \u9700\u7528\u6237\u53CD\u9988\uFF08\u7425\u73C0\uFF09 = DSH state 'warning'\uFF08\u6709\u8FFD\u95EE\u9700\u7528\u6237\u53CD\u9988\uFF09\n// \u5B8C\u6210\u540E\u672A\u8BFB\uFF08\u7EFF\uFF09 = DSH state 'done' \u4E14\u7528\u6237\u5C1A\u672A\u8BFB\u8FC7\uFF08read \u96C6\u5408\uFF09\n// \u5B8C\u6210\u5DF2\u8BFB\uFF08\u4E0D\u663E\u793A\uFF09 = DSH state 'done' \u4E14\u5DF2\u8BFB\u8FC7\uFF08read \u96C6\u5408\u6301\u4E45\u5316\uFF09\n// \u624B\u52A8\u672A\u8BFB\u96C6\u5408 + read \u96C6\u5408\u5747\u6301\u4E45\u5316\u4E8E localStorage\uFF1B\u6253\u5F00\u8FC7\u5373\u8BB0\u5165 read\uFF0C\u7EFF\u70B9\u4E0D\u518D\u51FA\u73B0\u3002\n// \u53E6\u5916\uFF1A\u8FDB\u5165\u56DE\u6536\u7AD9\u7684\u4F1A\u8BDD\u4F1A\u6574\u884C\u9690\u85CF\uFF08\u4E0D\u51FA\u73B0\u5728\u300C\u672A\u5206\u7EC4\u300D\u91CC\uFF09\u3002\nfunction installSidebarStatusDots() {\n if (typeof document === 'undefined') return\n const DOT = 'data-dsm-dot'\n if (!document.querySelector('style[data-dsm=aug]')) {\n const s = document.createElement('style')\n s.dataset.dsm = 'aug'\n s.textContent = SIDEBAR_AUG_CSS\n document.head.appendChild(s)\n }\n const findFiber = (el) => {\n const k = Object.keys(el).find((kk) => kk.startsWith('__reactFiber') || kk.startsWith('__reactInternalInstance'))\n return k ? el[k] : null\n }\n const fiberProp = (el, pred) => {\n let f = findFiber(el)\n let g = 0\n while (f && g++ < 300) {\n const p = f.memoizedProps\n if (p && pred(p)) return pred(p)\n f = f.return\n }\n return null\n }\n const rowNode = (row) => fiberProp(row, (p) => (p.node && typeof p.node.id === 'string' && p.node.id ? p.node : null))\n const rowId = (row) => { const node = rowNode(row); return node ? node.id : null }\n let curActive = null\n const activeRowId = () => {\n const sel = document.querySelector('[role=\"treeitem\"][aria-selected=\"true\"]')\n return sel ? rowId(sel) : null\n }\n // Dot colors per the user's scheme. We read DSH's REAL session status from the\n // row's own StateDot (its [data-state] attr) and recolor it:\n // running \u2192 \u9EC4 \u5DE5\u4F5C\u4E2D\n // warning \u2192 \u7425\u73C0 \u6709\u8FFD\u95EE\u9700\u7528\u6237\u53CD\u9988\n // done \u2192 \u7EFF \u5B8C\u6210\u540E\u672A\u8BFB\uFF08\u8BFB\u8FC7\u5219\u4E0D\u518D\u663E\u793A\uFF09\n // error \u2192 \u7EA2 \u51FA\u9519/\u9700\u5173\u6CE8\uFF08\u4E0E DSH \u81EA\u5E26 StateDot \u4E00\u81F4\uFF09\n // (manual \u2192 \u84DD \u624B\u52A8\u6807\u8BB0\u672A\u8BFB\uFF0C\u6700\u9AD8\u4F18\u5148\u7EA7)\n const COLOR = {\n manual: 'var(--dsw-alias-state-business-primary)', // \u84DD \u624B\u52A8\u6807\u8BB0\u672A\u8BFB\n running: '#EAB308', // \u9EC4 \u5DE5\u4F5C\u4E2D (DSH running)\n feedback: 'var(--dsw-alias-state-warning-primary)', // \u7425\u73C0 \u9700\u7528\u6237\u53CD\u9988 (DSH warning)\n done: 'var(--dsw-alias-state-success-primary)', // \u7EFF \u5B8C\u6210\u540E\u672A\u8BFB (DSH done)\n error: 'var(--dsw-alias-state-error-primary)', // \u7EA2 \u51FA\u9519/\u9700\u5173\u6CE8 (DSH error)\n }\n const manualUnread = dsmLoadManual()\n const paint = () => {\n // Recompute the active session on every paint so the active row is never\n // shown from a stale `curActive` (the click that changes aria-selected\n // mutates the DOM and triggers paint immediately, before the 1.2s tick()\n // would have run \u2014 without this, the clicked session flashed green).\n const activeId = activeRowId()\n // Clicking into a manually-marked session auto-clears the manual unread\n // flag (it becomes read on open) \u2014 only on the active transition, so a\n // flag set while already viewing it isn't wiped until you re-enter it.\n if (activeId !== curActive && activeId && manualUnread.has(activeId)) {\n manualUnread.delete(activeId)\n dsmSaveManual()\n }\n curActive = activeId\n const rows = document.querySelectorAll('[role=\"treeitem\"]')\n rows.forEach((row) => {\n const id = rowId(row)\n if (!id) return\n // Trashed sessions belong in \u56DE\u6536\u7AD9, not the sidebar (DSH would group\n // them under \"\u672A\u5206\u7EC4\"). Hide the row entirely and skip its dot. So do\n // hard-purged sessions \u2014 they're gone for good and must never resurface\n // (otherwise DSH re-renders the orphan under a \"\u672A\u5206\u7EC4\" group).\n const purged = dsmLoadPurged()\n if ((dsmTrashIds && dsmTrashIds.has(id)) || purged.has(id)) {\n if (row.style.display !== 'none') row.style.display = 'none'\n const d = row.querySelector('[' + DOT + ']'); if (d) d.remove()\n return\n }\n if (row.style.display === 'none') row.style.display = ''\n // DSH's cold list baseline can expose a stale header title until the\n // Session is opened. Paint the latest log-folded title from the host\n // authority without materializing the Session or changing its log.\n const authoritativeTitle = dsmAuthoritativeTitles.get(id)\n if (authoritativeTitle) {\n const node = rowNode(row) || {}\n const expected = new Set([node.title, node.displayTitle, node.name].filter((value) => typeof value === 'string'))\n const spans = [...row.children].filter((el) => el.tagName === 'SPAN' && !el.querySelector('[data-state]') && (el.textContent || '').trim())\n const titleEl = spans.find((el) => expected.has((el.textContent || '').trim())) || spans[0]\n if (titleEl && titleEl.textContent !== authoritativeTitle) titleEl.textContent = authoritativeTitle\n }\n // Read DSH's REAL session status from the row's own StateDot and recolor\n // it with the user's scheme (we also hide DSH's dot so only ours shows).\n const sd = row.querySelector('[data-state]')\n if (sd) sd.style.display = 'none'\n let dot = row.querySelector('[' + DOT + ']')\n let color = null\n if (manualUnread.has(id)) color = COLOR.manual\n else if (sd) {\n const st = sd.getAttribute('data-state')\n if (st === 'running') color = COLOR.running\n else if (st === 'warning') color = COLOR.feedback\n else if (st === 'error') color = COLOR.error\n else if (st === 'done') color = (activeId === id) ? null : COLOR.done\n }\n if (!color) { if (dot) dot.remove(); return }\n if (!dot) {\n dot = document.createElement('span')\n dot.setAttribute(DOT, '')\n dot.className = 'dsm-dot'\n if (!row.hasAttribute('data-dsm-pos')) {\n if (getComputedStyle(row).position === 'static') row.style.position = 'relative'\n row.setAttribute('data-dsm-pos', '')\n }\n dot.addEventListener('click', (e) => {\n e.stopPropagation(); e.preventDefault()\n dsmToggleManual(id)\n })\n row.insertBefore(dot, row.firstChild)\n }\n dot.style.background = color\n })\n }\n dsmRepaintDots = paint\n const tick = () => { if (++dsmTrashTick % 8 === 0) dsmLoadTrashIds(); paint() }\n let raf = 0\n const schedulePaint = () => { if (raf) return; raf = requestAnimationFrame(() => { raf = 0; paint() }) }\n tick()\n dsmLoadTrashIds()\n paint()\n const obs = new MutationObserver(schedulePaint)\n obs.observe(document.body, { childList: true, subtree: true })\n setInterval(tick, 1200)\n}\n\n// Cross-workspace drag/drop for the native DSH sidebar. DSH does not expose a\n// sidebar-row plugin slot, so the adapter discovers session/workspace rows from\n// their React fiber nodes, while the actual move remains entirely host-owned.\n// The existing \u201C\u79FB\u52A8\u4F1A\u8BDD\u201D menu is also the keyboard-accessible fallback.\nfunction installSidebarWorkspaceDrag() {\n if (typeof document === 'undefined') return\n let sessions = new Map()\n let dragging = null\n let moving = false\n\n const findFiber = (el) => {\n const key = Object.keys(el).find((k) => k.startsWith('__reactFiber') || k.startsWith('__reactInternalInstance'))\n return key ? el[key] : null\n }\n const fiberNodes = (el) => {\n const out = []\n let fiber = findFiber(el)\n let guard = 0\n while (fiber && guard++ < 300) {\n const props = fiber.memoizedProps\n if (props && props.node && typeof props.node === 'object') out.push(props.node)\n // DSH's SessionNodeItem receives `node`, while ProjectRowItem (the\n // workspace heading) receives `group`. Without the latter every session\n // can start dragging but no workspace can ever become a valid drop zone.\n if (props && props.group && typeof props.group === 'object') out.push(props.group)\n fiber = fiber.return\n }\n return out\n }\n const sessionForRow = (row) => {\n for (const node of fiberNodes(row)) {\n const id = node && node.id != null ? String(node.id) : ''\n if (sessions.has(id)) return sessions.get(id)\n // The live DSH row is authoritative even before the async sidebar-state\n // refresh finishes. Workspace groups use `workspaceId`, never `id`.\n if (id && node.workspaceId == null && (node.title != null || node.updatedAt != null || node.blank != null)) {\n return { sessionId: id, title: node.title || '', workspacePath: null }\n }\n }\n return null\n }\n const workspaceForRow = (row) => {\n // A session row's fiber chain also contains its parent workspace node.\n // Reject it explicitly so only the visible workspace header is a drop zone.\n if (sessionForRow(row)) return null\n for (const group of fiberNodes(row)) {\n if (group.workspaceId != null && typeof group.cwd === 'string' && group.cwd) {\n return { workspaceId: String(group.workspaceId), path: group.cwd, title: group.label || group.cwd }\n }\n }\n return null\n }\n const eventRow = (event) => {\n for (const item of event.composedPath ? event.composedPath() : []) {\n if (item instanceof Element && item.getAttribute('role') === 'treeitem') return item\n }\n return event.target instanceof Element ? event.target.closest('[role=\"treeitem\"]') : null\n }\n const toast = (message) => {\n const el = document.createElement('div')\n el.className = 'dsm-toast'\n el.setAttribute('role', 'status')\n el.textContent = message\n document.body.appendChild(el)\n setTimeout(() => el.remove(), 2600)\n }\n const clearVisuals = () => {\n document.querySelectorAll('.dsm-drag-source,.dsm-drop-target').forEach((el) => el.classList.remove('dsm-drag-source', 'dsm-drop-target'))\n }\n const decorateRows = () => {\n document.querySelectorAll('[role=\"treeitem\"]').forEach((row) => {\n const session = sessionForRow(row)\n const ws = workspaceForRow(row)\n if (session) {\n row.setAttribute('aria-description', '\u53EF\u62D6\u52A8\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A\uFF1B\u952E\u76D8\u7528\u6237\u53EF\u901A\u8FC7\u66F4\u591A\u83DC\u5355\u4E2D\u7684\u79FB\u52A8\u4F1A\u8BDD\u64CD\u4F5C')\n }\n if (ws) row.setAttribute('data-dsm-workspace-drop', '')\n })\n }\n const refresh = async () => {\n try {\n const sessionResult = await postJSON('/archived-sessions/sessions', {})\n sessions = new Map((sessionResult.items || []).map((item) => [String(item.sessionId), item]))\n decorateRows()\n } catch (e) { /* sidebar enhancement remains optional */ }\n }\n\n // Capture before DSH's delegated React handlers. DSH reserves the same\n // native drag gesture for reordering sessions inside one group; only a real\n // workspace-heading target is intercepted here, so same-group sorting keeps\n // its official behavior.\n document.addEventListener('dragstart', (event) => {\n const row = eventRow(event)\n const item = row && sessionForRow(row)\n if (!item || moving) return\n dragging = item\n row.classList.add('dsm-drag-source')\n }, true)\n document.addEventListener('dragover', (event) => {\n const row = eventRow(event)\n const target = row && workspaceForRow(row)\n if (!dragging || !target || moving) return\n if (dragging.workspacePath && target.path === dragging.workspacePath) return\n event.preventDefault()\n event.stopPropagation()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n document.querySelectorAll('.dsm-drop-target').forEach((el) => { if (el !== row) el.classList.remove('dsm-drop-target') })\n row.classList.add('dsm-drop-target')\n }, true)\n document.addEventListener('drop', async (event) => {\n const row = eventRow(event)\n const item = dragging\n const target = row && workspaceForRow(row)\n if (!item || !target || moving || (item.workspacePath && target.path === item.workspacePath)) return\n event.preventDefault()\n event.stopPropagation()\n moving = true\n clearVisuals()\n row.classList.add('dsm-drag-busy')\n try {\n const result = await postJSON('/archived-sessions/move', { sessionId: item.sessionId, targetPath: target.path })\n sessions.set(item.sessionId, { ...item, workspacePath: result.workspacePath || target.path, workspaceTitle: result.workspaceTitle || target.title })\n await dsmLoadTrashIds()\n toast(`\u5DF2\u79FB\u5230\u300C${result.workspaceTitle || target.title}\u300D`)\n } catch (error) {\n toast('\u79FB\u52A8\u5931\u8D25\uFF1A' + String((error && error.message) || error))\n } finally {\n moving = false\n dragging = null\n row.classList.remove('dsm-drag-busy')\n decorateRows()\n }\n }, true)\n document.addEventListener('dragend', () => {\n dragging = null\n clearVisuals()\n }, true)\n\n let decorateTimer = null\n const scheduleDecorate = () => {\n if (decorateTimer) return\n decorateTimer = requestAnimationFrame(() => { decorateTimer = null; decorateRows() })\n }\n refresh()\n const observer = new MutationObserver(scheduleDecorate)\n observer.observe(document.body, { childList: true, subtree: true })\n setInterval(refresh, 5000)\n}\n\nexport function apply(ctx) {\n installSettingsNavIcons(ctx)\n installSidebarSessionMenuAug()\n installSidebarStatusDots()\n installSidebarWorkspaceDrag()\n const workspacesSvc = ctx.get('workspaces')\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n { name: 'settings.section', id: 'session-manager', order: 90, label: '\u4F1A\u8BDD\u7BA1\u7406' },\n (props) => <SessionPanel {...props} workspacesSvc={workspacesSvc} />,\n ),\n )\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../src/client/index.jsx", "../src/client/logic.js"],
4
+ "sourcesContent": ["/**\n * dsh-sessions-manager \u2014 browser half: renders a single \"\u4F1A\u8BDD\u7BA1\u7406\" settings\n * section (settings.section list slot) that unifies archived-session\n * management and cross-workspace moving. It talks to the host half's\n * /archived-sessions/* JSON routes by fetch, showing every conversation with\n * its archive state and offering archive / restore / delete / move (and batch)\n * actions. All DOM/runtime wiring failures are logged, never thrown \u2014 a thrown\n * plugin apply takes down the whole web-shell boot.\n *\n * @module dsh-sessions-manager/client\n */\n\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\nimport { canDropOnWorkspace, dotStateFor, sessionForNodes, workspaceForNodes } from './logic.js'\n\nexport const inject = ['slots']\n\nconst PANEL_PREFS_KEY = 'dsm-panel-prefs-v1'\nfunction loadPanelPrefs() {\n try { return JSON.parse(localStorage.getItem(PANEL_PREFS_KEY) || '{}') || {} } catch (e) { return {} }\n}\n\nconst CSS = `\n.archv{--dsm-radius-tag:4px;display:flex;flex-direction:column;gap:4px;max-width:800px;padding:8px 2px 28px}\n.archv-head{display:flex;align-items:center;gap:10px;margin:0 0 2px}\n.archv-title{font-size:16px;font-weight:650;color:var(--dsw-alias-label-primary);letter-spacing:-0.01em;margin:0}\n.archv-count{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:999px;padding:1px 8px;flex:none}\n.archv-sub{font-size:12px;line-height:1.55;color:var(--dsw-alias-label-tertiary);margin:0 0 12px;max-width:64ch}\n.archv-err{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);border-radius:10px;color:var(--dsw-alias-state-error-primary);font-size:12px;margin-bottom:10px}\n.archv-errretry{appearance:none;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent);background:transparent;color:inherit;border-radius:8px;padding:4px 10px;font-size:11px;cursor:pointer;flex:none}\n.sess-filter{display:flex;align-items:center;gap:6px;margin:0 0 12px}\n.sess-fbtn{appearance:none;min-height:30px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:999px;font-size:12px;font-weight:500;cursor:pointer}\n.sess-fbtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.sess-fbtn-on{background:var(--dsw-alias-interactive-bg-active);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l3)}\n.sess-tools{display:grid;grid-template-columns:minmax(180px,1fr) minmax(140px,.7fr) minmax(130px,.55fr);gap:8px;margin:0 0 8px}\n.sess-field{display:flex;flex-direction:column;gap:5px;min-width:0}\n.sess-field label{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary)}\n.sess-field input,.sess-field select{box-sizing:border-box;width:100%;min-height:36px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);font:inherit;font-size:12px}\n.sess-results{font-size:11px;color:var(--dsw-alias-label-tertiary);margin:0 0 4px}\n.archv button:focus-visible,.archv input:focus-visible,.archv select:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}\n.sess-batch{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 2px 4px;margin-bottom:4px}\n.sess-btntext{font-size:12px;color:var(--dsw-alias-label-tertiary);flex:none}\n.archv-list{display:flex;flex-direction:column;gap:8px}\n.archv-card{display:flex;flex-direction:column;align-items:stretch;gap:0;padding:12px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-fill-elevated);transition:border-color .15s ease,background-color .15s ease}\n.archv-card:hover{border-color:var(--dsw-alias-border-l4)}\n.archv-card-exp{border-color:var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-1)}\n.archv-row{display:flex;align-items:center;gap:14px;width:100%;min-width:0}\n.archv-main{min-width:0;display:flex;flex-direction:column;gap:4px}\n.archv-name{font-size:13px;font-weight:550;color:var(--dsw-alias-label-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;min-width:0}\n.archv-wtag{display:inline-flex;align-items:center;gap:4px;max-width:100%;font-size:11px;font-weight:500;line-height:1;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-subtle);border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsm-radius-tag);padding:3px 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.archv-wgone{border-style:dashed;color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 55%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 7%,transparent)}\n.archv-active{color:var(--dsw-alias-state-success-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 45%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent)}\n.archv-date{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none}\n.archv-id{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:10.5px;color:var(--dsw-alias-label-tertiary);flex:none}\n.archv-dot{color:var(--dsw-alias-border-l3);flex:none}\n.archv-check{width:15px;height:15px;accent-color:var(--dsw-alias-state-business-primary);flex:none;cursor:pointer}\n.archv-body{flex:1;min-width:0;display:flex;align-items:center;gap:12px}\n.archv-actions{display:flex;gap:8px;flex:none;flex-wrap:nowrap;justify-content:flex-end}\n.archv-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;justify-content:center;gap:6px;text-align:center;transition:background-color .15s ease,border-color .15s ease,color .15s ease}\n.archv-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.archv-btn:disabled{opacity:.5;cursor:default}\n.archv-del{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent)}\n.archv-del:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.archv-go{color:var(--dsw-alias-state-business-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent)}\n.archv-go:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent);color:var(--dsw-alias-state-business-primary)}\n.archv-empty{display:flex;align-items:center;gap:10px;padding:20px 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:12px;color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.archv-skel{display:flex;flex-direction:column;gap:8px}\n.archv-skel-card{height:58px;border-radius:12px;background:var(--dsw-alias-fill-subtle);position:relative;overflow:hidden}\n.archv-skel-card::after{content:'';position:absolute;inset:0;transform:translateX(-100%);background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--dsw-alias-fill-elevated) 75%,transparent),transparent);animation:archv-shimmer 1.4s infinite}\n.archv-status{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:60;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);display:flex;align-items:center;gap:8px;animation:archv-pop .18s ease-out;max-width:min(90vw,420px)}\n.archv-spin{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dsw-alias-label-secondary) 35%,transparent);border-top-color:var(--dsw-alias-label-secondary);border-radius:50%;animation:archv-rot .8s linear infinite;flex:none}\n@keyframes archv-shimmer{100%{transform:translateX(100%)}}\n@keyframes archv-rot{to{transform:rotate(360deg)}}\n@keyframes archv-pop{from{opacity:0;transform:translateX(-50%) translateY(10px)}}\n@media (prefers-reduced-motion:reduce){.archv-skel-card::after{animation:none}.archv-card,.archv-btn{transition:none}.archv-status,.archv-spin{animation:none}}\n@media (max-width:640px){.archv-card{flex-direction:column;align-items:stretch;gap:10px}.archv-actions{justify-content:flex-end}.sess-tools{grid-template-columns:1fr}.sess-fbtn,.archv-btn{min-height:40px}}\n.mv-sheet{width:100%;box-sizing:border-box;display:flex;flex-direction:column;gap:12px;margin-top:12px;padding:14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-fill-subtle)}\n.mv-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:10px}\n.mv-sheet-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin:0}\n.mv-sheet-close{appearance:none;width:26px;height:26px;color:var(--dsw-alias-label-secondary);background:0 0;border:none;border-radius:7px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;font-size:16px;line-height:1}\n.mv-sheet-close:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.mv-seg{display:flex;gap:2px;padding:2px;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);border-radius:10px;width:100%}\n.mv-segbtn{appearance:none;flex:1;min-height:30px;padding:0 12px;border:none;background:transparent;color:var(--dsw-alias-label-secondary);border-radius:8px;font-size:12px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:6px}\n.mv-segbtn:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.mv-segbtn-on{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);box-shadow:0 1px 2px rgb(0 0 0/.08)}\n.mv-field{display:flex;flex-direction:column;gap:6px}\n.mv-field label.mv-field-label{font-size:12px;font-weight:500;color:var(--dsw-alias-label-secondary)}\n.mv-field select,.mv-field input[type=text]{box-sizing:border-box;appearance:none;width:100%;min-height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);font-size:12px;font-family:inherit}\n.mv-field select:focus-visible,.mv-field input[type=text]:focus-visible,.mv-sheet-close:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}\n.mv-browse-row{display:flex;align-items:center;gap:8px}\n.mv-browse-row input[type=text]{flex:1;min-width:0}\n.mv-foot{display:flex;justify-content:flex-end;align-items:center;gap:8px;margin-top:2px}\n@media (max-width:640px){.archv-row{flex-wrap:wrap}.mv-sheet{padding:12px}}\n.dtl-sheet{margin-top:12px;padding:14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-fill-subtle)}\n.dtl-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:10px}\n.dtl-sheet-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin:0}\n.dtl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:8px;margin-top:10px}\n.dtl-cell{display:flex;flex-direction:column;gap:2px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-fill-elevated);min-width:0}\n.dtl-k{font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dtl-v{font-size:12px;color:var(--dsw-alias-label-primary);word-break:break-all}\n.dtl-sec{margin-top:12px}\n.dtl-sec-t{font-size:11px;font-weight:600;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.03em;margin-bottom:6px}\n.dtl-tags{display:flex;flex-wrap:wrap;gap:6px}\n.dtl-tag{display:inline-flex;font-size:11px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsm-radius-tag);padding:2px 8px}\n.dtl-list{margin:0;padding-left:18px;display:flex;flex-direction:column;gap:3px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}\n.dtl-list code,.dtl-paths code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;color:var(--dsw-alias-label-primary);word-break:break-all}\n.dtl-filetool{color:var(--dsw-alias-label-tertiary)}\n.dtl-paths{display:flex;flex-direction:column;gap:4px;font-size:11.5px;color:var(--dsw-alias-label-secondary);word-break:break-all}\n.more-wrap{position:relative;flex:none}\n.more-btn{appearance:none;width:28px;height:28px;border:none;border-radius:8px;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;line-height:1}\n.more-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.more-menu{position:absolute;top:calc(100% + 4px);right:0;z-index:60;min-width:160px;padding:5px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);border-radius:10px;box-shadow:0 10px 32px rgb(0 0 0/.24);display:flex;flex-direction:column;gap:1px}\n.more-item{appearance:none;display:flex;align-items:center;gap:8px;width:100%;padding:7px 10px;border:none;background:transparent;color:var(--dsw-alias-label-primary);border-radius:7px;font-size:12.5px;cursor:pointer;white-space:nowrap;text-align:left}\n.more-item:hover{background:var(--dsw-alias-interactive-bg-hover)}\n.more-item-danger{color:var(--dsw-alias-state-error-primary)}\n.more-item-danger:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.dlg-backdrop{position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.dlg{width:min(420px,92vw);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);border-radius:14px;padding:18px;box-shadow:0 16px 48px rgb(0 0 0/.28);display:flex;flex-direction:column;gap:12px}\n.dlg-title{font-size:15px;font-weight:650;color:var(--dsw-alias-label-primary);margin:0}\n.dlg-text{font-size:13px;line-height:1.6;color:var(--dsw-alias-label-secondary);margin:0;word-break:break-all}\n.dlg-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:2px}\n`\n\nfunction fmtDate(iso) {\n if (!iso) return null\n const d = new Date(iso)\n if (isNaN(d.getTime())) return null\n try {\n return new Intl.DateTimeFormat('zh-CN', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }).format(d)\n } catch {\n return String(iso)\n }\n}\n\nfunction fmtBytes(n) {\n if (!n && n !== 0) return null\n if (n < 1024) return `${n} B`\n const units = ['KB', 'MB', 'GB', 'TB']\n let v = n\n let u = -1\n do { v /= 1024; u++ } while (v >= 1024 && u < units.length - 1)\n return `${v >= 100 ? v.toFixed(0) : v.toFixed(1)} ${units[u]}`\n}\n\nfunction pathName(p) {\n if (!p) return null\n const parts = String(p).replace(/\\\\+$/, '').split(/[/\\\\]/)\n return parts[parts.length - 1] || p\n}\n\nasync function postJSON(path, body) {\n const res = await fetch(path, {\n method: 'POST',\n headers: { 'content-type': 'application/json', accept: 'application/json' },\n body: JSON.stringify(body || {}),\n })\n const data = await res.json().catch(() => null)\n if (!res.ok || !data) throw new Error((data && (data.error || data.message)) || `request failed (${res.status})`)\n return data\n}\n\n// Left-nav icon swap: DSH's settings shell renders a shared fallback gear for\n// every custom section and settings.section has no per-section icon field.\n// Like dsh-better-sidebar, we mark our own row by matching its visible label\n// text, then CSS swaps the gear for an archive-box glyph. The marker owns no\n// shell structure and is removed on fiber disposal (HMR-safe, ships with the\n// plugin).\nconst NAV_CSS = `\n[data-dsh-nav-sessions] > svg:first-child { display: none; }\n[data-dsh-nav-sessions]::before {\n content: ''; flex: none; width: 16px; height: 16px; background: currentColor;\n -webkit-mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E\") center / contain no-repeat;\n mask: url(\"data:image/svg+xml,%3Csvg%20xmlns%3D'http://www.w3.org/2000/svg'%20width%3D'24'%20height%3D'24'%20viewBox%3D'0%200%2024%2024'%20fill%3D'none'%20stroke%3D'black'%20stroke-width%3D'2'%20stroke-linecap%3D'round'%20stroke-linejoin%3D'round'%3E%3Cpath%20d%3D'M21%208v13H3V8'/%3E%3Cpath%20d%3D'M1%203h22v5H1z'/%3E%3Cpath%20d%3D'M10%2012h4'/%3E%3C/svg%3E\") center / contain no-repeat;\n}\n`\n\nfunction markSettingsNav() {\n const LABEL = '\u4F1A\u8BDD\u7BA1\u7406'\n let disposed = false\n const sync = () => {\n if (disposed) return\n const buttons = document.querySelectorAll('[role=\"dialog\"] nav button')\n for (const b of buttons) {\n const t = (b.textContent || '').trim()\n if (t === LABEL) b.setAttribute('data-dsh-nav-sessions', '')\n else b.removeAttribute('data-dsh-nav-sessions')\n }\n }\n sync()\n const obs = new MutationObserver(sync)\n obs.observe(document.body, { childList: true, subtree: true, characterData: true })\n return () => {\n disposed = true\n obs.disconnect()\n document.querySelectorAll('[data-dsh-nav-sessions]').forEach((e) => e.removeAttribute('data-dsh-nav-sessions'))\n }\n}\n\nfunction installSettingsNavIcons(ctx) {\n const styleEl = document.createElement('style')\n styleEl.textContent = NAV_CSS\n document.head.appendChild(styleEl)\n const dispose = markSettingsNav()\n ctx.effect(() => () => {\n dispose()\n if (styleEl.parentNode) styleEl.parentNode.removeChild(styleEl)\n })\n}\n\nfunction SessionPanel({ workspacesSvc }) {\n const [sessions, setSessions] = useState(null)\n const [workspaces, setWorkspaces] = useState([])\n const initialPrefs = useRef(loadPanelPrefs()).current\n const [filter, setFilter] = useState(() => ['all', 'active', 'archived', 'trash'].includes(initialPrefs.filter) ? initialPrefs.filter : 'all')\n const [query, setQuery] = useState('')\n const [workspaceFilter, setWorkspaceFilter] = useState(() => initialPrefs.workspaceFilter || 'all')\n const [sortBy, setSortBy] = useState(() => ['newest', 'oldest', 'title'].includes(initialPrefs.sortBy) ? initialPrefs.sortBy : 'newest')\n const [selected, setSelected] = useState({})\n const [delTarget, setDelTarget] = useState(null)\n const [confirmBatch, setConfirmBatch] = useState(false)\n const [busy, setBusy] = useState(null)\n const [openMove, setOpenMove] = useState(null)\n const [moveMode, setMoveMode] = useState('existing')\n const [targetWs, setTargetWs] = useState('')\n const [newPath, setNewPath] = useState('')\n const [error, setError] = useState(null)\n const [toast, setToast] = useState(null)\n const [picking, setPicking] = useState(false)\n const [trash, setTrash] = useState([])\n const [trashBusy, setTrashBusy] = useState(null)\n const [trashSettings, setTrashSettings] = useState({ retentionDays: 0 })\n const [trashCheck, setTrashCheck] = useState(null)\n const [purgeTarget, setPurgeTarget] = useState(null)\n const [details, setDetails] = useState({})\n const [openDetails, setOpenDetails] = useState(null)\n const [detailsLoading, setDetailsLoading] = useState(null)\n const [openMenu, setOpenMenu] = useState(null)\n const timer = useRef(null)\n const menuRef = useRef(null)\n const dialogRef = useRef(null)\n\n const showToast = (msg) => {\n if (timer.current) clearTimeout(timer.current)\n setToast(msg)\n timer.current = setTimeout(() => setToast(null), 2400)\n }\n\n const refresh = () => {\n setError(null)\n Promise.all([\n postJSON('/archived-sessions/sessions', {}),\n postJSON('/archived-sessions/workspaces', {}),\n ])\n .then(([s, works]) => {\n // Permanently-purged sessions must never re-appear here, even if DSH's\n // in-memory session index still lists them after the file was unlinked.\n const purged = dsmLoadPurged()\n const visible = (s.items || []).filter((x) => !purged.has(String(x.sessionId)))\n setSessions(visible)\n setWorkspaces(works.items || [])\n setSelected({})\n setDelTarget(null)\n setConfirmBatch(false)\n if (!targetWs && works.items && works.items.length) setTargetWs(works.items[0].workspaceId)\n loadTrash()\n })\n .catch((e) => setError(String((e && e.message) || e)))\n }\n\n useEffect(() => {\n refresh()\n return () => { if (timer.current) clearTimeout(timer.current) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n\n useEffect(() => {\n try { localStorage.setItem(PANEL_PREFS_KEY, JSON.stringify({ filter, workspaceFilter, sortBy })) } catch (e) {}\n }, [filter, workspaceFilter, sortBy])\n\n // Close the \u22EF menu on outside click / Escape (no full-screen backdrop).\n useEffect(() => {\n if (openMenu === null) return\n const onDown = (e) => {\n if (menuRef.current && !menuRef.current.contains(e.target)) setOpenMenu(null)\n }\n const onKey = (e) => { if (e.key === 'Escape') setOpenMenu(null) }\n document.addEventListener('mousedown', onDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [openMenu])\n\n useEffect(() => {\n if (!delTarget && !purgeTarget) return\n const previous = document.activeElement\n const onKey = (e) => {\n if (e.key === 'Escape') { setDelTarget(null); setPurgeTarget(null) }\n }\n document.addEventListener('keydown', onKey)\n requestAnimationFrame(() => dialogRef.current && dialogRef.current.querySelector('button')?.focus())\n return () => {\n document.removeEventListener('keydown', onKey)\n if (previous && typeof previous.focus === 'function') previous.focus()\n }\n }, [delTarget, purgeTarget])\n\n const wsPath = (id) => {\n const w = workspaces.find((x) => x.workspaceId === id)\n return w ? w.path : ''\n }\n\n const archivedList = sessions ? sessions.filter((x) => x.archived) : []\n const activeList = sessions ? sessions.filter((x) => !x.archived) : []\n const list = useMemo(() => {\n if (filter === 'trash') return []\n const base = filter === 'archived' ? archivedList : filter === 'active' ? activeList : sessions || []\n const needle = query.trim().toLocaleLowerCase()\n const filtered = base.filter((item) => {\n if (workspaceFilter !== 'all' && (item.workspacePath || '') !== workspaceFilter) return false\n if (!needle) return true\n return [item.title, item.sessionId, item.workspaceTitle, item.workspacePath].some((value) => String(value || '').toLocaleLowerCase().includes(needle))\n })\n return [...filtered].sort((a, b) => {\n if (sortBy === 'oldest') return Number(a.createdAt || 0) - Number(b.createdAt || 0)\n if (sortBy === 'title') return String(a.title || '').localeCompare(String(b.title || ''), 'zh-CN')\n return Number(b.createdAt || 0) - Number(a.createdAt || 0)\n })\n }, [sessions, filter, query, workspaceFilter, sortBy])\n const selIds = Object.keys(selected).filter((k) => selected[k])\n\n const toggle = (id) => setSelected((s) => ({ ...s, [id]: !s[id] }))\n const clearSel = () => setSelected({})\n const selectAll = () => {\n const o = {}\n list.forEach((x) => { o[x.sessionId] = true })\n setSelected(o)\n }\n\n const act = (action, it) => {\n if (busy) return\n setBusy(it.sessionId)\n postJSON('/archived-sessions/' + action, { sessionId: it.sessionId })\n .then(() => {\n setBusy(null)\n const n = it.title || it.sessionId\n showToast(action === 'archive' ? `\u5DF2\u5F52\u6863\u300C${n}\u300D` : `\u5DF2\u6062\u590D\u300C${n}\u300D`)\n refresh()\n })\n .catch((e) => { setBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const doDeleteConfirmed = () => {\n if (!delTarget || busy) return\n setBusy(delTarget.sessionId)\n postJSON('/archived-sessions/delete', { sessionId: delTarget.sessionId })\n .then(() => {\n setBusy(null)\n const n = delTarget.title || delTarget.sessionId\n showToast(`\u5DF2\u5220\u9664 ${n}\uFF08\u5DF2\u79FB\u5165\u56DE\u6536\u7AD9\uFF09`)\n setDelTarget(null)\n refresh()\n })\n .catch((e) => { setBusy(null); setDelTarget(null); setError(String((e && e.message) || e)) })\n }\n\n const loadTrash = () => {\n postJSON('/archived-sessions/trash/list', {})\n .then((r) => { setTrash(r.items || []); setTrashSettings(r.settings || { retentionDays: 0 }) })\n .catch(() => {})\n }\n\n const updateRetention = (days) => {\n setTrashBusy('__settings')\n postJSON('/archived-sessions/trash/settings', { retentionDays: Number(days) })\n .then((r) => { setTrashBusy(null); setTrashSettings(r.settings); showToast('\u5DF2\u66F4\u65B0\u81EA\u52A8\u6E05\u7406\u7B56\u7565') })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const verifyTrash = () => {\n setTrashBusy('__verify')\n postJSON('/archived-sessions/trash/verify', {})\n .then((r) => { setTrashBusy(null); setTrashCheck(r); showToast(r.missing ? `\u53D1\u73B0 ${r.missing} \u6761\u65E5\u5FD7\u7F3A\u5931` : '\u56DE\u6536\u7AD9\u6821\u9A8C\u901A\u8FC7') })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const restoreTrash = (sid) => {\n if (trashBusy) return\n setTrashBusy(sid)\n postJSON('/archived-sessions/trash/restore', { sessionId: sid })\n .then(() => { setTrashBusy(null); showToast('\u5DF2\u6062\u590D\u4F1A\u8BDD'); loadTrash(); refresh() })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n const purgeTrash = (sid) => {\n if (trashBusy) return\n setTrashBusy(sid)\n postJSON('/archived-sessions/trash/purge', { sessionId: sid })\n .then(() => { setTrashBusy(null); showToast('\u5DF2\u5F7B\u5E95\u5220\u9664'); dsmMarkPurged([sid]); dsmLoadTrashIds(); loadTrash() })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n const purgeAllTrash = () => {\n if (trashBusy || !trash.length) return\n setTrashBusy('__all')\n const all = trash.map((t) => t.sessionId)\n postJSON('/archived-sessions/trash/purge-many', { sessionIds: all })\n .then((result) => {\n setTrashBusy(null)\n const rows = result.results || []\n const succeeded = rows.filter((item) => item.ok).map((item) => item.sessionId)\n const failed = rows.filter((item) => !item.ok)\n if (succeeded.length) dsmMarkPurged(succeeded)\n dsmLoadTrashIds()\n loadTrash()\n if (failed.length) {\n const first = failed[0]\n setError(`\u6E05\u7406\u5B8C\u6210 ${succeeded.length} \u6761\uFF0C\u5931\u8D25 ${failed.length} \u6761\uFF1A${first.error || first.sessionId}`)\n } else showToast('\u5DF2\u6E05\u7A7A\u56DE\u6536\u7AD9')\n })\n .catch((e) => { setTrashBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const doMove = (it) => {\n const targetPath = moveMode === 'new' ? newPath.trim() : wsPath(targetWs)\n if (!targetPath) { setError('\u8BF7\u9009\u62E9\u5DF2\u6709\u5DE5\u4F5C\u533A\u6216\u8F93\u5165\u65B0\u7684\u76EE\u6807\u76EE\u5F55\u8DEF\u5F84'); return }\n setBusy(it.sessionId)\n setError(null)\n postJSON('/archived-sessions/move', { sessionId: it.sessionId, targetPath })\n .then((r) => {\n setBusy(null)\n setOpenMove(null)\n setMoveMode('existing')\n setNewPath('')\n showToast(`\u5DF2\u628A\u300C${it.title || it.sessionId}\u300D\u79FB\u5230 ${r.workspaceTitle || targetPath}`)\n refresh()\n })\n .catch((e) => { setBusy(null); setError(String((e && e.message) || e)) })\n }\n\n const doBatch = (action) => {\n if (!selIds.length || busy) return\n if (action === 'delete-many') {\n if (!confirmBatch) { setConfirmBatch(true); return }\n setConfirmBatch(false)\n }\n setBusy('__batch__')\n postJSON('/archived-sessions/' + action, { sessionIds: selIds })\n .then((r) => {\n setBusy(null)\n const n = (r && (r.archived || r.restored || r.deleted)) || selIds.length\n showToast(`\u5DF2\u5904\u7406 ${n} \u4E2A\u4F1A\u8BDD`)\n refresh()\n })\n .catch((e) => { setBusy(null); setConfirmBatch(false); setError(String((e && e.message) || e)) })\n }\n\n const openMoveFor = (it) => {\n if (openMove === it.sessionId) { setOpenMove(null); return }\n setTargetWs(workspaces.length ? (targetWs || workspaces[0].workspaceId) : '')\n setMoveMode('existing')\n setNewPath('')\n setOpenMove(it.sessionId)\n }\n\n const pickDirectory = async () => {\n if (!workspacesSvc || picking) return\n setPicking(true)\n try {\n const p = await workspacesSvc.pickDirectory()\n if (p) { setNewPath(p); setMoveMode('new') }\n } catch (e) {\n setError(String((e && e.message) || e))\n } finally {\n setPicking(false)\n }\n }\n\n const toggleDetails = (it) => {\n if (openDetails === it.sessionId) { setOpenDetails(null); return }\n if (details[it.sessionId]) { setOpenDetails(it.sessionId); return }\n setDetailsLoading(it.sessionId)\n postJSON('/archived-sessions/details', { sessionId: it.sessionId })\n .then((d) => {\n setDetails((m) => ({ ...m, [it.sessionId]: d }))\n setDetailsLoading(null)\n setOpenDetails(it.sessionId)\n })\n .catch((e) => { setDetailsLoading(null); setError(String((e && e.message) || e)) })\n }\n\n const workspaceTag = (it) => {\n if (it.hasWorkspace && it.workspaceGone) {\n return <span className=\"archv-wtag archv-wgone\" title={(it.workspacePath || '') + '\uFF08\u539F\u5DE5\u4F5C\u533A\u5DF2\u5220\u9664\uFF09'}>\u5DE5\u4F5C\u533A\u5DF2\u5220 \u00B7 {pathName(it.workspacePath) || '?'}</span>\n }\n const wName = it.workspaceTitle || pathName(it.workspacePath)\n if (wName) return <span className=\"archv-wtag\" title={it.workspacePath || ''}>{wName}</span>\n return <span className=\"archv-wtag\">\u672A\u5206\u7EC4</span>\n }\n\n const runMenu = (id, it) => {\n setOpenMenu(null)\n if (id === 'restore') act('restore', it)\n else if (id === 'archive') act('archive', it)\n else if (id === 'delete') setDelTarget(it)\n else if (id === 'move') openMoveFor(it)\n else if (id === 'details') toggleDetails(it)\n }\n\n const rowMenu = (it) => {\n const items = it.archived\n ? [\n ['restore', '\u6062\u590D'],\n ['move', openMove === it.sessionId ? '\u6536\u8D77\u79FB\u52A8' : '\u79FB\u52A8'],\n ['details', openDetails === it.sessionId ? '\u6536\u8D77\u8BE6\u60C5' : '\u8BE6\u60C5'],\n ['delete', '\u5220\u9664'],\n ]\n : [['archive', '\u5F52\u6863'], ['move', '\u79FB\u52A8'], ['details', '\u8BE6\u60C5'], ['delete', '\u5220\u9664']]\n return (\n <div ref={openMenu === it.sessionId ? menuRef : null} className=\"more-wrap\">\n <button\n type=\"button\"\n className=\"more-btn\"\n aria-label=\"\u66F4\u591A\u64CD\u4F5C\"\n aria-haspopup=\"true\"\n aria-expanded={openMenu === it.sessionId}\n onClick={(e) => { e.stopPropagation(); setOpenMenu(openMenu === it.sessionId ? null : it.sessionId) }}\n >\u22EF</button>\n {openMenu === it.sessionId && (\n <div className=\"more-menu\" role=\"menu\">\n {items.map(([id, label]) => (\n <button\n key={id}\n type=\"button\"\n role=\"menuitem\"\n className={'more-item' + (id === 'delete' ? ' more-item-danger' : '')}\n onClick={() => runMenu(id, it)}\n >{label}</button>\n ))}\n </div>\n )}\n </div>\n )\n }\n\n return (\n <div className=\"archv\" role=\"region\" aria-label=\"\u4F1A\u8BDD\u7BA1\u7406\">\n <style>{CSS}</style>\n <div className=\"archv-head\">\n <h2 className=\"archv-title\">\u4F1A\u8BDD\u7BA1\u7406</h2>\n {sessions !== null && <span className=\"archv-count\" aria-label={`${sessions.length} \u4E2A\u4F1A\u8BDD`}>{sessions.length}</span>}\n </div>\n <p className=\"archv-sub\">\n \u7EDF\u4E00\u7BA1\u7406\u5168\u90E8\u4F1A\u8BDD\uFF1A\u5F52\u6863 / \u6062\u590D / \u79FB\u52A8\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A / \u4F1A\u8BDD\u8BE6\u60C5 / \u6279\u91CF\u64CD\u4F5C\uFF0C\u5220\u9664\u4F1A\u5148\u8FDB\u5165\u56DE\u6536\u7AD9\uFF0C\u53EF\u5728\u56DE\u6536\u7AD9\u5185\u6062\u590D\u6216\u5F7B\u5E95\u6E05\u7406\u3002\n </p>\n {error && (\n <div className=\"archv-err\" role=\"alert\">\n <span>{error}</span>\n <button type=\"button\" className=\"archv-errretry\" onClick={refresh}>\u91CD\u8BD5</button>\n </div>\n )}\n {sessions === null ? (\n <div className=\"archv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">\n {[0, 1, 2].map((i) => <div key={i} className=\"archv-skel-card\" />)}\n </div>\n ) : (\n <>\n <div className=\"sess-filter\" role=\"tablist\" aria-label=\"\u4F1A\u8BDD\u7B5B\u9009\">\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'all'} className={'sess-fbtn' + (filter === 'all' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('all'); clearSel(); setConfirmBatch(false) }}>\u5168\u90E8 ({sessions.length})</button>\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'active'} className={'sess-fbtn' + (filter === 'active' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('active'); clearSel(); setConfirmBatch(false) }}>\u6D3B\u52A8 ({activeList.length})</button>\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'archived'} className={'sess-fbtn' + (filter === 'archived' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('archived'); clearSel(); setConfirmBatch(false) }}>\u5DF2\u5F52\u6863 ({archivedList.length})</button>\n <button type=\"button\" role=\"tab\" aria-selected={filter === 'trash'} className={'sess-fbtn' + (filter === 'trash' ? ' sess-fbtn-on' : '')} onClick={() => { setFilter('trash'); clearSel(); setConfirmBatch(false) }}>\u56DE\u6536\u7AD9 ({trash.length})</button>\n </div>\n\n {filter !== 'trash' && (\n <>\n <div className=\"sess-tools\" aria-label=\"\u67E5\u627E\u548C\u6574\u7406\u4F1A\u8BDD\">\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-search\">\u641C\u7D22\u4F1A\u8BDD</label>\n <input id=\"dsm-search\" type=\"search\" value={query} onChange={(e) => setQuery(e.target.value)} placeholder=\"\u6807\u9898\u3001\u4F1A\u8BDD ID \u6216\u5DE5\u4F5C\u533A\" />\n </div>\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-workspace-filter\">\u5DE5\u4F5C\u533A</label>\n <select id=\"dsm-workspace-filter\" value={workspaceFilter} onChange={(e) => setWorkspaceFilter(e.target.value)}>\n <option value=\"all\">\u5168\u90E8\u5DE5\u4F5C\u533A</option>\n {workspaces.map((w) => <option key={w.workspaceId} value={w.path}>{w.title}</option>)}\n </select>\n </div>\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-sort\">\u6392\u5E8F</label>\n <select id=\"dsm-sort\" value={sortBy} onChange={(e) => setSortBy(e.target.value)}>\n <option value=\"newest\">\u6700\u65B0\u521B\u5EFA</option><option value=\"oldest\">\u6700\u65E9\u521B\u5EFA</option><option value=\"title\">\u6807\u9898 A\u2013Z</option>\n </select>\n </div>\n </div>\n <div className=\"sess-results\" role=\"status\">\u663E\u793A {list.length} \u4E2A\u4F1A\u8BDD{query || workspaceFilter !== 'all' ? `\uFF0C\u5171 ${filter === 'archived' ? archivedList.length : filter === 'active' ? activeList.length : sessions.length} \u4E2A` : ''}</div>\n </>\n )}\n\n {filter !== 'trash' && list.length > 0 && (\n <div className=\"sess-batch\">\n <span className=\"sess-btntext\">{selIds.length ? `\u5DF2\u9009 ${selIds.length} \u9879` : (filter === 'archived' ? `\u5171 ${archivedList.length} \u4E2A\u5F52\u6863\u4F1A\u8BDD` : `\u5171 ${sessions.length} \u4E2A\u4F1A\u8BDD\uFF08\u6D3B\u52A8 ${activeList.length} / \u5DF2\u5F52\u6863 ${archivedList.length}\uFF09`)}</span>\n <button type=\"button\" className=\"archv-btn\" disabled={list.length === 0} onClick={selectAll}>\u5168\u9009</button>\n {selIds.length > 0 && (\n <>\n {filter === 'archived' && (\n <>\n <button type=\"button\" className=\"archv-btn\" disabled={busy !== null} onClick={() => doBatch('restore-many')}>\u6062\u590D\u6240\u9009</button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={busy !== null} onClick={() => doBatch('delete-many')}>{confirmBatch ? '\u786E\u8BA4\u5220\u9664\u6240\u9009?' : '\u5220\u9664\u6240\u9009'}</button>\n </>\n )}\n {filter !== 'archived' && (\n <button type=\"button\" className=\"archv-btn\" disabled={busy !== null} onClick={() => doBatch('archive-many')}>\u5F52\u6863\u6240\u9009</button>\n )}\n <button type=\"button\" className=\"archv-btn\" onClick={clearSel}>\u53D6\u6D88\u9009\u62E9</button>\n </>\n )}\n </div>\n )}\n\n {filter !== 'trash' && list.length === 0 ? (\n <div className=\"archv-empty\">{query || workspaceFilter !== 'all' ? '\u6CA1\u6709\u5339\u914D\u7684\u4F1A\u8BDD\u3002\u8BF7\u8C03\u6574\u641C\u7D22\u8BCD\u6216\u5DE5\u4F5C\u533A\u7B5B\u9009\u3002' : filter === 'archived' ? '\u76EE\u524D\u6CA1\u6709\u5F52\u6863\u4F1A\u8BDD\u3002\u5728\u201C\u5168\u90E8\u201D\u91CC\u9009\u4E2D\u4F1A\u8BDD\u70B9\u201C\u5F52\u6863\u201D\u5373\u53EF\u6536\u7EB3\u8FDB\u6765\u3002' : filter === 'active' ? '\u76EE\u524D\u6CA1\u6709\u6D3B\u52A8\u4F1A\u8BDD\u3002' : '\u6682\u65E0\u53EF\u7BA1\u7406\u7684\u4F1A\u8BDD\u3002'}</div>\n ) : filter !== 'trash' ? (\n <div className=\"archv-list\" role=\"list\">\n {list.map((it) => {\n const date = fmtDate(it.createdAt)\n const expanded = openMove === it.sessionId\n return (\n <div key={it.sessionId} className={'archv-card' + (expanded ? ' archv-card-exp' : '')} role=\"listitem\">\n <div className=\"archv-row\">\n <input\n type=\"checkbox\"\n className=\"archv-check\"\n checked={!!selected[it.sessionId]}\n onChange={() => toggle(it.sessionId)}\n aria-label={'\u9009\u62E9 ' + (it.title || it.sessionId)}\n />\n <div className=\"archv-body\">\n <div className=\"archv-main\">\n <div className=\"archv-name\" title={it.title || ''}>{it.title || '(\u65E0\u6807\u9898)'}</div>\n <div className=\"archv-meta\">\n {it.archived ? <span className=\"archv-wtag archv-wgone\">\u5DF2\u5F52\u6863</span> : <span className=\"archv-wtag archv-active\">\u6D3B\u52A8</span>}\n {workspaceTag(it)}\n {date && <><span className=\"archv-dot\">\u00B7</span><span className=\"archv-date\">{date}</span></>}\n <span className=\"archv-id\">{it.sessionId}</span>\n </div>\n </div>\n {rowMenu(it)}\n </div>\n </div>\n {expanded && (\n <div className=\"mv-sheet\" role=\"region\" aria-label=\"\u79FB\u52A8\u5230\u5DE5\u4F5C\u533A\">\n <div className=\"mv-sheet-head\">\n <h3 className=\"mv-sheet-title\">\u79FB\u52A8\u5230\u5DE5\u4F5C\u533A</h3>\n <button type=\"button\" className=\"mv-sheet-close\" aria-label=\"\u5173\u95ED\" onClick={() => setOpenMove(null)}>\u00D7</button>\n </div>\n <div className=\"mv-seg\" role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={moveMode === 'existing'} className={'mv-segbtn' + (moveMode === 'existing' ? ' mv-segbtn-on' : '')} onClick={() => setMoveMode('existing')}>\u5DF2\u6709\u5DE5\u4F5C\u533A</button>\n <button type=\"button\" role=\"tab\" aria-selected={moveMode === 'new'} className={'mv-segbtn' + (moveMode === 'new' ? ' mv-segbtn-on' : '')} onClick={() => setMoveMode('new')}>\u65B0\u5EFA\u76EE\u5F55</button>\n </div>\n {moveMode === 'existing' ? (\n <div className=\"mv-field\">\n <label className=\"mv-field-label\" htmlFor=\"mv-target-ws\">\u76EE\u6807\u5DE5\u4F5C\u533A</label>\n <select id=\"mv-target-ws\" value={targetWs} onChange={(e) => setTargetWs(e.target.value)}>\n {workspaces.length === 0 && <option value=\"\">\uFF08\u6682\u65E0\u5DE5\u4F5C\u533A\uFF09</option>}\n {workspaces.map((w) => (\n <option key={w.workspaceId} value={w.workspaceId}>{w.title} \u00B7 {w.path}</option>\n ))}\n </select>\n </div>\n ) : (\n <div className=\"mv-field\">\n <label className=\"mv-field-label\" htmlFor=\"mv-new-path\">\u65B0\u5DE5\u4F5C\u533A\u76EE\u5F55\u8DEF\u5F84</label>\n <div className=\"mv-browse-row\">\n <input\n id=\"mv-new-path\"\n type=\"text\"\n value={newPath}\n onChange={(e) => setNewPath(e.target.value)}\n placeholder=\"\u4F8B\u5982 /Users/you/Projects/demo \u6216 ~/demo\"\n />\n <button\n type=\"button\"\n className=\"archv-btn\"\n onClick={pickDirectory}\n disabled={busy !== null || picking || !workspacesSvc}\n title={!workspacesSvc ? '\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u4E0D\u652F\u6301\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9' : '\u6253\u5F00\u7CFB\u7EDF\u76EE\u5F55\u9009\u62E9\u7A97\u53E3'}\n >\n {picking ? '\u9009\u62E9\u4E2D\u2026' : '\u6D4F\u89C8\u2026'}\n </button>\n </div>\n </div>\n )}\n <div className=\"mv-foot\">\n <button type=\"button\" className=\"archv-btn\" onClick={() => setOpenMove(null)}>\u53D6\u6D88</button>\n <button type=\"button\" className=\"archv-btn archv-go\" disabled={busy !== null} onClick={() => doMove(it)}>\n {busy === it.sessionId && <span className=\"archv-spin\" aria-hidden=\"true\" />}\u786E\u8BA4\u79FB\u52A8\n </button>\n </div>\n </div>\n )}\n {openDetails === it.sessionId && (\n <div className=\"dtl-sheet\" role=\"region\" aria-label=\"\u4F1A\u8BDD\u8BE6\u60C5\">\n <div className=\"dtl-sheet-head\">\n <h3 className=\"dtl-sheet-title\">\u4F1A\u8BDD\u8BE6\u60C5</h3>\n <button type=\"button\" className=\"mv-sheet-close\" aria-label=\"\u5173\u95ED\u8BE6\u60C5\" onClick={() => setOpenDetails(null)}>\u00D7</button>\n </div>\n {detailsLoading === it.sessionId ? (\n <div className=\"archv-skel\" aria-label=\"\u52A0\u8F7D\u4E2D\">{[0, 1].map((i) => <div key={i} className=\"archv-skel-card\" />)}</div>\n ) : (() => {\n const d = details[it.sessionId]\n if (!d) return <div className=\"dtl-paths\">\u6682\u65E0\u8BE6\u60C5</div>\n const st = d.stats || {}\n const tools = st.toolCounts ? Object.entries(st.toolCounts).sort((a, b) => b[1] - a[1]).slice(0, 10) : []\n return (\n <div>\n <div className=\"dtl-grid\">\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u78C1\u76D8\u5360\u7528</span><span className=\"dtl-v\">{fmtBytes(d.sizeBytes) || '\u2014'}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u8F6E\u6B21 / \u6B65\u9AA4</span><span className=\"dtl-v\">{st.turns ?? 0} / {st.steps ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u7528\u6237 / \u52A9\u624B</span><span className=\"dtl-v\">{st.userMessages ?? 0} / {st.assistantMessages ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u5DE5\u5177\u8C03\u7528</span><span className=\"dtl-v\">{st.toolCalls ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u56FE\u7247\u9644\u4EF6</span><span className=\"dtl-v\">{st.attachments ?? 0}</span></div>\n <div className=\"dtl-cell\"><span className=\"dtl-k\">\u521B\u5EFA / \u66F4\u65B0</span><span className=\"dtl-v\">{fmtDate(d.createdAt) || '\u2014'} \u00B7 {fmtDate(d.updatedAt) || '\u2014'}</span></div>\n </div>\n {tools.length > 0 && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u5DE5\u5177\u4F7F\u7528</div>\n <div className=\"dtl-tags\">{tools.map(([t, c]) => <span className=\"dtl-tag\" key={t}>{t} \u00D7{c}</span>)}</div>\n </div>\n )}\n {st.fetches && st.fetches.length > 0 && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u641C\u7D22 / \u6293\u53D6</div>\n <ul className=\"dtl-list\">{st.fetches.map((f, i) => <li key={i}>{f.tool}{f.query ? ` \u300C${f.query}\u300D` : ''}</li>)}</ul>\n </div>\n )}\n {d.files && d.files.length > 0 && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u5199\u8FC7\u7684\u6587\u4EF6\uFF08{d.files.length}\uFF09</div>\n <ul className=\"dtl-list\">{d.files.map((f, i) => <li key={i}><code>{f.path}</code> <span className=\"dtl-filetool\">({f.tool})</span></li>)}</ul>\n </div>\n )}\n {d.lineage && (d.lineage.parentSessionId || (d.lineage.children && d.lineage.children.length > 0) || (d.lineage.subagents && d.lineage.subagents.length > 0)) && (\n <div className=\"dtl-sec\"><div className=\"dtl-sec-t\">\u8840\u7EDF</div>\n <div className=\"dtl-paths\">\n {d.lineage.parentSessionId && <div>\u7236\u4F1A\u8BDD: <code>{d.lineage.parentSessionId}</code></div>}\n {d.lineage.children && d.lineage.children.length > 0 && <div>\u5B50\u4F1A\u8BDD ({d.lineage.children.length}): <code>{d.lineage.children.join(', ')}</code></div>}\n {d.lineage.subagents && d.lineage.subagents.length > 0 && <div>\u5B50\u4EE3\u7406 ({d.lineage.subagents.length}): <code>{d.lineage.subagents.join(', ')}</code></div>}\n </div>\n </div>\n )}\n </div>\n )\n })()}\n </div>\n )}\n </div>\n )\n })}\n </div>\n ) : null}\n </>\n )}\n {toast && <div className=\"archv-status\" role=\"status\">{toast}</div>}\n {delTarget && (\n <div className=\"dlg-backdrop\" onClick={() => setDelTarget(null)}>\n <div ref={dialogRef} className=\"dlg\" role=\"alertdialog\" aria-modal=\"true\" aria-label=\"\u5220\u9664\u4F1A\u8BDD\" onClick={(e) => e.stopPropagation()}>\n <h3 className=\"dlg-title\">\u5220\u9664\u4F1A\u8BDD</h3>\n <p className=\"dlg-text\">\u786E\u8BA4\u5220\u9664\u300C{delTarget.title || delTarget.sessionId}\u300D\uFF1F\u5C06\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u53EF\u5728\u672C\u9875\u5E95\u90E8\u300C\u56DE\u6536\u7AD9\u300D\u4E2D\u6062\u590D\u6216\u5F7B\u5E95\u5220\u9664\u3002</p>\n <div className=\"dlg-actions\">\n <button type=\"button\" className=\"archv-btn\" disabled={busy !== null} onClick={() => setDelTarget(null)}>\u53D6\u6D88</button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={busy !== null} onClick={doDeleteConfirmed}>\u79FB\u5165\u56DE\u6536\u7AD9</button>\n </div>\n </div>\n </div>\n )}\n {filter === 'trash' && <section className=\"dsm-trash\" aria-label=\"\u56DE\u6536\u7AD9\">\n <div className=\"dsm-trash-h\">\n <h3>\u56DE\u6536\u7AD9</h3>\n <span className=\"dsm-trash-count\">{trash.length ? `\uFF08${trash.length} \u4E2A\u5F85\u6E05\u7406\uFF09` : '\uFF08\u7A7A\uFF09'}</span>\n </div>\n <div className=\"sess-tools\">\n <div className=\"sess-field\">\n <label htmlFor=\"dsm-retention\">\u81EA\u52A8\u6E05\u7406</label>\n <select id=\"dsm-retention\" value={trashSettings.retentionDays || 0} disabled={trashBusy !== null} onChange={(e) => updateRetention(e.target.value)}>\n <option value=\"0\">\u4E0D\u81EA\u52A8\u6E05\u7406</option><option value=\"7\">\u4FDD\u7559 7 \u5929</option><option value=\"30\">\u4FDD\u7559 30 \u5929</option><option value=\"90\">\u4FDD\u7559 90 \u5929</option>\n </select>\n </div>\n <div className=\"sess-field\"><label>\u6570\u636E\u68C0\u67E5</label><button type=\"button\" className=\"archv-btn\" disabled={trashBusy !== null} onClick={verifyTrash}>{trashBusy === '__verify' ? '\u6821\u9A8C\u4E2D\u2026' : '\u6821\u9A8C\u65E5\u5FD7\u5B8C\u6574\u6027'}</button></div>\n <div className=\"sess-field\"><label>\u6C38\u4E45\u6E05\u7406</label><button type=\"button\" className=\"archv-btn archv-del\" disabled={trashBusy !== null || !trash.length} onClick={() => setPurgeTarget('__all')}>\u6E05\u7A7A\u56DE\u6536\u7AD9</button></div>\n </div>\n {trashCheck && <div className={trashCheck.missing ? 'archv-err' : 'archv-empty'} role=\"status\">\u6821\u9A8C\u5B8C\u6210\uFF1A{trashCheck.healthy} \u6761\u6B63\u5E38\uFF0C{trashCheck.missing} \u6761\u65E5\u5FD7\u7F3A\u5931\u3002</div>}\n {trash.length === 0 ? (\n <div className=\"dsm-trash-empty\">\u56DE\u6536\u7AD9\u4E3A\u7A7A\u3002\u5220\u9664\u7684\u4F1A\u8BDD\u4F1A\u5148\u8FDB\u5165\u8FD9\u91CC\uFF0C\u53EF\u6062\u590D\u6216\u5F7B\u5E95\u5220\u9664\u3002</div>\n ) : (\n <div className=\"dsm-trash-list\">\n {trash.map((t) => (\n <div key={t.sessionId} className=\"dsm-trash-row\">\n <span className=\"dsm-trash-name\" title={t.sessionId}>{t.title || t.sessionId}</span>\n <span className=\"dsm-trash-date\">{fmtDate(t.deletedAt)}</span>\n <span className=\"dsm-trash-actions\">\n <button type=\"button\" className=\"archv-btn\" disabled={trashBusy !== null} onClick={() => restoreTrash(t.sessionId)}>\u6062\u590D</button>\n <button type=\"button\" className=\"archv-btn archv-del\" disabled={trashBusy !== null} onClick={() => setPurgeTarget(t.sessionId)}>\u5F7B\u5E95\u5220\u9664</button>\n </span>\n </div>\n ))}\n </div>\n )}\n </section>}\n {purgeTarget && (\n <div className=\"dlg-backdrop\" onClick={() => setPurgeTarget(null)}>\n <div ref={dialogRef} className=\"dlg\" role=\"alertdialog\" aria-modal=\"true\" aria-labelledby=\"dsm-purge-title\" onClick={(e) => e.stopPropagation()}>\n <h3 id=\"dsm-purge-title\" className=\"dlg-title\">\u6C38\u4E45\u5220\u9664{purgeTarget === '__all' ? '\u5168\u90E8\u56DE\u6536\u7AD9\u4F1A\u8BDD' : '\u8FD9\u4E2A\u4F1A\u8BDD'}\uFF1F</h3>\n <p className=\"dlg-text\">\u6B64\u64CD\u4F5C\u4F1A\u7269\u7406\u5220\u9664\u65E5\u5FD7\uFF0C\u65E0\u6CD5\u6062\u590D\u3002\u5F52\u6863\u3001\u7B5B\u9009\u548C\u91CD\u65B0\u5B89\u88C5\u63D2\u4EF6\u90FD\u4E0D\u80FD\u627E\u56DE\u8FD9\u4E9B\u6570\u636E\u3002</p>\n <div className=\"dlg-actions\">\n <button type=\"button\" className=\"archv-btn\" onClick={() => setPurgeTarget(null)}>\u53D6\u6D88</button>\n <button type=\"button\" className=\"archv-btn archv-del\" onClick={() => { const target = purgeTarget; setPurgeTarget(null); target === '__all' ? purgeAllTrash() : purgeTrash(target) }}>\u786E\u8BA4\u6C38\u4E45\u5220\u9664</button>\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n\n// ---- Main-page sidebar session \"\u22EF\" menu augmentation (DOM shim) -----------\n// DSH core renders the sidebar session list (dsh-client-ui-workspace) with a\n// per-row \"\u22EF\" Menu whose items (rename / fork / archive) are hardcoded \u2014 there\n// is NO plugin slot for adding per-session menu items, and the row DOM carries\n// no sessionId. To honor the request we augment the already-opened portalled\n// menu via DOM: we watch for a [role=\"menu\"] portalled to document.body whose\n// React fiber chain reaches a SessionNodeItem (i.e. it is a session menu), read\n// the session id (and current cwd) off that fiber, then clone an existing menu\n// item to append \"\u79FB\u52A8\u4F1A\u8BDD\" / \"\u5220\u9664\u4F1A\u8BDD\". This is intentionally a DOM shim and is\n// fragile against DSH UI updates (class names / fiber shape / menu markup).\nconst SIDEBAR_AUG_CSS = `\n.dsm-backdrop{position:fixed;inset:0;z-index:2147483600;background:rgba(0,0,0,.45);display:flex;align-items:center;justify-content:center;padding:16px}\n.dsm-dlg{width:min(420px,92vw);background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l3);border-radius:14px;padding:18px;box-shadow:0 16px 48px rgb(0 0 0/.28);display:flex;flex-direction:column;gap:12px}\n.dsm-title{font-size:15px;font-weight:650;color:var(--dsw-alias-label-primary);margin:0}\n.dsm-text{font-size:13px;line-height:1.6;color:var(--dsw-alias-label-secondary);margin:0;word-break:break-all}\n.dsm-body{display:flex;flex-direction:column;gap:4px;max-height:280px;overflow:auto}\n.dsm-loading,.dsm-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:4px 2px}\n.dsm-err{font-size:12px;color:var(--dsw-alias-state-error-primary);padding:4px 2px}\n.dsm-opt{appearance:none;display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;padding:9px 11px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-elevated);color:var(--dsw-alias-label-primary);border-radius:9px;font-size:12.5px;cursor:pointer;text-align:left}\n.dsm-opt:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l4)}\n.dsm-opt:disabled{opacity:.55;cursor:default}\n.dsm-opt-cur{border-color:color-mix(in srgb,var(--dsw-alias-state-business-primary) 45%,transparent);color:var(--dsw-alias-state-business-primary)}\n.dsm-opt-name{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}\n.dsm-opt-sub{font-size:11px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:none;margin-left:8px}\n.dsm-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:2px}\n.dsm-btn{appearance:none;min-height:32px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-fill-subtle);color:var(--dsw-alias-label-secondary);border-radius:9px;font-size:12px;font-weight:500;cursor:pointer}\n.dsm-btn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}\n.dsm-del{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 45%,transparent)}\n.dsm-del:hover{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary)}\n.dsm-toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:2147483601;background:var(--dsw-alias-fill-elevated);border:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-primary);padding:9px 16px;border-radius:999px;font-size:12px;box-shadow:0 8px 24px rgb(0 0 0/.18);max-width:min(90vw,420px)}\n.dsm-sub{position:fixed;z-index:1100;box-sizing:border-box;min-width:190px;max-width:320px;padding:4px;display:flex;flex-direction:column;gap:0;background:var(--dsw-specific-menu);border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;box-shadow:var(--dsw-shadow-lv3)}\n.dsm-sub-loading,.dsm-sub-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:6px 10px}\n.dsm-sub-err{font-size:12px;color:var(--dsw-alias-state-error-primary);padding:6px 10px}\n.dsm-sub-item{display:flex;align-items:center;gap:8px;width:100%;min-height:36px;padding:6px 10px;border:none;border-radius:8px;background:transparent;cursor:pointer;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);text-align:left}\n.dsm-sub-item:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsm-sub-item:disabled{opacity:.5;cursor:default}\n.dsm-sub-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsm-sub-cur{font-size:11px;color:var(--dsw-alias-state-business-primary);flex:none;margin-left:8px}\n.dsm-dot{position:absolute;left:6px;top:50%;transform:translateY(-50%);width:8px;height:8px;border-radius:50%;box-sizing:border-box;cursor:pointer;pointer-events:auto;z-index:1}\n.dsm-dot-unread-manual{background:var(--dsw-alias-state-business-primary)}\n.dsm-dot-waiting{background:var(--dsw-alias-state-warning-primary)}\n.dsm-dot-unread{background:var(--dsw-alias-state-success-primary)}\n.dsm-drag-source{opacity:.48}\n.dsm-drop-target{position:relative;background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 10%,transparent)!important;outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px;border-radius:8px}\n.dsm-drop-target::after{content:'\u79FB\u52A8\u5230\u8FD9\u91CC';position:absolute;right:8px;top:50%;transform:translateY(-50%);padding:1px 6px;border-radius:4px;background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-inverted);font-size:10px;font-weight:600;line-height:16px;pointer-events:none}\n.dsm-drag-busy{cursor:progress!important}\n.dsm-trash{margin-top:18px;border-top:1px solid var(--dsw-alias-border-l2);padding-top:14px}\n.dsm-trash-h{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:8px}\n.dsm-trash-h h3{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);margin:0}\n.dsm-trash-count{font-size:11px;color:var(--dsw-alias-label-tertiary)}\n.dsm-trash-list{display:flex;flex-direction:column;gap:6px;max-height:260px;overflow:auto}\n.dsm-trash-row{display:flex;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-alias-fill-elevated)}\n.dsm-trash-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12.5px;color:var(--dsw-alias-label-primary)}\n.dsm-trash-date{font-size:11px;color:var(--dsw-alias-label-tertiary);flex:none;white-space:nowrap}\n.dsm-trash-actions{display:flex;gap:6px;flex:none}.dsm-trash-actions .archv-btn{min-width:72px}\n.dsm-trash-empty{font-size:12px;color:var(--dsw-alias-label-tertiary);padding:6px 2px}\n`\n\n// Shared status-dot state so the \u22EF-menu \"\u6807\u8BB0\u672A\u8BFB\" action can toggle the\n// manual flag and trigger a repaint without coupling the two installers.\nconst DSM_KEY_MANUAL = 'dsm-manual-unread-v1'\nlet dsmManualUnread = null\nlet dsmRepaintDots = null\nfunction dsmLoadManual() {\n if (dsmManualUnread) return dsmManualUnread\n try { dsmManualUnread = new Set(JSON.parse(localStorage.getItem(DSM_KEY_MANUAL) || '[]')) } catch (e) { dsmManualUnread = new Set() }\n return dsmManualUnread\n}\nfunction dsmSaveManual() { try { localStorage.setItem(DSM_KEY_MANUAL, JSON.stringify([...dsmLoadManual()])) } catch (e) {} }\nfunction dsmToggleManual(id) {\n const s = dsmLoadManual()\n if (s.has(id)) s.delete(id); else s.add(id)\n dsmSaveManual()\n if (dsmRepaintDots) dsmRepaintDots()\n}\n\n// Recycle-bin membership (session ids currently in \u56DE\u6536\u7AD9). The sidebar\n// status-dot installer uses this to hide trashed sessions so they don't show\n// up under DSH's \"\u672A\u5206\u7EC4\" group. Loaded from the backend on a throttle and\n// updated optimistically when our own \u22EF-menu deletes a session.\nlet dsmTrashIds = null\nlet dsmServerPurgedIds = new Set()\nlet dsmAuthoritativeTitles = new Map()\nlet dsmTrashTick = 0\nasync function dsmLoadTrashIds() {\n try {\n const r = await postJSON('/archived-sessions/sidebar-state', {})\n dsmTrashIds = new Set(((r && r.trashedSessionIds) || []).map(String))\n dsmServerPurgedIds = new Set(((r && r.purgedSessionIds) || []).map(String))\n dsmAuthoritativeTitles = new Map(Object.entries((r && r.titles) || {}).map(([id, title]) => [String(id), String(title)]))\n if (dsmRepaintDots) dsmRepaintDots()\n } catch (e) { /* keep last known set */ }\n return dsmTrashIds\n}\n\n// Permanently-hidden set: sessions the user hard-purged from the \u56DE\u6536\u7AD9. Unlike\n// dsmTrashIds (which the backend poll refreshes and can drop), these are GONE for\n// good, so we keep them hidden forever \u2014 otherwise DSH re-surfaces the orphan\n// under a \"\u672A\u5206\u7EC4\" group after the trash poll drops it from dsmTrashIds.\nconst DSM_KEY_PURGED = 'dsm-purged-v1'\nlet dsmPurgedIds = null\nfunction dsmLoadPurged() {\n if (!dsmPurgedIds) {\n try { dsmPurgedIds = new Set(JSON.parse(localStorage.getItem(DSM_KEY_PURGED) || '[]')) } catch (e) { dsmPurgedIds = new Set() }\n }\n dsmServerPurgedIds.forEach((id) => dsmPurgedIds.add(id))\n return dsmPurgedIds\n}\nfunction dsmSavePurged() { try { localStorage.setItem(DSM_KEY_PURGED, JSON.stringify([...dsmLoadPurged()])) } catch (e) {} }\nfunction dsmMarkPurged(ids) {\n const s = dsmLoadPurged()\n ids.forEach((id) => s.add(String(id)))\n dsmSavePurged()\n if (dsmRepaintDots) dsmRepaintDots()\n}\n\nfunction installSidebarSessionMenuAug() {\n if (typeof document === 'undefined') return\n const AUG = 'data-dsm-aug'\n let styleInjected = false\n let activeSubClose = null\n let hoverTimer = null\n\n const findFiber = (el) => {\n const k = Object.keys(el).find((kk) => kk.startsWith('__reactFiber') || kk.startsWith('__reactInternalInstance'))\n return k ? el[k] : null\n }\n // Walk the React fiber chain from the portalled menu element up to the\n // SessionNodeItem component, which carries `node.id` (the session id).\n const sessionInfoFromMenu = (menuEl) => {\n let f = findFiber(menuEl)\n let guard = 0\n while (f && guard++ < 300) {\n const p = f.memoizedProps\n if (p && p.node && typeof p.node.id === 'string' && p.node.id) {\n return { id: p.node.id, cwd: p.node.cwd || p.node.workspacePath || null }\n }\n f = f.return\n }\n return null\n }\n const closeMenu = () => {\n try { document.dispatchEvent(new MouseEvent('mousedown', { bubbles: true })) } catch (e) {}\n try { document.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true })) } catch (e) {}\n }\n const escapeHtml = (s) => {\n const d = document.createElement('div')\n d.textContent = s == null ? '' : String(s)\n return d.innerHTML\n }\n const toast = (msg) => {\n const t = document.createElement('div')\n t.className = 'dsm-toast'\n t.textContent = msg\n document.body.appendChild(t)\n setTimeout(() => t.remove(), 2600)\n }\n const ensureStyle = () => {\n if (styleInjected) return\n const s = document.createElement('style')\n s.dataset.dsm = 'aug'\n s.textContent = SIDEBAR_AUG_CSS\n document.head.appendChild(s)\n styleInjected = true\n }\n const closeMoveSubmenu = () => {\n if (activeSubClose) { const f = activeSubClose; activeSubClose = null; f() }\n }\n const openMoveSubmenu = (moveBtn, info) => {\n ensureStyle()\n closeMoveSubmenu()\n const sub = document.createElement('div')\n sub.className = 'dsm-sub'\n sub.setAttribute('role', 'menu')\n sub.setAttribute('data-dsm-sub', '')\n sub.innerHTML = '<div class=\"dsm-sub-loading\">\u52A0\u8F7D\u5DE5\u4F5C\u533A\u2026</div>'\n const r = moveBtn.getBoundingClientRect()\n sub.style.top = Math.max(8, Math.round(r.top - 4)) + 'px'\n sub.style.left = Math.round(r.right + 10) + 'px'\n document.body.appendChild(sub)\n const closeSub = () => {\n activeSubClose = null\n if (sub.parentNode) sub.remove()\n document.removeEventListener('mousedown', onDocDown, true)\n window.removeEventListener('blur', closeSub)\n }\n const onDocDown = (e) => {\n if (sub.contains(e.target) || moveBtn.contains(e.target)) return\n closeSub()\n }\n // Keep DSH's own outside-click handler from closing the parent menu while\n // the pointer is over our submenu (it lives outside the portalled card).\n sub.addEventListener('mousedown', (e) => e.stopPropagation())\n // Hover bridging: moving from the trigger button across the 10px gap to\n // the submenu must not dismiss it; entering the submenu cancels the\n // pending close timer set on the button's mouseleave.\n sub.addEventListener('mouseenter', () => { if (hoverTimer) { clearTimeout(hoverTimer); hoverTimer = null } })\n sub.addEventListener('mouseleave', () => { hoverTimer = setTimeout(() => closeSub(), 160) })\n setTimeout(() => document.addEventListener('mousedown', onDocDown, true), 0)\n window.addEventListener('blur', closeSub)\n activeSubClose = closeSub\n Promise.all([\n postJSON('/archived-sessions/workspaces', {}),\n postJSON('/archived-sessions/sessions', {}),\n ]).then(([ws, sess]) => {\n const items = ws.items || []\n const cur = (sess.items || []).find((x) => x.sessionId === info.id)\n const curPath = cur ? cur.workspacePath : (info.cwd || null)\n if (!items.length) { sub.innerHTML = '<div class=\"dsm-sub-empty\">\uFF08\u6682\u65E0\u53EF\u7528\u5DE5\u4F5C\u533A\uFF09</div>'; return }\n sub.innerHTML = ''\n items.forEach((w) => {\n const isCur = !!curPath && w.path === curPath\n const b = document.createElement('button')\n b.type = 'button'\n b.className = 'dsm-sub-item'\n b.setAttribute('role', 'menuitem')\n b.disabled = isCur\n const name = document.createElement('span')\n name.className = 'dsm-sub-name'\n name.textContent = w.title || pathName(w.path) || w.workspaceId\n b.appendChild(name)\n if (isCur) {\n const c = document.createElement('span')\n c.className = 'dsm-sub-cur'\n c.textContent = '\u5F53\u524D'\n b.appendChild(c)\n }\n b.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n closeSub()\n closeMenu()\n postJSON('/archived-sessions/move', { sessionId: info.id, targetPath: w.path })\n .then(() => toast('\u79FB\u52A8\u6210\u529F'))\n .catch((ee) => toast('\u79FB\u52A8\u5931\u8D25\uFF1A' + String((ee && ee.message) || ee)))\n })\n sub.appendChild(b)\n })\n }).catch((e) => {\n sub.innerHTML = '<div class=\"dsm-sub-err\">' + escapeHtml(String((e && e.message) || e)) + '</div>'\n })\n }\n const openDeleteConfirm = (id) => {\n ensureStyle()\n const backdrop = document.createElement('div')\n backdrop.className = 'dsm-backdrop'\n const dlg = document.createElement('div')\n dlg.className = 'dsm-dlg'\n dlg.innerHTML = '<h3 class=\"dsm-title\">\u5220\u9664\u4F1A\u8BDD</h3><p class=\"dsm-text\">\u786E\u8BA4\u5C06\u8BE5\u4F1A\u8BDD\u79FB\u5165\u56DE\u6536\u7AD9\uFF1F\u53EF\u5728\u300C\u8BBE\u7F6E \u2192 \u4F1A\u8BDD\u7BA1\u7406 \u2192 \u56DE\u6536\u7AD9\u300D\u4E2D\u6062\u590D\u6216\u5F7B\u5E95\u5220\u9664\u3002</p><div class=\"dsm-actions\"><button type=\"button\" class=\"dsm-btn\" data-role=\"cancel\">\u53D6\u6D88</button><button type=\"button\" class=\"dsm-btn dsm-del\" data-role=\"ok\">\u79FB\u5165\u56DE\u6536\u7AD9</button></div>'\n backdrop.appendChild(dlg)\n document.body.appendChild(backdrop)\n const close = () => backdrop.remove()\n backdrop.addEventListener('click', (e) => { if (e.target === backdrop) close() })\n dlg.querySelector('[data-role=cancel]').addEventListener('click', close)\n dlg.querySelector('[data-role=ok]').addEventListener('click', () => {\n close()\n postJSON('/archived-sessions/delete', { sessionId: id })\n .then(() => {\n if (dsmTrashIds) dsmTrashIds.add(String(id))\n if (dsmRepaintDots) dsmRepaintDots()\n toast('\u5DF2\u79FB\u5165\u56DE\u6536\u7AD9')\n })\n .catch((e) => toast('\u5220\u9664\u5931\u8D25\uFF1A' + String((e && e.message) || e)))\n })\n }\n const augmentMenu = (menuEl, info) => {\n if (menuEl.querySelector('[' + AUG + ']')) return\n const viewport = menuEl.querySelector('[role=\"presentation\"]') || menuEl.firstElementChild\n if (!viewport) return\n const proto = menuEl.querySelector('[role=\"menuitem\"]')\n if (!proto) return\n const protoWrap = proto.parentElement\n const protoCls = proto.className\n const protoWrapCls = protoWrap ? protoWrap.className : ''\n const ICON_MOVE = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"/><path d=\"M12 11v4\"/><path d=\"M10 13l2 2 2-2\"/></svg>'\n const ICON_DEL = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 7h16\"/><path d=\"M10 11v6\"/><path d=\"M14 11v6\"/><path d=\"M6 7l1 13a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1l1-13\"/><path d=\"M9 7V4h6v3\"/></svg>'\n const ICON_UNREAD = '<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"8\"/><circle cx=\"12\" cy=\"12\" r=\"3\" fill=\"currentColor\" stroke=\"none\"/></svg>'\n const mk = (label, svg, danger) => {\n const wrap = protoWrap ? protoWrap.cloneNode(false) : document.createElement('div')\n if (protoWrapCls) wrap.className = protoWrapCls\n const btn = document.createElement('button')\n btn.type = 'button'\n btn.setAttribute('role', 'menuitem')\n btn.className = protoCls // same `.item` class DSH uses \u2192 identical layout/alignment\n const icon = document.createElement('span')\n icon.style.cssText = 'display:inline-flex;flex:none;width:16px;height:16px;align-items:center;justify-content:center;color:' + (danger ? 'var(--dsw-alias-state-error-primary)' : 'var(--dsw-alias-label-tertiary)')\n icon.innerHTML = svg\n const lab = document.createElement('span')\n lab.style.cssText = 'flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap'\n lab.textContent = label\n btn.appendChild(icon)\n btn.appendChild(lab)\n if (danger) btn.style.color = 'var(--dsw-alias-state-error-primary)'\n btn.setAttribute(AUG, '')\n wrap.appendChild(btn)\n return { wrap, btn }\n }\n const move = mk('\u79FB\u52A8\u4F1A\u8BDD', ICON_MOVE, false)\n const del = mk('\u5220\u9664\u4F1A\u8BDD', ICON_DEL, true)\n const mark = mk(dsmLoadManual().has(info.id) ? '\u6807\u8BB0\u5DF2\u8BFB' : '\u6807\u8BB0\u672A\u8BFB', ICON_UNREAD, false)\n if (mark.btn.firstChild) mark.btn.firstChild.style.color = 'var(--dsw-alias-state-business-primary)'\n const chev = document.createElement('span')\n chev.style.cssText = 'margin-left:auto;flex:none;color:var(--dsw-alias-label-tertiary);font-size:14px;line-height:1'\n chev.textContent = '\u203A'\n move.btn.appendChild(chev)\n move.btn.addEventListener('mouseenter', () => {\n if (!document.querySelector('[data-dsm-sub]')) openMoveSubmenu(move.btn, info)\n })\n move.btn.addEventListener('mouseleave', () => {\n hoverTimer = setTimeout(() => closeMoveSubmenu(), 160)\n })\n move.btn.addEventListener('click', (e) => { e.stopPropagation(); e.preventDefault() })\n del.btn.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n closeMoveSubmenu()\n openDeleteConfirm(info.id)\n })\n mark.btn.addEventListener('click', (e) => {\n e.stopPropagation()\n e.preventDefault()\n closeMoveSubmenu()\n dsmToggleManual(info.id)\n closeMenu()\n })\n viewport.appendChild(move.wrap)\n viewport.appendChild(del.wrap)\n // \u6807\u8BB0\u672A\u8BFB goes to the very top of the menu (above DSH's native items).\n viewport.insertBefore(mark.wrap, viewport.firstElementChild)\n }\n\n const seen = new WeakSet()\n const obs = new MutationObserver(() => {\n const menus = document.querySelectorAll('body > [role=\"menu\"]')\n menus.forEach((menuEl) => {\n if (seen.has(menuEl)) return\n const info = sessionInfoFromMenu(menuEl)\n if (!info) return // not a session menu (e.g. settings / header dropdown)\n seen.add(menuEl)\n try { augmentMenu(menuEl, info) } catch (e) { /* best-effort DOM shim */ }\n })\n })\n obs.observe(document.body, { childList: true, subtree: false })\n}\n\n// Left-side per-session status dot (DOM shim). The color is driven by DSH's\n// REAL session status, read from the row's own StateDot ([data-state]):\n// \u624B\u52A8\u6807\u8BB0\u672A\u8BFB\uFF08\u84DD\uFF09 = \u7528\u6237\u5728 \u22EF \u83DC\u5355\u6216\u70B9\u51FB\u5706\u70B9\u624B\u52A8\u6807\u8BB0\uFF0ClocalStorage \u6301\u4E45\u5316\uFF08\u6700\u9AD8\u4F18\u5148\u7EA7\uFF09\n// \u5DE5\u4F5C\u4E2D\uFF08\u9EC4\uFF09 = DSH state 'running'\n// \u9700\u7528\u6237\u53CD\u9988\uFF08\u7425\u73C0\uFF09 = DSH state 'warning'\uFF08\u6709\u8FFD\u95EE\u9700\u7528\u6237\u53CD\u9988\uFF09\n// \u5B8C\u6210\u540E\u672A\u8BFB\uFF08\u7EFF\uFF09 = DSH state 'done' \u4E14\u7528\u6237\u5C1A\u672A\u8BFB\u8FC7\uFF08read \u96C6\u5408\uFF09\n// \u5B8C\u6210\u5DF2\u8BFB\uFF08\u4E0D\u663E\u793A\uFF09 = DSH state 'done' \u4E14\u5DF2\u8BFB\u8FC7\uFF08read \u96C6\u5408\u6301\u4E45\u5316\uFF09\n// \u624B\u52A8\u672A\u8BFB\u96C6\u5408 + read \u96C6\u5408\u5747\u6301\u4E45\u5316\u4E8E localStorage\uFF1B\u6253\u5F00\u8FC7\u5373\u8BB0\u5165 read\uFF0C\u7EFF\u70B9\u4E0D\u518D\u51FA\u73B0\u3002\n// \u53E6\u5916\uFF1A\u8FDB\u5165\u56DE\u6536\u7AD9\u7684\u4F1A\u8BDD\u4F1A\u6574\u884C\u9690\u85CF\uFF08\u4E0D\u51FA\u73B0\u5728\u300C\u672A\u5206\u7EC4\u300D\u91CC\uFF09\u3002\nfunction installSidebarStatusDots() {\n if (typeof document === 'undefined') return\n const DOT = 'data-dsm-dot'\n if (!document.querySelector('style[data-dsm=aug]')) {\n const s = document.createElement('style')\n s.dataset.dsm = 'aug'\n s.textContent = SIDEBAR_AUG_CSS\n document.head.appendChild(s)\n }\n const findFiber = (el) => {\n const k = Object.keys(el).find((kk) => kk.startsWith('__reactFiber') || kk.startsWith('__reactInternalInstance'))\n return k ? el[k] : null\n }\n const fiberProp = (el, pred) => {\n let f = findFiber(el)\n let g = 0\n while (f && g++ < 300) {\n const p = f.memoizedProps\n if (p && pred(p)) return pred(p)\n f = f.return\n }\n return null\n }\n const rowNode = (row) => fiberProp(row, (p) => (p.node && typeof p.node.id === 'string' && p.node.id ? p.node : null))\n const rowId = (row) => { const node = rowNode(row); return node ? node.id : null }\n let curActive = null\n const activeRowId = () => {\n const sel = document.querySelector('[role=\"treeitem\"][aria-selected=\"true\"]')\n return sel ? rowId(sel) : null\n }\n // Dot colors per the user's scheme. We read DSH's REAL session status from the\n // row's own StateDot (its [data-state] attr) and recolor it:\n // running \u2192 \u9EC4 \u5DE5\u4F5C\u4E2D\n // warning \u2192 \u7425\u73C0 \u6709\u8FFD\u95EE\u9700\u7528\u6237\u53CD\u9988\n // done \u2192 \u7EFF \u5B8C\u6210\u540E\u672A\u8BFB\uFF08\u8BFB\u8FC7\u5219\u4E0D\u518D\u663E\u793A\uFF09\n // error \u2192 \u7EA2 \u51FA\u9519/\u9700\u5173\u6CE8\uFF08\u4E0E DSH \u81EA\u5E26 StateDot \u4E00\u81F4\uFF09\n // (manual \u2192 \u84DD \u624B\u52A8\u6807\u8BB0\u672A\u8BFB\uFF0C\u6700\u9AD8\u4F18\u5148\u7EA7)\n const COLOR = {\n manual: 'var(--dsw-alias-state-business-primary)', // \u84DD \u624B\u52A8\u6807\u8BB0\u672A\u8BFB\n running: '#EAB308', // \u9EC4 \u5DE5\u4F5C\u4E2D (DSH running)\n feedback: 'var(--dsw-alias-state-warning-primary)', // \u7425\u73C0 \u9700\u7528\u6237\u53CD\u9988 (DSH warning)\n done: 'var(--dsw-alias-state-success-primary)', // \u7EFF \u5B8C\u6210\u540E\u672A\u8BFB (DSH done)\n error: 'var(--dsw-alias-state-error-primary)', // \u7EA2 \u51FA\u9519/\u9700\u5173\u6CE8 (DSH error)\n }\n const manualUnread = dsmLoadManual()\n const paint = () => {\n // Recompute the active session on every paint so the active row is never\n // shown from a stale `curActive` (the click that changes aria-selected\n // mutates the DOM and triggers paint immediately, before the 1.2s tick()\n // would have run \u2014 without this, the clicked session flashed green).\n const activeId = activeRowId()\n // Clicking into a manually-marked session auto-clears the manual unread\n // flag (it becomes read on open) \u2014 only on the active transition, so a\n // flag set while already viewing it isn't wiped until you re-enter it.\n if (activeId !== curActive && activeId && manualUnread.has(activeId)) {\n manualUnread.delete(activeId)\n dsmSaveManual()\n }\n curActive = activeId\n const rows = document.querySelectorAll('[role=\"treeitem\"]')\n rows.forEach((row) => {\n const id = rowId(row)\n if (!id) return\n // Trashed sessions belong in \u56DE\u6536\u7AD9, not the sidebar (DSH would group\n // them under \"\u672A\u5206\u7EC4\"). Hide the row entirely and skip its dot. So do\n // hard-purged sessions \u2014 they're gone for good and must never resurface\n // (otherwise DSH re-renders the orphan under a \"\u672A\u5206\u7EC4\" group).\n const purged = dsmLoadPurged()\n if ((dsmTrashIds && dsmTrashIds.has(id)) || purged.has(id)) {\n if (row.style.display !== 'none') row.style.display = 'none'\n const d = row.querySelector('[' + DOT + ']'); if (d) d.remove()\n return\n }\n if (row.style.display === 'none') row.style.display = ''\n // DSH's cold list baseline can expose a stale header title until the\n // Session is opened. Paint the latest log-folded title from the host\n // authority without materializing the Session or changing its log.\n const authoritativeTitle = dsmAuthoritativeTitles.get(id)\n if (authoritativeTitle) {\n const node = rowNode(row) || {}\n const expected = new Set([node.title, node.displayTitle, node.name].filter((value) => typeof value === 'string'))\n const spans = [...row.children].filter((el) => el.tagName === 'SPAN' && !el.querySelector('[data-state]') && (el.textContent || '').trim())\n const titleEl = spans.find((el) => expected.has((el.textContent || '').trim())) || spans[0]\n if (titleEl && titleEl.textContent !== authoritativeTitle) titleEl.textContent = authoritativeTitle\n }\n // Read DSH's REAL session status from the row's own StateDot and recolor\n // it with the user's scheme (we also hide DSH's dot so only ours shows).\n const sd = row.querySelector('[data-state]')\n if (sd) sd.style.display = 'none'\n let dot = row.querySelector('[' + DOT + ']')\n const state = dotStateFor({ manualUnread: manualUnread.has(id), dataState: sd ? sd.getAttribute('data-state') : '', isActive: activeId === id })\n const color = state ? COLOR[state] : null\n if (!color) { if (dot) dot.remove(); return }\n if (!dot) {\n dot = document.createElement('span')\n dot.setAttribute(DOT, '')\n dot.className = 'dsm-dot'\n if (!row.hasAttribute('data-dsm-pos')) {\n if (getComputedStyle(row).position === 'static') row.style.position = 'relative'\n row.setAttribute('data-dsm-pos', '')\n }\n dot.addEventListener('click', (e) => {\n e.stopPropagation(); e.preventDefault()\n dsmToggleManual(id)\n })\n row.insertBefore(dot, row.firstChild)\n }\n dot.style.background = color\n })\n }\n dsmRepaintDots = paint\n const tick = () => { if (++dsmTrashTick % 8 === 0) dsmLoadTrashIds(); paint() }\n let raf = 0\n const schedulePaint = () => { if (raf) return; raf = requestAnimationFrame(() => { raf = 0; paint() }) }\n tick()\n dsmLoadTrashIds()\n paint()\n const obs = new MutationObserver(schedulePaint)\n obs.observe(document.body, { childList: true, subtree: true })\n setInterval(tick, 1200)\n}\n\n// Cross-workspace drag/drop for the native DSH sidebar. DSH does not expose a\n// sidebar-row plugin slot, so the adapter discovers session/workspace rows from\n// their React fiber nodes, while the actual move remains entirely host-owned.\n// The existing \u201C\u79FB\u52A8\u4F1A\u8BDD\u201D menu is also the keyboard-accessible fallback.\nfunction installSidebarWorkspaceDrag() {\n if (typeof document === 'undefined') return\n let sessions = new Map()\n let dragging = null\n let moving = false\n\n const findFiber = (el) => {\n const key = Object.keys(el).find((k) => k.startsWith('__reactFiber') || k.startsWith('__reactInternalInstance'))\n return key ? el[key] : null\n }\n const fiberNodes = (el) => {\n const out = []\n let fiber = findFiber(el)\n let guard = 0\n while (fiber && guard++ < 300) {\n const props = fiber.memoizedProps\n if (props && props.node && typeof props.node === 'object') out.push(props.node)\n // DSH's SessionNodeItem receives `node`, while ProjectRowItem (the\n // workspace heading) receives `group`. Without the latter every session\n // can start dragging but no workspace can ever become a valid drop zone.\n if (props && props.group && typeof props.group === 'object') out.push(props.group)\n fiber = fiber.return\n }\n return out\n }\n const sessionForRow = (row) => sessionForNodes(fiberNodes(row), sessions)\n const workspaceForRow = (row) => {\n // A session row's fiber chain also contains its parent workspace node.\n // Reject it explicitly so only the visible workspace header is a drop zone.\n if (sessionForRow(row)) return null\n return workspaceForNodes(fiberNodes(row))\n }\n const eventRow = (event) => {\n for (const item of event.composedPath ? event.composedPath() : []) {\n if (item instanceof Element && item.getAttribute('role') === 'treeitem') return item\n }\n return event.target instanceof Element ? event.target.closest('[role=\"treeitem\"]') : null\n }\n const toast = (message) => {\n const el = document.createElement('div')\n el.className = 'dsm-toast'\n el.setAttribute('role', 'status')\n el.textContent = message\n document.body.appendChild(el)\n setTimeout(() => el.remove(), 2600)\n }\n const clearVisuals = () => {\n document.querySelectorAll('.dsm-drag-source,.dsm-drop-target').forEach((el) => el.classList.remove('dsm-drag-source', 'dsm-drop-target'))\n }\n const decorateRows = () => {\n document.querySelectorAll('[role=\"treeitem\"]').forEach((row) => {\n const session = sessionForRow(row)\n const ws = workspaceForRow(row)\n if (session) {\n row.setAttribute('aria-description', '\u53EF\u62D6\u52A8\u5230\u5176\u4ED6\u5DE5\u4F5C\u533A\uFF1B\u952E\u76D8\u7528\u6237\u53EF\u901A\u8FC7\u66F4\u591A\u83DC\u5355\u4E2D\u7684\u79FB\u52A8\u4F1A\u8BDD\u64CD\u4F5C')\n }\n if (ws) row.setAttribute('data-dsm-workspace-drop', '')\n })\n }\n const refresh = async () => {\n try {\n const sessionResult = await postJSON('/archived-sessions/sessions', {})\n sessions = new Map((sessionResult.items || []).map((item) => [String(item.sessionId), item]))\n decorateRows()\n } catch (e) { /* sidebar enhancement remains optional */ }\n }\n\n // Capture before DSH's delegated React handlers. DSH reserves the same\n // native drag gesture for reordering sessions inside one group; only a real\n // workspace-heading target is intercepted here, so same-group sorting keeps\n // its official behavior.\n document.addEventListener('dragstart', (event) => {\n const row = eventRow(event)\n const item = row && sessionForRow(row)\n if (!item || moving) return\n dragging = item\n row.classList.add('dsm-drag-source')\n }, true)\n document.addEventListener('dragover', (event) => {\n const row = eventRow(event)\n const target = row && workspaceForRow(row)\n if (!dragging || !target || moving) return\n if (!canDropOnWorkspace(dragging, target)) return\n event.preventDefault()\n event.stopPropagation()\n if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'\n document.querySelectorAll('.dsm-drop-target').forEach((el) => { if (el !== row) el.classList.remove('dsm-drop-target') })\n row.classList.add('dsm-drop-target')\n }, true)\n document.addEventListener('drop', async (event) => {\n const row = eventRow(event)\n const item = dragging\n const target = row && workspaceForRow(row)\n if (!item || !target || moving || !canDropOnWorkspace(item, target)) return\n event.preventDefault()\n event.stopPropagation()\n moving = true\n clearVisuals()\n row.classList.add('dsm-drag-busy')\n try {\n const result = await postJSON('/archived-sessions/move', { sessionId: item.sessionId, targetPath: target.path })\n sessions.set(item.sessionId, { ...item, workspacePath: result.workspacePath || target.path, workspaceTitle: result.workspaceTitle || target.title })\n await dsmLoadTrashIds()\n toast(`\u5DF2\u79FB\u5230\u300C${result.workspaceTitle || target.title}\u300D`)\n } catch (error) {\n toast('\u79FB\u52A8\u5931\u8D25\uFF1A' + String((error && error.message) || error))\n } finally {\n moving = false\n dragging = null\n row.classList.remove('dsm-drag-busy')\n decorateRows()\n }\n }, true)\n document.addEventListener('dragend', () => {\n dragging = null\n clearVisuals()\n }, true)\n\n let decorateTimer = null\n const scheduleDecorate = () => {\n if (decorateTimer) return\n decorateTimer = requestAnimationFrame(() => { decorateTimer = null; decorateRows() })\n }\n refresh()\n const observer = new MutationObserver(scheduleDecorate)\n observer.observe(document.body, { childList: true, subtree: true })\n setInterval(refresh, 5000)\n}\n\nexport function apply(ctx) {\n installSettingsNavIcons(ctx)\n installSidebarSessionMenuAug()\n installSidebarStatusDots()\n installSidebarWorkspaceDrag()\n const workspacesSvc = ctx.get('workspaces')\n ctx.slots.inject('settings.section', () =>\n ctx.slots.register(\n { name: 'settings.section', id: 'session-manager', order: 90, label: '\u4F1A\u8BDD\u7BA1\u7406' },\n (props) => <SessionPanel {...props} workspacesSvc={workspacesSvc} />,\n ),\n )\n}\n", "// dsh-sessions-manager \u2014 client \u7EAF\u5224\u5B9A\u903B\u8F91\u3002\n//\n// \u4FA7\u680F\u589E\u5F3A\u91CC\u6700\u5BB9\u6613\u968F DSH \u4E0A\u6E38\u53D8\u5316\u51FA\u56DE\u5F52\u7684\u4E09\u5757\u5224\u5B9A\u62BD\u5230\u8FD9\u91CC\uFF1A\n// \u72B6\u6001\u70B9\u8BED\u4E49\u3001\u62D6\u62FD\u53EF\u653E\u7F6E\u6821\u9A8C\u3001fiber node \u2192 \u4F1A\u8BDD/\u5DE5\u4F5C\u533A\u8BC6\u522B\u3002\n// \u672C\u6A21\u5757\u4E0D\u78B0 DOM\uFF0Cnode --test \u76F4\u63A5\u53EF\u6D4B\uFF08tests/client-logic.test.js\uFF09\u3002\n\n// \u72B6\u6001\u70B9\u8BED\u4E49\uFF1Amanual \u672A\u8BFB\u6700\u9AD8\u4F18\u5148\uFF1Bdone \u5728\u5F53\u524D\u67E5\u770B\u7684\u884C\u4E0A\u4E0D\u4EAE\u7EFF\n// \uFF08\u8BFB\u8FC7\u5373\u89C6\u4E3A\u5DF2\u8BFB\uFF09\u3002\u8FD4\u56DE\u903B\u8F91\u6001\u540D\uFF0C\u989C\u8272\u6620\u5C04\u7559\u5728 UI \u5C42\u3002\n// \u5386\u53F2\u56DE\u5F52\uFF1ADSH \u66FE\u628A running \u62A5\u4E3A ongoing\uFF089766476\uFF09\uFF0C\u4E0A\u6E38\u679A\u4E3E\u53D8\u5316\u8981\u76EF\u8FD9\u91CC\u3002\nexport function dotStateFor({ manualUnread = false, dataState = '', isActive = false } = {}) {\n if (manualUnread) return 'manual'\n switch (dataState) {\n case 'running': return 'running'\n case 'warning': return 'feedback'\n case 'error': return 'error'\n case 'done': return isActive ? null : 'done'\n default: return null\n }\n}\n\n// \u62D6\u62FD\u8FC1\u79FB\u524D\u7F6E\u6821\u9A8C\uFF1A\u540C\u5DE5\u4F5C\u533A\u62E6\u622A\uFF08workspacePath \u76F8\u7B49\u5373\u62D2\u7EDD\uFF09\u3002\n// \u65E0 workspacePath \u7684\u4F1A\u8BDD\uFF08\u5982\u4FA7\u680F live \u884C\u5C1A\u672A\u540C\u6B65\uFF09\u653E\u884C\uFF0C\u7531 host \u6700\u7EC8\u88C1\u51B3\u3002\nexport function canDropOnWorkspace(item, target) {\n if (!item || !target) return false\n if (item.workspacePath && target.path === item.workspacePath) return false\n return true\n}\n\n// \u4ECE React fiber \u94FE\u6536\u96C6\u5230\u7684 node \u6570\u7EC4\u8BC6\u522B\u4F1A\u8BDD\u884C\u3002knownSessions \u662F\n// host /archived-sessions/sessions \u7684\u6743\u5A01\u8868\uFF1Blive \u884C\uFF08\u8FD8\u6CA1\u540C\u6B65\u5230\u6743\u5A01\u8868\uFF09\n// \u7528\u542F\u53D1\u5F0F\u515C\u5E95\uFF1A\u6709 id\u3001\u4E0D\u662F\u5DE5\u4F5C\u533A\u5206\u7EC4\uFF08\u65E0 workspaceId\uFF09\u3001\u4E14\u5E26\u6807\u9898/\u65F6\u95F4\u3002\nexport function sessionForNodes(nodes, knownSessions) {\n for (const node of nodes || []) {\n const id = node && node.id != null ? String(node.id) : ''\n if (knownSessions.has(id)) return knownSessions.get(id)\n // DSH \u7684\u884C\u8282\u70B9\u6709 id\uFF1B\u5DE5\u4F5C\u533A\u5206\u7EC4\u7528 workspaceId\u3001\u4ECE\u4E0D\u7528\u88F8 id\u3002\n if (id && node.workspaceId == null && (node.title != null || node.updatedAt != null || node.blank != null)) {\n return { sessionId: id, title: node.title || '', workspacePath: null }\n }\n }\n return null\n}\n\n// \u4ECE fiber node \u6570\u7EC4\u8BC6\u522B\u53EF\u89C1\u7684\u5DE5\u4F5C\u533A\u6807\u9898\u884C\uFF08\u53EF\u653E\u7F6E\u76EE\u6807\uFF09\u3002\n// \u4F1A\u8BDD\u884C\u7684 fiber \u94FE\u4E5F\u4F1A\u5E26\u51FA\u7236\u5DE5\u4F5C\u533A\u8282\u70B9\uFF0C\u8C03\u7528\u65B9\u987B\u5148\u7528 sessionForNodes \u62E6\u622A\u3002\nexport function workspaceForNodes(nodes) {\n for (const group of nodes || []) {\n if (group && group.workspaceId != null && typeof group.cwd === 'string' && group.cwd) {\n return { workspaceId: String(group.workspaceId), path: group.cwd, title: group.label || group.cwd }\n }\n }\n return null\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-sessions-manager",
3
3
  "description": "DSH 设置面板会话管理器:归档 / 恢复 / 彻底删除 / 移动到其他工作区,带工作区标签与会话日期;统一「会话管理」面板。Session manager for the DeepSeek Harness settings panel — archive / restore / permanently delete / move sessions across workspaces, with workspace tags & session dates in one unified panel.",
4
- "version": "3.2.1",
4
+ "version": "3.2.2",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import React, { useEffect, useMemo, useRef, useState } from 'react'
14
+ import { canDropOnWorkspace, dotStateFor, sessionForNodes, workspaceForNodes } from './logic.js'
14
15
 
15
16
  export const inject = ['slots']
16
17
 
@@ -1263,15 +1264,8 @@ function installSidebarStatusDots() {
1263
1264
  const sd = row.querySelector('[data-state]')
1264
1265
  if (sd) sd.style.display = 'none'
1265
1266
  let dot = row.querySelector('[' + DOT + ']')
1266
- let color = null
1267
- if (manualUnread.has(id)) color = COLOR.manual
1268
- else if (sd) {
1269
- const st = sd.getAttribute('data-state')
1270
- if (st === 'running') color = COLOR.running
1271
- else if (st === 'warning') color = COLOR.feedback
1272
- else if (st === 'error') color = COLOR.error
1273
- else if (st === 'done') color = (activeId === id) ? null : COLOR.done
1274
- }
1267
+ const state = dotStateFor({ manualUnread: manualUnread.has(id), dataState: sd ? sd.getAttribute('data-state') : '', isActive: activeId === id })
1268
+ const color = state ? COLOR[state] : null
1275
1269
  if (!color) { if (dot) dot.remove(); return }
1276
1270
  if (!dot) {
1277
1271
  dot = document.createElement('span')
@@ -1331,28 +1325,12 @@ function installSidebarWorkspaceDrag() {
1331
1325
  }
1332
1326
  return out
1333
1327
  }
1334
- const sessionForRow = (row) => {
1335
- for (const node of fiberNodes(row)) {
1336
- const id = node && node.id != null ? String(node.id) : ''
1337
- if (sessions.has(id)) return sessions.get(id)
1338
- // The live DSH row is authoritative even before the async sidebar-state
1339
- // refresh finishes. Workspace groups use `workspaceId`, never `id`.
1340
- if (id && node.workspaceId == null && (node.title != null || node.updatedAt != null || node.blank != null)) {
1341
- return { sessionId: id, title: node.title || '', workspacePath: null }
1342
- }
1343
- }
1344
- return null
1345
- }
1328
+ const sessionForRow = (row) => sessionForNodes(fiberNodes(row), sessions)
1346
1329
  const workspaceForRow = (row) => {
1347
1330
  // A session row's fiber chain also contains its parent workspace node.
1348
1331
  // Reject it explicitly so only the visible workspace header is a drop zone.
1349
1332
  if (sessionForRow(row)) return null
1350
- for (const group of fiberNodes(row)) {
1351
- if (group.workspaceId != null && typeof group.cwd === 'string' && group.cwd) {
1352
- return { workspaceId: String(group.workspaceId), path: group.cwd, title: group.label || group.cwd }
1353
- }
1354
- }
1355
- return null
1333
+ return workspaceForNodes(fiberNodes(row))
1356
1334
  }
1357
1335
  const eventRow = (event) => {
1358
1336
  for (const item of event.composedPath ? event.composedPath() : []) {
@@ -1404,7 +1382,7 @@ function installSidebarWorkspaceDrag() {
1404
1382
  const row = eventRow(event)
1405
1383
  const target = row && workspaceForRow(row)
1406
1384
  if (!dragging || !target || moving) return
1407
- if (dragging.workspacePath && target.path === dragging.workspacePath) return
1385
+ if (!canDropOnWorkspace(dragging, target)) return
1408
1386
  event.preventDefault()
1409
1387
  event.stopPropagation()
1410
1388
  if (event.dataTransfer) event.dataTransfer.dropEffect = 'move'
@@ -1415,7 +1393,7 @@ function installSidebarWorkspaceDrag() {
1415
1393
  const row = eventRow(event)
1416
1394
  const item = dragging
1417
1395
  const target = row && workspaceForRow(row)
1418
- if (!item || !target || moving || (item.workspacePath && target.path === item.workspacePath)) return
1396
+ if (!item || !target || moving || !canDropOnWorkspace(item, target)) return
1419
1397
  event.preventDefault()
1420
1398
  event.stopPropagation()
1421
1399
  moving = true
@@ -0,0 +1,53 @@
1
+ // dsh-sessions-manager — client 纯判定逻辑。
2
+ //
3
+ // 侧栏增强里最容易随 DSH 上游变化出回归的三块判定抽到这里:
4
+ // 状态点语义、拖拽可放置校验、fiber node → 会话/工作区识别。
5
+ // 本模块不碰 DOM,node --test 直接可测(tests/client-logic.test.js)。
6
+
7
+ // 状态点语义:manual 未读最高优先;done 在当前查看的行上不亮绿
8
+ // (读过即视为已读)。返回逻辑态名,颜色映射留在 UI 层。
9
+ // 历史回归:DSH 曾把 running 报为 ongoing(9766476),上游枚举变化要盯这里。
10
+ export function dotStateFor({ manualUnread = false, dataState = '', isActive = false } = {}) {
11
+ if (manualUnread) return 'manual'
12
+ switch (dataState) {
13
+ case 'running': return 'running'
14
+ case 'warning': return 'feedback'
15
+ case 'error': return 'error'
16
+ case 'done': return isActive ? null : 'done'
17
+ default: return null
18
+ }
19
+ }
20
+
21
+ // 拖拽迁移前置校验:同工作区拦截(workspacePath 相等即拒绝)。
22
+ // 无 workspacePath 的会话(如侧栏 live 行尚未同步)放行,由 host 最终裁决。
23
+ export function canDropOnWorkspace(item, target) {
24
+ if (!item || !target) return false
25
+ if (item.workspacePath && target.path === item.workspacePath) return false
26
+ return true
27
+ }
28
+
29
+ // 从 React fiber 链收集到的 node 数组识别会话行。knownSessions 是
30
+ // host /archived-sessions/sessions 的权威表;live 行(还没同步到权威表)
31
+ // 用启发式兜底:有 id、不是工作区分组(无 workspaceId)、且带标题/时间。
32
+ export function sessionForNodes(nodes, knownSessions) {
33
+ for (const node of nodes || []) {
34
+ const id = node && node.id != null ? String(node.id) : ''
35
+ if (knownSessions.has(id)) return knownSessions.get(id)
36
+ // DSH 的行节点有 id;工作区分组用 workspaceId、从不用裸 id。
37
+ if (id && node.workspaceId == null && (node.title != null || node.updatedAt != null || node.blank != null)) {
38
+ return { sessionId: id, title: node.title || '', workspacePath: null }
39
+ }
40
+ }
41
+ return null
42
+ }
43
+
44
+ // 从 fiber node 数组识别可见的工作区标题行(可放置目标)。
45
+ // 会话行的 fiber 链也会带出父工作区节点,调用方须先用 sessionForNodes 拦截。
46
+ export function workspaceForNodes(nodes) {
47
+ for (const group of nodes || []) {
48
+ if (group && group.workspaceId != null && typeof group.cwd === 'string' && group.cwd) {
49
+ return { workspaceId: String(group.workspaceId), path: group.cwd, title: group.label || group.cwd }
50
+ }
51
+ }
52
+ return null
53
+ }