@huanlin/dsh-plugin-yet-another-subagent 0.1.2 → 0.1.3

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.
Files changed (4) hide show
  1. package/README.md +136 -130
  2. package/lib/client.js +1578 -1436
  3. package/lib/index.js +5487 -5225
  4. package/package.json +158 -158
package/README.md CHANGED
@@ -1,130 +1,136 @@
1
- # yet-another-subagent
2
-
3
- 可配置的子代理(subagent)profile 系统,提供单一 `subagent` 工具 + `profile` 参数选择,支持 Web UI 设置、实时进度展示(工具调用/token/活动)、子代理树标签页、点击跳转子会话。
4
-
5
- ## 架构
6
-
7
- bundle,三入口(host `.` + invariant `./invariant` + client `./client`)。
8
-
9
- - **Host 半**(`src/index.ts`):
10
- - 单一 `subagent` 工具,通过 `profile` 枚举参数选择 profile(非每 profile 一个工具)
11
- - 复用官方 `spawn` provider,支持前台(foreground)和后台(continuable / one-shot)两种模式
12
- - Profile 状态通过 settings seam 持久化到 `$DSH_HOME/settings.yaml`
13
- - RPC CRUD:`profiles.list` / `.add` / `.update` / `.remove`(专用 `/ya-subagent` 通道,不共享 `/api`)
14
- - 两个 session projection:`subagentProfile`(父会话 childId→profileId 映射 + callId→childId)+ `yaSubagentProgress`(子会话实时 toolcall/token/活动状态)
15
- - **Client 半**(`src/client/index.ts`):
16
- - `settings.section` Profile 编辑页
17
- - `tool.call.toolview`(key `subagent`)— `SubagentCard` 工具调用卡片
18
- - `conversation.view`(id `subagent-tree`)— `SubagentTreeView` 子代理树标签页
19
-
20
- `cordis.patch.yml` 只禁用官方 `tool-subagent`(spawn 路径),保留 `tool-subagent-fork`(无名称冲突)。
21
-
22
- ## 配置
23
-
24
- ```yaml
25
- # cordis.patch.yml
26
- - id: tool-subagent
27
- disabled: true
28
-
29
- - insert:
30
- - id: yet-another-subagent
31
- name: '@huanlin/dsh-plugin-yet-another-subagent'
32
- config:
33
- profiles:
34
- - id: general
35
- label: General
36
- model: { kind: 'auto' }
37
- persona: { kind: 'inherit' }
38
- toolFilter: { kind: 'none' }
39
- maxDepth: 3
40
- backgroundMode: continuable
41
- builtin: true
42
- generalFixed: true
43
- ```
44
-
45
- ### Profile 字段
46
-
47
- | 字段 | 类型 | 默认值 | 说明 |
48
- |------|------|--------|------|
49
- | `id` | `string`(小写字母/数字/连字符,1-32 字符) | — | Profile 唯一标识 |
50
- | `label` | `string` | — | 显示名 |
51
- | `model.kind` | `'auto'` \| `'manual'` | — | `auto` 继承父代理模型;`manual` 指定 |
52
- | `model.provider` | `string` | `''` | Provider(仅 `manual` 时使用) |
53
- | `model.model` | `string` | `''` | 模型 ID(仅 `manual` 时使用) |
54
- | `persona.kind` | `'inherit'` \| `'custom'` | `'inherit'` | `inherit` 跟随部署人设;`custom` 自定义 |
55
- | `persona.text` | `string` | `''` | 自定义人设文本(仅 `custom` 时使用) |
56
- | `toolFilter.kind` | `'none'` \| `'allow'` \| `'deny'` | `'none'` | 工具过滤策略 |
57
- | `toolFilter.tools` | `string[]` | `[]` | 过滤工具列表 |
58
- | `maxDepth` | `number` | `3` | 最大递归深度 |
59
- | `backgroundMode` | `'continuable'` \| `'one-shot'` | `'continuable'` | `run_in_background: true` 时的后台策略 |
60
- | `builtin` | `boolean` | `false` | 是否为内置 profile(仅展示用) |
61
-
62
- ## 开发
63
-
64
- ```sh
65
- pnpm install # 安装开发依赖 + zod(唯一运行时 npm 依赖)
66
- pnpm run typecheck # tsc --noEmit(通过 ../dsh 解析 DSH 源码)
67
- pnpm test # vitest run
68
- pnpm run build # tsc + tsdown → lib/index.js, lib/invariant.js, lib/client.js
69
- ```
70
-
71
- ### 类型检查
72
-
73
- `tsconfig.json` 继承 `../dsh/tsconfig.base.client.json`,通过 `pnpm-workspace.yaml` `packages/*/*` glob 解析 DSH checkout 的源码。需在 `../dsh` 存在 DSH checkout 的同级目录下运行。
74
-
75
- ## 运行
76
-
77
- ```sh
78
- # 本地引用(开发热更新)
79
- dsh plugin --profile web add "link:D:/Projects/deepseek-harness/yet-another-subagent"
80
-
81
- # 远端引用(分发/部署)
82
- dsh plugin --profile web add "github:huanlinoto/dsh-plugin-yet-another-subagent"
83
- ```
84
-
85
- 安装后重启 `dsh web` 进程,浏览器硬刷新(`Ctrl+Shift+R`)。
86
-
87
- ## 检查
88
-
89
- ```sh
90
- pnpm run typecheck # 0 errors
91
- pnpm test # 55 tests passing
92
- pnpm run build # lib/index.js + lib/invariant.js + lib/client.js
93
- ```
94
-
95
- ### 产物验证
96
-
97
- - `lib/index.js` Host bundle
98
- - `lib/invariant.js` Invariant companion
99
- - `lib/client.js` — Client bundle(CSS-modules inline,`d` 前缀 hash 防 CSS 类名数字开头)
100
- - `cordis.patch.yml` — Bundle patch layer
101
-
102
- ## 持久化
103
-
104
- Profile 状态通过 DSH settings seam 持久化到 `$DSH_HOME/settings.yaml` 的 `ya-subagent` 命名空间。cordis.yml 的 `profiles` 字段是组合 `base`(首次启动种子),运行时变更通过 `scope.replace()` 写入用户层。外部 yaml 编辑通过 `scope.watch` 热重载。
105
-
106
- settings provider 的无头组装回退到内存状态(仅 cordis.yml 种子,不持久化)。
107
-
108
- ## RPC API
109
-
110
- Profile CRUD host 的专用 `/ya-subagent` 通道(不共享 `/api`,避免与 Typert gateway 的单拦截器冲突):
111
-
112
- | endpoint | payload | result (ok) |
113
- |----------|---------|-------------|
114
- | `profiles.list` | `{}` | `{ profiles: SubagentProfile[] }` |
115
- | `profiles.add` | `{ profile: SubagentProfile }` | `{ profiles: SubagentProfile[] }` |
116
- | `profiles.update` | `{ profile: SubagentProfile }` | `{ profiles: SubagentProfile[] }` |
117
- | `profiles.remove` | `{ id: string }` | `{ profiles: SubagentProfile[] }` |
118
- | `tools.list` | `{}` | `{ tools: { name, description }[] }` |
119
-
120
- URL 形如 `POST /ya-subagent/profiles.list`。业务错误返回 `{ ok: false, error: { code: 'internal', message } }`。
121
-
122
- ## 已知限制
123
-
124
- - **旧会话不兼容**:`completed <label> subagent <id>` render 格式变更后,旧会话的结果文本无法被 `parseResult` 匹配,卡片不可点击。仅新会话(host 重启后)正常。
125
- - **`yaSubagentProgress` stateVersion 2**:projection schema 变更(`activity` 字段 + `assistant/chunk` fold)需要 host 重启才能生效。
126
-
127
- ## 设计参考
128
-
129
- - 官方 continuable subagent 设计:`.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md`
130
- - 插件开发指南:`plugin-development-guide.md`
1
+ <p align="center">
2
+ <a href="https://dshfind.com/zh/plugins/huanlinoto/dsh-plugin-yet-another-subagent"><img src="https://dshfind.com/api/card/huanlinoto/dsh-plugin-yet-another-subagent?lang=zh" alt="dsh-plugin-yet-another-subagent card"></a>
3
+ </p>
4
+
5
+ # yet-another-subagent
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@huanlin/dsh-plugin-yet-another-subagent)](https://www.npmjs.com/package/@huanlin/dsh-plugin-yet-another-subagent)
8
+
9
+ 可配置的子代理(subagent)profile 系统,提供单一 `subagent` 工具 + `profile` 参数选择,支持 Web UI 设置、实时进度展示(工具调用/token/活动)、子代理树标签页、点击跳转子会话。
10
+
11
+ ## 架构
12
+
13
+ bundle,三入口(host `.` + invariant `./invariant` + client `./client`)。
14
+
15
+ - **Host 半**(`src/index.ts`):
16
+ - 单一 `subagent` 工具,通过 `profile` 枚举参数选择 profile(非每 profile 一个工具)
17
+ - 复用官方 `spawn` provider,支持前台(foreground)和后台(continuable / one-shot)两种模式
18
+ - Profile 状态通过 settings seam 持久化到 `$DSH_HOME/settings.yaml`
19
+ - RPC CRUD:`profiles.list` / `.add` / `.update` / `.remove`(专用 `/ya-subagent` 通道,不共享 `/api`)
20
+ - 两个 session projection:`subagentProfile`(父会话 childId→profileId 映射 + callId→childId)+ `yaSubagentProgress`(子会话实时 toolcall/token/活动状态)
21
+ - **Client 半**(`src/client/index.ts`):
22
+ - `settings.section` — Profile 编辑页
23
+ - `tool.call.toolview`(key `subagent`)— `SubagentCard` 工具调用卡片
24
+ - `conversation.view`(id `subagent-tree`)— `SubagentTreeView` 子代理树标签页
25
+
26
+ `cordis.patch.yml` 只禁用官方 `tool-subagent`(spawn 路径),保留 `tool-subagent-fork`(无名称冲突)。
27
+
28
+ ## 配置
29
+
30
+ ```yaml
31
+ # cordis.patch.yml
32
+ - id: tool-subagent
33
+ disabled: true
34
+
35
+ - insert:
36
+ - id: yet-another-subagent
37
+ name: '@huanlin/dsh-plugin-yet-another-subagent'
38
+ config:
39
+ profiles:
40
+ - id: general
41
+ label: General
42
+ model: { kind: 'auto' }
43
+ persona: { kind: 'inherit' }
44
+ toolFilter: { kind: 'none' }
45
+ maxDepth: 3
46
+ backgroundMode: continuable
47
+ builtin: true
48
+ generalFixed: true
49
+ ```
50
+
51
+ ### Profile 字段
52
+
53
+ | 字段 | 类型 | 默认值 | 说明 |
54
+ |------|------|--------|------|
55
+ | `id` | `string`(小写字母/数字/连字符,1-32 字符) | | Profile 唯一标识 |
56
+ | `label` | `string` | | 显示名 |
57
+ | `model.kind` | `'auto'` \| `'manual'` | | `auto` 继承父代理模型;`manual` 指定 |
58
+ | `model.provider` | `string` | `''` | Provider(仅 `manual` 时使用) |
59
+ | `model.model` | `string` | `''` | 模型 ID(仅 `manual` 时使用) |
60
+ | `persona.kind` | `'inherit'` \| `'custom'` | `'inherit'` | `inherit` 跟随部署人设;`custom` 自定义 |
61
+ | `persona.text` | `string` | `''` | 自定义人设文本(仅 `custom` 时使用) |
62
+ | `toolFilter.kind` | `'none'` \| `'allow'` \| `'deny'` | `'none'` | 工具过滤策略 |
63
+ | `toolFilter.tools` | `string[]` | `[]` | 过滤工具列表 |
64
+ | `maxDepth` | `number` | `3` | 最大递归深度 |
65
+ | `backgroundMode` | `'continuable'` \| `'one-shot'` | `'continuable'` | `run_in_background: true` 时的后台策略 |
66
+ | `builtin` | `boolean` | `false` | 是否为内置 profile(仅展示用) |
67
+
68
+ ## 开发
69
+
70
+ ```sh
71
+ pnpm install # 安装开发依赖 + zod(唯一运行时 npm 依赖)
72
+ pnpm run typecheck # tsc --noEmit(通过 ../dsh 解析 DSH 源码)
73
+ pnpm test # vitest run
74
+ pnpm run build # tsc + tsdown → lib/index.js, lib/invariant.js, lib/client.js
75
+ ```
76
+
77
+ ### 类型检查
78
+
79
+ `tsconfig.json` 继承 `../dsh/tsconfig.base.client.json`,通过 `pnpm-workspace.yaml` `packages/*/*` glob 解析 DSH checkout 的源码。需在 `../dsh` 存在 DSH checkout 的同级目录下运行。
80
+
81
+ ## 运行
82
+
83
+ ```sh
84
+ # 从 npm 安装(推荐):
85
+ dsh plugin --profile web add @huanlin/dsh-plugin-yet-another-subagent
86
+
87
+ # 本地引用(开发热更新)
88
+ dsh plugin --profile web add "link:D:/Projects/deepseek-harness/yet-another-subagent"
89
+ ```
90
+
91
+ 安装后重启 `dsh web` 进程,浏览器硬刷新(`Ctrl+Shift+R`)。
92
+
93
+ ## 检查
94
+
95
+ ```sh
96
+ pnpm run typecheck # 0 errors
97
+ pnpm test # 55 tests passing
98
+ pnpm run build # lib/index.js + lib/invariant.js + lib/client.js
99
+ ```
100
+
101
+ ### 产物验证
102
+
103
+ - `lib/index.js` — Host bundle
104
+ - `lib/invariant.js` Invariant companion
105
+ - `lib/client.js` — Client bundle(CSS-modules inline,`d` 前缀 hash 防 CSS 类名数字开头)
106
+ - `cordis.patch.yml` — Bundle patch layer
107
+
108
+ ## 持久化
109
+
110
+ Profile 状态通过 DSH settings seam 持久化到 `$DSH_HOME/settings.yaml` 的 `ya-subagent` 命名空间。cordis.yml `profiles` 字段是组合 `base`(首次启动种子),运行时变更通过 `scope.replace()` 写入用户层。外部 yaml 编辑通过 `scope.watch` 热重载。
111
+
112
+ settings provider 的无头组装回退到内存状态(仅 cordis.yml 种子,不持久化)。
113
+
114
+ ## RPC API
115
+
116
+ Profile CRUD host 的专用 `/ya-subagent` 通道(不共享 `/api`,避免与 Typert gateway 的单拦截器冲突):
117
+
118
+ | endpoint | payload | result (ok) |
119
+ |----------|---------|-------------|
120
+ | `profiles.list` | `{}` | `{ profiles: SubagentProfile[] }` |
121
+ | `profiles.add` | `{ profile: SubagentProfile }` | `{ profiles: SubagentProfile[] }` |
122
+ | `profiles.update` | `{ profile: SubagentProfile }` | `{ profiles: SubagentProfile[] }` |
123
+ | `profiles.remove` | `{ id: string }` | `{ profiles: SubagentProfile[] }` |
124
+ | `tools.list` | `{}` | `{ tools: { name, description }[] }` |
125
+
126
+ URL 形如 `POST /ya-subagent/profiles.list`。业务错误返回 `{ ok: false, error: { code: 'internal', message } }`。
127
+
128
+ ## 已知限制
129
+
130
+ - **旧会话不兼容**:`completed <label> subagent <id>` render 格式变更后,旧会话的结果文本无法被 `parseResult` 匹配,卡片不可点击。仅新会话(host 重启后)正常。
131
+ - **`yaSubagentProgress` stateVersion 2**:projection schema 变更(`activity` 字段 + `assistant/chunk` fold)需要 host 重启才能生效。
132
+
133
+ ## 设计参考
134
+
135
+ - 官方 continuable subagent 设计:`.agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md`
136
+ - 插件开发指南:`plugin-development-guide.md`