dsh-plugin-subagent-bridge 0.7.2 → 0.7.4

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 CHANGED
@@ -233,7 +233,7 @@ mkdir -p ~/.dsh/skills && cp -R skills/delegate-to-codex ~/.dsh/skills/
233
233
  node --test "test/*.test.mjs"
234
234
  ```
235
235
 
236
- 57 项:握手与版本协商、通知处理、工具清单、未知方法与未知工具、参数校验、元数据列表不含消息内容、派发调用形状、拒绝与错误透出、结果读取的时间基线、未派发会话的拒绝、长轮询(文本晚到即返回 / 超时 / 调用方取消)、真实 HTTP 往返(含 404/405/202 与 bearer 分支)、`codex exec` 事件解析、二进制解析、成功/失败/超时三种运行结果、resume 的参数分叉、工具结果的 lossless JSON 约束、**只回最终回答**(多步叙述被丢弃)、`dsh_wait` 的任一完成 / 超时 / 错误 / 未派发四种状态、`dsh_spawn` 立即返回与注册、`fork_turns=all` 走 fork、并发上限与 `dsh_close` 释放名额、`dsh_followup` 的重基线与最终回答切换、注册表落盘与重启后复原、冷会话下的缓存回答与 `offline` 状态、注册表 200 条上限的淘汰顺序、`maxHops` 拒绝回派而放行首层、在飞链路阻塞嵌套派发、速率突发的拒绝与窗口过期、followup 计入同一预算、握手版本号取自 `package.json`(不再硬编码)、阻塞式 `dsh_task` 不占 spawn 名额(重启后也不占)、按 `cwd` 分桶的每项目预算与全局上限、过期记录到期释放名额、超时返回 `running: true` 与续等指引、阻塞时长被夹到 240 秒以内。
236
+ 58 项:握手与版本协商、通知处理、工具清单、未知方法与未知工具、参数校验、元数据列表不含消息内容、派发调用形状、拒绝与错误透出、结果读取的时间基线、未派发会话的拒绝、长轮询(文本晚到即返回 / 超时 / 调用方取消)、真实 HTTP 往返(含 404/405/202 与 bearer 分支)、`codex exec` 事件解析、二进制解析、成功/失败/超时三种运行结果、resume 的参数分叉、工具结果的 lossless JSON 约束、**只回最终回答**(多步叙述被丢弃)、`dsh_wait` 的任一完成 / 超时 / 错误 / 未派发四种状态、`dsh_spawn` 立即返回与注册、`fork_turns=all` 走 fork、并发上限与 `dsh_close` 释放名额、`dsh_followup` 的重基线与最终回答切换、注册表落盘与重启后复原、冷会话下的缓存回答与 `offline` 状态、注册表 200 条上限的淘汰顺序、`maxHops` 拒绝回派而放行首层、在飞链路阻塞嵌套派发、速率突发的拒绝与窗口过期、followup 计入同一预算、握手版本号取自 `package.json`(不再硬编码)、新建的 worker 会按 `cwd` 自动归入对应工作区(不再落到「未分组」)、阻塞式 `dsh_task` 不占 spawn 名额(重启后也不占)、按 `cwd` 分桶的每项目预算与全局上限、过期记录到期释放名额、超时返回 `running: true` 与续等指引、阻塞时长被夹到 240 秒以内。
237
237
  `test/persistence.test.mjs` 单独覆盖持久化:文件权限 0600、缺失/损坏/畸形记录、spawn 返回时文件已落盘、完成即缓存、followup 清缓存、close 后重启仍为 closed、冷会话走缓存或 `offline`、并发写不串。
238
238
 
239
239
  ---
@@ -245,6 +245,8 @@ node --test "test/*.test.mjs"
245
245
  | [dsh-plugin-composer-predict](https://github.com/Dogtiti/dsh-plugin-composer-predict) | 预测下一条指令并显示为占位文字,`Tab` 采纳 |
246
246
  | [dsh-plugin-composer-history](https://github.com/Dogtiti/dsh-plugin-composer-history) | 输入框中按 `↑` / `↓` 回填历史消息 |
247
247
  | **dsh-plugin-subagent-bridge**(本仓库) | 让 Codex 通过本机 MCP 把 DSH 当 subagent 用(spawn / wait / followup),反向也能把任务派给 Codex |
248
+ | [dsh-plugin-usage-panel](https://github.com/Dogtiti/dsh-plugin-usage-panel) | 在模型选择器旁显示供应商套餐额度余量(目前 GLM Coding Plan),点开是明细浮层 |
249
+
248
250
 
249
251
  ## 许可
250
252
 
package/index.js CHANGED
@@ -612,6 +612,7 @@ export function createApi(ctx, state, settings) {
612
612
  } else {
613
613
  const opened = await service.create(cwd === undefined ? {} : { cwd })
614
614
  sessionId = opened?.sessionId
615
+ if (typeof sessionId === 'string' && sessionId !== '') await attachToWorkspace(ctx, sessionId, cwd ?? undefined)
615
616
  if (typeof sessionId !== 'string' || sessionId === '') throw new Error('session controller did not return a session id')
616
617
  }
617
618
 
@@ -695,6 +696,7 @@ export function createApi(ctx, state, settings) {
695
696
  if (targetId === undefined) {
696
697
  const opened = await service.create(cwd === undefined ? {} : { cwd })
697
698
  targetId = opened?.sessionId
699
+ if (typeof targetId === 'string' && targetId !== '') await attachToWorkspace(ctx, targetId, cwd ?? undefined)
698
700
  if (typeof targetId !== 'string' || targetId === '') throw new Error('session controller did not return a session id')
699
701
  created = true
700
702
  } else if (ctx.get('agents')?.get?.(targetId)?.status === 'running') {
@@ -1012,6 +1014,26 @@ function callerDepth(state, sessionId) {
1012
1014
  }
1013
1015
 
1014
1016
 
1017
+ /**
1018
+ * Place a freshly created session in the workspace its directory belongs to.
1019
+ * `sessionController.create` only records a working directory; the sidebar groups
1020
+ * live in a separate registry, so without this step a worker shows up as ungrouped.
1021
+ * @param ctx - Host context.
1022
+ * @param sessionId - session just created.
1023
+ * @param cwd - directory the session was opened in.
1024
+ */
1025
+ async function attachToWorkspace(ctx, sessionId, cwd) {
1026
+ if (typeof cwd !== 'string' || cwd === '') return
1027
+ try {
1028
+ const registry = ctx.get('workspaceRegistry')
1029
+ const workspace = await registry?.resolveByPath?.(cwd)
1030
+ await workspace?.attachSession?.(sessionId)
1031
+ } catch {
1032
+ /* Grouping is cosmetic: a failure here must not fail the dispatch. */
1033
+ }
1034
+ }
1035
+
1036
+
1015
1037
  /**
1016
1038
  * Restore the worker registry written by a previous process.
1017
1039
  * @param settings - resolved settings.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-subagent-bridge",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "type": "module",
5
5
  "description": "Subagent bridge: lets Codex delegate a task to DeepSeek Harness the way it would spawn a subagent (one call, waits for the answer), plus a codex_dispatch tool for the reverse direction.",
6
6
  "keywords": [
@@ -104,6 +104,23 @@ dsh_spawn({ "task_name": "continue_here", "fork_turns": "all",
104
104
  `fork_turns: "all"` 会 fork 那个会话作为 worker 的起点(继承到最近一个已完成 turn),worker 的后续改动**不会**污染原会话。默认 `"none"` 是全新空会话。
105
105
 
106
106
 
107
+ ## 让它自己并行(DSH 也有 subagent)
108
+
109
+ DSH **自带** `subagent` 工具(和这座桥无关,是它自己的能力,worker 在深度 0,可以开子 agent)。但它**默认不会用**——不提示就一个人串行干完。
110
+
111
+ 任务能拆成互不依赖的几块时,在 prompt 末尾加一句:
112
+
113
+ > 这几块互不依赖,可以用你自己的 subagent 并行处理,最后汇总。
114
+
115
+ 实测:4 个互不依赖的乘法 + 这句提示 → 它开了 **4 个 subagent 并行**,43 秒返回汇总,结果全对。不加这句,同样的活它串行做完。
116
+
117
+ 判断标准和 Codex 的 proactive 策略一致:
118
+
119
+ - ✅ 子任务互不依赖、并行能省时间或提高质量 → 加这句
120
+ - ❌ 有先后依赖、要改同一批文件、验收标准还没想清 → 不要加,串行更稳
121
+
122
+ DSH 自己的委派深度上限是 1:worker(depth 0)能开子 agent(depth 1),子 agent 不能再往下开。所以不会无限递归。
123
+
107
124
  ## 怎么写 prompt
108
125
 
109
126
  worker **看不到你这段对话**,它只有 `prompt` 和 `cwd`。写成可以独立开工的工单: