dsh-subagent-workspace-ui 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -2
- package/README.zh.md +18 -10
- package/lib/client.js +130 -100
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -53,7 +53,17 @@ A full persistent workspace-wide archive view requires a host-side catalog RPC (
|
|
|
53
53
|
|
|
54
54
|
## Compatibility
|
|
55
55
|
|
|
56
|
-
v1.
|
|
56
|
+
v1.4.0 supports dsh **0.1.5-rc.2** and stays backward compatible with all DeepSeek Harness versions: the 0.1.2-series capability-detection paths (live output via `binding.eventSource`, chat-tab switch via slot `actions`) remain the primary branches, and the **0.1.1-rc.2** legacy fallbacks (`chat.legacy` snapshot) are unchanged.
|
|
57
|
+
|
|
58
|
+
## v1.4.0
|
|
59
|
+
|
|
60
|
+
- **Compatibility**: supports DeepSeek Harness **0.1.5-rc.2**, backward compatible with all dsh versions. 0.1.5-rc.2 changed the conversation view structure (the slot renderer no longer injects store `actions` into entries that do not declare a store, and the selected view is now persisted per session, with new tabs such as Trajectory) — clicking a subagent lands back on the Chat tab again (when `actions` is unavailable the plugin clicks the host's own Chat tab, preserving the host's activation and persistence semantics). The 0.1.2 capability-detection path remains the untouched primary branch and the 0.1.1 legacy fallback is unchanged.
|
|
61
|
+
- **TypeScript migration**: `src/client/*.ts` is now the single source of truth and `lib/client.js` is generated by `pnpm run build` (sucrase type erasure + deterministic linker) instead of being hand-written. New tooling: `verify-build` (token/line-level diff against the v1.3.4 hand-written golden — migration equivalence proof and delta viewer for intentional changes) and `verify-fresh` (stale-bundle gate); `pnpm run check` runs build + typecheck + syntax + freshness in one shot.
|
|
62
|
+
- **Fix**: a latent `scopeKey` ReferenceError in the collapsed filter summary (found during the TypeScript migration) is corrected to `workspaceKey`.
|
|
63
|
+
|
|
64
|
+
## v1.3.4
|
|
65
|
+
|
|
66
|
+
- **Feature**: the whole UI is localized through DSH client-locale (zh/en, AI-assisted English strings). Labels, buttons, stats, live output (context injection / thinking / tool details) and confirm dialogs now use translation keys and follow the host language. Contributed by [@Marcuss2](https://github.com/Marcuss2) in [PR #1](https://github.com/miuzel/dsh-subagent-ui/pull/1) — thank you!
|
|
57
67
|
|
|
58
68
|
## v1.3.3
|
|
59
69
|
|
|
@@ -70,10 +80,16 @@ v1.3.1 is compatible with dsh **0.1.2-alpha.2** (new `binding.eventSource` live-
|
|
|
70
80
|
|
|
71
81
|
## Validation
|
|
72
82
|
|
|
83
|
+
The client bundle `lib/client.js` is **generated from the TypeScript sources** in [`src/client/`](src/client/) — edit those, never the bundle, then rebuild:
|
|
84
|
+
|
|
73
85
|
```bash
|
|
74
|
-
pnpm
|
|
86
|
+
pnpm install # dev deps: sucrase + typescript
|
|
87
|
+
pnpm run build # scripts/build.mjs -> lib/client.js
|
|
88
|
+
pnpm run check # build + tsc --noEmit + node --check lib/index.js + bundle freshness gate
|
|
75
89
|
```
|
|
76
90
|
|
|
91
|
+
`pnpm run verify:build` compares the generated bundle with the hand-written pre-refactor bundle (git ref `v1.3.4`) up to insignificant whitespace, using token-level and line-level comparison. After the migration it doubles as a delta viewer that prints the exact differences of any intentional change.
|
|
92
|
+
|
|
77
93
|
Smoke-test a specific dsh version:
|
|
78
94
|
|
|
79
95
|
```bash
|
|
@@ -83,5 +99,6 @@ DSH_VERSION=0.1.1-rc.2 ./test.sh # pnpx @deepseek-ai/dsh@0.1.1-rc.
|
|
|
83
99
|
|
|
84
100
|
## Acknowledgements
|
|
85
101
|
|
|
102
|
+
- UI localization (zh/en) contributed by [@Marcuss2](https://github.com/Marcuss2) via [PR #1](https://github.com/miuzel/dsh-subagent-ui/pull/1) — many thanks!
|
|
86
103
|
- Subagent permanent deletion and session cleanup design inspired by and referencing [@heiheiha798/dsh-plugin-subagent-delete](https://github.com/heiheiha798/dsh-plugin-subagent-delete).
|
|
87
104
|
|
package/README.zh.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
面向 DeepSeek Harness Web 的子代理管理插件。插件在会话标题栏提供一个紧凑的 `🧩 子代理 active/total` 入口,用于搜索、筛选、分组、排序、查看和批量归档当前运行时已发现的子代理。
|
|
4
4
|
|
|
5
|
-
当前发布版本:**v1.
|
|
5
|
+
当前发布版本:**v1.4.0**
|
|
6
6
|
|
|
7
7
|
## 主要功能
|
|
8
8
|
|
|
@@ -204,24 +204,21 @@ sessions.binding(childId).session
|
|
|
204
204
|
→ session.getSnapshot().chat.legacy
|
|
205
205
|
```
|
|
206
206
|
|
|
207
|
-
|
|
207
|
+
如果在当前宿主拿不到对应的实时数据,插件只能显示持久化的会话摘要和统计信息。本版本支持 **dsh 0.1.5-rc.2**,并向下兼容所有 DeepSeek Harness 版本(0.1.2 系列能力探测路径为首选分支,**0.1.1-rc.2** legacy 回退路径保持不变)。
|
|
208
208
|
|
|
209
209
|
归档、分类和最近使用顺序保存在浏览器本地 `localStorage` 中,不会写入 DSH 会话日志。
|
|
210
210
|
|
|
211
211
|
## 开发与验证
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
执行语法检查:
|
|
213
|
+
插件的客户端实现自 v1.4.0 起使用 TypeScript 编写,位于 [`src/client/`](src/client/);发布产物 [`lib/client.js`](lib/client.js) 由构建脚本生成,**不要直接编辑**。宿主入口 [`lib/index.js`](lib/index.js) 仍为手写。
|
|
216
214
|
|
|
217
215
|
```bash
|
|
218
|
-
pnpm
|
|
216
|
+
pnpm install # 安装开发依赖(sucrase + typescript)
|
|
217
|
+
pnpm run build # scripts/build.mjs 从 src/client 生成 lib/client.js
|
|
218
|
+
pnpm run check # 构建 + tsc --noEmit + node --check lib/index.js + 产物新鲜度门禁
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
- `lib/client.js`
|
|
224
|
-
- `lib/index.js`
|
|
221
|
+
`pnpm run verify:build` 会对生成的 `lib/client.js` 与改造前的手写版本(git 引用 `v1.3.4`)做 token 级与行级比对;迁移完成后它同时充当差异查看器,可精确显示任何有意改动引入的 token/行差异。
|
|
225
222
|
|
|
226
223
|
### 冒烟测试(可指定 dsh 版本)
|
|
227
224
|
|
|
@@ -235,8 +232,19 @@ DSH_VERSION=0.1.1-rc.2 ./test.sh # 用 pnpx 拉取指定 dsh 版本跑 web(
|
|
|
235
232
|
|
|
236
233
|
## 致谢与参考
|
|
237
234
|
|
|
235
|
+
- UI 本地化(zh/en)由 [@Marcuss2](https://github.com/Marcuss2) 在 [PR #1](https://github.com/miuzel/dsh-subagent-ui/pull/1) 中贡献,特此致谢!
|
|
238
236
|
- 子代理永久删除、会话生命周期清理及快照刷新机制的设计参考并致谢开源项目:[@heiheiha798/dsh-plugin-subagent-delete](https://github.com/heiheiha798/dsh-plugin-subagent-delete)。
|
|
239
237
|
|
|
238
|
+
## v1.4.0 发布说明
|
|
239
|
+
|
|
240
|
+
- **支持 DeepSeek Harness 0.1.5-rc.2,向下兼容所有 dsh 版本**:适配 0.1.5-rc.2 的对话页视图结构变化(slot 渲染器不再向未声明 store 的注册项注入 `actions`;视图选择改为按会话持久化,新增「轨迹」等标签页)——点击子代理重新正确落回「对话」标签页(`actions` 缺失时改为点击宿主自身的「对话」标签完成切换,激活与持久化语义完整)。0.1.2 系列能力探测路径保留为首选分支、调用方式不变,0.1.1 legacy 回退路径零改动,旧版本行为完全一致。
|
|
241
|
+
- **客户端迁移至 TypeScript**:`src/client/*.ts` 成为唯一源码,`lib/client.js` 由 `pnpm run build`(sucrase 逐字类型擦除 + 确定性链接)生成,不再手写。新增 `verify-build`(与 v1.3.4 手写 golden 做 token/行级比对——迁移等价证明兼有意改动差异查看器)与 `verify-fresh`(过期 bundle 门禁);`pnpm run check` 一键完成构建 + 类型检查 + 语法检查 + 新鲜度校验。
|
|
242
|
+
- **修复:筛选摘要潜伏 ReferenceError**:折叠筛选区且选中具体工作区时,`scopeKey` 未定义变量导致报错,已修正为 `workspaceKey`(TS 迁移期间发现)。
|
|
243
|
+
|
|
244
|
+
## v1.3.4 发布说明
|
|
245
|
+
|
|
246
|
+
- **特性:UI 本地化(zh/en)**:通过 DSH client-locale 将插件全部 UI 文案本地化,支持中文/英文(英文为 AI 辅助翻译)。标签、按钮、统计、实时输出(上下文注入 / 思考中 / 工具说明)、确认弹窗等均改为走翻译键;跟随宿主语言切换。由 [@Marcuss2](https://github.com/Marcuss2) 在 [PR #1](https://github.com/miuzel/dsh-subagent-ui/pull/1) 中贡献,感谢!
|
|
247
|
+
|
|
240
248
|
## v1.3.3 发布说明
|
|
241
249
|
|
|
242
250
|
- **修复:批量删除大数量不再报错**:服务端请求体上限从 64 KiB 提升到 8 MiB,批量删除选中数百上千个子代理时不再触发「body too large」导致「删除请求失败」。
|
package/lib/client.js
CHANGED
|
@@ -3,7 +3,7 @@ window.__ModuleLoader__.load({
|
|
|
3
3
|
factory: (require) => {
|
|
4
4
|
const React = require('react')
|
|
5
5
|
const { jsx, jsxs } = require('react/jsx-runtime')
|
|
6
|
-
|
|
6
|
+
const css = `.dsh-sam-head-sub{display:flex;align-items:center;justify-content:flex-start;gap:10px;margin-top:6px;width:100%;flex-wrap:wrap}
|
|
7
7
|
.dsh-sam-head-float-toggle{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--dsw-alias-label-secondary);cursor:pointer;user-select:none}
|
|
8
8
|
.dsh-sam-head-float-toggle input{margin:0;width:13px;height:13px;cursor:pointer}
|
|
9
9
|
.dsh-sam-collapsed-info{order:2;font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary);padding:4px 8px;border-radius:6px;background:var(--dsw-alias-bg-layer-2);display:flex;align-items:center;justify-content:space-between;gap:8px;overflow:hidden;white-space:nowrap}
|
|
@@ -21,108 +21,138 @@ body[data-ds-dark-theme] .dsh-sam-row-hidden{background:rgba(255,255,255,0.03)!i
|
|
|
21
21
|
.dsh-sam-search-clear:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}
|
|
22
22
|
.dsh-sam-filter-toggle{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;padding:6px 10px;font-size:11px;line-height:1;border-radius:6px;display:inline-flex;align-items:center;gap:2px}
|
|
23
23
|
.dsh-sam-filter-toggle:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}.dsh-sam-hide-btn{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;padding:0 4px;font-size:12px;line-height:16px;white-space:nowrap;align-self:start;min-width:max-content;display:inline-flex;align-items:center;gap:2px}.dsh-sam-hide-btn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);border-radius:5px}.dsh-sam-hidden-badge{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary);white-space:nowrap}.dsh-sam-delete-btn{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;padding:0 4px;font-size:12px;line-height:16px;white-space:nowrap;align-self:start;min-width:max-content}.dsh-sam-delete-btn:hover{color:var(--dsw-alias-state-error-primary,#ef4444);background:var(--dsw-alias-interactive-bg-hover-danger,rgba(236,19,19,.12));border-radius:5px}.dsh-sam-batch-delete-btn{color:var(--dsw-alias-state-error-primary,#ef4444)!important}.dsh-sam-batch-delete-btn:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(236,19,19,.12))!important}.dsh-sam-trigger{display:inline-flex;align-items:center;gap:0;border:0;background:transparent;color:var(--dsw-alias-label-secondary);border-radius:7px;padding:5px 7px;font:inherit;font-size:12px;cursor:pointer}.dsh-sam-trigger:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.dsh-sam-trigger-wrap{position:relative;display:inline-flex;align-items:center}.dsh-sam-active-float{position:fixed;top:56px;right:12px;z-index:999;box-sizing:border-box;width:min(360px,calc(100vw - 24px));max-height:calc(100vh - 24px);overflow:auto;padding:6px 8px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-2));box-shadow:var(--dsw-shadow-lv3);color:var(--dsw-alias-label-primary)}.dsh-sam-active-head{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:1px 2px 5px;color:var(--dsw-alias-label-secondary);font-size:11px;font-weight:600;user-select:none}.dsh-sam-active-drag-handle{cursor:move}.dsh-sam-active-drag-handle:active{cursor:grabbing}.dsh-sam-active-actions{display:inline-flex;align-items:center;gap:6px;margin-left:auto}.dsh-sam-active-live-toggle{display:inline-flex;align-items:center;gap:3px;color:var(--dsw-alias-label-tertiary);font-size:10px;font-weight:400;cursor:pointer}.dsh-sam-active-live-toggle input{width:12px;height:12px;margin:0;accent-color:#42bd7b}.dsh-sam-active-close{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);font-size:17px;line-height:17px;cursor:pointer;padding:0 2px}.dsh-sam-active-close:hover{color:var(--dsw-alias-label-primary)}.dsh-sam-active-item{padding:7px 4px;border-top:1px solid var(--dsw-alias-border-l2);cursor:pointer}.dsh-sam-active-item:hover{background:var(--dsw-alias-interactive-bg-hover);border-radius:6px}.dsh-sam-active-title{display:flex;align-items:center;gap:5px;min-width:0;font-size:12px;line-height:17px;font-weight:600}.dsh-sam-active-icon{flex:none;color:#42bd7b;font-size:12px}.dsh-sam-active-elapsed{margin-left:auto;flex:none;color:var(--dsw-alias-label-tertiary);font-size:10px;font-weight:400}.dsh-sam-stop-btn{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:5px;padding:2px 5px;font:inherit;font-size:10px;line-height:15px;white-space:nowrap;cursor:pointer}.dsh-sam-stop-btn:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(236,19,19,.12));color:var(--dsw-alias-state-error-primary,#ef4444)}.dsh-sam-stop-btn:disabled{opacity:.45;cursor:wait}.dsh-sam-stop-all-btn{border:0;background:transparent;color:var(--dsw-alias-state-warn-label,var(--dsw-alias-label-tertiary));border-radius:4px;padding:1px 5px;font:inherit;font-size:10px;line-height:14px;white-space:nowrap;cursor:pointer}.dsh-sam-stop-all-btn:hover{background:var(--dsw-alias-interactive-bg-hover-danger,rgba(236,19,19,.12));color:var(--dsw-alias-state-error-primary,#ef4444)}.dsh-sam-stop-all-btn:disabled{opacity:.45;cursor:wait}.dsh-sam-row-actions{display:inline-flex;align-items:center;gap:2px;white-space:nowrap}.dsh-sam-active-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsh-sam-active-item .dsh-sam-live{margin:3px 0 3px 17px;max-height:32px;font-size:11px;line-height:15px;pointer-events:none;user-select:none}.dsh-sam-active-stats{margin-left:17px;color:var(--dsw-alias-label-tertiary);font-size:10px;line-height:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dsh-sam-new-agent{position:absolute;top:calc(100% + 6px);left:0;z-index:1001;max-width:280px;padding:7px 10px;border:1px solid var(--dsw-alias-interactive-label-brand);border-radius:8px;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-2));box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-primary);font-size:12px;white-space:nowrap;pointer-events:none;transform-origin:top left;animation:dsh-sam-new-agent 5s ease-out both}@keyframes dsh-sam-new-agent{0%{opacity:0;transform:translateY(-5px) scale(.96)}8%,78%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:0;transform:translateY(-3px) scale(.98)}}.dsh-sam-pulse{width:7px;height:7px;border-radius:50%;background:#42bd7b;animation:dsh-sam-pulse 1.5s ease-in-out infinite}@keyframes dsh-sam-pulse{0%,100%{box-shadow:0 0 0 0 rgba(66,189,123,.55)}50%{box-shadow:0 0 0 4px rgba(66,189,123,0)}}.dsh-sam-count{font-variant-numeric:tabular-nums}.dsh-sam-icon{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px}.dsh-sam-icon.dsh-sam-pulse{width:18px;height:18px;background:transparent}.dsh-sam-panel mark{background:#d7a83d;color:#171717;border-radius:2px;padding:0 1px}.dsh-sam-backdrop{position:fixed;inset:0;z-index:1000;background:rgba(0,0,0,.38);display:flex;justify-content:flex-end;pointer-events:auto}.dsh-sam-panel{height:100%;width:min(680px,100vw);box-sizing:border-box;display:flex;flex-direction:column;background:var(--dsw-specific-sidebar-fill,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-primary);box-shadow:var(--dsw-shadow-lv3);padding:22px;gap:14px}.dsh-sam-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}.dsh-sam-head h2{font-size:20px;margin:0}.dsh-sam-close{border:0;background:transparent;color:inherit;font-size:26px;line-height:24px;cursor:pointer}.dsh-sam-controls{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1.45fr) minmax(0,1.1fr) minmax(0,1.1fr);gap:8px;align-items:center;order:1;position:relative}.dsh-sam-controls input{grid-column:1/-1;grid-row:1}.dsh-sam-controls>select{display:block;grid-row:2;box-sizing:border-box;width:100%;min-width:0;height:30px!important;min-height:30px!important;padding:0 16px 0 8px!important;font:inherit;font-size:11px!important;line-height:normal!important;vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsh-sam-controls option{font:inherit;font-size:12px!important;line-height:normal!important}.dsh-sam-tabs{display:flex;flex-wrap:wrap;align-items:center;gap:6px}.dsh-sam-tab-wrap{display:inline-flex;align-items:center}.dsh-sam-tab-count{display:inline-block;margin-left:5px;min-width:14px;color:var(--dsw-alias-label-tertiary);font-size:10px;font-weight:500;line-height:14px;vertical-align:middle}.dsh-sam-custom-wrap{border-radius:7px;background:transparent;overflow:hidden}.dsh-sam-custom-wrap.dsh-sam-tab-selected{background:var(--dsw-alias-interactive-bg-hover)}.dsh-sam-custom-wrap:hover{box-shadow:inset 0 0 0 1px var(--dsw-alias-interactive-label-brand)}.dsh-sam-custom-wrap .dsh-sam-custom-tab,.dsh-sam-custom-wrap .dsh-sam-custom-tab[aria-pressed=true]{background:transparent!important;border-radius:0}.dsh-sam-custom-wrap .dsh-sam-delete-tab{margin-left:0;padding:0 6px 0 2px}.dsh-sam-tab-wrap:has(.dsh-sam-other-tab){order:99}.dsh-sam-new-tab{order:98}.dsh-sam-other-tab{order:0}.dsh-sam-delete-tab{border:0;background:transparent;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1;padding:0 2px;margin-left:-5px;cursor:pointer}.dsh-sam-delete-tab:hover{color:var(--dsw-alias-label-primary)}.dsh-sam-one-shot{display:inline-block;margin-left:6px;padding:1px 4px;border-radius:4px;background:rgba(214,166,70,.18);color:#d6a646;font-size:10px;font-weight:500;vertical-align:middle}.dsh-sam-session-id{display:inline-block;margin-left:8px;color:var(--dsw-alias-label-tertiary,var(--dsw-alias-label-secondary));font-size:11px;font-weight:400;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;max-width:45%}.dsh-sam-controls>select:nth-of-type(1){grid-column:1}.dsh-sam-controls>select:nth-of-type(2){grid-column:2}.dsh-sam-controls>select:nth-of-type(3){grid-column:4}.dsh-sam-controls>select:nth-of-type(4){grid-column:3}.dsh-sam-filter-btn{display:none}.dsh-sam-tabs{order:2;min-width:0;width:100%;overflow-x:auto;scrollbar-width:none}.dsh-sam-options{order:2}.dsh-sam-panel>.dsh-sam-summary{order:3}.dsh-sam-summary-line{order:3;display:flex;align-items:center;justify-content:space-between;gap:10px}.dsh-sam-batch-btn{border:0;background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:5px;padding:4px 8px;font:inherit;font-size:12px;cursor:pointer}.dsh-sam-batch-done{background:#d6a646;color:#171717;font-weight:700;box-shadow:0 0 0 2px rgba(214,166,70,.28)}.dsh-sam-row-batch{cursor:default}.dsh-sam-row-batch:hover{background:rgba(214,166,70,.08)}.dsh-sam-row-selected{background:rgba(214,166,70,.16)}.dsh-sam-archive-btn:disabled{opacity:.4;cursor:not-allowed}.dsh-sam-row-batch .dsh-sam-archive-btn{opacity:.4;cursor:default}.dsh-sam-archived-label{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary);white-space:nowrap}.dsh-sam-batch-bar{order:3;display:flex;flex-wrap:wrap;gap:6px;align-items:center}.dsh-sam-batch-bar button{border:0;background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary);border-radius:5px;padding:4px 7px;font:inherit;font-size:11px;cursor:pointer}.dsh-sam-batch-bar button:disabled{opacity:.45;cursor:not-allowed}.dsh-sam-panel>.dsh-sam-list{order:4}.dsh-sam-filter-popover{display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:9px;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-2));box-shadow:var(--dsw-shadow-lv2)}.dsh-sam-filter-popover label{font-size:11px;color:var(--dsw-alias-label-tertiary);display:flex;flex-direction:column;gap:4px}.dsh-sam-filter-popover select{color:inherit;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:7px;font:inherit}.dsh-sam-filter-popover .dsh-sam-filter-wide{grid-column:1/-1}.dsh-sam-controls>*{height:40px;box-sizing:border-box}.dsh-sam-controls input,.dsh-sam-controls select,.dsh-sam-options select{min-width:0;color:inherit;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;padding:8px;font:inherit}.dsh-sam-tabs{display:flex;gap:6px;overflow-x:auto;padding-bottom:2px}.dsh-sam-tabs button{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);padding:6px 9px;border-radius:6px;white-space:nowrap;cursor:pointer}.dsh-sam-tabs button:hover,.dsh-sam-tabs button[aria-pressed="true"]{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.dsh-sam-tabs button[aria-pressed="true"]{box-shadow:inset 0 -2px 0 var(--dsw-alias-interactive-label-brand)}.dsh-sam-options{display:flex;flex-wrap:wrap;gap:12px;align-items:center;color:var(--dsw-alias-label-secondary);font-size:12px}.dsh-sam-options label{display:flex;align-items:center;gap:5px;cursor:pointer}.dsh-sam-bg-config{display:inline-flex;align-items:center;gap:6px;padding:2px 6px;border-radius:6px;background:var(--dsw-alias-interactive-bg-hover)}.dsh-sam-color-input{width:18px;height:18px;padding:0;border:0;border-radius:4px;cursor:pointer;background:transparent;vertical-align:middle}.dsh-sam-summary{font-size:12px;color:var(--dsw-alias-label-tertiary)}.dsh-sam-list{min-height:0;flex:1;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;display:flex;flex-direction:column;gap:10px;padding:2px 4px 20px 2px;scrollbar-gutter:stable}.dsh-sam-group{border:1px solid var(--dsw-alias-border-l2);border-radius:10px;overflow:hidden;flex:none}.dsh-sam-group-head{width:100%;border:0;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);padding:9px 12px;text-align:left;display:flex;justify-content:space-between;align-items:center;font:inherit;font-size:12px;font-weight:600;cursor:pointer}.dsh-sam-group-head-actions{display:inline-flex;align-items:center;gap:8px}.dsh-sam-row{width:100%;box-sizing:border-box;min-width:0;border:0;border-top:1px solid var(--dsw-alias-border-l2);background:transparent;color:inherit;text-align:left;padding:10px 12px;cursor:pointer;display:grid;grid-template-columns:minmax(22px,auto) minmax(0,1fr) auto auto;gap:9px;align-items:start}.dsh-sam-row:hover{background:var(--dsw-alias-bg-layer-2)}.dsh-sam-marker{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:18px;height:18px;align-self:center}.dsh-sam-marker input{margin:0;width:16px;height:16px}.dsh-sam-dot{width:8px;height:8px;border-radius:50%;background:var(--dsw-alias-label-caption);display:inline-block;flex:none}.dsh-sam-dot.running{background:#42bd7b;box-shadow:0 0 0 3px rgba(66,189,123,.16)}.dsh-sam-dot.hidden-dot{background:transparent!important;border-radius:0!important;font-size:13px;line-height:1;width:auto;height:auto;box-shadow:none!important;display:inline-flex;align-items:center;justify-content:center}.dsh-sam-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.dsh-sam-meta{margin-top:3px;font-size:11px;color:var(--dsw-alias-label-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dsh-sam-time{font-size:11px;line-height:16px;color:var(--dsw-alias-label-tertiary);white-space:nowrap;align-self:start}.dsh-sam-details{grid-column:2/-1;box-sizing:border-box;width:100%;color:var(--dsw-alias-label-tertiary);font-size:11px}.dsh-sam-details summary{cursor:pointer;color:var(--dsw-alias-label-secondary)}.dsh-sam-live{color:#42bd7b;white-space:pre-wrap;line-height:16px;max-height:32px;overflow:hidden}.dsh-sam-live-old{display:block;opacity:.48}.dsh-sam-live-latest{display:block;opacity:1;font-weight:500}.dsh-sam-live-running{color:#42bd7b}.dsh-sam-live-running .dsh-sam-live-latest{background:linear-gradient(110deg,#42bd7b 20%,#f2fff7 45%,#42bd7b 70%);background-size:220% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:dsh-sam-live-shine 2.4s linear infinite}@keyframes dsh-sam-live-shine{from{background-position:180% 0}to{background-position:-20% 0}}.dsh-sam-live-final{color:var(--dsw-alias-label-tertiary);opacity:.82}.dsh-sam-load-live-btn{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;padding:0 4px;font-size:11px;line-height:16px;border-radius:4px;display:inline-flex;align-items:center;gap:3px;margin:2px 0;opacity:.85}.dsh-sam-load-live-btn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);opacity:1}.dsh-sam-archive-btn{border:0;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;padding:0 4px;font-size:12px;line-height:16px;white-space:nowrap;align-self:start;min-width:max-content}.dsh-sam-archive-btn:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover);border-radius:5px}.dsh-sam-more{width:100%;border:0;border-top:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);padding:9px 12px;text-align:left;font:inherit;font-size:12px;cursor:pointer}.dsh-sam-more:hover{background:var(--dsw-alias-bg-layer-2)}.dsh-sam-empty{padding:30px 12px;text-align:center;color:var(--dsw-alias-label-tertiary)}@media(max-width:560px){.dsh-sam-panel{padding:16px;max-width:100vw;overflow:hidden}.dsh-sam-controls{grid-template-columns:minmax(0,1fr);width:100%}.dsh-sam-controls>*{grid-column:auto!important;width:100%;box-sizing:border-box}.dsh-sam-controls input{grid-column:1/-1!important}.dsh-sam-row{grid-template-columns:8px minmax(0,1fr) auto 42px;gap:6px}.dsh-sam-meta{max-width:100%;overflow:hidden;text-overflow:ellipsis}.dsh-sam-archive-btn{white-space:nowrap;font-size:11px;padding:2px}.dsh-sam-list{width:100%;box-sizing:border-box}}.dsh-sam-thinking{display:inline-flex;align-items:center;gap:5px;font-size:11px;line-height:15px;color:var(--dsw-alias-label-secondary);font-weight:500}.dsh-sam-thinking::before{content:"";width:9px;height:9px;border-radius:50%;border:2px solid transparent;border-top-color:currentColor;border-right-color:currentColor;animation:dsh-sam-spin .7s linear infinite;flex:none}@keyframes dsh-sam-spin{to{transform:rotate(360deg)}}`
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
24
|
+
|
|
25
|
+
if (!document.querySelector('style[data-plugin-css="dsh-subagent-workspace-ui"]')) { const tag=document.createElement('style'); tag.dataset.pluginCss='dsh-subagent-workspace-ui'; tag.textContent=css; document.head.appendChild(tag) }
|
|
26
|
+
const DAY=86400000, PAGE=40, key='dsh-subagent-workspace-ui/preferences', defaultTabs=[{id:'all',nameKey:'tab.all',regex:'__ALL__'},{id:'other',nameKey:'tab.other',regex:'__OTHER__'},{id:'preset-review',nameKey:'tab.audit',regex:'\\b(?:re[- ]?)?review\\b|\\baudit\\b|\\bverify\\b|\\bverification\\b|\\binspect\\b|审计|评审|复核|核查|验证'},{id:'preset-test',nameKey:'tab.test',regex:'\\btests?\\b|\\bspecs?\\b|测试'},{id:'preset-implement',nameKey:'tab.implement',regex:'\\bimplement(?:ation)?\\b|\\bfeatures?\\b|\\bdevelop(?:ment)?\\b|\\bfix(?:es|ed)?\\b|\\brepair\\b|实现|开发|修复|修改'},{id:'preset-planning',nameKey:'tab.planning',regex:'\\bplans?\\b|\\bplanning\\b|\\bdesign\\b|\\broadmap\\b|规划|计划|方案|设计'}]
|
|
27
|
+
const DEFAULT_LIGHT_BG='#edf3fe', DEFAULT_DARK_BG='#1c2333'
|
|
28
|
+
const load=()=>{try{return JSON.parse(localStorage.getItem(key))||{}}catch{return {}}}
|
|
29
|
+
|
|
30
|
+
const age=(tr,stamp)=>{const seconds=Math.max(0,Math.floor((Date.now()-(stamp||Date.now()))/1000));if(seconds<60)return tr('age.sAgo',{s:seconds});const minutes=Math.floor(seconds/60);if(minutes<60)return tr('age.mAgo',{m:minutes});const hours=Math.floor(minutes/60);if(hours<24)return tr('age.hmAgo',{h:hours,m:minutes%60});return tr('age.dAgo',{d:Math.floor(hours/24)})}
|
|
31
|
+
const title=s=>s.title||s.displayTitle||s.id, short=(tr,v)=>v?v.replace(/^session-/,'').slice(0,8):tr('unknown'), workspace=(tr,s)=>s?.cwd?s.cwd.split(/[\\/]/).filter(Boolean).pop():tr('unknownWorkspace'), modeLabel=(tr,m)=>m==='one-shot'?tr('oneShot'):m==='continuable'?tr('continuable'):tr('typeLoading'), tokenTotal=s=>{const u=s?.projectionValues?.tokenUsage;return u?u.uncachedInputTokens+u.outputTokens+u.cacheReadTokens+u.cacheWriteTokens:undefined},fmt=(tr,n)=>n==null?tr('unknown'):n>=1e6?`${(n/1e6).toFixed(1)}m`:n>=1e3?`${(n/1e3).toFixed(1)}k`:String(n), promptPreview=s=>String(s?.prompt||s?.projectionValues?.prompt||'').slice(0,100),statsLine=(tr,row)=>{const u=row?.projectionValues?.tokenUsage,t=tokenTotal(row);return tr('statsLine',{input:fmt(tr,u?.uncachedInputTokens),output:fmt(tr,u?.outputTokens),cacheHit:u?.cacheReadTokens!=null&&t?Math.round(u.cacheReadTokens/t*100):tr('unknown'),turns:row?.projectionValues?.sessionStats?.turns??row?.projectionValues?.turns??tr('unknown'),steps:row?.projectionValues?.sessionStats?.steps??row?.projectionValues?.steps??tr('unknown')})}
|
|
32
|
+
const category=(tr,name)=>{const clean=name.trim();const part=clean.split(/[::|—–-]/)[0].trim();return part.length>1&&part.length<28?part:clean.split(/\\s+/).slice(0,2).join(' ')||tr('uncategorized')},rootSession=(byId,id)=>{let current=id,seen=new Set();while(current&&byId[current]?.origin==='subagent'&&byId[current].parentId&&!seen.has(current)){seen.add(current);current=byId[current].parentId}return current}
|
|
33
|
+
const modeMap=c=>Object.values(c||{}).flatMap(x=>x.entries||[]).reduce((o,e)=>{if(e.kind==='child')o[e.id]={mode:e.mode,label:e.label};return o},{}), highlight=(text,term)=>{if(!term)return text;const parts=String(text).split(new RegExp(`(${term.replace(/[.*+?^${}()|[\\]\\\\]/g,'\\\\$&')})`,'ig'));return parts.map((part,i)=>i%2?jsx('mark',{children:part},i):part)}
|
|
34
|
+
|
|
35
|
+
let sessionsRt=null
|
|
36
|
+
const NOOP=()=>()=>{}
|
|
37
|
+
|
|
38
|
+
function LiveOutput({t:tr,parentId,childId,running,prefix=true,autoLoad=true,onLoad,live=true}){
|
|
39
|
+
const [loading,setLoading]=React.useState(false),[,bump]=React.useState(0),[lastText,setLastText]=React.useState(''),wantLive=live&&(running||autoLoad),binding=React.useMemo(()=>{if(!wantLive)return null;try{return sessionsRt?.binding?.(childId)||null}catch{return null}},[childId,wantLive]),session=binding?.session||null,feed=binding?.eventSource||null
|
|
40
|
+
React.useEffect(()=>{if(!binding)return;let alive=true,timer=null,scheduled=false;const notify=()=>{if(!alive||scheduled)return;scheduled=true;timer=setTimeout(()=>{scheduled=false;timer=null;if(alive)bump(v=>v+1)},100)};const setup=async()=>{try{if(parentId){const entries=sessionsRt?.list?.getSnapshot?.().subagentsByParent?.[parentId]?.entries||[],entry=entries.find(e=>e.kind==='child'&&e.id===childId);if(entry)session?.configureSubagent?.({parentSessionId:parentId,childSessionId:childId,mode:entry.mode})}await session?.open?.()}catch{}finally{if(alive){setLoading(false);bump(v=>v+1)}}};setup();const source=feed||session,unsub=source?.subscribe?.(notify)||NOOP();return()=>{alive=false;if(timer)clearTimeout(timer);unsub()}},[binding,session,feed,parentId,childId])
|
|
41
|
+
let text='',thinking=false;if(feed){const win=feed.getSnapshot?.();if(win&&win.entries){const out=liveFromEvents(tr,win.entries,running);thinking=!!out.thinking;const parts=[];if(out.activity.length)parts.push(out.activity.join('\n'));if(running&&out.streamText&&!out.thinking)parts.push(out.streamText);text=parts.length?parts.join('\n'):out.finalText}}else{const snap=session?.getSnapshot?.(),chat=snap?.chat,blocks=chat?.legacy?.partial?.blocks||[],runningCalls=chat?.legacy?.runningCalls||[],nodes=chat?.legacy?.nodes||[];const activity=[];runningCalls.slice(-2).forEach(c=>activity.push(`▶ ${c.name||tr('toolCall')}${c.argsRaw?` · ${toolDetail(c.argsRaw)}`:''}`));if(!activity.length)nodes.slice(-8).filter(n=>n.kind==='context'||n.kind==='tool-result'||n.kind==='command').slice(-2).forEach(n=>{if(n.kind==='context')activity.push(tr('contextInjection',{name:`${n.provenance?.label||n.form||'context'}`}));else if(n.kind==='tool-result')activity.push(`${n.isError?'✖':'✓'} ${n.call?.name||tr('toolCall')}${n.call?.argsRaw?` · ${toolDetail(n.call.argsRaw)}`:''}`);else activity.push(tr('command.named',{name:`${n.name||tr('command')}`}))});let streamText='';for(let i=blocks.length-1;i>=0;i--){const b=blocks[i];if((b.kind==='text'||b.kind==='reasoning')&&b.text){const lines=b.text.split('\n').map(x=>x.trim()).filter(Boolean);if(lines.length){streamText=(b.kind==='reasoning'?'💭 ':'')+lines.slice(-2).join('\n');break}}}if(runningCalls.length)text=activity.join('\n');else if(running&&streamText)text=streamText;else if(activity.length)text=activity.join('\n');else for(let i=blocks.length-1;i>=0;i--){const b=blocks[i];if((b.kind==='text'||b.kind==='reasoning')&&b.text){const lines=b.text.split('\n').map(x=>x.trim()).filter(Boolean);if(lines.length){text=(b.kind==='reasoning'?'💭 ':'')+lines.slice(-2).join('\n');break}}else if(b.kind==='tool-call'&&b.name){text=tr('callTool')+b.name;break}}}
|
|
42
|
+
React.useEffect(()=>{if(text)setLastText(text)},[text])
|
|
43
|
+
if(!wantLive){return jsx('button',{type:'button',className:'dsh-sam-load-live-btn',onClick:e=>{e.stopPropagation();setLoading(true);onLoad?.()},title:tr('loadHistoryTitle'),children:loading?tr('loading'):tr('loadLatest')})}
|
|
44
|
+
if(!session)return null
|
|
45
|
+
const showText=thinking?text:(text||lastText),lines=showText.slice(-400).split('\n').filter(Boolean);return (showText||(thinking&&running))?jsx('div',{className:`dsh-sam-live ${running?'dsh-sam-live-running':'dsh-sam-live-final'}`,children:[prefix&&jsx('span',{className:'dsh-sam-live-prefix',children:tr('liveOutputPrefix')}),(thinking&&running)&&jsx('span',{className:'dsh-sam-thinking',children:tr('thinking')}),lines.map((line,index)=>jsx('span',{className:index===lines.length-1?'dsh-sam-live-latest':'dsh-sam-live-old',children:line},index))]}):null
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const elapsed=(tr,stamp)=>{const seconds=Math.max(0,Math.floor((Date.now()-(stamp||Date.now()))/1000));return seconds>=3600?tr('elapsed.hm',{h:Math.floor(seconds/3600),m:Math.floor(seconds%3600/60)}):seconds>=60?tr('elapsed.ms',{m:Math.floor(seconds/60),s:seconds%60}):tr('elapsed.s',{s:seconds})},compactPath=v=>{const value=String(v).replace(/\\/g,'/'),max=72;if(value.length<=max)return value;const parts=value.split('/').filter(Boolean);let result=parts.pop()||value;while(parts.length&&(`.../${parts[parts.length-1]}/${result}`).length<=max)result=`${parts.pop()}/${result}`;return `.../${result}`},toolDetail=v=>{if(!v)return '';try{const value=JSON.parse(v),key=value.description!=null?'description':value.command!=null?'command':value.file_path!=null?'file_path':value.path!=null?'path':value.prompt!=null?'prompt':null,preferred=key?value[key]:undefined;if(preferred)return (key==='file_path'||key==='path'?compactPath: String)(String(preferred).split('\n')[0].slice(0,100));const first=Object.values(value).find(x=>typeof x==='string');return first?first.split('\n')[0].slice(0,100):String(v).slice(0,100)}catch{return String(v).split('\n')[0].slice(0,100)}}
|
|
49
|
+
|
|
50
|
+
const liveFromEvents=(tr,entries,running)=>{const tail=s=>{const lines=String(s||'').split('\n').map(x=>x.trim()).filter(Boolean);return lines.length?lines.slice(-2).join('\n'):''},finalOf=blocks=>{const list=Array.isArray(blocks)?blocks:[];for(let i=list.length-1;i>=0;i--){const b=list[i];if(b?.type==='text'||b?.type==='reasoning'){const t=tail(b.text);if(t)return (b.type==='reasoning'?'💭 ':'')+t}if(b?.type==='tool-call'&&b.name)return tr('callTool')+b.name}return ''};let text='',reasoning='',finalText='',hasStream=false,lastKind='text';const pending=[],done=[],context=[],byCall=new Map();for(const entry of entries){if(!entry||entry.type!=='event')continue;const e=entry.event;if(!e||typeof e.type!=='string')continue;switch(e.type){case 'assistant/chunk':{const c=e.data?.chunk;if(!c)break;if(c.type==='text-delta'){text+=c.text||'';hasStream=true;lastKind='text'}else if(c.type==='reasoning-delta'){reasoning+=c.text||'';hasStream=true;lastKind='reasoning'}else if(c.type==='tool-call-delta'&&c.id){let rec=byCall.get(c.id);if(!rec){rec={name:c.name||tr('toolCall'),args:'',complete:false,running:true};byCall.set(c.id,rec);pending.push(rec)}if(c.name)rec.name=c.name;rec.args+=c.argumentsDelta||''}else if(c.type==='block-end'&&c.block?.type==='tool-call'){let rec=byCall.get(c.block.id);if(!rec){rec={name:c.block.name||tr('toolCall'),args:'',complete:false,running:true};byCall.set(c.block.id,rec);pending.push(rec)}if(c.block.name)rec.name=c.block.name;rec.args=c.block.arguments||rec.args;rec.complete=true}break}case 'user/message':{const src=e.data?.source;if(src?.kind==='plugin'||src?.kind==='relay'||src?.kind==='recall')context.push(tr('contextInjection',{name:`${src?.form||src?.plugin||src?.kind}`}));break}case 'assistant/message':{finalText=finalOf(e.data?.message?.content);text='';reasoning='';hasStream=false;break}case 'tool/call':{let rec=byCall.get(e.data?.callId);if(!rec){rec={name:e.data?.name||tr('toolCall'),args:'',complete:false,running:true};byCall.set(e.data?.callId,rec);pending.push(rec)}if(e.data?.name)rec.name=e.data?.name;if(e.data?.arguments!=null){rec.args=e.data?.arguments;rec.complete=true}rec.running=true;break}case 'tool/result':{const rec=byCall.get(e.data?.message?.source?.callId),block=e.data?.message?.content?.[0];if(rec){rec.running=false;done.push({name:rec.name,args:rec.args,complete:rec.complete,isError:block?.isError})}break}default:break}}const open=pending.filter(r=>r.running!==false);return{pendingCount:open.length,activity:[...open.slice(-2).map(r=>`▶ ${r.name||tr('toolCall')}${r.complete&&r.args?` · ${toolDetail(r.args)}`:''}`),...done.slice(-2).map(r=>`${r.isError?'✖':'✓'} ${r.name||tr('toolCall')}${r.complete&&r.args?` · ${toolDetail(r.args)}`:''}`),...context.slice(-2)],streamText:hasStream?((lastKind==='reasoning'?'💭 ':'')+tail(lastKind==='reasoning'?reasoning:text)):'',thinking:hasStream&&lastKind==='reasoning',finalText}}
|
|
51
|
+
|
|
52
|
+
function ActiveFloat({t:tr,rows,openRow,onHide,stopAgent,stopAllAgents,stoppingIds,liveEnabled,onLiveChange,liveCap}){const [,tick]=React.useState(0),[position,setPosition]=React.useState(null),drag=React.useRef(null);React.useEffect(()=>{const timer=setInterval(()=>tick(v=>v+1),1000);return()=>clearInterval(timer)},[]);const move=e=>{if(!drag.current)return;const {offsetX,offsetY,width,height}=drag.current;setPosition({x:Math.max(8,Math.min(window.innerWidth-width-8,e.clientX-offsetX)),y:Math.max(8,Math.min(window.innerHeight-height-8,e.clientY-offsetY))})},startDrag=e=>{if(e.button!==0||e.target.closest('button,input,label'))return;const rect=e.currentTarget.parentElement.getBoundingClientRect();drag.current={offsetX:e.clientX-rect.left,offsetY:e.clientY-rect.top,width:rect.width,height:rect.height};e.currentTarget.setPointerCapture?.(e.pointerId)},stopDrag=()=>{drag.current=null},dragStyle=position?{left:position.x,top:position.y,right:'auto'}:undefined;const continuableRows=rows.filter(r=>r.mode!=='one-shot');return jsx('aside',{className:'dsh-sam-active-float',style:dragStyle,onPointerMove:move,onPointerUp:stopDrag,onPointerCancel:stopDrag,role:'status',children:[jsxs('div',{className:'dsh-sam-active-head dsh-sam-active-drag-handle',onPointerDown:startDrag,children: [jsx('span',{children:tr('activeFloat.title',{count:rows.length})}),jsxs('div',{className:'dsh-sam-active-actions',children:[continuableRows.length>0&&jsx('button',{type:'button',className:'dsh-sam-stop-all-btn',title:tr('pauseAllActive'),disabled:continuableRows.some(r=>stoppingIds.has(r.id)),onClick:e=>{e.stopPropagation();stopAllAgents(continuableRows)},children:continuableRows.some(r=>stoppingIds.has(r.id))?tr('pausing'):tr('pauseAll')}),jsx('label',{className:'dsh-sam-active-live-toggle',children:[jsx('input',{type:'checkbox',checked:liveEnabled,onChange:e=>onLiveChange(e.target.checked)}),tr('liveOutput')]}),jsx('button',{type:'button',className:'dsh-sam-active-close',onClick:e=>{e.stopPropagation();onHide()},'aria-label':tr('hideActiveFloat'),children:'×'})]})]}),rows.map((row,idx)=>jsxs('div',{className:'dsh-sam-active-item',onClick:()=>openRow(row),children:[jsxs('div',{className:'dsh-sam-active-title',children:[jsx('span',{className:'dsh-sam-active-icon',children:'🧩'}),jsx('span',{className:'dsh-sam-active-name',children:row.name}),jsx('span',{className:'dsh-sam-active-elapsed',children:elapsed(tr,row.createdAt||row.updatedAt)}),row.mode!=='one-shot'&&jsx('button',{type:'button',className:'dsh-sam-stop-btn',disabled:stoppingIds.has(row.id),onClick:e=>{e.stopPropagation();stopAgent(row)},'aria-label':tr('pause.named',{name:row.name}),'title':tr('pauseSubagent'),children:stoppingIds.has(row.id)?tr('pausing'):tr('pause')})]}),liveEnabled&&(liveCap<=0||idx<liveCap)&&jsx(LiveOutput,{t:tr,parentId:row.parentId,childId:row.id,running:true,prefix:false}),jsx('div',{className:'dsh-sam-active-stats',children:tr('statsLine',{input:fmt(tr,row.projectionValues?.tokenUsage?.uncachedInputTokens),output:fmt(tr,row.projectionValues?.tokenUsage?.outputTokens),cacheHit:row.projectionValues?.tokenUsage?.cacheReadTokens!=null&&tokenTotal(row)?Math.round(row.projectionValues.tokenUsage.cacheReadTokens/tokenTotal(row)*100):tr('unknown'),turns:row.projectionValues?.sessionStats?.turns??row.projectionValues?.turns??tr('unknown'),steps:row.projectionValues?.sessionStats?.steps??row.projectionValues?.steps??tr('unknown')})})]},row.id))]})}
|
|
53
|
+
|
|
54
|
+
let chatViewPinGen=0
|
|
55
|
+
function pinChatViewTab(sessionId){
|
|
56
|
+
const gen=++chatViewPinGen,until=Date.now()+8000
|
|
57
|
+
const tryPin=()=>{
|
|
58
|
+
if(gen!==chatViewPinGen||Date.now()>until)return
|
|
59
|
+
if(sessionsRt?.list?.getSnapshot?.().current!==sessionId){setTimeout(tryPin,100);return}
|
|
60
|
+
const lists=document.querySelectorAll('header div[role="tablist"]')
|
|
61
|
+
for(const list of lists){
|
|
62
|
+
const tabs=Array.from(list.querySelectorAll('button[role="tab"]'))
|
|
63
|
+
if(!tabs.length)continue
|
|
64
|
+
const chatTab=tabs.find(b=>{const label=b.textContent?.trim();return label==='对话'||label==='Chat'})||tabs[0]
|
|
65
|
+
if(chatTab.getAttribute('aria-selected')!=='true')chatTab.dispatchEvent(new MouseEvent('click',{bubbles:true}))
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
setTimeout(tryPin,100)
|
|
69
|
+
}
|
|
70
|
+
setTimeout(tryPin,0)
|
|
71
|
+
}
|
|
72
|
+
function Manager({t:tr,useSessions,openChild,openSession,refresh,setCatalogOpen,sessionId,actions}){
|
|
73
|
+
const state=useSessions(s=>s,(a,b)=>a?.byId===b?.byId&&a?.subagentsByParent===b?.subagentsByParent&&a?.current===b?.current),[open,setOpen]=React.useState(false),[query,setQuery]=React.useState(''),[grouping,setGrouping]=React.useState('session'),[sort,setSort]=React.useState('recent'),[prefs,setPrefs]=React.useState(load),[limit,setLimit]=React.useState(PAGE),[tab,setTab]=React.useState('all'),[scope,setScope]=React.useState('currentWorkspace'),[filterOpen,setFilterOpen]=React.useState(false),[activeOpen,setActiveOpen]=React.useState(true),[scopeDetail,setScopeDetail]=React.useState(''),[sessionScope,setSessionScope]=React.useState(''),[recentIds,setRecentIds]=React.useState([]),[batchMode,setBatchMode]=React.useState(false),[selectedIds,setSelectedIds]=React.useState(new Set),[lastSelectedIndex,setLastSelectedIndex]=React.useState(-1),[lastSelectedAction,setLastSelectedAction]=React.useState(null),[oldHours,setOldHours]=React.useState(null),[newAgents,setNewAgents]=React.useState([]),[floatHidden,setFloatHidden]=React.useState(false),[stoppingIds,setStoppingIds]=React.useState(new Set),[manualLoadedIds,setManualLoadedIds]=React.useState(new Set),runningSeen=React.useRef(false),runningIdsSeen=React.useRef(new Set),noticeTimers=React.useRef(new Map)
|
|
74
|
+
const nameOf=tab=>tab.nameKey?tr(tab.nameKey):tab.name,tabs=[...defaultTabs,...(prefs.tabs||[])].filter(t=>t.id!=='filtered').filter((t,i,a)=>a.findIndex(x=>x.id===t.id)===i), archived=new Set(prefs.archived||[]), archivedParents=prefs.archivedParents||{}, currentId=rootSession(state.byId,sessionId||state.current), current=state.byId[currentId], currentCwd=current?.cwd, parentRows=Object.values(state.byId).filter(s=>s.origin!=='subagent'), scopeOptions=[...new Set(parentRows.map(s=>s.cwd).filter(Boolean))],workspaceKey=scope.startsWith('workspace:')?scope.slice(10):scope==='currentWorkspace'?currentCwd:undefined,availableSessions=parentRows.filter(s=>!workspaceKey||s.cwd===workspaceKey),selectedSession=sessionScope||currentId
|
|
75
|
+
const modes=React.useMemo(()=>modeMap(state.subagentsByParent),[state.subagentsByParent]),subagentRows=React.useMemo(()=>{const byId=state.byId;return Object.values(byId).filter(s=>s.origin==='subagent').map(s=>({...s,...modes[s.id],name:modes[s.id]?.label||title(s),parentCwd:byId[s.parentId]?.cwd}))},[state.byId,modes]),allRows=React.useMemo(()=>{if(!open)return [];const rawTerm=query.trim().toLocaleLowerCase(),idOnly=rawTerm.startsWith('id:'),term=idOnly?rawTerm.slice(3).trim():rawTerm;return subagentRows.filter(s=>{if(workspaceKey&&s.parentCwd!==workspaceKey)return false;if(selectedSession!=='all'&&s.parentId!==selectedSession)return false;const unfiltered=tab==='all';if(!prefs.showArchived&&archived.has(s.id))return false;if(prefs.hideOneShot&&s.mode==='one-shot')return false;if(!unfiltered&&prefs.hideOld&&!s.running&&Date.now()-s.updatedAt>(prefs.oldDays||30)*DAY)return false;const custom=tabs.find(t=>t.id===tab);if(custom?.regex==='__OTHER__'){const matched=tabs.some(t=>!['filtered','all','other'].includes(t.id)&&t.regex&&(()=>{try{return new RegExp(t.regex,'i').test(s.name)}catch{return false}})());if(matched)return false}else if(custom?.regex&&custom.regex!=='__ALL__'){try{if(!new RegExp(custom.regex,'i').test(s.name))return false}catch{return false}}return !term||`${idOnly?`${s.id} ${s.parentId||''}`:`${s.name} ${title(s)} ${workspace(tr,s)}`}`.toLocaleLowerCase().includes(term)}).sort((a,b)=>{const ar=recentIds.indexOf(a.id),br=recentIds.indexOf(b.id);return ar!==br?(ar<0?1:br<0?-1:ar-br):a.running!==b.running?(b.running?1:-1):sort==='title'?a.name.localeCompare(b.name):sort==='type'?modeLabel(tr,a.mode).localeCompare(modeLabel(tr,b.mode)):b.updatedAt-a.updatedAt})},[open,subagentRows,query,sort,prefs,scope,currentCwd,currentId,scopeDetail,workspaceKey,selectedSession,tab,tabs,recentIds,tr])
|
|
76
|
+
const deferredSubagentRows=React.useDeferredValue(subagentRows),activeRows=React.useMemo(()=>subagentRows.filter(s=>s.running).filter(s=>(!currentCwd||s.parentCwd===currentCwd)&&(prefs.showArchived||!archived.has(s.id))&&(!prefs.hideOneShot||s.mode!=='one-shot')).sort((a,b)=>b.updatedAt-a.updatedAt),[subagentRows,currentCwd,prefs,archived])
|
|
77
|
+
const stopAgent=async row=>{if(row.mode==='one-shot'||stoppingIds.has(row.id))return;if(!window.confirm(tr('confirm.pauseNamed',{name:row.name})))return;setStoppingIds(prev=>new Set(prev).add(row.id));try{const session=sessionsRt?.binding?.(row.id)?.session;if(session){if(row.parentId&&row.mode){session.configureSubagent?.({parentSessionId:row.parentId,childSessionId:row.id,mode:row.mode})}await session.open?.();await session.cancel?.();if(row.parentId){sessionsRt?.refreshSubagents?.(row.parentId)}}}catch(e){console.warn('Unable to stop subagent',e)}finally{setStoppingIds(prev=>{const next=new Set(prev);next.delete(row.id);return next})}}
|
|
78
|
+
const stopAllAgents=async rowsToStop=>{const targetRows=rowsToStop.filter(r=>r.mode!=='one-shot'&&!stoppingIds.has(r.id));if(!targetRows.length)return;if(!window.confirm(tr('confirm.pauseSelected',{count:targetRows.length})))return;const ids=targetRows.map(r=>r.id);setStoppingIds(prev=>new Set([...prev,...ids]));try{await Promise.allSettled(targetRows.map(async row=>{try{const session=sessionsRt?.binding?.(row.id)?.session;if(session){if(row.parentId&&row.mode){session.configureSubagent?.({parentSessionId:row.parentId,childSessionId:row.id,mode:row.mode})}await session.open?.();await session.cancel?.();if(row.parentId){sessionsRt?.refreshSubagents?.(row.parentId)}}}catch(e){console.warn('Unable to stop subagent',row.id,e)}}))}finally{setStoppingIds(prev=>{const next=new Set(prev);ids.forEach(id=>next.delete(id));return next})}}
|
|
79
|
+
|
|
80
|
+
const deleteSubagent=async row=>{
|
|
81
|
+
if(row.running){
|
|
82
|
+
if(!window.confirm(tr('confirm.deleteRunning',{name:row.name})))return
|
|
83
|
+
}
|
|
84
|
+
if(!window.confirm(tr('confirm.deleteOne',{name:row.name})))return
|
|
85
|
+
try{
|
|
86
|
+
const resp=await fetch('/api/dsh-subagent-workspace-ui/delete',{
|
|
87
|
+
method:'POST',
|
|
88
|
+
headers:{'content-type':'application/json'},
|
|
89
|
+
body:JSON.stringify({sessionId:row.id,parentSessionId:row.parentId})
|
|
90
|
+
})
|
|
91
|
+
const data=await resp.json()
|
|
92
|
+
if(data.ok){
|
|
93
|
+
if(row.parentId){sessionsRt?.refreshSubagents?.(row.parentId)}
|
|
94
|
+
sessionsRt?.refresh?.()
|
|
95
|
+
setPrefs(p=>({
|
|
96
|
+
...p,
|
|
97
|
+
archived:(p.archived||[]).filter(x=>x!==row.id),
|
|
98
|
+
archivedParents:(()=>{const np={...(p.archivedParents||{})};delete np[row.id];return np})()
|
|
99
|
+
}))
|
|
100
|
+
}else{
|
|
101
|
+
window.alert(tr('deleteFailed')+(data.error||tr('unknownError')))
|
|
80
102
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
}catch(e){
|
|
104
|
+
window.alert(tr('deleteRequestFailed')+e.message)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const batchDeleteSubagents=async idsToDelete=>{
|
|
108
|
+
if(!idsToDelete.length)return
|
|
109
|
+
if(!window.confirm(tr('confirm.deleteMany',{count:idsToDelete.length})))return
|
|
110
|
+
const items=idsToDelete.map(id=>({sessionId:id,parentSessionId:state.byId[id]?.parentId}))
|
|
111
|
+
try{
|
|
112
|
+
const resp=await fetch('/api/dsh-subagent-workspace-ui/batch-delete',{
|
|
113
|
+
method:'POST',
|
|
114
|
+
headers:{'content-type':'application/json'},
|
|
115
|
+
body:JSON.stringify({items})
|
|
116
|
+
})
|
|
117
|
+
const data=await resp.json()
|
|
118
|
+
if(data.ok){
|
|
119
|
+
const parents=new Set(items.map(x=>x.parentSessionId).filter(Boolean))
|
|
120
|
+
parents.forEach(pid=>sessionsRt?.refreshSubagents?.(pid))
|
|
121
|
+
sessionsRt?.refresh?.()
|
|
122
|
+
setPrefs(p=>({
|
|
123
|
+
...p,
|
|
124
|
+
archived:(p.archived||[]).filter(x=>!idsToDelete.includes(x)),
|
|
125
|
+
archivedParents:(()=>{const np={...(p.archivedParents||{})};idsToDelete.forEach(id=>delete np[id]);return np})()
|
|
126
|
+
}))
|
|
127
|
+
setSelectedIds(new Set)
|
|
128
|
+
}else{
|
|
129
|
+
window.alert(tr('batchDeleteFailed')+(data.error||tr('unknownError')))
|
|
108
130
|
}
|
|
131
|
+
}catch(e){
|
|
132
|
+
window.alert(tr('batchDeleteRequestFailed')+e.message)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
109
135
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
currentGroupName=grouping==='session'?'按会话':grouping==='workspace'?'按工作区':grouping==='category'?'按分类':grouping==='type'?'按类型':'不分组'
|
|
136
|
+
const currentTabName=nameOf(tabs.find(t=>t.id===tab)||{})||tr('tab.all'),
|
|
137
|
+
currentScopeName=scope==='currentWorkspace'?tr('scope.currentWorkspace'):scope==='currentSession'?tr('scope.currentSession'):scope==='all'?tr('scope.allWorkspaces'):(workspace(tr,{cwd:workspaceKey})||scope),
|
|
138
|
+
currentSessionName=selectedSession==='all'?tr('scope.allSessions'):(selectedSession===currentId?tr('session.currentParen',{name:title(current)}):(title(state.byId[selectedSession])||short(tr,selectedSession))),
|
|
139
|
+
currentSortName=sort==='recent'?tr('sort.recent'):sort==='title'?tr('name'):tr('type'),
|
|
140
|
+
currentGroupName=grouping==='session'?tr('grouping.bySession'):grouping==='workspace'?tr('grouping.byWorkspace'):grouping==='category'?tr('grouping.byCategory'):grouping==='type'?tr('grouping.byType'):tr('grouping.none')
|
|
116
141
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return jsxs(React.Fragment,{children:[(!open&&prefs.activeFloat!==false&&Boolean(activeRows.length)&&!floatHidden)?jsx(ActiveFloat,{rows:activeRows,openRow,onHide:()=>setFloatHidden(true),stopAgent,stopAllAgents,stoppingIds,liveEnabled:prefs.activeFloatLive!==false,onLiveChange:value=>setPrefs(p=>({...p,activeFloatLive:value})),liveCap}):null,jsxs('div',{className:'dsh-sam-trigger-wrap',children:[jsx('button',{type:'button',className:'dsh-sam-trigger',onClick:()=>{setLimit(PAGE);setOpen(true)},title:'打开子代理管理',children:[jsx('span',{className:`dsh-sam-icon ${active>0?'dsh-sam-pulse':''}`,children:'🧩'}),jsx('span',{children:`子代理 ${active}/${currentCount}`})]}),!open&&newAgents.map((item,index)=>jsx('div',{className:'dsh-sam-new-agent',style:{top:`calc(100% + ${6+index*34}px)`},role:'status',children:`新子代理:${item.name}`},item.id))]}),open&&jsx('div',{className:'dsh-sam-backdrop',onMouseDown:e=>{if(e.target===e.currentTarget){setOpen(false);setBatchMode(false);setSelectedIds(new Set);setLastSelectedIndex(-1);setLastSelectedAction(null)}},children:jsxs('section',{className:'dsh-sam-panel',role:'dialog','aria-modal':true,children:[jsxs('header',{className:'dsh-sam-head',children:[jsxs('div',{style:{flex:1,minWidth:0},children:[jsx('h2',{children:'子代理管理'}),jsxs('div',{className:'dsh-sam-head-sub',children:[jsx('div',{className:'dsh-sam-summary',children:`当前会话 ${allRows.filter(r=>r.parentId===currentId).length} 个 · 当前工作区 ${allRows.filter(r=>currentCwd&&state.byId[r.parentId]?.cwd===currentCwd).length} 个 · 活跃 ${active} 个`}),jsx('span',{className:'dsh-sam-summary',style:{opacity:0.6},children:'·'}),jsx('label',{className:'dsh-sam-head-float-toggle',children:[jsx('input',{type:'checkbox',checked:prefs.activeFloat!==false,onChange:()=>{setFloatHidden(false);setPrefs(p=>({...p,activeFloat:p.activeFloat===false}))}}),'显示活跃浮窗']})]})]}),jsx('button',{className:'dsh-sam-close',type:'button',onClick:()=>{setOpen(false);setBatchMode(false);setSelectedIds(new Set);setLastSelectedIndex(-1)},children:'×'})]}),!prefs.filterCollapsed&&jsxs('div',{className:'dsh-sam-tabs',children:[tabs.map(t=>jsxs('span',{className:`dsh-sam-tab-wrap ${(prefs.tabs?.some(x=>x.id===t.id)&&!defaultTabs.some(x=>x.id===t.id))?`dsh-sam-custom-wrap ${tab===t.id?'dsh-sam-tab-selected':''}`:''}`,children:[jsx('button',{type:'button',className:`${t.id==='other'?'dsh-sam-other-tab ':''}${(prefs.tabs?.some(x=>x.id===t.id)&&!defaultTabs.some(x=>x.id===t.id))?'dsh-sam-custom-tab':''}`,'aria-pressed':tab===t.id,onClick:()=>{setTab(t.id);setLimit(PAGE)},children:jsxs(React.Fragment,{children:[t.name,jsx('small',{className:'dsh-sam-tab-count',children:tabCounts[t.id]>99?'99+':tabCounts[t.id]||0})]})},`tab-select-${t.id}`),...((prefs.tabs?.some(x=>x.id===t.id)&&!defaultTabs.some(x=>x.id===t.id))?[jsx('button',{type:'button',className:'dsh-sam-delete-tab',title:`删除分类“${t.name}”`,'aria-label':`删除分类“${t.name}”`,onClick:e=>{e.stopPropagation();if(!window.confirm(`确认删除分类“${t.name}”?`))return;setPrefs(p=>({...p,tabs:(p.tabs||[]).filter(x=>x.id!==t.id)}));if(tab===t.id)setTab('all')},children:'×'},`tab-delete-${t.id}`)]:[])]},t.id)),jsx('button',{type:'button',className:'dsh-sam-new-tab',onClick:()=>{const name=window.prompt('分类名称');if(!name)return;const regex=window.prompt('匹配正则(例如:^审计|review)');if(!regex)return;setPrefs(p=>({...p,tabs:[...(p.tabs||defaultTabs),{id:`tab-${Date.now()}`,name,regex}]}))},children:'+ 新建分类'})]}),jsxs('div',{className:'dsh-sam-controls',children:[jsx('button',{type:'button',className:'dsh-sam-filter-btn',onClick:()=>setFilterOpen(v=>!v),children:`⚙ 筛选排序 · ${scope==='currentWorkspace'?'当前工作区':scope==='currentSession'?'当前会话':'自定义范围'} · ${sort==='recent'?'最近活跃':sort==='title'?'名字':'类型'}`}),!prefs.filterCollapsed&&jsx('select',{value:scope,onChange:e=>{setScope(e.target.value);setSessionScope('all');setLimit(PAGE)},'aria-label':'显示范围',children:[jsx('option',{value:'currentWorkspace',children:'当前工作区'}),jsx('option',{value:'all',children:'全部工作区'}),...scopeOptions.map(c=>jsx('option',{value:`workspace:${c}`,children:workspace({cwd:c})},c))]}),!prefs.filterCollapsed&&jsx('select',{value:selectedSession,onChange:e=>setSessionScope(e.target.value),children:[jsx('option',{value:'all',children:'全部会话'}),...availableSessions.map(s=>jsx('option',{value:s.id,children:s.id===currentId?`当前会话 · ${title(s)}`:title(s)},s.id))]}),jsxs('div',{className:'dsh-sam-search-wrap',children:[jsx('input',{autoFocus:true,value:query,placeholder:'搜索名称、标题或工作区;输入 id: 搜索 Session ID',onChange:e=>{setQuery(e.target.value);setLimit(PAGE)}}),jsxs('div',{className:'dsh-sam-search-actions',children:[query&&jsx('button',{type:'button',className:'dsh-sam-search-clear',title:'清空搜索',onClick:()=>setQuery(''),children:'×'}),jsx('button',{type:'button',className:'dsh-sam-filter-toggle',title:prefs.filterCollapsed?'展开筛选与配置':'折叠筛选与配置',onClick:()=>setPrefs(p=>({...p,filterCollapsed:!p.filterCollapsed})),children:prefs.filterCollapsed?'⚙ 展开筛选 ▾':'⚙ 折叠 ▴'})]})]}),!prefs.filterCollapsed&&jsx('select',{value:grouping,onChange:e=>{setGrouping(e.target.value);setLimit(PAGE)},children:[['session','分组:按会话'],['workspace','分组:按工作区'],['category','分组:按分类'],['type','分组:按类型'],['none','分组:不分组']].map(([v,l])=>jsx('option',{value:v,children:l},v))}),!prefs.filterCollapsed&&jsx('select',{value:sort,onChange:e=>setSort(e.target.value),children:[['recent','排序:最近活跃'],['title','排序:名字'],['type','排序:类型']].map(([v,l])=>jsx('option',{value:v,children:l},v))})]}),filterOpen&&jsxs('div',{className:'dsh-sam-filter-popover',children:[jsx('label',{children:['范围',jsx('select',{value:scope,onChange:e=>{setScope(e.target.value);setSessionScope('all');setLimit(PAGE)},children:[jsx('option',{value:'currentWorkspace',children:'当前工作区'}),jsx('option',{value:'currentSession',children:'当前会话'}),jsx('option',{value:'all',children:'全部工作区'}),...scopeOptions.map(c=>jsx('option',{value:`workspace:${c}`,children:`工作区 · ${workspace({cwd:c})}`},c)),...parentRows.map(s=>jsx('option',{value:`session:${s.id}`,children:`会话 · ${workspace(s)} / ${title(s)}`},s.id))]})]}),jsx('label',{children:['分组',jsx('select',{value:grouping,onChange:e=>{setGrouping(e.target.value);setLimit(PAGE)},children:[['session','按会话'],['workspace','按工作区'],['category','按分类'],['type','按类型'],['none','不分组']].map(([v,l])=>jsx('option',{value:v,children:l},v))})]}),jsx('label',{children:['排序',jsx('select',{value:sort,onChange:e=>{setSort(e.target.value);setLimit(PAGE)},children:[['recent','最近活跃'],['title','名字'],['type','类型']].map(([v,l])=>jsx('option',{value:v,children:l},v))})]})]}),!prefs.filterCollapsed&&jsxs('div',{className:'dsh-sam-options',children:[jsx('label',{children:[jsx('input',{type:'checkbox',checked:!!prefs.hideOneShot,onChange:()=>setPrefs(p=>({...p,hideOneShot:!p.hideOneShot}))}),'隐藏一次性']}),jsx('label',{children:[jsx('input',{type:'checkbox',checked:!!prefs.hideOld,onChange:()=>setPrefs(p=>({...p,hideOld:!p.hideOld}))}),'隐藏长期未活跃']}),jsxs('span',{className:'dsh-sam-bg-config',children:[jsx('label',{children:[jsx('input',{type:'checkbox',checked:prefs.customSubagentBg!==false,onChange:()=>setPrefs(p=>({...p,customSubagentBg:p.customSubagentBg===false}))}),'子代理背景色']}),prefs.customSubagentBg!==false&&jsxs(React.Fragment,{children:[jsx('label',{title:'浅色主题下的子代理背景色',children:[jsx('input',{type:'color',className:'dsh-sam-color-input',value:prefs.subagentBgLight||DEFAULT_LIGHT_BG,onChange:e=>setPrefs(p=>({...p,subagentBgLight:e.target.value}))}),'浅色']}),jsx('label',{title:'深色主题下的子代理背景色',children:[jsx('input',{type:'color',className:'dsh-sam-color-input',value:prefs.subagentBgDark||DEFAULT_DARK_BG,onChange:e=>setPrefs(p=>({...p,subagentBgDark:e.target.value}))}),'深色']})]})]}),jsx('button',{type:'button',onClick:()=>{setQuery('');setScope('currentWorkspace');setScopeDetail('');setSessionScope('all');setTab('all');setGrouping('session');setSort('recent');setLimit(PAGE)},children:'重置筛选'})]}),prefs.filterCollapsed&&jsxs('div',{className:'dsh-sam-collapsed-info',children:[jsxs('div',{className:'dsh-sam-collapsed-left',children:[jsx('span',{className:'dsh-sam-collapsed-tag',children:currentScopeName}),jsx('span',{children:'·'}),jsx('span',{className:'dsh-sam-collapsed-tag',children:currentSessionName}),jsx('span',{children:'·'}),jsx('span',{className:'dsh-sam-collapsed-tag',children:currentTabName})]}),jsxs('div',{className:'dsh-sam-collapsed-right',children:[jsx('span',{children:`排序 · ${currentSortName}`}),jsx('span',{children:`分组 · ${currentGroupName}`})]})]}),jsxs('div',{className:'dsh-sam-summary-line',children:[jsxs('div',{className:'dsh-sam-summary-items',children:[jsx('span',{className:'dsh-sam-summary',children:`显示 ${rows.length}/${allRows.length} 个`}),jsx('label',{className:'dsh-sam-summary-hidden-toggle',children:[jsx('input',{type:'checkbox',checked:prefs.showDetails!==false,onChange:()=>setPrefs(p=>({...p,showDetails:p.showDetails===false}))}),'显示详情']}),jsx('label',{className:'dsh-sam-summary-hidden-toggle',children:[jsx('input',{type:'checkbox',checked:!!prefs.showArchived,onChange:()=>setPrefs(p=>({...p,showArchived:!p.showArchived}))}),'显示已隐藏']}),jsx('span',{className:'dsh-sam-summary',style:{fontSize:'11px'},children:'隐藏仅在列表不显示,不删除会话'})]}),jsx('button',{type:'button',className:`dsh-sam-batch-btn ${batchMode?'dsh-sam-batch-done':''}`,onClick:()=>{setBatchMode(v=>!v);setSelectedIds(new Set)},children:batchMode?'完成':'批量操作'})]}),batchMode&&jsxs('div',{className:'dsh-sam-batch-bar',children:[jsx('button',{type:'button',onClick:()=>setSelectedIds(new Set(allRows.map(r=>r.id))),children:'全选'}),jsx('button',{type:'button',onClick:()=>setSelectedIds(new Set),children:'清空'}),jsx('button',{type:'button',onClick:selectOld,children:'选择 N 小时前'}),jsx('button',{type:'button',disabled:!selectedIds.size,onClick:()=>archiveSelected(false),title:'将选中的子代理隐藏',children:`批量隐藏 (${selectedIds.size})`}),jsx('button',{type:'button',disabled:!selectedIds.size,onClick:()=>archiveSelected(true),title:'取消隐藏选中的子代理',children:'批量显示'}),jsx('button',{type:'button',onClick:()=>{if(!window.confirm('确认隐藏当前筛选出的全部子代理?'))return;batchArchive(allRows.map(r=>r.id));setSelectedIds(new Set)},children:'一键全部隐藏'}),jsx('button',{type:'button',className:'dsh-sam-batch-delete-btn',disabled:!selectedIds.size,onClick:()=>batchDeleteSubagents([...selectedIds]),children:`批量删除 (${selectedIds.size})`}),jsx('button',{type:'button',className:'dsh-sam-batch-delete-btn',onClick:()=>batchDeleteSubagents(allRows.map(r=>r.id)),children:'一键删除全部'})]}),jsx('div',{className:'dsh-sam-list',onWheel:e=>e.stopPropagation(),children:Object.keys(groups).length===0?jsx('div',{className:'dsh-sam-empty',children:'没有符合条件的子代理。'}):Object.entries(groups).map(([name,entries])=>jsxs('section',{className:'dsh-sam-group',children:[jsxs('div',{className:'dsh-sam-group-head',onClick:()=>name==='活跃子代理'&&setActiveOpen(v=>!v),children:[jsx('span',{children:`${name}${name==='活跃子代理'?(activeOpen?' ▾':' ▸'):''}`}),jsxs('div',{className:'dsh-sam-group-head-actions',children:[name==='活跃子代理'&&activeGroupContinuableRows.length>0&&jsx('button',{type:'button',className:'dsh-sam-stop-all-btn',title:'一键暂停所有活跃可继续子代理',disabled:activeGroupContinuableRows.some(r=>stoppingIds.has(r.id)),onClick:e=>{e.stopPropagation();stopAllAgents(activeGroupContinuableRows)},children:activeGroupContinuableRows.some(r=>stoppingIds.has(r.id))?'暂停中':'⏸ 一键暂停'}),jsx('span',{children:entries.length})]})]}),(name==='活跃子代理'&&!activeOpen?[]:entries).map(row=>jsx('div',{className:`dsh-sam-row ${batchMode?'dsh-sam-row-batch':''}${selectedIds.has(row.id)?' dsh-sam-row-selected':''}${archived.has(row.id)?' dsh-sam-row-hidden':''}`,onClick:e=>{if(batchMode)toggleSelected(row,rows.indexOf(row),e);else openRow(row)},title:prefs.showDetails!==false?undefined:statsLine(row),children:[jsx('span',{className:'dsh-sam-marker',children:[batchMode&&jsx('input',{type:'checkbox',checked:selectedIds.has(row.id),onChange:e=>toggleSelected(row,rows.indexOf(row),e),onClick:e=>e.stopPropagation(),'aria-label':`选择 ${row.name}`}),archived.has(row.id)?jsx('span',{className:'dsh-sam-dot hidden-dot',title:'已隐藏',children:'\u{1F648}'}):jsx('span',{className:`dsh-sam-dot ${row.running?'running':''}`})]}),jsx('button',{type:'button',className:'dsh-sam-row-open',style:{all:'unset',cursor:batchMode?'default':'pointer',minWidth:0},onClick:e=>{e.stopPropagation();if(batchMode)toggleSelected(row,rows.indexOf(row),e);else openRow(row)},title:prefs.showDetails!==false?`${row.name}\n${row.id}`:`${row.name}\n${statsLine(row)}`,children:jsxs('span',{children:[jsx('div',{className:'dsh-sam-title',children:jsxs('span',{children:[highlight(row.name,query),row.mode==='one-shot'&&jsx('small',{className:'dsh-sam-one-shot',children:'⚡ 一次性'}),jsx('small',{className:'dsh-sam-session-id',children:row.id})]})}),grouping==='session'?null:jsx('div',{className:'dsh-sam-meta',children:highlight(`${modeLabel(row.mode)}${grouping==='session'?'':` · ${row.parentId?`${workspace(state.byId[row.parentId]||row)} / ${title(state.byId[row.parentId]||row)}`:'无父会话'}`}`,query)})]})}),jsx('span',{className:'dsh-sam-time',title:`最近活动:${new Date(row.updatedAt).toLocaleString()}`,children:age(row.updatedAt)}),batchMode?(archived.has(row.id)&&jsx('span',{className:'dsh-sam-archived-label',children:'已隐藏'})):jsxs('span',{className:'dsh-sam-row-actions',children:[row.running&&row.mode!=='one-shot'&&jsx('button',{type:'button',className:'dsh-sam-stop-btn',disabled:stoppingIds.has(row.id),onClick:e=>{e.stopPropagation();stopAgent(row)},'aria-label':`暂停 ${row.name}`,'title':'暂停子代理',children:stoppingIds.has(row.id)?'暂停中':'⏸ 暂停'}),jsx('button',{type:'button',className:'dsh-sam-hide-btn',onClick:e=>{e.stopPropagation();archive(row)},title:archived.has(row.id)?'取消隐藏':'隐藏(仅在列表隐藏,不删除会话)','aria-label':`${archived.has(row.id)?'取消隐藏':'隐藏'} ${row.name}`,children:archived.has(row.id)?'👁 显示':'⊘ 隐藏'}),jsx('button',{type:'button',className:'dsh-sam-delete-btn',onClick:e=>{e.stopPropagation();deleteSubagent(row)},title:'永久删除该子代理','aria-label':`删除 ${row.name}`,children:'\u{1F5D1} 删除'})]}),prefs.showDetails!==false&&jsxs('div',{className:'dsh-sam-details',children:[jsx('div',{children:`输入 ${fmt(row.projectionValues?.tokenUsage?.uncachedInputTokens)} / 输出 ${fmt(row.projectionValues?.tokenUsage?.outputTokens)} · 缓存命中 ${row.projectionValues?.tokenUsage?.cacheReadTokens!=null&&tokenTotal(row)?Math.round(row.projectionValues.tokenUsage.cacheReadTokens/tokenTotal(row)*100):'未知'}% · 轮数 ${row.projectionValues?.sessionStats?.turns??row.projectionValues?.turns??'未知'} · 步数 ${row.projectionValues?.sessionStats?.steps??row.projectionValues?.steps??'未知'}`}),promptPreview(row)&&jsx('div',{children:`提示词:${promptPreview(row)}`}),jsx(LiveOutput,{parentId:row.parentId,childId:row.id,running:row.running,autoLoad:rows.slice(0,10).some(r=>r.id===row.id)||manualLoadedIds.has(row.id),live:(!row.running||(runningLiveIds?runningLiveIds.has(row.id):true)||manualLoadedIds.has(row.id)),onLoad:()=>setManualLoadedIds(prev=>new Set(prev).add(row.id))})]})]},row.id)),limit<allRows.length&&jsx('button',{type:'button',className:'dsh-sam-more',onClick:()=>setLimit(n=>n+PAGE),children:`加载下一页(剩余 ${allRows.length-limit} 个)`})]},name))})]})})]})
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
142
|
+
const tabCounts=React.useMemo(()=>{if(!open)return {};const candidates=deferredSubagentRows.filter(s=>(!workspaceKey||s.parentCwd===workspaceKey)&&(selectedSession==='all'||s.parentId===selectedSession)&&(prefs.showArchived||!archived.has(s.id))&&(!prefs.hideOneShot||s.mode!=='one-shot')&&(!prefs.hideOld||s.running||Date.now()-s.updatedAt<=(prefs.oldDays||30)*DAY)),counts={};for(const t of tabs){if(t.id==='all')counts[t.id]=candidates.length;else if(t.regex==='__OTHER__')counts[t.id]=candidates.filter(s=>!tabs.some(x=>!['all','other','filtered'].includes(x.id)&&x.regex&&(()=>{try{return new RegExp(x.regex,'i').test(s.name)}catch{return false}})())).length;else counts[t.id]=candidates.filter(s=>{try{return t.regex&&new RegExp(t.regex,'i').test(s.name)}catch{return false}}).length}return counts},[open,deferredSubagentRows,workspaceKey,selectedSession,prefs,tabs]),rows=allRows.slice(0,limit),currentSessionRows=subagentRows.filter(r=>r.parentId===currentId&&(prefs.showArchived||!archived.has(r.id))&&(!prefs.hideOneShot||r.mode!=='one-shot')),active=currentSessionRows.filter(r=>r.running).length,currentCount=currentSessionRows.length,liveCap=Math.max(0,prefs.liveCap??3),runningLiveIds=liveCap>0?new Set(rows.filter(r=>r.running).slice(0,liveCap).map(r=>r.id)):null
|
|
143
|
+
const groups=React.useMemo(()=>{const out={};for(const row of rows){const parent=row.parentId?state.byId[row.parentId]:undefined,sameSession=row.parentId===currentId,sameWorkspace=currentCwd&&parent?.cwd===currentCwd;let bucket=row.running?tr('group.active'):grouping==='session'?`${workspace(tr,parent||row)} · ${title(parent||current)}`:grouping==='type'?modeLabel(tr,row.mode):grouping==='category'?(()=>{const hit=tabs.find(t=>t.id!=='filtered'&&t.id!=='all'&&t.regex&&(()=>{try{return new RegExp(t.regex,'i').test(row.name)}catch{return false}})());return hit?nameOf(hit):tr('group.other')})():grouping==='workspace'?workspace(tr,parent||row):grouping==='none'?tr('group.allResults'):sameSession?tr('scope.currentSession'):sameWorkspace?tr('session.currentWorkspaceDot',{name:workspace(tr,parent||row)}):(parent?`${workspace(tr,parent)} · ${title(parent)}`:tr('group.otherSessions'));(out[bucket]||=[]).push(row)}return out},[rows,grouping,state.byId,sessionId,state.current,currentCwd,tr])
|
|
144
|
+
React.useEffect(()=>{localStorage.setItem(key,JSON.stringify(prefs))},[prefs]);React.useEffect(()=>{if(!open)return;const ps=[...new Set(rows.map(r=>r.parentId).filter(Boolean))];ps.forEach(p=>{setCatalogOpen(p,true);refresh(p)});return()=>ps.forEach(p=>setCatalogOpen(p,false))},[open,limit,grouping,sort,query])
|
|
145
|
+
React.useEffect(()=>{const runningIds=subagentRows.filter(r=>r.running).map(r=>r.id);if(!runningIds.length)return;setRecentIds(prev=>{const next=[...runningIds,...prev.filter(id=>!runningIds.includes(id))].slice(0,100);return next.length===prev.length&&next.every((id,i)=>id===prev[i])?prev:next})},[subagentRows]);React.useEffect(()=>{if(!subagentRows.length)return;const runningIds=subagentRows.filter(r=>r.running).map(r=>r.id),current=new Set(runningIds);if(!runningSeen.current){runningSeen.current=true;runningIdsSeen.current=current;return}const fresh=runningIds.filter(id=>!runningIdsSeen.current.has(id));runningIdsSeen.current=current;if(!fresh.length)return;const names=fresh.map(id=>({id,name:subagentRows.find(r=>r.id===id)?.name})).filter(r=>r.name).slice(0,5);if(!names.length)return;setFloatHidden(false);setNewAgents(prev=>[...prev,...names].slice(-5));names.forEach(item=>{const timer=setTimeout(()=>{setNewAgents(prev=>prev.filter(x=>x.id!==item.id));noticeTimers.current.delete(item.id)},5000);if(noticeTimers.current.has(item.id))clearTimeout(noticeTimers.current.get(item.id));noticeTimers.current.set(item.id,timer)})},[subagentRows]);React.useEffect(()=>()=>{noticeTimers.current.forEach(timer=>clearTimeout(timer));noticeTimers.current.clear()},[]);const toggleSelected=(row,index,e)=>{const isShift=Boolean(e?.shiftKey&&lastSelectedIndex>=0);setSelectedIds(prev=>{const next=new Set(prev);if(isShift){const from=Math.min(lastSelectedIndex,index),to=Math.max(lastSelectedIndex,index);const shouldSelect=lastSelectedAction!==false;for(let i=from;i<=to;i++){const id=rows[i]?.id;if(!id)continue;if(shouldSelect)next.add(id);else next.delete(id)}}else{const willSelect=!next.has(row.id);if(willSelect)next.add(row.id);else next.delete(row.id);setLastSelectedAction(willSelect)};return next});setLastSelectedIndex(index)},batchArchive=(ids,restore=false)=>setPrefs(p=>{const current=new Set(p.archived||[]);ids.forEach(id=>restore?current.delete(id):current.add(id));const nextParents={...(p.archivedParents||{})};if(restore)ids.forEach(id=>delete nextParents[id]);else ids.forEach(id=>{const row=state.byId[id];if(row)nextParents[id]=row.parentId});return {...p,archived:[...current],archivedParents:nextParents}}),archiveSelected=(restore=false)=>{const ids=[...selectedIds];if(ids.length){batchArchive(ids,restore);setSelectedIds(new Set)}},selectOld=()=>{const hours=Number(window.prompt(tr('selectHoursPrompt'),'24'));if(!Number.isFinite(hours)||hours<0)return;const cutoff=Date.now()-hours*3600000;setSelectedIds(new Set(allRows.filter(r=>r.updatedAt&&r.updatedAt<=cutoff).slice(0,1000).map(r=>r.id)));setLimit(1000);setOldHours(hours);parentRows.forEach(p=>{setCatalogOpen(p.id,true);refresh(p.id)})},archive=row=>setPrefs(p=>{const was=p.archived?.includes(row.id);const nextArchived=was?p.archived.filter(x=>x!==row.id):[...(p.archived||[]),row.id];const nextParents={...(p.archivedParents||{})};if(was)delete nextParents[row.id];else nextParents[row.id]=row.parentId;return {...p,archived:nextArchived,archivedParents:nextParents}}),openRow=r=>{try{if(r.parentId&&r.mode)openChild({parentSessionId:r.parentId,childSessionId:r.id,mode:r.mode});else openSession(r.id);if(actions?.setView)actions.setView('chat');else pinChatViewTab(r.id);setOpen(false);setBatchMode(false)}catch(e){console.warn('Unable to open subagent',e)}}
|
|
146
|
+
React.useEffect(()=>{const styleId='dsh-sam-subagent-bg-style';let el=document.getElementById(styleId);const isSubagent=sessionId&&state.byId[sessionId]?.origin==='subagent';if(isSubagent){const lightBg=prefs.subagentBgLight||DEFAULT_LIGHT_BG,darkBg=prefs.subagentBgDark||DEFAULT_DARK_BG;const bgRule=prefs.customSubagentBg!==false?`body:not([data-ds-dark-theme]) [data-conversation-scroll],body:not([data-ds-dark-theme]) [data-conversation-scroll] > *{--dsw-alias-bg-base:${lightBg}!important}body[data-ds-dark-theme] [data-conversation-scroll],body[data-ds-dark-theme] [data-conversation-scroll] > *{--dsw-alias-bg-base:${darkBg}!important}`:'';const statsRule=`div[class*="StatsLine_root"],.FJxK0a_root{background:var(--dsw-alias-bg-layer-2,rgba(128,128,128,0.08))!important;border:1px solid var(--dsw-alias-border-l1,rgba(128,128,128,0.15))!important;border-radius:999px!important;padding:3px 14px 4px 10px!important;margin:6px auto!important;width:fit-content!important;max-width:min(calc(100% - 32px),var(--dsh-chat-content-width,748px))!important;box-shadow:var(--dsw-shadow-lv1,0 1px 3px rgba(0,0,0,0.05))!important;backdrop-filter:blur(8px)!important;color:var(--dsw-alias-label-secondary)!important;display:flex!important;align-items:center!important;justify-content:center!important}div[class*="StatsLine_root"]::before,.FJxK0a_root::before{content:"\\1F9E9";margin-right:6px;font-size:13px;line-height:1;display:inline-block;flex:none}`;if(!el){el=document.createElement('style');el.id=styleId;document.head.appendChild(el)}el.textContent=`${bgRule}${statsRule}`}else{if(el)el.remove()}},[sessionId,state.byId,prefs.customSubagentBg,prefs.subagentBgLight,prefs.subagentBgDark])
|
|
147
|
+
const activeGroupContinuableRows=groups[tr('group.active')]?.filter(r=>r.mode!=='one-shot')||[]
|
|
148
|
+
return jsxs(React.Fragment,{children:[(!open&&prefs.activeFloat!==false&&Boolean(activeRows.length)&&!floatHidden)?jsx(ActiveFloat,{t:tr,rows:activeRows,openRow,onHide:()=>setFloatHidden(true),stopAgent,stopAllAgents,stoppingIds,liveEnabled:prefs.activeFloatLive!==false,onLiveChange:value=>setPrefs(p=>({...p,activeFloatLive:value})),liveCap}):null,jsxs('div',{className:'dsh-sam-trigger-wrap',children:[jsx('button',{type:'button',className:'dsh-sam-trigger',onClick:()=>{setLimit(PAGE);setOpen(true)},title:tr('openManager'),children:[jsx('span',{className:`dsh-sam-icon ${active>0?'dsh-sam-pulse':''}`,children:'🧩'}),jsx('span',{children:tr('chip.count',{active:active,total:currentCount})})]}),!open&&newAgents.map((item,index)=>jsx('div',{className:'dsh-sam-new-agent',style:{top:`calc(100% + ${6+index*34}px)`},role:'status',children:tr('newAgent',{name:item.name})},item.id))]}),open&&jsx('div',{className:'dsh-sam-backdrop',onMouseDown:e=>{if(e.target===e.currentTarget){setOpen(false);setBatchMode(false);setSelectedIds(new Set);setLastSelectedIndex(-1);setLastSelectedAction(null)}},children:jsxs('section',{className:'dsh-sam-panel',role:'dialog','aria-modal':true,children:[jsxs('header',{className:'dsh-sam-head',children:[jsxs('div',{style:{flex:1,minWidth:0},children:[jsx('h2',{children:tr('managerTitle')}),jsxs('div',{className:'dsh-sam-head-sub',children:[jsx('div',{className:'dsh-sam-summary',children:tr('head.summary',{session:allRows.filter(r=>r.parentId===currentId).length,workspace:allRows.filter(r=>currentCwd&&state.byId[r.parentId]?.cwd===currentCwd).length,active:active})}),jsx('span',{className:'dsh-sam-summary',style:{opacity:0.6},children:'·'}),jsx('label',{className:'dsh-sam-head-float-toggle',children:[jsx('input',{type:'checkbox',checked:prefs.activeFloat!==false,onChange:()=>{setFloatHidden(false);setPrefs(p=>({...p,activeFloat:p.activeFloat===false}))}}),tr('showActiveFloat')]})]})]}),jsx('button',{className:'dsh-sam-close',type:'button',onClick:()=>{setOpen(false);setBatchMode(false);setSelectedIds(new Set);setLastSelectedIndex(-1)},children:'×'})]}),!prefs.filterCollapsed&&jsxs('div',{className:'dsh-sam-tabs',children:[tabs.map(t=>jsxs('span',{className:`dsh-sam-tab-wrap ${(prefs.tabs?.some(x=>x.id===t.id)&&!defaultTabs.some(x=>x.id===t.id))?`dsh-sam-custom-wrap ${tab===t.id?'dsh-sam-tab-selected':''}`:''}`,children:[jsx('button',{type:'button',className:`${t.id==='other'?'dsh-sam-other-tab ':''}${(prefs.tabs?.some(x=>x.id===t.id)&&!defaultTabs.some(x=>x.id===t.id))?'dsh-sam-custom-tab':''}`,'aria-pressed':tab===t.id,onClick:()=>{setTab(t.id);setLimit(PAGE)},children:jsxs(React.Fragment,{children:[nameOf(t),jsx('small',{className:'dsh-sam-tab-count',children:tabCounts[t.id]>99?'99+':tabCounts[t.id]||0})]})},`tab-select-${t.id}`),...((prefs.tabs?.some(x=>x.id===t.id)&&!defaultTabs.some(x=>x.id===t.id))?[jsx('button',{type:'button',className:'dsh-sam-delete-tab',title:tr('deleteCategory.named',{name:t.name}),'aria-label':tr('deleteCategory.named',{name:t.name}),onClick:e=>{e.stopPropagation();if(!window.confirm(tr('confirm.deleteCategory',{name:t.name})))return;setPrefs(p=>({...p,tabs:(p.tabs||[]).filter(x=>x.id!==t.id)}));if(tab===t.id)setTab('all')},children:'×'},`tab-delete-${t.id}`)]:[])]},t.id)),jsx('button',{type:'button',className:'dsh-sam-new-tab',onClick:()=>{const name=window.prompt(tr('categoryNamePrompt'));if(!name)return;const regex=window.prompt(tr('regexPrompt'));if(!regex)return;setPrefs(p=>({...p,tabs:[...(p.tabs||defaultTabs),{id:`tab-${Date.now()}`,name,regex}]}))},children:tr('newCategory')})]}),jsxs('div',{className:'dsh-sam-controls',children:[jsx('button',{type:'button',className:'dsh-sam-filter-btn',onClick:()=>setFilterOpen(v=>!v),children:`⚙ ${tr('filterSort')} · ${scope==='currentWorkspace'?tr('scope.currentWorkspace'):scope==='currentSession'?tr('scope.currentSession'):tr('scope.custom')} · ${sort==='recent'?tr('sort.recent'):sort==='title'?tr('sort.name'):tr('sort.type')}`}),!prefs.filterCollapsed&&jsx('select',{value:scope,onChange:e=>{setScope(e.target.value);setSessionScope('all');setLimit(PAGE)},'aria-label':tr('scopeAria'),children:[jsx('option',{value:'currentWorkspace',children:tr('scope.currentWorkspace')}),jsx('option',{value:'all',children:tr('scope.allWorkspaces')}),...scopeOptions.map(c=>jsx('option',{value:`workspace:${c}`,children:workspace(tr,{cwd:c})},c))]}),!prefs.filterCollapsed&&jsx('select',{value:selectedSession,onChange:e=>setSessionScope(e.target.value),children:[jsx('option',{value:'all',children:tr('scope.allSessions')}),...availableSessions.map(s=>jsx('option',{value:s.id,children:s.id===currentId?tr('session.currentDot',{name:title(s)}):title(s)},s.id))]}),jsxs('div',{className:'dsh-sam-search-wrap',children:[jsx('input',{autoFocus:true,value:query,placeholder:tr('searchPlaceholder'),onChange:e=>{setQuery(e.target.value);setLimit(PAGE)}}),jsxs('div',{className:'dsh-sam-search-actions',children:[query&&jsx('button',{type:'button',className:'dsh-sam-search-clear',title:tr('clearSearch'),onClick:()=>setQuery(''),children:'×'}),jsx('button',{type:'button',className:'dsh-sam-filter-toggle',title:prefs.filterCollapsed?tr('expandFiltersFull'):tr('collapseFiltersFull'),onClick:()=>setPrefs(p=>({...p,filterCollapsed:!p.filterCollapsed})),children:prefs.filterCollapsed?tr('expandFilters'):tr('collapseFilters')})]})]}),!prefs.filterCollapsed&&jsx('select',{value:grouping,onChange:e=>{setGrouping(e.target.value);setLimit(PAGE)},children:[['session',tr('grouping.optionSession')],['workspace',tr('grouping.optionWorkspace')],['category',tr('grouping.optionCategory')],['type',tr('grouping.optionType')],['none',tr('grouping.optionNone')]].map(([v,l])=>jsx('option',{value:v,children:l},v))}),!prefs.filterCollapsed&&jsx('select',{value:sort,onChange:e=>setSort(e.target.value),children:[['recent',tr('sort.optionRecent')],['title',tr('sort.optionName')],['type',tr('sort.optionType')]].map(([v,l])=>jsx('option',{value:v,children:l},v))})]}),filterOpen&&jsxs('div',{className:'dsh-sam-filter-popover',children:[jsx('label',{children:[tr('scope'),jsx('select',{value:scope,onChange:e=>{setScope(e.target.value);setSessionScope('all');setLimit(PAGE)},children:[jsx('option',{value:'currentWorkspace',children:tr('scope.currentWorkspace')}),jsx('option',{value:'currentSession',children:tr('scope.currentSession')}),jsx('option',{value:'all',children:tr('scope.allWorkspaces')}),...scopeOptions.map(c=>jsx('option',{value:`workspace:${c}`,children:tr('workspace.named',{name:workspace(tr,{cwd:c})})},c)),...parentRows.map(s=>jsx('option',{value:`session:${s.id}`,children:tr('session.named',{name:`${workspace(tr,s)} / ${title(s)}`})},s.id))]})]}),jsx('label',{children:[tr('grouping'),jsx('select',{value:grouping,onChange:e=>{setGrouping(e.target.value);setLimit(PAGE)},children:[['session',tr('grouping.bySession')],['workspace',tr('grouping.byWorkspace')],['category',tr('grouping.byCategory')],['type',tr('grouping.byType')],['none',tr('grouping.none')]].map(([v,l])=>jsx('option',{value:v,children:l},v))})]}),jsx('label',{children:[tr('sort'),jsx('select',{value:sort,onChange:e=>{setSort(e.target.value);setLimit(PAGE)},children:[['recent',tr('sort.recent')],['title',tr('name')],['type',tr('type')]].map(([v,l])=>jsx('option',{value:v,children:l},v))})]})]}),!prefs.filterCollapsed&&jsxs('div',{className:'dsh-sam-options',children:[jsx('label',{children:[jsx('input',{type:'checkbox',checked:!!prefs.hideOneShot,onChange:()=>setPrefs(p=>({...p,hideOneShot:!p.hideOneShot}))}),tr('hideOneShot')]}),jsx('label',{children:[jsx('input',{type:'checkbox',checked:!!prefs.hideOld,onChange:()=>setPrefs(p=>({...p,hideOld:!p.hideOld}))}),tr('hideLongInactive')]}),jsxs('span',{className:'dsh-sam-bg-config',children:[jsx('label',{children:[jsx('input',{type:'checkbox',checked:prefs.customSubagentBg!==false,onChange:()=>setPrefs(p=>({...p,customSubagentBg:p.customSubagentBg===false}))}),tr('subagentBg')]}),prefs.customSubagentBg!==false&&jsxs(React.Fragment,{children:[jsx('label',{title:tr('subagentBgLightTitle'),children:[jsx('input',{type:'color',className:'dsh-sam-color-input',value:prefs.subagentBgLight||DEFAULT_LIGHT_BG,onChange:e=>setPrefs(p=>({...p,subagentBgLight:e.target.value}))}),tr('light')]}),jsx('label',{title:tr('subagentBgDarkTitle'),children:[jsx('input',{type:'color',className:'dsh-sam-color-input',value:prefs.subagentBgDark||DEFAULT_DARK_BG,onChange:e=>setPrefs(p=>({...p,subagentBgDark:e.target.value}))}),tr('dark')]})]})]}),jsx('button',{type:'button',onClick:()=>{setQuery('');setScope('currentWorkspace');setScopeDetail('');setSessionScope('all');setTab('all');setGrouping('session');setSort('recent');setLimit(PAGE)},children:tr('resetFilters')})]}),prefs.filterCollapsed&&jsxs('div',{className:'dsh-sam-collapsed-info',children:[jsxs('div',{className:'dsh-sam-collapsed-left',children:[jsx('span',{className:'dsh-sam-collapsed-tag',children:currentScopeName}),jsx('span',{children:'·'}),jsx('span',{className:'dsh-sam-collapsed-tag',children:currentSessionName}),jsx('span',{children:'·'}),jsx('span',{className:'dsh-sam-collapsed-tag',children:currentTabName})]}),jsxs('div',{className:'dsh-sam-collapsed-right',children:[jsx('span',{children:tr('sort.current',{name:currentSortName})}),jsx('span',{children:tr('grouping.current',{name:currentGroupName})})]})]}),jsxs('div',{className:'dsh-sam-summary-line',children:[jsxs('div',{className:'dsh-sam-summary-items',children:[jsx('span',{className:'dsh-sam-summary',children:tr('summary.showing',{shown:rows.length,total:allRows.length})}),jsx('label',{className:'dsh-sam-summary-hidden-toggle',children:[jsx('input',{type:'checkbox',checked:prefs.showDetails!==false,onChange:()=>setPrefs(p=>({...p,showDetails:p.showDetails===false}))}),tr('showDetails')]}),jsx('label',{className:'dsh-sam-summary-hidden-toggle',children:[jsx('input',{type:'checkbox',checked:!!prefs.showArchived,onChange:()=>setPrefs(p=>({...p,showArchived:!p.showArchived}))}),tr('showHidden')]}),jsx('span',{className:'dsh-sam-summary',style:{fontSize:'11px'},children:tr('hideNote')})]}),jsx('button',{type:'button',className:`dsh-sam-batch-btn ${batchMode?'dsh-sam-batch-done':''}`,onClick:()=>{setBatchMode(v=>!v);setSelectedIds(new Set)},children:batchMode?tr('done'):tr('batch')})]}),batchMode&&jsxs('div',{className:'dsh-sam-batch-bar',children:[jsx('button',{type:'button',onClick:()=>setSelectedIds(new Set(allRows.map(r=>r.id))),children:tr('selectAll')}),jsx('button',{type:'button',onClick:()=>setSelectedIds(new Set),children:tr('clear')}),jsx('button',{type:'button',onClick:selectOld,children:tr('selectOld')}),jsx('button',{type:'button',disabled:!selectedIds.size,onClick:()=>archiveSelected(false),title:tr('hideSelectedTitle'),children:tr('batch.hide',{count:selectedIds.size})}),jsx('button',{type:'button',disabled:!selectedIds.size,onClick:()=>archiveSelected(true),title:tr('unhideSelectedTitle'),children:tr('batchUnhide')}),jsx('button',{type:'button',onClick:()=>{if(!window.confirm(tr('confirmHideAll')))return;batchArchive(allRows.map(r=>r.id));setSelectedIds(new Set)},children:tr('hideAll')}),jsx('button',{type:'button',className:'dsh-sam-batch-delete-btn',disabled:!selectedIds.size,onClick:()=>batchDeleteSubagents([...selectedIds]),children:tr('batch.delete',{count:selectedIds.size})}),jsx('button',{type:'button',className:'dsh-sam-batch-delete-btn',onClick:()=>batchDeleteSubagents(allRows.map(r=>r.id)),children:tr('deleteAll')})]}),jsx('div',{className:'dsh-sam-list',onWheel:e=>e.stopPropagation(),children:Object.keys(groups).length===0?jsx('div',{className:'dsh-sam-empty',children:tr('empty')}):Object.entries(groups).map(([name,entries])=>jsxs('section',{className:'dsh-sam-group',children:[jsxs('div',{className:'dsh-sam-group-head',onClick:()=>name===tr('group.active')&&setActiveOpen(v=>!v),children:[jsx('span',{children:`${name}${name===tr('group.active')?(activeOpen?' ▾':' ▸'):''}`}),jsxs('div',{className:'dsh-sam-group-head-actions',children:[name===tr('group.active')&&activeGroupContinuableRows.length>0&&jsx('button',{type:'button',className:'dsh-sam-stop-all-btn',title:tr('pauseAllActive'),disabled:activeGroupContinuableRows.some(r=>stoppingIds.has(r.id)),onClick:e=>{e.stopPropagation();stopAllAgents(activeGroupContinuableRows)},children:activeGroupContinuableRows.some(r=>stoppingIds.has(r.id))?tr('pausing'):tr('pauseAll')}),jsx('span',{children:entries.length})]})]}),(name===tr('group.active')&&!activeOpen?[]:entries).map(row=>jsx('div',{className:`dsh-sam-row ${batchMode?'dsh-sam-row-batch':''}${selectedIds.has(row.id)?' dsh-sam-row-selected':''}${archived.has(row.id)?' dsh-sam-row-hidden':''}`,onClick:e=>{if(batchMode)toggleSelected(row,rows.indexOf(row),e);else openRow(row)},title:prefs.showDetails!==false?undefined:statsLine(tr,row),children:[jsx('span',{className:'dsh-sam-marker',children:[batchMode&&jsx('input',{type:'checkbox',checked:selectedIds.has(row.id),onChange:e=>toggleSelected(row,rows.indexOf(row),e),onClick:e=>e.stopPropagation(),'aria-label':tr('select.named',{name:row.name})}),archived.has(row.id)?jsx('span',{className:'dsh-sam-dot hidden-dot',title:tr('hidden'),children:'\u{1F648}'}):jsx('span',{className:`dsh-sam-dot ${row.running?'running':''}`})]}),jsx('button',{type:'button',className:'dsh-sam-row-open',style:{all:'unset',cursor:batchMode?'default':'pointer',minWidth:0},onClick:e=>{e.stopPropagation();if(batchMode)toggleSelected(row,rows.indexOf(row),e);else openRow(row)},title:prefs.showDetails!==false?`${row.name}\n${row.id}`:`${row.name}\n${statsLine(tr,row)}`,children:jsxs('span',{children:[jsx('div',{className:'dsh-sam-title',children:jsxs('span',{children:[highlight(row.name,query),row.mode==='one-shot'&&jsx('small',{className:'dsh-sam-one-shot',children:tr('oneShotBadge')}),jsx('small',{className:'dsh-sam-session-id',children:row.id})]})}),grouping==='session'?null:jsx('div',{className:'dsh-sam-meta',children:highlight(`${modeLabel(tr,row.mode)}${grouping==='session'?'':` · ${row.parentId?`${workspace(tr,state.byId[row.parentId]||row)} / ${title(state.byId[row.parentId]||row)}`:tr('noParent')}`}`,query)})]})}),jsx('span',{className:'dsh-sam-time',title:tr('lastActivity',{time:new Date(row.updatedAt).toLocaleString()}),children:age(tr,row.updatedAt)}),batchMode?(archived.has(row.id)&&jsx('span',{className:'dsh-sam-archived-label',children:tr('hidden')})):jsxs('span',{className:'dsh-sam-row-actions',children:[row.running&&row.mode!=='one-shot'&&jsx('button',{type:'button',className:'dsh-sam-stop-btn',disabled:stoppingIds.has(row.id),onClick:e=>{e.stopPropagation();stopAgent(row)},'aria-label':tr('pause.named',{name:row.name}),'title':tr('pauseSubagent'),children:stoppingIds.has(row.id)?tr('pausing'):tr('pause')}),jsx('button',{type:'button',className:'dsh-sam-hide-btn',onClick:e=>{e.stopPropagation();archive(row)},title:archived.has(row.id)?tr('unhide'):tr('hideTitle'),'aria-label':`${archived.has(row.id)?tr('unhide'):tr('hide')} ${row.name}`,children:archived.has(row.id)?tr('unhideShort'):tr('hideShort')}),jsx('button',{type:'button',className:'dsh-sam-delete-btn',onClick:e=>{e.stopPropagation();deleteSubagent(row)},title:tr('deleteForever'),'aria-label':tr('delete.named',{name:row.name}),children:tr('deleteTrash')})]}),prefs.showDetails!==false&&jsxs('div',{className:'dsh-sam-details',children:[jsx('div',{children:tr('statsLine',{input:fmt(tr,row.projectionValues?.tokenUsage?.uncachedInputTokens),output:fmt(tr,row.projectionValues?.tokenUsage?.outputTokens),cacheHit:row.projectionValues?.tokenUsage?.cacheReadTokens!=null&&tokenTotal(row)?Math.round(row.projectionValues.tokenUsage.cacheReadTokens/tokenTotal(row)*100):tr('unknown'),turns:row.projectionValues?.sessionStats?.turns??row.projectionValues?.turns??tr('unknown'),steps:row.projectionValues?.sessionStats?.steps??row.projectionValues?.steps??tr('unknown')})}),promptPreview(row)&&jsx('div',{children:tr('prompt.label',{prompt:promptPreview(row)})}),jsx(LiveOutput,{t:tr,parentId:row.parentId,childId:row.id,running:row.running,autoLoad:rows.slice(0,10).some(r=>r.id===row.id)||manualLoadedIds.has(row.id),live:(!row.running||(runningLiveIds?runningLiveIds.has(row.id):true)||manualLoadedIds.has(row.id)),onLoad:()=>setManualLoadedIds(prev=>new Set(prev).add(row.id))})]})]},row.id)),limit<allRows.length&&jsx('button',{type:'button',className:'dsh-sam-more',onClick:()=>setLimit(n=>n+PAGE),children:tr('loadMore',{remaining:allRows.length-limit})})]},name))})]})})]})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const NS='subagent-workspace-ui'
|
|
152
|
+
const zh={"activeFloat.title": "活跃子代理 · {count}", "age.dAgo": "{d} 天前", "age.hmAgo": "{h} 小时 {m} 分钟前", "age.mAgo": "{m} 分钟前", "age.sAgo": "{s} 秒前", "batch": "批量操作", "batch.delete": "批量删除 ({count})", "batch.hide": "批量隐藏 ({count})", "batchDeleteFailed": "批量删除失败:", "batchDeleteRequestFailed": "批量删除请求失败:", "batchUnhide": "批量显示", "callTool": "⚙ 调用工具 ", "categoryNamePrompt": "分类名称", "chip.count": "子代理 {active}/{total}", "clear": "清空", "clearSearch": "清空搜索", "collapseFilters": "⚙ 折叠 ▴", "collapseFiltersFull": "折叠筛选与配置", "command": "命令", "command.named": "⌘ {name}", "confirm.deleteCategory": "确认删除分类“{name}”?", "confirm.deleteMany": "确认永久删除选中的 {count} 个子代理?删除后不可恢复!", "confirm.deleteOne": "确认永久删除子代理“{name}”?删除后不可恢复!", "confirm.deleteRunning": "子代理“{name}”正在运行中,删除将强制终止它。确认继续?", "confirm.pauseNamed": "确认暂停子代理“{name}”?", "confirm.pauseSelected": "确认暂停选中的 {count} 个子代理?", "confirmHideAll": "确认隐藏当前筛选出的全部子代理?", "contextInjection": "上下文注入 · {name}", "continuable": "可继续", "dark": "深色", "delete.named": "删除 {name}", "deleteAll": "一键删除全部", "deleteCategory.named": "删除分类“{name}”", "deleteFailed": "删除失败:", "deleteForever": "永久删除该子代理", "deleteRequestFailed": "删除请求失败:", "deleteTrash": "🗑 删除", "done": "完成", "elapsed.hm": "{h}时{m}分", "elapsed.ms": "{m}分{s}秒", "elapsed.s": "{s}秒", "empty": "没有符合条件的子代理。", "expandFilters": "⚙ 展开筛选 ▾", "expandFiltersFull": "展开筛选与配置", "filterSort": "筛选排序", "group.active": "活跃子代理", "group.allResults": "全部结果", "group.other": "其他", "group.otherSessions": "其他会话", "grouping": "分组", "grouping.byCategory": "按分类", "grouping.bySession": "按会话", "grouping.byType": "按类型", "grouping.byWorkspace": "按工作区", "grouping.current": "分组 · {name}", "grouping.none": "不分组", "grouping.optionCategory": "分组:按分类", "grouping.optionNone": "分组:不分组", "grouping.optionSession": "分组:按会话", "grouping.optionType": "分组:按类型", "grouping.optionWorkspace": "分组:按工作区", "head.summary": "当前会话 {session} 个 · 当前工作区 {workspace} 个 · 活跃 {active} 个", "hidden": "已隐藏", "hide": "隐藏", "hideActiveFloat": "隐藏活跃子代理浮窗", "hideAll": "一键全部隐藏", "hideLongInactive": "隐藏长期未活跃", "hideNote": "隐藏仅在列表不显示,不删除会话", "hideOneShot": "隐藏一次性", "hideSelectedTitle": "将选中的子代理隐藏", "hideShort": "⊘ 隐藏", "hideTitle": "隐藏(仅在列表隐藏,不删除会话)", "lastActivity": "最近活动:{time}", "light": "浅色", "liveOutput": "实时输出", "liveOutputPrefix": "实时输出:", "loadHistoryTitle": "加载该子代理的历史最新消息", "loadLatest": "📥 加载最新消息", "loadMore": "加载下一页(剩余 {remaining} 个)", "loading": "⏳ 加载中...", "managerTitle": "子代理管理", "name": "名字", "newAgent": "新子代理:{name}", "newCategory": "+ 新建分类", "noParent": "无父会话", "oneShot": "一次性", "oneShotBadge": "⚡ 一次性", "openManager": "打开子代理管理", "pause": "⏸ 暂停", "pause.named": "暂停 {name}", "pauseAll": "⏸ 一键暂停", "pauseAllActive": "一键暂停所有活跃可继续子代理", "pauseSubagent": "暂停子代理", "pausing": "暂停中", "prompt.label": "提示词:{prompt}", "regexPrompt": "匹配正则(例如:^审计|review)", "resetFilters": "重置筛选", "scope": "范围", "scope.allSessions": "全部会话", "scope.allWorkspaces": "全部工作区", "scope.currentSession": "当前会话", "scope.currentWorkspace": "当前工作区", "scope.custom": "自定义范围", "scopeAria": "显示范围", "searchPlaceholder": "搜索名称、标题或工作区;输入 id: 搜索 Session ID", "select.named": "选择 {name}", "selectAll": "全选", "selectHoursPrompt": "选择多少小时前的子代理?", "selectOld": "选择 N 小时前", "session.currentDot": "当前会话 · {name}", "session.currentParen": "当前会话 ({name})", "session.currentWorkspaceDot": "当前工作区 · {name}", "session.named": "会话 · {name}", "showActiveFloat": "显示活跃浮窗", "showDetails": "显示详情", "showHidden": "显示已隐藏", "sort": "排序", "sort.current": "排序 · {name}", "sort.name": "名字", "sort.optionName": "排序:名字", "sort.optionRecent": "排序:最近活跃", "sort.optionType": "排序:类型", "sort.recent": "最近活跃", "sort.type": "类型", "statsLine": "输入 {input} / 输出 {output} · 缓存命中 {cacheHit}% · 轮数 {turns} · 步数 {steps}", "subagentBg": "子代理背景色", "subagentBgDarkTitle": "深色主题下的子代理背景色", "subagentBgLightTitle": "浅色主题下的子代理背景色", "summary.showing": "显示 {shown}/{total} 个", "tab.all": "全部", "tab.audit": "审计", "tab.implement": "实现", "tab.other": "其他", "tab.planning": "规划", "tab.test": "测试", "thinking": "思考中…", "toolCall": "工具调用", "type": "类型", "typeLoading": "类型待加载", "uncategorized": "未分类", "unhide": "取消隐藏", "unhideSelectedTitle": "取消隐藏选中的子代理", "unhideShort": "👁 显示", "unknown": "未知", "unknownError": "未知错误", "unknownWorkspace": "未知工作区", "workspace.named": "工作区 · {name}"}
|
|
153
|
+
const en={"activeFloat.title": "Active subagents · {count}", "age.dAgo": "{d}d ago", "age.hmAgo": "{h}h {m}m ago", "age.mAgo": "{m}m ago", "age.sAgo": "{s}s ago", "batch": "Batch", "batch.delete": "Delete ({count})", "batch.hide": "Hide ({count})", "batchDeleteFailed": "Batch delete failed: ", "batchDeleteRequestFailed": "Batch delete request failed: ", "batchUnhide": "Unhide", "callTool": "⚙ Call tool ", "categoryNamePrompt": "Category name", "chip.count": "Subagents {active}/{total}", "clear": "Clear", "clearSearch": "Clear search", "collapseFilters": "⚙ Collapse ▴", "collapseFiltersFull": "Collapse filters & options", "command": "Command", "command.named": "⌘ {name}", "confirm.deleteCategory": "Delete category \"{name}\"?", "confirm.deleteMany": "Permanently delete the selected {count} subagents? This cannot be undone!", "confirm.deleteOne": "Permanently delete subagent \"{name}\"? This cannot be undone!", "confirm.deleteRunning": "Subagent \"{name}\" is still running; deleting will force-terminate it. Continue?", "confirm.pauseNamed": "Pause subagent \"{name}\"?", "confirm.pauseSelected": "Pause the selected {count} subagents?", "confirmHideAll": "Hide ALL currently filtered subagents?", "contextInjection": "Context injection · {name}", "continuable": "continuable", "dark": "Dark", "delete.named": "Delete {name}", "deleteAll": "Delete all", "deleteCategory.named": "Delete category \"{name}\"", "deleteFailed": "Delete failed: ", "deleteForever": "Permanently delete this subagent", "deleteRequestFailed": "Delete request failed: ", "deleteTrash": "🗑 Delete", "done": "Done", "elapsed.hm": "{h}h{m}m", "elapsed.ms": "{m}m{s}s", "elapsed.s": "{s}s", "empty": "No subagents match the current filters.", "expandFilters": "⚙ Expand ▾", "expandFiltersFull": "Expand filters & options", "filterSort": "Filter & sort", "group.active": "Active subagents", "group.allResults": "All results", "group.other": "Other", "group.otherSessions": "Other sessions", "grouping": "Grouping", "grouping.byCategory": "by category", "grouping.bySession": "by session", "grouping.byType": "by type", "grouping.byWorkspace": "by workspace", "grouping.current": "Group · {name}", "grouping.none": "none", "grouping.optionCategory": "Group: by category", "grouping.optionNone": "Group: none", "grouping.optionSession": "Group: by session", "grouping.optionType": "Group: by type", "grouping.optionWorkspace": "Group: by workspace", "head.summary": "Current session {session} · Current workspace {workspace} · Active {active}", "hidden": "hidden", "hide": "Hide", "hideActiveFloat": "Hide the active-subagents float", "hideAll": "Hide all", "hideLongInactive": "Hide long-inactive", "hideNote": "Hiding only removes it from the list; the session is not deleted", "hideOneShot": "Hide one-shot", "hideSelectedTitle": "Hide the selected subagents", "hideShort": "⊘ Hide", "hideTitle": "Hide (hides from the list only; the session is not deleted)", "lastActivity": "Last activity: {time}", "light": "Light", "liveOutput": "Live output", "liveOutputPrefix": "Live output: ", "loadHistoryTitle": "Load the latest messages from this subagent’s history", "loadLatest": "📥 Load latest messages", "loadMore": "Load next page ({remaining} left)", "loading": "⏳ Loading...", "managerTitle": "Subagent manager", "name": "name", "newAgent": "New subagent: {name}", "newCategory": "+ New category", "noParent": "no parent session", "oneShot": "one-shot", "oneShotBadge": "⚡ one-shot", "openManager": "Open subagent manager", "pause": "⏸ Pause", "pause.named": "Pause {name}", "pauseAll": "⏸ Pause all", "pauseAllActive": "Pause all active continuable subagents", "pauseSubagent": "Pause subagent", "pausing": "Pausing…", "prompt.label": "Prompt: {prompt}", "regexPrompt": "Match regex (e.g. ^audit|review)", "resetFilters": "Reset filters", "scope": "Scope", "scope.allSessions": "All sessions", "scope.allWorkspaces": "All workspaces", "scope.currentSession": "Current session", "scope.currentWorkspace": "Current workspace", "scope.custom": "Custom scope", "scopeAria": "Scope", "searchPlaceholder": "Search names, titles, or workspaces; type id: to search Session IDs", "select.named": "Select {name}", "selectAll": "Select all", "selectHoursPrompt": "Select subagents from how many hours back?", "selectOld": "Select N hours ago", "session.currentDot": "Current session · {name}", "session.currentParen": "Current session ({name})", "session.currentWorkspaceDot": "Current workspace · {name}", "session.named": "Session · {name}", "showActiveFloat": "Show active float", "showDetails": "Show details", "showHidden": "Show hidden", "sort": "Sort", "sort.current": "Sort · {name}", "sort.name": "name", "sort.optionName": "Sort: name", "sort.optionRecent": "Sort: recent activity", "sort.optionType": "Sort: type", "sort.recent": "recent activity", "sort.type": "type", "statsLine": "in {input} / out {output} · cache hit {cacheHit}% · turns {turns} · steps {steps}", "subagentBg": "Subagent background color", "subagentBgDarkTitle": "Subagent background color in dark theme", "subagentBgLightTitle": "Subagent background color in light theme", "summary.showing": "Showing {shown}/{total}", "tab.all": "All", "tab.audit": "audit", "tab.implement": "implement", "tab.other": "Other", "tab.planning": "planning", "tab.test": "test", "thinking": "thinking…", "toolCall": "Tool call", "type": "type", "typeLoading": "type loading…", "uncategorized": "uncategorized", "unhide": "Unhide", "unhideSelectedTitle": "Unhide selected subagents", "unhideShort": "👁 Unhide", "unknown": "unknown", "unknownError": "unknown error", "unknownWorkspace": "Unknown workspace", "workspace.named": "Workspace · {name}"}
|
|
154
|
+
|
|
155
|
+
function apply(ctx){sessionsRt=ctx.sessions;ctx.effect(()=>ctx.locale.register(NS,{zh,en}),'subagent-workspace-ui: dictionaries');const actions={openChild:a=>ctx.sessions.openSubagent(a),openSession:id=>ctx.sessions.open(id),refresh:p=>ctx.sessions.refreshSubagents(p),setCatalogOpen:(p,o)=>ctx.sessions.setSubagentCatalogOpen(p,o)},face=()=>actions;ctx.slots.inject('conversation.session.header.actions',()=>ctx.slots.register({name:'conversation.session.header.actions',id:'subagent-workspace-manager',order:100,locale:NS,inject:face},Manager))}
|
|
156
|
+
return {inject:['sessions','slots','locale'],apply}
|
|
127
157
|
}
|
|
128
158
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-subagent-workspace-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Searchable workspace subagent manager for DeepSeek Harness Web",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,14 @@
|
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@deepseek-ai/cordis": "^4.0.1"
|
|
39
39
|
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"sucrase": "^3.35.1",
|
|
42
|
+
"typescript": "^7.0.2"
|
|
43
|
+
},
|
|
40
44
|
"scripts": {
|
|
41
|
-
"
|
|
45
|
+
"build": "node scripts/build.mjs",
|
|
46
|
+
"verify:build": "node scripts/verify-build.mjs",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"check": "node scripts/build.mjs && tsc --noEmit && node --check lib/index.js && node scripts/verify-fresh.mjs"
|
|
42
49
|
}
|
|
43
50
|
}
|