dsh-my-go 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KuoHu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # MyGO!!!!! 编排调度 | DSH
2
+
3
+ > **My** tasks, where to **GO**?????
4
+
5
+ dsh-my-go 是构建在 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH) 之上的**智能体编排系统**。
6
+
7
+ 它以星型 + 单线嵌套拓扑把 DSH 主会话(Sisyphus)与 7 个专业子智能体组织起来:Sisyphus 负责调度、审查与驳回,子智能体负责执行与汇报。参考了 oh-my-openagent 的编排设计。
8
+
9
+ ## 特性
10
+
11
+ - **星型拓扑**:所有子智能体(叶子)不直接通信,全部经 Sisyphus 中转。
12
+ - **单线阻塞**:同一时段只有一个子智能体运行,多余任务自动排队。
13
+ - **7 个专业工种**:Hermes(快速执行)、Explore(检索)、Librarian(文档)、Multimodal Looker(看图)、Hephaestus(写代码)、Prometheus(规划)、Oracle(调试 + 终验)。
14
+ - **按工种绑定模型**:快活小工用轻模型(mimo-v2.5),重活用重模型(deepseek-v4-pro-0813)。
15
+ - **4 个通信工具**:`go_work`(派发)、`continue`(驳回/追问)、`need_help`(求助挂起)、`forward`(转发),加 `orchestration_status`(状态总览)和 `list_subagents`(列出已有 sub-agent 及其最后 prompt)。
16
+ - **步骤级调度**:Prometheus 把需求拆成步骤序列,Sisyphus 逐步骤选择最省 token 的工种——轻活派轻工种、重活派重工种、同工种上下文连续则 `continue` 复用。
17
+ - **Sisyphus 质检规则**:结论不达标可驳回重做,被驳回的子智能体保留上下文继续。
18
+ - **WebUI 配置**:每个工种的模型 / 思考档位 / DSV4P0813 补丁开关,均可在 DSH 设置页配置。
19
+ - **UI 适配**:右侧编排面板树状图实时显示运行/队列/求助/历史;子智能体运行时自动跳转子会话,结束后跳回。
20
+ - **DSV4P0813 补丁开关**:让 DSV4Pro 发挥最大的实力。
21
+
22
+ ## 环境要求
23
+
24
+ ### 理论最低要求
25
+
26
+ - DeepSeek Harness `0.1.0-rc.6`+(基于 `agent/request` waterfall 与 continuable subagent API)
27
+ - Node.js 20+
28
+ - 一个可用的 LLM provider
29
+ - Windows / macOS / Linux(DSH 均支持)
30
+
31
+ ### 开发时的环境
32
+
33
+ - DSH `0.1.0-rc.8` + Windows 11 + Node.js 22(作者实际组合)
34
+
35
+ ## 快速开始
36
+
37
+ ### 安装(推荐:npm 插件)
38
+
39
+ ```bash
40
+ # 一条命令安装到 web profile
41
+ dsh plugin --profile web add dsh-my-go@latest --config.minimumReleaseAge=0
42
+ # 重启 dsh web 生效
43
+ dsh web
44
+ ```
45
+
46
+ 安装后 broker 插件(编排工具 + 模型绑定 + 树状图面板 + 设置页)自动挂载;
47
+ 会话预设「MyGO!!!!! 模式」提供 Sisyphus 的完整编排。
48
+
49
+ ### 最小示例
50
+
51
+ 新开一个 DSH 会话,预设选择 **MyGO!!!!! 模式**
52
+ 然后对 Sisyphus 说:
53
+
54
+ > 告诉我这个项目是干啥的。
55
+
56
+ ### 运行
57
+
58
+ ```bash
59
+ dsh web # 启动 Web GUI,新会话选择 MyGO!!!!! 模式
60
+ ```
61
+
62
+ ## 架构
63
+
64
+ ```
65
+ 用户 ──► Sisyphus(调度+质检)──► Hermes / Explore / Librarian / Looker
66
+ │ Hephaestus / Prometheus / Oracle
67
+ └── 单线阻塞队列 ◄── 所有子智能体结论回流
68
+ ```
69
+
70
+ - 子智能体 = DSH **continuable subagent**(`subagents.startContinuable`),
71
+ 持久化独立 Session,支持 `followup` 续接。
72
+ - 模型绑定 = 创建时 `agentOptions` + `agent/request` waterfall 覆盖
73
+ `reasoningEffort`(**跟随 DSH 模型目录**:只设置该模型实际支持的思考档位;
74
+ 模型无思考选项或档位不支持时不设置,走模型默认)。
75
+ - 单线阻塞 = broker 编排状态机(当前运行 / 队列 / 求助 / 历史)。
76
+ - 详细设计见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
77
+
78
+ ## 配置
79
+
80
+ broker 注册 settings 命名空间 `dsh-my-go`(WebUI 设置页「dsh-my-go 编排」):
81
+
82
+ | 配置项 | 默认值 | 说明 |
83
+ | ------ | ------ | ---- |
84
+ | `agents.<type>.provider` | 继承父级 | 该工种的 provider 路由 |
85
+ | `agents.<type>.model` | 见表 | 该工种的模型 |
86
+ | `agents.<type>.reasoningEffort` | 见表 | 期望思考档位(如 high/max);**只在模型实际支持时应用**,否则走模型默认 |
87
+ | `agents.<type>.dsv4p0813` | false | 是否对该工种启用 DSV4P0813 两阶段锚定补丁 |
88
+
89
+ 工种模型(建议):
90
+
91
+ | 工种 | 模型 | Effort |
92
+ | --- | --- | --- |
93
+ | Sisyphus | 用户所选 | high |
94
+ | Hermes / Explore / Librarian / Looker | mimo-v2.5 | default |
95
+ | Hephaestus | deepseek-v4-flash | high |
96
+ | Prometheus | deepseek-v4-pro | max |
97
+ | Oracle | deepseek-v4-pro | max |
98
+
99
+ ## 智能体 Prompt
100
+
101
+ 每个工种的完整 persona / 职责 / 汇报格式见 [`prompts/`](prompts/):
102
+
103
+ | 文件 | 工种 |
104
+ | --- | --- |
105
+ | [prompts/sisyphus.md](prompts/sisyphus.md) | 总调度 + 质检官 |
106
+ | [prompts/hermes.md](prompts/hermes.md) | 快速执行 |
107
+ | [prompts/explore.md](prompts/explore.md) | 快速检索 |
108
+ | [prompts/librarian.md](prompts/librarian.md) | 文档查询 |
109
+ | [prompts/looker.md](prompts/looker.md) | 多模态识别 |
110
+ | [prompts/hephaestus.md](prompts/hephaestus.md) | 代码编写 |
111
+ | [prompts/prometheus.md](prompts/prometheus.md) | 需求规划 |
112
+ | [prompts/oracle.md](prompts/oracle.md) | 架构调试 + 终验 |
113
+
114
+ ## 目录结构
115
+
116
+ ```
117
+ dsh-my-go/
118
+ ├── AGENTS.md # 本项目的编排规格(Sisyphus 系统)
119
+ ├── README.md # 本文档
120
+ ├── package.json # npm 包声明(dsh.bundle.patch → cordis.patch.yml)
121
+ ├── cordis.patch.yml # bundle patch(dsh plugin add 后自动挂载 host 插件)
122
+ ├── lib/index.js # npm 包 host 半(编排工具 + 状态机 + 模型绑定)
123
+ ├── src/client.js # client 半源码(树状图面板 / 设置页 / 自动跳转)
124
+ ├── scripts/build-client.mjs # esbuild 打包 client → dist/client.js
125
+ ├── dist/ # 构建产物(发布时生成)
126
+ ├── preset/ # agent preset「MyGO!!!!! 模式」(复制到 ~/.dsh/.agent-presets/)
127
+ │ ├── preset.yml
128
+ │ ├── agent.cordis.yml
129
+ │ └── tools/broker.mjs # 自包含 host 插件(工具 + 模型绑定 + 状态机)
130
+ ├── broker/ # broker 插件 TS 源码(参考实现)
131
+ ├── prompts/ # 8 个智能体 prompt
132
+ └── docs/ARCHITECTURE.md # 架构设计
133
+ ```
134
+
135
+ ## 贡献
136
+
137
+ ```bash
138
+ git clone git@github.com:daizihan233/dsh-my-go.git
139
+ cd dsh-my-go
140
+ bun install
141
+ bun run build:client # 构建 client bundle
142
+ bunx tsc --noEmit # 类型检查
143
+ bun run test # 冒烟测试
144
+ ```
145
+
146
+ ## 维护状态
147
+
148
+ - 开发中
149
+ - 已知限制:
150
+ - 子智能体模型绑定依赖 `agent/request` waterfall(DSH 未原生支持动态子代理模型,
151
+ 见 [dsh-handbook 9.2](https://github.com/deepseek-ai/deepseek-harness/discussions/118));
152
+ - 结论注入依赖 `subagent/end` 事件;`reportFrom` 为子→父补充通道。
153
+ - 单线阻塞由 broker 状态机执行;Sisyphus 需遵守编排规则(由 system-prompt section 约束)。
154
+ - 感谢以下一位开发者:
155
+ - DeepSeek V4 Flash 0731
156
+
157
+ ## 许可证
158
+
159
+ [MIT](LICENSE) © dsh-my-go contributors
@@ -0,0 +1,8 @@
1
+ # dsh-my-go bundle layer — applied automatically when a profile lists this
2
+ # package in dsh.profile.bundles (via the dsh.bundle.patch declaration in
3
+ # package.json). `dsh plugin --profile web add dsh-my-go` installs the
4
+ # dependency and reconciles the bundle list, so this patch takes effect on
5
+ # the next `dsh web` boot without any manual configuration.
6
+ - insert:
7
+ - id: dsh-my-go
8
+ name: 'dsh-my-go'
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name2 in all)
8
+ __defProp(target, name2, { get: all[name2], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/client.js
21
+ var client_exports = {};
22
+ __export(client_exports, {
23
+ apply: () => apply,
24
+ inject: () => inject,
25
+ name: () => name
26
+ });
27
+ module.exports = __toCommonJS(client_exports);
28
+ var name = "dsh-my-go";
29
+ var inject = ["slots"];
30
+ function apply(ctx) {
31
+ const client = ctx;
32
+ const slots = client.get("slots");
33
+ if (!slots) return;
34
+ const host = client.get("host");
35
+ const sessions = client.get("sessions");
36
+ const timer = client.get("timer");
37
+ let panelOpen = false;
38
+ let snapshot = { seq: 0, current: null, queue: [], helpRequests: [], history: [] };
39
+ const listeners = /* @__PURE__ */ new Set();
40
+ const emit = () => {
41
+ for (const l of [...listeners]) {
42
+ try {
43
+ l();
44
+ } catch {
45
+ }
46
+ }
47
+ };
48
+ async function refresh() {
49
+ if (!host || typeof host.call !== "function") return;
50
+ try {
51
+ const next = await host.call("dsh-my-go/snapshot");
52
+ const changed = next && next.seq !== snapshot.seq;
53
+ if (next) snapshot = next;
54
+ if (changed) emit();
55
+ } catch {
56
+ }
57
+ }
58
+ const stopPolling = timer && typeof timer.interval === "function" ? timer.interval(() => {
59
+ void refresh();
60
+ }, 600) : void 0;
61
+ function statusGlyph(status) {
62
+ switch (status) {
63
+ case "running":
64
+ return "\u25CF";
65
+ case "waiting":
66
+ return "\u2753";
67
+ case "spawning":
68
+ return "\u25D0";
69
+ case "queued":
70
+ return "\u23F3";
71
+ case "done":
72
+ return "\u2713";
73
+ case "failed":
74
+ return "\u2717";
75
+ default:
76
+ return "\u25CB";
77
+ }
78
+ }
79
+ function TreePanel(_props) {
80
+ const [open, setOpen] = React.useState(panelOpen);
81
+ const [, force] = React.useState(0);
82
+ React.useEffect(() => {
83
+ const unsub2 = () => listeners.delete(force);
84
+ listeners.add(force);
85
+ return unsub2;
86
+ }, []);
87
+ if (!open) return null;
88
+ const s = snapshot;
89
+ const node = (label, status, childId, onClick) => React.createElement(
90
+ "div",
91
+ {
92
+ style: { padding: "2px 8px", cursor: onClick ? "pointer" : "default", display: "flex", gap: 8, alignItems: "center" },
93
+ onClick
94
+ },
95
+ React.createElement("span", null, status),
96
+ React.createElement("span", null, label),
97
+ childId ? React.createElement("span", { style: { color: "#888", fontSize: 11 } }, childId) : null
98
+ );
99
+ const jump = (childId) => {
100
+ if (sessions && typeof sessions.openSubagent === "function") {
101
+ sessions.openSubagent({ parentSessionId: "", childSessionId: childId, mode: "continuable" });
102
+ }
103
+ };
104
+ const current = s.current;
105
+ return React.createElement(
106
+ "div",
107
+ {
108
+ style: {
109
+ position: "fixed",
110
+ top: 64,
111
+ right: 16,
112
+ width: 320,
113
+ maxHeight: "70vh",
114
+ overflowY: "auto",
115
+ background: "var(--surface, #1e1e1e)",
116
+ border: "1px solid var(--separator, #333)",
117
+ borderRadius: 8,
118
+ padding: 12,
119
+ zIndex: 9999,
120
+ fontFamily: "var(--font, sans-serif)",
121
+ fontSize: 13
122
+ }
123
+ },
124
+ React.createElement(
125
+ "div",
126
+ { style: { display: "flex", justifyContent: "space-between", marginBottom: 8 } },
127
+ React.createElement("strong", null, "Sisyphus \u7F16\u6392"),
128
+ React.createElement("button", { onClick: () => setOpen(false) }, "\xD7")
129
+ ),
130
+ React.createElement(
131
+ "div",
132
+ { style: { marginBottom: 8 } },
133
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, "\u8FD0\u884C\u4E2D"),
134
+ current ? node(current.agentType ?? "?", statusGlyph(current.status), current.childId, () => current.childId && jump(current.childId)) : React.createElement("div", { style: { color: "#888" } }, "\u25CB \u7A7A\u95F2")
135
+ ),
136
+ React.createElement(
137
+ "div",
138
+ { style: { marginBottom: 8 } },
139
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u961F\u5217 (${s.queue.length})`),
140
+ s.queue.map((w) => node(String(w.agentType ?? "?"), "\u23F3"))
141
+ ),
142
+ React.createElement(
143
+ "div",
144
+ { style: { marginBottom: 8 } },
145
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u6C42\u52A9 (${s.helpRequests.length})`),
146
+ s.helpRequests.map((h) => node(`[${h.intent ?? "?"}]`, "\u2753", h.childId, () => h.childId && jump(h.childId)))
147
+ ),
148
+ React.createElement(
149
+ "div",
150
+ null,
151
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u5386\u53F2 (${s.history.length})`),
152
+ s.history.slice(-8).map((r) => {
153
+ const rec = r;
154
+ return node(`${rec.agentType ?? "?"} \u2014 ${String(rec.conclusion ?? "").replace(/\s+/g, " ").slice(0, 60)}`, statusGlyph(rec.status), rec.childId, () => rec.childId && jump(rec.childId));
155
+ })
156
+ )
157
+ );
158
+ }
159
+ slots.inject("shell.overlay", () => slots.register(
160
+ { name: "shell.overlay", id: "dsh-my-go-panel" },
161
+ (props) => React.createElement(TreePanel, props)
162
+ ));
163
+ slots.inject("sidebar.footer.action", () => slots.register(
164
+ { name: "sidebar.footer.action", id: "dsh-my-go-toggle" },
165
+ (props) => React.createElement("button", {
166
+ onClick: () => {
167
+ panelOpen = !panelOpen;
168
+ emit();
169
+ },
170
+ title: "Sisyphus \u7F16\u6392\u9762\u677F",
171
+ style: { width: props && props.wide ? "100%" : 32, height: 32, border: "none", background: "transparent", cursor: "pointer" }
172
+ }, "\u{1F9ED}")
173
+ ));
174
+ slots.inject("settings.section", () => slots.register(
175
+ { name: "settings.section", id: "dsh-my-go", order: 30, label: "MyGO \u7F16\u6392" },
176
+ (props) => React.createElement(SettingsPage, props)
177
+ ));
178
+ function SettingsPage(_props) {
179
+ return React.createElement(
180
+ "div",
181
+ { style: { padding: 16 } },
182
+ React.createElement("h2", null, "MyGO \u7F16\u6392\u914D\u7F6E"),
183
+ React.createElement("p", null, "\u6BCF\u4E2A\u5B50\u667A\u80FD\u4F53\u7684\u6A21\u578B / \u601D\u8003\u7A0B\u5EA6 / DSV4P0813 \u8865\u4E01\u5F00\u5173\u3002\u4FEE\u6539\u540E\u901A\u8FC7 Settings \u670D\u52A1\u6301\u4E45\u5316\u3002"),
184
+ React.createElement("div", { style: { color: "#888", marginTop: 12 } }, "\u914D\u7F6E\u9879\u7531 host \u4FA7 settings \u547D\u540D\u7A7A\u95F4 dsh-my-go \u63D0\u4F9B\uFF1B\u4FEE\u6539\u540E\u751F\u6548\u4E8E\u4E0B\u4E00\u6B21\u6D3E\u53D1\u3002")
185
+ );
186
+ }
187
+ let lastJumpedTo = null;
188
+ const unsub = () => {
189
+ listeners.delete(refresh);
190
+ };
191
+ listeners.add(refresh);
192
+ const stopAutoJump = timer && typeof timer.interval === "function" ? timer.interval(() => {
193
+ const current = snapshot.current;
194
+ if (current && current.childId && current.status === "running" && lastJumpedTo !== current.childId && sessions) {
195
+ lastJumpedTo = current.childId;
196
+ sessions.openSubagent({ parentSessionId: "", childSessionId: current.childId, mode: "continuable" });
197
+ } else if (!current && lastJumpedTo && sessions) {
198
+ lastJumpedTo = null;
199
+ }
200
+ }, 800) : void 0;
201
+ return () => {
202
+ if (stopPolling) stopPolling();
203
+ if (stopAutoJump) stopAutoJump();
204
+ unsub();
205
+ };
206
+ }
package/dist/client.js ADDED
@@ -0,0 +1,215 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-my-go",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ "use strict";
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __export = (target, all) => {
12
+ for (var name2 in all)
13
+ __defProp(target, name2, { get: all[name2], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
+
25
+ // src/client.js
26
+ var client_exports = {};
27
+ __export(client_exports, {
28
+ apply: () => apply,
29
+ inject: () => inject,
30
+ name: () => name
31
+ });
32
+ module.exports = __toCommonJS(client_exports);
33
+ var name = "dsh-my-go";
34
+ var inject = ["slots"];
35
+ function apply(ctx) {
36
+ const client = ctx;
37
+ const slots = client.get("slots");
38
+ if (!slots) return;
39
+ const host = client.get("host");
40
+ const sessions = client.get("sessions");
41
+ const timer = client.get("timer");
42
+ let panelOpen = false;
43
+ let snapshot = { seq: 0, current: null, queue: [], helpRequests: [], history: [] };
44
+ const listeners = /* @__PURE__ */ new Set();
45
+ const emit = () => {
46
+ for (const l of [...listeners]) {
47
+ try {
48
+ l();
49
+ } catch {
50
+ }
51
+ }
52
+ };
53
+ async function refresh() {
54
+ if (!host || typeof host.call !== "function") return;
55
+ try {
56
+ const next = await host.call("dsh-my-go/snapshot");
57
+ const changed = next && next.seq !== snapshot.seq;
58
+ if (next) snapshot = next;
59
+ if (changed) emit();
60
+ } catch {
61
+ }
62
+ }
63
+ const stopPolling = timer && typeof timer.interval === "function" ? timer.interval(() => {
64
+ void refresh();
65
+ }, 600) : void 0;
66
+ function statusGlyph(status) {
67
+ switch (status) {
68
+ case "running":
69
+ return "\u25CF";
70
+ case "waiting":
71
+ return "\u2753";
72
+ case "spawning":
73
+ return "\u25D0";
74
+ case "queued":
75
+ return "\u23F3";
76
+ case "done":
77
+ return "\u2713";
78
+ case "failed":
79
+ return "\u2717";
80
+ default:
81
+ return "\u25CB";
82
+ }
83
+ }
84
+ function TreePanel(_props) {
85
+ const [open, setOpen] = React.useState(panelOpen);
86
+ const [, force] = React.useState(0);
87
+ React.useEffect(() => {
88
+ const unsub2 = () => listeners.delete(force);
89
+ listeners.add(force);
90
+ return unsub2;
91
+ }, []);
92
+ if (!open) return null;
93
+ const s = snapshot;
94
+ const node = (label, status, childId, onClick) => React.createElement(
95
+ "div",
96
+ {
97
+ style: { padding: "2px 8px", cursor: onClick ? "pointer" : "default", display: "flex", gap: 8, alignItems: "center" },
98
+ onClick
99
+ },
100
+ React.createElement("span", null, status),
101
+ React.createElement("span", null, label),
102
+ childId ? React.createElement("span", { style: { color: "#888", fontSize: 11 } }, childId) : null
103
+ );
104
+ const jump = (childId) => {
105
+ if (sessions && typeof sessions.openSubagent === "function") {
106
+ sessions.openSubagent({ parentSessionId: "", childSessionId: childId, mode: "continuable" });
107
+ }
108
+ };
109
+ const current = s.current;
110
+ return React.createElement(
111
+ "div",
112
+ {
113
+ style: {
114
+ position: "fixed",
115
+ top: 64,
116
+ right: 16,
117
+ width: 320,
118
+ maxHeight: "70vh",
119
+ overflowY: "auto",
120
+ background: "var(--surface, #1e1e1e)",
121
+ border: "1px solid var(--separator, #333)",
122
+ borderRadius: 8,
123
+ padding: 12,
124
+ zIndex: 9999,
125
+ fontFamily: "var(--font, sans-serif)",
126
+ fontSize: 13
127
+ }
128
+ },
129
+ React.createElement(
130
+ "div",
131
+ { style: { display: "flex", justifyContent: "space-between", marginBottom: 8 } },
132
+ React.createElement("strong", null, "Sisyphus \u7F16\u6392"),
133
+ React.createElement("button", { onClick: () => setOpen(false) }, "\xD7")
134
+ ),
135
+ React.createElement(
136
+ "div",
137
+ { style: { marginBottom: 8 } },
138
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, "\u8FD0\u884C\u4E2D"),
139
+ current ? node(current.agentType ?? "?", statusGlyph(current.status), current.childId, () => current.childId && jump(current.childId)) : React.createElement("div", { style: { color: "#888" } }, "\u25CB \u7A7A\u95F2")
140
+ ),
141
+ React.createElement(
142
+ "div",
143
+ { style: { marginBottom: 8 } },
144
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u961F\u5217 (${s.queue.length})`),
145
+ s.queue.map((w) => node(String(w.agentType ?? "?"), "\u23F3"))
146
+ ),
147
+ React.createElement(
148
+ "div",
149
+ { style: { marginBottom: 8 } },
150
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u6C42\u52A9 (${s.helpRequests.length})`),
151
+ s.helpRequests.map((h) => node(`[${h.intent ?? "?"}]`, "\u2753", h.childId, () => h.childId && jump(h.childId)))
152
+ ),
153
+ React.createElement(
154
+ "div",
155
+ null,
156
+ React.createElement("div", { style: { fontWeight: 600, marginBottom: 4 } }, `\u5386\u53F2 (${s.history.length})`),
157
+ s.history.slice(-8).map((r) => {
158
+ const rec = r;
159
+ return node(`${rec.agentType ?? "?"} \u2014 ${String(rec.conclusion ?? "").replace(/\s+/g, " ").slice(0, 60)}`, statusGlyph(rec.status), rec.childId, () => rec.childId && jump(rec.childId));
160
+ })
161
+ )
162
+ );
163
+ }
164
+ slots.inject("shell.overlay", () => slots.register(
165
+ { name: "shell.overlay", id: "dsh-my-go-panel" },
166
+ (props) => React.createElement(TreePanel, props)
167
+ ));
168
+ slots.inject("sidebar.footer.action", () => slots.register(
169
+ { name: "sidebar.footer.action", id: "dsh-my-go-toggle" },
170
+ (props) => React.createElement("button", {
171
+ onClick: () => {
172
+ panelOpen = !panelOpen;
173
+ emit();
174
+ },
175
+ title: "Sisyphus \u7F16\u6392\u9762\u677F",
176
+ style: { width: props && props.wide ? "100%" : 32, height: 32, border: "none", background: "transparent", cursor: "pointer" }
177
+ }, "\u{1F9ED}")
178
+ ));
179
+ slots.inject("settings.section", () => slots.register(
180
+ { name: "settings.section", id: "dsh-my-go", order: 30, label: "MyGO \u7F16\u6392" },
181
+ (props) => React.createElement(SettingsPage, props)
182
+ ));
183
+ function SettingsPage(_props) {
184
+ return React.createElement(
185
+ "div",
186
+ { style: { padding: 16 } },
187
+ React.createElement("h2", null, "MyGO \u7F16\u6392\u914D\u7F6E"),
188
+ React.createElement("p", null, "\u6BCF\u4E2A\u5B50\u667A\u80FD\u4F53\u7684\u6A21\u578B / \u601D\u8003\u7A0B\u5EA6 / DSV4P0813 \u8865\u4E01\u5F00\u5173\u3002\u4FEE\u6539\u540E\u901A\u8FC7 Settings \u670D\u52A1\u6301\u4E45\u5316\u3002"),
189
+ React.createElement("div", { style: { color: "#888", marginTop: 12 } }, "\u914D\u7F6E\u9879\u7531 host \u4FA7 settings \u547D\u540D\u7A7A\u95F4 dsh-my-go \u63D0\u4F9B\uFF1B\u4FEE\u6539\u540E\u751F\u6548\u4E8E\u4E0B\u4E00\u6B21\u6D3E\u53D1\u3002")
190
+ );
191
+ }
192
+ let lastJumpedTo = null;
193
+ const unsub = () => {
194
+ listeners.delete(refresh);
195
+ };
196
+ listeners.add(refresh);
197
+ const stopAutoJump = timer && typeof timer.interval === "function" ? timer.interval(() => {
198
+ const current = snapshot.current;
199
+ if (current && current.childId && current.status === "running" && lastJumpedTo !== current.childId && sessions) {
200
+ lastJumpedTo = current.childId;
201
+ sessions.openSubagent({ parentSessionId: "", childSessionId: current.childId, mode: "continuable" });
202
+ } else if (!current && lastJumpedTo && sessions) {
203
+ lastJumpedTo = null;
204
+ }
205
+ }, 800) : void 0;
206
+ return () => {
207
+ if (stopPolling) stopPolling();
208
+ if (stopAutoJump) stopAutoJump();
209
+ unsub();
210
+ };
211
+ }
212
+
213
+ return module.exports;
214
+ }
215
+ });