dsh-agent-board 1.5.0 → 1.6.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 +50 -4
- package/index.mjs +57 -1267
- package/lib/client/board-list.js +204 -0
- package/lib/client/dashboard.js +387 -0
- package/lib/client/kernel.js +479 -0
- package/lib/client/task-detail.js +200 -0
- package/lib/client.js +638 -499
- package/lib/core.mjs +99 -2
- package/lib/dispatch.mjs +585 -0
- package/lib/notify.mjs +157 -0
- package/lib/policy.mjs +49 -0
- package/lib/rpc.mjs +538 -0
- package/lib/session.mjs +60 -0
- package/lib/store.mjs +187 -0
- package/lib/usage.mjs +134 -0
- package/package.json +11 -5
- package/test/core.test.mjs +132 -5
package/README.md
CHANGED
|
@@ -80,6 +80,10 @@ dsh plugin --profile web remove dsh-agent-board
|
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
> 看板数据存在 `~/.dsh/tasks-<sessionId>.json`,卸载不删数据。
|
|
83
|
+
>
|
|
84
|
+
> - **归属**:看板文件按**会话**分文件,同时在文件里记 `ownerCwd`(创建该看板的会话工作区路径,取不到则省略该字段)——`~/.dsh/tasks-*.json` 每个文件是一块看板,`list-boards` 全局视图可看到本机所有板。
|
|
85
|
+
> - **重启继承**:DSH 重启后同一会话的根 id 可能漂移,此时新 id 没有对应文件——若同工作区(`ownerCwd` 严格相等)存在**唯一**「原主已不在 `agents.roots()`」的看板,则自动继承:文件重命名为新 id、文件内 `ownerSession` 改写为新 id、`console.error` 留一行 `[task-board] 继承看板 <旧sid> → <新sid>`;**多个候选一律不自动接管**(记一行日志后按空板处理,防误合并,旧板仍可在 `list-boards` 全局视图里看到)。
|
|
86
|
+
> - **写盘保护**:落盘走 临时文件+rename 原子写(EPERM/EBUSY 退避重试);瞬时读失败/坏文件隔离后返回的空板**禁止回写**(防一个"读不到"的瞬间把看板覆成空板),坏文件隔离为 `.corrupt-<时间戳>` 留档不丢数据。
|
|
83
87
|
|
|
84
88
|
## 功能总览
|
|
85
89
|
|
|
@@ -123,12 +127,16 @@ draft → pending → in-progress → verifying → resolved → archived
|
|
|
123
127
|
- **里程碑进展通道**:Worker 每完成一个可验证的里程碑,可调用 `board_report`(`kind: "progress"`,`question` 写一行进展摘要 ≤200 字符)上报——进行中的卡片显示「📈 最近进展 · 相对时间」(覆盖式只留最新一条),详情页消息流保留全部 progress 条目
|
|
124
128
|
- **防表演式汇报**:进展契约只写在 Worker prompt 里、且要求「有实际产物/结论才报」(禁止定时汇报);progress **静默不通知主窗口**(不进回执聚合),也不写 `history` 流转记录,避免刷屏
|
|
125
129
|
- **子任务**:父子层级 + 上下文继承 + 父任务自动流转 + 级联归档
|
|
130
|
+
- **删除通道(真删,无 undo)**:`delete-task` RPC(卡片 hover 垃圾桶按钮 / 详情页「删除」按钮,均先 `confirm('删除不可恢复,确认删除「标题」?')`)+ `batch-op op='delete'`(多选模式底部「批量删除」,同样 confirm)。状态门禁:**草稿/待办/阻塞可删**;进行中/验证中拒绝并提示先用 `terminate-agent` 终止(避免在跑的 run 变孤儿);已完成/取消引导改用归档(`archive-task`,留档可检索);有**未归档子任务**时拒删(防 `parentId` 悬空破坏父任务自动流转);已归档任务幂等返回 ok。是真删(从 `tasks` 数组移除),因此**不产生 `batch-undo` 撤销快照**(批量条对 delete 不显示「↩️ 撤销」),删除操作在 host 端 `console.error` 留一行日志便于溯源
|
|
126
131
|
- **任务粒度建议**:单任务 **10~30 分钟**可独立完成为甜区;预计超过 30 分钟的大任务先建一张 **epic 父卡**(`pipeline: direct`,不进池派发),再挂若干 10~30 分钟的子任务(`task_create` 传 `parentId=父卡 id`,有先后顺序用 `dependsOn` 串联),子任务全部完成后父卡自动流转(`checkParentAuto`)——`task_create` 工具描述与 Team 模式提示词都写了这条契约
|
|
127
132
|
- **suggestSplit 软提示**:`task_create` / `create-task` 发现描述超 500 字符、或标题/描述命中「全量 / 整体 / 系统级 / 全面 / 重构 / 所有模块 / 整个」等史诗特征词时,返回体附带一行 `suggestSplit` 建议文案(**只提示,不阻断创建与派发**;未命中则不出现该字段,老调用方无感)
|
|
128
133
|
|
|
129
134
|
### 一次性派发(v74 去池化)
|
|
130
135
|
|
|
131
136
|
- 每个任务 spawn 一个**一次性子代理**(Worker/Verifier),上下文全量注入 prompt,做完即销毁——无常驻池、无池化状态残留
|
|
137
|
+
- **预研上下文注入(contextFiles/contextNotes)**:主窗口调研时读过的文件与笔记,由 host 在派发时读盘取最新内容,经「上下文注入」区块提供给 Worker/Verifier(不混进 user prompt);预算口径单文件 8KB、总包 40KB
|
|
138
|
+
- **锚点行段**:`contextFiles` 支持 `path:L2350-L2420` / `path:L2350` 行段语法(只认尾部 `:L<行号>`,兼容 Windows 盘符),只注入该段(段长上限 400 行,超出截断并标注);锚点无效(越界/写法错)自动回退头部注入并标注「锚点无效,已回退头部」
|
|
139
|
+
- **截断结构索引**:头部注入被预算截断时,标注升级为「截断:共 N 行,已注入 1–M 行」,并附结构索引块(JS/TS 顶层函数/类/箭头赋值、Markdown 标题及行号,上限 40 条)——Worker 照索引用锚点语法补读目标段即可,不用全文盘点
|
|
132
140
|
- **Worker/Verifier 均可配置异构模型**(⚙️ 弹出层下拉选择,空 = 继承父级),避免同源盲点;模型故障自动熔断回退父级模型
|
|
133
141
|
- 孤儿回收:子代理 run 结束/丢失超 2 分钟 → 任务自动回待办重派
|
|
134
142
|
- 看门狗:运行超时且事件流停滞 → 标记"疑似卡死"(不自动杀,裁决权交主窗口/用户)
|
|
@@ -176,11 +184,14 @@ Team 托管档独有(调度员体验):
|
|
|
176
184
|
## 仓库结构
|
|
177
185
|
|
|
178
186
|
```
|
|
179
|
-
└── packages/dsh-agent-board/ #
|
|
180
|
-
│ ├── index.mjs # host
|
|
187
|
+
└── packages/dsh-agent-board/ # 插件全部源码
|
|
188
|
+
│ ├── index.mjs # host 端薄壳(~70 行):cordis 契约 + 共享 state 构建 + 模块接线
|
|
181
189
|
│ ├── lib/core.mjs # 纯逻辑核心:状态机/依赖/分类/prompt/解析(无 IO,可单测)
|
|
182
|
-
│ ├── lib
|
|
183
|
-
│ ├──
|
|
190
|
+
│ ├── lib/*.mjs # host 端领域模块(按任务边界拆分,见下节)
|
|
191
|
+
│ ├── lib/client/ # client 端模块源(按用户感知域拆分,见下节)
|
|
192
|
+
│ ├── lib/client.js # client 端产物(⚠️ GENERATED:scripts/build-client.cjs 拼装,勿直接编辑)
|
|
193
|
+
│ ├── scripts/build-client.cjs # 零依赖组装器(模块源 → 产物;--check 校验产物新鲜度)
|
|
194
|
+
│ ├── test/core.test.mjs # 单元测试(node --test,84 例)
|
|
184
195
|
│ ├── package.json # dsh.bundle.patch + dsh.client 元数据
|
|
185
196
|
│ └── cordis.patch.yml # bundle 挂载行
|
|
186
197
|
└── docs/
|
|
@@ -190,6 +201,41 @@ Team 托管档独有(调度员体验):
|
|
|
190
201
|
└── REGRESSION-v59.md # 端到端回归测试记录
|
|
191
202
|
```
|
|
192
203
|
|
|
204
|
+
### host 模块边界(lib/*.mjs)
|
|
205
|
+
|
|
206
|
+
v1.6.0 起 host 端从单体 index.mjs(1487 行)拆为薄壳 + 7 个领域模块,
|
|
207
|
+
共享闭包状态收进显式 `state` 对象逐模块注入——模块边界即任务边界,并行任务不再全员互锁:
|
|
208
|
+
|
|
209
|
+
| 模块 | 域 | 内容 |
|
|
210
|
+
|---|---|---|
|
|
211
|
+
| `policy.mjs` | 策略层 | 粒度治理软闸门 + 学习飞轮候选教训(纯函数零状态) |
|
|
212
|
+
| `usage.mjs` | 统计 | v4 会话日志定位 / zstd 分帧 / token usage 聚合(纯函数) |
|
|
213
|
+
| `session.mjs` | 会话 | root 解析缓存 / 会话 id 归一 / workMode 派生 / runsFor |
|
|
214
|
+
| `store.mjs` | 持久化 | boardPath / rt / wt 原子落盘 / 跨重启继承 / fileLocks 串行化 / mutateLocked |
|
|
215
|
+
| `notify.mjs` | 通知 | makeMsg / 歧义 25s 去抖 / 回执聚合 + 空闲门控 / 投递前过滤 |
|
|
216
|
+
| `dispatch.mjs` | 派发引擎 | poolCycle / spawnOneShot / settleRun / 两级超时 / 孤儿回收 |
|
|
217
|
+
| `rpc.mjs` | 接口层 | RPC 路由 + 13 个 Agent 工具注册 |
|
|
218
|
+
|
|
219
|
+
(store→dispatch 的循环依赖由 `deps.poolCycle` 晚绑定解开;index.mjs 对外 re-export 契约不变。)
|
|
220
|
+
|
|
221
|
+
### 前端模块边界(lib/client/)
|
|
222
|
+
|
|
223
|
+
dsh web 的 client 运行时不具备模块解析能力(entry 被整体读成字符串经 `new Function` 求值,
|
|
224
|
+
相对 import 是语法错误),所以前端模块化走**构建时拼装**:模块源在 `lib/client/`,
|
|
225
|
+
`npm run build-client`(pretest/prepublishOnly 已挂链)拼装成单文件产物 `lib/client.js`。
|
|
226
|
+
四个模块按**用户感知域**划分——边界即未来任务边界,新功能先想清楚落在哪个域:
|
|
227
|
+
|
|
228
|
+
| 模块 | 域 | 内容 |
|
|
229
|
+
|---|---|---|
|
|
230
|
+
| `kernel.js` | 底座(用户不可感知) | 渲染原语(ic/icText/ActorLink)、RPC 封装与轮询族、共享状态(state/listeners/notify)、图标(ICONS)、共享任务工具,以及面板骨架入口(BoardButton/ViewTab/TopPanel/slots.inject) |
|
|
231
|
+
| `board-list.js` | 看板列表 | 看板列与卡片(Card)、筛选条、多选批量操作条、建卡表单、归档列表 |
|
|
232
|
+
| `task-detail.js` | 任务详情 | 详情抽屉(编辑/流转/冻结/touches/历史会话/高优介入)、歧义裁决对话与候选教训沉淀、依赖区块 |
|
|
233
|
+
| `dashboard.js` | 仪表盘与设置 | 统计图表、Token 消耗、全局总览、报告生成、团队池视图、池/模型/超时设置与工作模式开关 |
|
|
234
|
+
|
|
235
|
+
四个模块拼进同一个 `apply(ctx)` 函数作用域(`var`/`function` 声明提升使跨模块引用与拼接顺序无关;
|
|
236
|
+
所有同步执行代码——DOM 监听、轮询注册、布局同步、slots.inject——都在 kernel 域内保持原相对顺序)。
|
|
237
|
+
改模块源后必须重新组装(`npm run build-client`)产物才更新;直接编辑 `lib/client.js` 会在下次拼装时被覆盖。
|
|
238
|
+
|
|
193
239
|
> v68 起拆除了"动态源码 → 静态包"的转换层(build-pkg.cjs):插件已稳定,
|
|
194
240
|
> 双形态维护的复杂度大于收益,包内文件即唯一源码,改完重启 dsh 即生效。
|
|
195
241
|
>
|