cs-bots 0.1.1 → 0.7.5

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 (48) hide show
  1. package/CHANGELOG.md +539 -0
  2. package/README.md +65 -10
  3. package/docs/01-/346/236/266/346/236/204/346/226/207/346/241/243.md +364 -0
  4. package/docs/02-/351/234/200/346/261/202/350/247/204/346/240/274/344/271/246.md +284 -0
  5. package/docs/03-/350/257/246/347/273/206/350/256/276/350/256/241.md +567 -0
  6. package/docs/04-/346/223/215/344/275/234/346/211/213/345/206/214.md +569 -0
  7. package/docs/ARCHITECTURE.md +277 -0
  8. package/docs/adr/ADR-001-/351/241/265/347/255/276/347/273/223/346/236/204/345/233/236/345/210/260/344/270/203/351/241/265.md +70 -0
  9. package/docs/steps/step-01-/345/216/237/346/236/266/346/236/204/345/244/215/345/216/237/344/270/216IA/350/257/212/346/226/255.md +80 -0
  10. package/docs/steps/step-02-/351/241/265/347/255/276/346/224/266/346/225/233/344/270/216/345/215/207/347/272/247/351/200/232/351/201/223.md +51 -0
  11. package/docs/steps/step-03-/346/236/266/346/236/204/350/265/204/346/226/231/346/210/220/346/226/207.md +16 -0
  12. package/docs/steps/step-04-/344/270/212/347/272/277/344/270/216/351/252/214/350/257/201.md +46 -0
  13. package/docs//344/272/244/344/273/230/350/257/264/346/230/216-v0.2.0.md +95 -0
  14. package/docs//346/223/215/344/275/234/346/211/213/345/206/214-v1.md +509 -0
  15. package/docs//350/277/201/347/247/273/346/226/271/346/241/210-v1.md +64 -0
  16. package/docs//351/225/277/346/234/237/350/256/260/345/277/206/346/226/271/346/241/210-v1.md +85 -0
  17. package/package.json +4 -2
  18. package/src/admission.js +365 -0
  19. package/src/api.js +4097 -420
  20. package/src/board.js +883 -14
  21. package/src/botprofile.js +190 -3
  22. package/src/client.js +6596 -1082
  23. package/src/cycle.js +516 -0
  24. package/src/delivery-watch.js +255 -0
  25. package/src/dirbrowse.js +20 -0
  26. package/src/discipline.js +1188 -0
  27. package/src/fence.js +142 -0
  28. package/src/index.js +387 -4
  29. package/src/kernel.js +636 -24
  30. package/src/library.js +1224 -11
  31. package/src/memory.js +617 -37
  32. package/src/metrics.js +339 -0
  33. package/src/prompts.js +1318 -0
  34. package/src/reviewer.js +709 -0
  35. package/src/room.js +655 -14
  36. package/src/roster.js +346 -26
  37. package/src/routing/complexity.js +320 -0
  38. package/src/routing/hints.js +707 -0
  39. package/src/scratch.js +477 -0
  40. package/src/settings.js +97 -0
  41. package/src/stage.js +263 -0
  42. package/src/store.js +133 -1
  43. package/src/subscription.js +571 -0
  44. package/src/suggest.js +1203 -0
  45. package/src/teams.js +527 -0
  46. package/src/todo.js +1301 -0
  47. package/src/tools.js +734 -10
  48. package/src/verify.js +356 -0
@@ -0,0 +1,364 @@
1
+ # cs-bots 架构总览(改造07 · 分层架构 + 改造08 · 人机分治)
2
+
3
+ > 版本:v0.7.3(改造07 分层 + 改造08 需求1–5)
4
+ > 日期:2026-11-09
5
+ > 状态:已实现,1108 项测试全通过(`bash test/run-all.sh` exit 0)
6
+
7
+ ---
8
+
9
+ ## 1. 一句话
10
+
11
+ **cs-bots 是一个跑在 DeepSeek Harness 上的多智能体协作平台。改造07 把它从「扁平的页签集合」升级为「分层架构」:上层是人类协作层,下层是 AI 基础设施层,两者通过穿透入口显式连接。**
12
+
13
+ ---
14
+
15
+ ## 2. 分层架构总览
16
+
17
+ ```
18
+ ┌─────────────────────────────────────────────────────────────┐
19
+ │ 上层:人类协作层 │
20
+ │ │
21
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
22
+ │ │ 工作台 │ │ 团队 │ │ 记忆 │ │ 技能库 │ │
23
+ │ │ │ │ │ │ │ │ │ │
24
+ │ │ 任务看板 │ │ Bot 档案 │ │ 事实偏好 │ │ 技能 │ │
25
+ │ │ PDCA复盘 │ │ 团队 │ │ 纪律要求 │ │ 工作流 │ │
26
+ │ │ 待办便签 │ │ 房间 │ │ 提示词 │ │ │ │
27
+ │ │ 成果 │ │ 成果 │ │ │ │ │ │
28
+ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
29
+ │ │
30
+ │ ┌──────────────────────────────────────────────────────┐ │
31
+ │ │ 人类操作界面(适合人看、人点) │ │
32
+ │ └──────────────────────────────────────────────────────┘ │
33
+ └──────────────────────┬──────────────────────────────────────┘
34
+ │ 顶部「⚙ 穿透」入口(显式,不隐藏)
35
+ ▼
36
+ ┌─────────────────────────────────────────────────────────────┐
37
+ │ 下层:AI 基础设施层 │
38
+ │ │
39
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
40
+ │ │ 注册表 │ │ 唤醒桥 │ │ 存储 │ │ 路由 │ │
41
+ │ │ Bot │ │ Dispatcher│ │ Store │ │ Routing │ │
42
+ │ │ 任务板 │ │ │ │ jsonl │ │ T0-T3 │ │
43
+ │ │ 团队 │ │ 事件流 │ │ 快照 │ │ free/paid│ │
44
+ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
45
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
46
+ │ │ 验证 │ │ 建议 │ │ 订阅 │ │
47
+ │ │ Verify │ │ Suggest │ │ Subscription│ │
48
+ │ │ 验收证据 │ │ 确认制 │ │ 扇出 │ │
49
+ │ └──────────┘ └──────────┘ └──────────┘ │
50
+ │ │
51
+ │ ┌──────────────────────────────────────────────────────┐ │
52
+ │ │ AI 智能体调用接口(机器友好、可审计) │ │
53
+ │ │ 41 个 bot_* 工具 + HTTP API │ │
54
+ │ └──────────────────────────────────────────────────────┘ │
55
+ └─────────────────────────────────────────────────────────────┘
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 3. 分层原则(为什么这样分)
61
+
62
+ ### 3.1 上层调用下层,下层不反向调用上层
63
+
64
+ - 上层的 UI 组件通过 HTTP API 获取数据
65
+ - 下层的域服务通过 `tools.js` 暴露给模型
66
+ - 两者互不感知对方的内部结构
67
+
68
+ ### 3.2 穿透是显式的,不是隐式的
69
+
70
+ - 正常页面只显示上层
71
+ - 下层通过顶部「⚙ 穿透」按钮显式进入
72
+ - 穿透面板是**只读 + 有限操作**,不暴露全部底层能力
73
+
74
+ ### 3.3 保持「绝不静默失败」
75
+
76
+ - 所有模块的所有操作都有明确返回值
77
+ - 失败时返回人话 + 下一步建议
78
+ - 所有操作落盘,可审计
79
+
80
+ ---
81
+
82
+ ## 4. 功能归属:哪些进上层,哪些进下层
83
+
84
+ ### 4.1 上层(人类协作层)—— 6 个页签
85
+
86
+ | 页签 | 包含功能 | 人类视角 |
87
+ |---|---|---|
88
+ | **工作台** | 任务看板、PDCA 复盘、待办、便签、成果 | 人建任务、看进度、验收 |
89
+ | **团队** | Bot 档案、团队列表、房间群聊 | 人管 Bot、看谁在干什么、进房间讨论 |
90
+ | **记忆** | 事实与偏好、纪律与要求、提示词 | 人看 AI 记住了什么、改 AI 的行为准则 |
91
+ | **技能库** | 技能、工作流 | 人看 AI 会什么、按什么步骤做 |
92
+ | **数据** | 文件浏览、PDCA 测量指标 | 人看数据、看效率 |
93
+ | **设置** | 平台参数、权限、安全 | 人配平台 |
94
+
95
+ ### 4.2 下层(AI 基础设施层)—— 7 个区块
96
+
97
+ | 区块 | 包含功能 | 人类穿透后能做什么 |
98
+ |---|---|---|
99
+ | **注册表** | Bot 注册表、任务板事件流、团队注册 | 查看 Bot 生命周期、任务 CAS 历史 |
100
+ | **唤醒桥** | Dispatcher 队列、去重表、背压状态 | 查看唤醒日志、手动触发唤醒、强制 flush |
101
+ | **存储** | jsonl 事件流、快照、原子写、幂等集 | 查看存储健康、坏行统计、手动 replay |
102
+ | **路由** | 复杂度路由 T0-T3、免费/付费策略 | 查看路由规则、查看路由决策日志 |
103
+ | **验证** | 验收证据、退出码、测试结果 | 查看验收记录、手动重跑验收 |
104
+ | **建议** | 建议确认队列、纪律提议 | 采纳/驳回建议 |
105
+ | **订阅** | 任务订阅、房间扇出 | 查看订阅关系、订阅/取消订阅 |
106
+
107
+ ---
108
+
109
+ ## 5. 借鉴 Super-agent 的三项能力
110
+
111
+ 改造07 从官方 Super-agent 原型(`deepseek-ai/dsh-superagent-prototype`,研究原型,非正式产品)借鉴了三项能力:
112
+
113
+ ### 5.1 借鉴 3:Subscription 扇出(`src/subscription.js`)
114
+
115
+ - 任务可订阅房间,房间后续消息自动到达任务(作为上下文)
116
+ - **只加上下文,不改任务状态、不授予开工权力**
117
+ - 幂等:同一 (taskId, roomId) 重复订阅返回既有记录
118
+ - 滚动窗口:默认保留最近 20 条消息
119
+ - 实现:`src/subscription.js` + API 端点 + 3 个新工具
120
+
121
+ ### 5.2 借鉴 4:工单阶段机(`src/stage.js`)
122
+
123
+ - 8 个执行阶段,自上而下首个命中
124
+ - 4 个 `person/*` 阶段需要人动手(强调色)
125
+ - 纯函数、无副作用、不落盘
126
+ - 实现:`src/stage.js` + API 附 `stageInfo` + 前端徽章
127
+
128
+ ### 5.3 借鉴 5:prepare command(`src/roster.js` + `src/api.js`)
129
+
130
+ - Bot 可设开工准备命令(如 `git worktree add ...`)
131
+ - claim 前先跑,失败则不认领(绝不产生半成品)
132
+ - 安全边界:白名单 + execFile + 硬超时
133
+ - 实现:`roster.setPrepareCommand` + API 集成 + `runPrepareCommand`
134
+
135
+ ---
136
+
137
+ ## 6. 技术栈
138
+
139
+ | 层 | 技术 |
140
+ |---|---|
141
+ | 后端运行时 | Node.js ≥22.5,ESM,零第三方运行时依赖 |
142
+ | HTTP API | 宿主 `webServer.register`(前缀路由 `/cs-bots/api`) |
143
+ | 前端 | React 18,宿主模块加载器 `window.__ModuleLoader__.load` |
144
+ | 模型工具 | 宿主 `tools.register`,41 个 `bot_*` 工具 |
145
+ | 持久化 | JSONL 事件流 + 原子快照,SQLite 不引入 |
146
+ | 安全 | 会话鉴权围栏 + 同源校验 + 受保护区 + CSRF 防护 |
147
+
148
+ ---
149
+
150
+ ## 7. 状态目录结构
151
+
152
+ ```
153
+ $DSH_HOME/cs-bots/
154
+ ├── board.jsonl 任务板事件流(真相源)
155
+ ├── board.snap.json 任务板快照
156
+ ├── roster.jsonl Bot 注册表事件流
157
+ ├── roster.snap.json Bot 注册表快照
158
+ ├── wakes.jsonl 唤醒审计
159
+ ├── rooms/<roomId>/
160
+ │ ├── log.jsonl 房间消息日志(永不截断)
161
+ │ └── bodies/*.txt 长正文旁路
162
+ ├── memory.jsonl 记忆事件流
163
+ ├── memory.snap.json 记忆快照
164
+ ├── memory-fts.db FTS5 检索索引
165
+ ├── discipline.jsonl 纪律事件流
166
+ ├── todo.jsonl 待办事件流
167
+ ├── prompts.jsonl 提示词库
168
+ ├── suggestions.jsonl 建议确认队列
169
+ ├── reviewer.jsonl 自审调度
170
+ ├── cycle.jsonl PDCA 复盘事件流
171
+ ├── cycle.snap.json PDCA 快照
172
+ ├── metrics.jsonl 指标记录
173
+ ├── subscription.jsonl 任务订阅事件流(改造07 新增)
174
+ ├── subscription.snap.json 任务订阅快照
175
+ ├── stage.json 阶段机(不落盘,纯派生,改造07 新增)
176
+ ├── scratch/<scope>.md 便签
177
+ └── library-skill-dirs.json 技能来源目录
178
+ ```
179
+
180
+ ---
181
+
182
+ ## 8. 模块地图
183
+
184
+ ### 8.1 上层(人类协作层)
185
+
186
+ ```
187
+ src/client.js 前端:6 页签 + 穿透面板 + 人类操作界面
188
+ src/api.js 后端 HTTP API:/cs-bots/api/*
189
+ ```
190
+
191
+ ### 8.2 下层(AI 基础设施层)
192
+
193
+ ```
194
+ src/board.js 任务板(CAS + 租约 + WIP + 验收 + 复杂度路由)
195
+ src/dispatcher.js 唤醒桥(定向、去重、节流、背压、TTL)
196
+ src/roster.js Bot 注册表(持久 Bot + 独立 cwd + prepare command)
197
+ src/teams.js 团队管理
198
+ src/room.js 房间群聊(长消息旁路)
199
+ src/memory.js 分层记忆 L0-L5 + FTS5 检索
200
+ src/discipline.js 分级纪律(全局/工作区/房间/Bot)
201
+ src/suggest.js 建议确认制
202
+ src/cycle.js PDCA 复盘(planned→doing→checking→acting→done)
203
+ src/reviewer.js 自审调度
204
+ src/verify.js 验收验证
205
+ src/metrics.js 指标记录与聚合
206
+ src/todo.js 待办(四轨 + 四象限)
207
+ src/scratch.js 便签
208
+ src/prompts.js 提示词库
209
+ src/registry.js 技能库
210
+ src/stage.js 工单阶段机(改造07 新增,纯派生)
211
+ src/subscription.js 任务订阅 + 房间扇出(改造07 新增)
212
+ src/routing/ 复杂度路由
213
+ src/store.js 存储原语(jsonl + 快照 + 幂等集 + 原子写)
214
+ src/kernel.js 宿主桥(唯一可引用宿主包的文件)
215
+ src/tools.js 41 个模型工具
216
+ src/index.js 装配入口
217
+ ```
218
+
219
+ ---
220
+
221
+ ## 9. 改造前后对比
222
+
223
+ | 维度 | 改造前(v0.6.x) | 改造后(v0.7.0) |
224
+ |---|---|---|
225
+ | 页签结构 | 10 个扁平页签 | 6 个上层页签 + 穿透面板 |
226
+ | 任务状态 | 5 个粗粒度值 | 5 状态 + 8 阶段(派生) |
227
+ | 房间→任务 | 无连接 | Subscription 扇出 |
228
+ | Bot 开工 | 无准备步骤 | prepare command |
229
+ | 底层可见性 | 无(黑盒) | 穿透面板(7 区块) |
230
+ | 工具数 | 38 个 | 41 个 |
231
+ | 测试数 | 949 项 | 1036 项 |
232
+
233
+ ---
234
+
235
+ ## 10. 设计原则(贯穿全部模块)
236
+
237
+ 1. **绝不静默失败**:所有失败都有明确返回值 + 落盘证据
238
+ 2. **事件流是真相源**:先落盘,再改内存,最后写快照
239
+ 3. **CAS 优先**:任何变更都要带 `expectedRev`
240
+ 4. **纯增量**:改造07 所有改动都是纯增量,不改动既有契约
241
+ 5. **零第三方运行时依赖**:只用 node 内置 + 宿主包
242
+ 6. **分层不隔层**:上层调用下层,下层不反向调用上层
243
+
244
+ ---
245
+
246
+ ## 11. 关键事实核对
247
+
248
+ | 事实 | 来源 | 核对日期 |
249
+ |---|---|---|
250
+ | Super-agent 是研究原型,非官方产品 | `deepseek-ai/dsh-superagent-prototype` README | 2026-11-08 |
251
+ | Agent Teams `maxMembers` 默认 8 | `dsh-experimental-agent-team` README | 2026-11-08 |
252
+ | 改造07 借鉴 Super-agent 的 3/4/5 项能力 | 用户指定 | 2026-11-08 |
253
+ | cs-bots 零第三方运行时依赖 | cs-bots README + package.json | 2026-11-08 |
254
+ | 改造07 工具数 41 个 | `src/tools.js` 的 `TOOL_NAMES` | 2026-11-08 |
255
+ | 改造07 测试数 1036 项 | `bash test/run-all.sh` | 2026-11-08 |
256
+ | 改造09 准入闸 + Mandate 授权留痕 + WIP 并发槽位 + 结构化 Report | 用户指定 | 2026-11-09 |
257
+ | 当前测试数 1108 项 | `bash test/run-all.sh` | 2026-11-09 |
258
+
259
+ ---
260
+
261
+ *架构文档完。详细接口见《详细设计文档》。*
262
+
263
+ ---
264
+
265
+ ## 改造08 · 需求 1–5(2026-11-09)
266
+
267
+ > 这一节的每一条都对应你原话里的一条要求,写完当天就上了线(0.7.3 已部署重启,启动图校验 PASS)。
268
+
269
+ ### 需求1 · 任务页只展示人建的任务,智能体任务单独一页
270
+
271
+ | | 改前 | 改后 |
272
+ |---|---|---|
273
+ | 「我的任务」页 | 人和智能体的任务混在一起 | 只显示 `source=human`(你自建的任务) |
274
+ | 智能体任务 | 混在同一个列表里翻 | 单独的「智能体任务」页签,按状态分类 |
275
+
276
+ - 后端 `GET /tasks?source=human|ai` 早已支持(`src/board.js` 里 `source` 字段),这次是**前端把它用起来**。
277
+ - 「我的任务」页保留「只看需要我处理的」开关;「智能体任务」页不显示这个开关(智能体的活不需要你逐条盯)。
278
+
279
+ ### 需求2 · 派活后能追踪进度、看到产出物、看到对话
280
+
281
+ 这一条挖到了一个**真 bug**,不是你操作的问题:
282
+
283
+ > `eventsToMessages` 只读 `ev.content`,而官方会话事件是 `{ type, seq, time, data }`,
284
+ > 内容在 `data.content` / `data.message.content` 里;`tool/call`、`tool/result` 是顶层事件。
285
+ > 结果:**对任何真实会话都恒定返回 0 条** —— 所以你看到的就是「没有对话内容可看」。
286
+
287
+ 实测同一个真实会话(4795 个事件):
288
+
289
+ | | 修前 | 修后 |
290
+ |---|---|---|
291
+ | 对话片段总数 | **0** | **2625** |
292
+ | 你的发言 | 0 | 110 |
293
+ | 执行者正文 | 0 | 74 |
294
+ | 思维链 | 0 | 465 |
295
+ | 工具调用 | 0 | 1306 |
296
+ | 工具结果 | 0 | 670 |
297
+
298
+ 新增/变更:
299
+
300
+ - 后端 `GET /tasks/conversation?id=&limit=` —— 只读打开执行者会话(`persistence.open(id,'read')`,不抢所有权),返回 `{ bot, sessionId, messages[], total, truncated, available }`。
301
+ - 前端任务详情新增**任务对话**面板:显示执行者身份、消息条数;默认只给正文(手机不被思维链淹没),点「看全部」才展开工具调用与思维链;「去对话」直接打开它的会话,宿主不支持就复制会话 ID 兜底。
302
+ - 无执行者时是**空态**(「还没有执行者」+ 下一步),不是报错。
303
+ - 产出物空态改成说清「为什么现在没有」:未完成时正常;已完成却没带证据时提示可以重开补交。
304
+
305
+ ### 需求3 · 团队页只显示你建的团队,负责人有标识,成员可选
306
+
307
+ - 团队页只拉 `GET /teams?type=big`(后端 `type` 字段保留不动,只是 UI 不再暴露「大小团队」概念)。
308
+ - 负责人带 `👑 负责人` 标识,成员列表里负责人加 `👑 ` 前缀;移出负责人会明确警告「移出后团队将没有负责人」。
309
+ - 建团队时负责人用下拉选择,成员用勾选组(可多选,支持新建 Bot 后再来选)。
310
+ - 「看房间」→ 跳房间页并**按团队名定向筛选**:房间页顶部出现「筛选房间:包含「X」→ N 个房间」和「✕ 清筛选」。
311
+ - 你要的「穿透房间看子团队工作内容」:房间页本来就是超级管理员视角,所有房间都能进、都能看长正文(`withBody=1` 一次取回),筛选只是在大列表里做定向。
312
+
313
+ ### 需求4 · PDCA 人机分治(这条改动最大)
314
+
315
+ 你的原话:「pdca 是对用户长任务进行复盘跟进的,人类主导;智能体的 pdca 流程你优化一下」。
316
+
317
+ 结论是**两种周期,两套纪律**:
318
+
319
+ | | `kind=human`(你的) | `kind=agent`(智能体的) |
320
+ |---|---|---|
321
+ | 谁主导 | **你** | 智能体自己 |
322
+ | 用途 | 跟长任务、防漂移 | 定期批量归纳、自我提升 |
323
+ | 阶段纪律 | 计划→执行→检查→改进→完成,**五步不可跳** | 复盘可**一次性提交**,提交即自动闭环 |
324
+ | UI 位置 | 「📋 我的任务周期」(主区) | 「🤖 智能体归纳周期」(折叠在下方) |
325
+ | 复盘后 | 留在「改进」等你显式推进到完成 | 自动 → 完成(`autoClosed: true`) |
326
+ | 产出 | 经验教训 + 标准化建议 | 同左,但**只进建议队列**,你采纳才落库 |
327
+
328
+ 为什么 agent 允许一次性提交:让它假装走 `planned→doing` 是对事实的虚构。你要的是「结论 + 可采纳的标准」,不是看它表演流程。
329
+
330
+ **「定期」怎么落地**:`reviewer` 只做被动回合计数(每回合 +1,到阈值就 `due`),它不自己起定时器(宿主生命周期不可控)。所以:
331
+
332
+ 1. 周期页读 `GET /review/status`,把到期会话列出来(当前线上实测 3 个会话到期,共 111 回合);
333
+ 2. 你点「让它归纳」→ `POST /review/urge` 唤醒它,并给它明确三步指令(开 `kind=agent` 周期 → 一次性复盘 → 建议进队列);
334
+ 3. 归纳出的纪律**不会自动改自己**,走 `bot_suggestion_propose`,你采纳才生效。
335
+
336
+ 这条暗道是被故意堵死的:智能体不能自己给自己立规矩。
337
+
338
+ ### 需求5 · 表述更正
339
+
340
+ 任务详情 5W 区:
341
+
342
+ - 「谁建的」:`source=human` → **用户**;智能体分发 → 显示 Bot 名。
343
+ - 「来源」:`source=human` → **用户自建**;否则 → 智能体分发。
344
+
345
+ 不再把「`ui`」这种平台伪身份暴露给你看。
346
+
347
+ ### 验证证据(可核查)
348
+
349
+ ```
350
+ test/kernel-conversation.test.mjs 8 项 ✅
351
+ test/client-anchor.test.mjs 39 项 ✅
352
+ 全套 node --test test/*.test.mjs → 1108 / 1108 pass, 0 fail
353
+ bash test/run-all.sh → ✅ 全部通过(exit 0)
354
+ dsh-plugins.sh precheck → OK cs-bots -> src/client.js
355
+ dsh web 重启 → 启动图端到端校验 PASS
356
+
357
+ 线上实测(http://150.158.175.241/)
358
+ GET /cs-bots/api/tasks/conversation?id=t-29 → ok=true(无对话时如实 0 条)
359
+ GET /cs-bots/api/review/status → sessions=24, due=true, dueSessions=3
360
+ GET /cs-bots/api/cycles?kind=human → 只返回 human 周期
361
+ GET /cs-bots/api/cycles?kind=agent → items=[](尚无 agent 周期)
362
+ GET /cs-bots/api/teams?type=big → 1 个团队(Myfree改造,leadId 有值)
363
+ 下发 bundle(362 KB) → 含 TaskConversationPanel / roomFilter / 让它归纳
364
+ ```
@@ -0,0 +1,284 @@
1
+ # cs-bots 改造07 + 改造08(需求1–5)需求规格书
2
+
3
+ > 版本:v0.7.3(改造07 分层 + 改造08 需求1–5)
4
+ > 日期:2026-11-09
5
+ > 状态:已实现
6
+
7
+ ---
8
+
9
+ ## 1. 背景与目标
10
+
11
+ ### 1.1 改造前的问题
12
+
13
+ cs-bots v0.6.x 有 10 个扁平页签,所有功能平铺在一起,人和 AI 的能力边界不分。用户提出三个核心诉求:
14
+
15
+ 1. **分层**:把「人用的功能」和「AI 用的底层工具」分开
16
+ 2. **穿透**:正常只看人用的,需要时能进底层查看/管理
17
+ 3. **借鉴**:借鉴 DSH Super-agent 的三项能力(不借鉴 Source 外部事件驱动、不借鉴 Eval 准入模型)
18
+
19
+ ### 1.2 改造目标
20
+
21
+ | 目标 | 验收标准 |
22
+ |---|---|
23
+ | G1 分层架构 | 6 个上层页签 + 7 个下层区块,职责清晰 |
24
+ | G2 穿透入口 | 顶部「⚙ 穿透」按钮,点开可见 7 个区块,每区块可展开详情 |
25
+ | G3 借鉴3 Subscription | 任务可订阅房间,房间消息自动作为上下文到达任务 |
26
+ | G4 借鉴4 阶段机 | 任务带 8 阶段派生信息,`needsPerson` 正确标识「该人动手」 |
27
+ | G5 借鉴5 prepare | Bot 可设准备命令,claim 前执行,失败不认领 |
28
+ | G6 文档交付 | 架构、需求规格、详设、操作手册四份文档 |
29
+ | G7 质量门禁 | 全部既有测试通过 + 新增测试覆盖新能力 |
30
+
31
+ ### 1.3 明确不做的事
32
+
33
+ | 不做 | 原因 |
34
+ |---|---|
35
+ | 不借鉴 Source(外部事件驱动建任务) | 用户明确不要 |
36
+ | 不借鉴 Eval(准入模型/gate+assessment) | 用户明确不要 |
37
+ | 不引入第三方运行时依赖 | 保持零依赖纪律 |
38
+ | 不改动既有 38 个工具的契约 | 纯增量原则 |
39
+
40
+ ---
41
+
42
+ ## 2. 功能需求
43
+
44
+ ### FR-1:分层导航
45
+
46
+ **描述**:把 10 个扁平页签重组为 6 个上层页签。
47
+
48
+ | 需求 | 说明 |
49
+ |---|---|
50
+ | FR-1.1 | 页签为:工作台、团队、记忆、技能库、数据、设置 |
51
+ | FR-1.2 | 工作台含:协作看板、复盘周期、我的待办、便签、成果 |
52
+ | FR-1.3 | 团队含:Bot 档案、团队、房间 |
53
+ | FR-1.4 | 记忆含:事实与偏好、纪律与要求、提示词 |
54
+ | FR-1.5 | 技能库含:技能、工作流 |
55
+ | FR-1.6 | 数据含:文件浏览、PDCA 测量 |
56
+ | FR-1.7 | 旧页签 id(tasks/bots/rooms/teams/artifacts)通过 `safeGoTab` 自动映射到新页签,向后兼容 |
57
+
58
+ **验收**:页面只剩 6 个页签;旧 `onGoto('tasks')` 等调用仍能正确跳转。
59
+
60
+ ### FR-2:穿透面板
61
+
62
+ **描述**:顶部「⚙ 穿透」按钮打开右侧抽屉,显示 7 个下层区块。
63
+
64
+ | 需求 | 说明 |
65
+ |---|---|
66
+ | FR-2.1 | 区块为:注册表、唤醒桥、存储、路由、验证、建议、订阅 |
67
+ | FR-2.2 | 每区块显示 label + description + stats 概览 |
68
+ | FR-2.3 | 点击区块展开详情(GET `/deepdive/block/:id`) |
69
+ | FR-2.4 | 支持的区块操作:唤醒桥 flush、存储 replay |
70
+ | FR-2.5 | 未知区块返回 404 + 可读原因;不支持的操作返回 400 |
71
+ | FR-2.6 | 所有操作有明确返回值(成功/失败 + 人话) |
72
+
73
+ **验收**:`GET /deepdive/blocks` 返回 7 个区块;`POST /deepdive/op {block:'store',op:'replay'}` 成功。
74
+
75
+ ### FR-3:Subscription 扇出(借鉴 Super-agent)
76
+
77
+ **描述**:任务可订阅房间,房间后续消息自动作为上下文到达任务。
78
+
79
+ | 需求 | 说明 |
80
+ |---|---|
81
+ | FR-3.1 | `subscribe(taskId, roomId, note?, by)` 创建订阅,幂等 |
82
+ | FR-3.2 | `unsubscribe(id, expectedRev?, by)` 取消订阅(终态) |
83
+ | FR-3.3 | `fanout(roomId, message, wake?)` 把消息扇出给订阅该房间的活任务 |
84
+ | FR-3.4 | 扇出**只加上下文,不改任务状态、不授予开工权力** |
85
+ | FR-3.5 | 上下文滚动窗口,默认保留最近 20 条(`fanoutKeep`) |
86
+ | FR-3.6 | 每条上下文文本截断到 2000 字符(防爆炸) |
87
+ | FR-3.7 | 扇出默认**不唤醒** owner(`wakeOnFanout:false`) |
88
+ | FR-3.8 | 房间发消息后(POST `/rooms/post`)自动触发扇出 |
89
+ | FR-3.9 | CAS:unsubscribe 带 `expectedRev` 不匹配即抛错 |
90
+
91
+ **验收**:订阅后发房间消息,任务 `context` 增加;取消订阅后不再增加。
92
+
93
+ ### FR-4:工单阶段机(借鉴 Super-agent)
94
+
95
+ **描述**:任务带 8 个执行阶段的派生信息。
96
+
97
+ | 需求 | 说明 |
98
+ |---|---|
99
+ | FR-4.1 | 8 阶段:person/delivery、person/answer、person/review、person/blocked、person/failed、working/queued、idle、working |
100
+ | FR-4.2 | 判定自上而下首个命中(顺序即优先级) |
101
+ | FR-4.3 | 投递失败最高优先级 |
102
+ | FR-4.4 | 4 个 `person/*` 阶段 `needsPerson=true` |
103
+ | FR-4.5 | 纯函数,不落盘,不修改入参 |
104
+ | FR-4.6 | `GET /tasks` 每条任务带 `stageInfo`,响应带 `stageSummary` |
105
+ | FR-4.7 | `GET /tasks/detail` 和 `GET /tasks/summary` 带 `stageInfo` |
106
+ | FR-4.8 | 前端任务卡片显示阶段徽章,person 阶段用强调色 |
107
+
108
+ **验收**:新建任务显示「排队中」;完成未验收显示「等你验收」。
109
+
110
+ ### FR-5:prepare command(借鉴 Super-agent)
111
+
112
+ **描述**:Bot 可设开工准备命令。
113
+
114
+ | 需求 | 说明 |
115
+ |---|---|
116
+ | FR-5.1 | Bot 注册表新增 `prepareCommand` 字段(可选) |
117
+ | FR-5.2 | 创建时带 `prepareCommand` 落盘 |
118
+ | FR-5.3 | `setPrepareCommand(id, prepareCommand, expectedRev, byId)` 设置/清除 |
119
+ | FR-5.4 | claim 前先执行 prepare;失败则不认领,任务保持原状 |
120
+ | FR-5.5 | 安全边界:命令首段必须在 `CMD_WHITELIST` 内 |
121
+ | FR-5.6 | 用 execFile 传参数组,不经 shell(无注入面) |
122
+ | FR-5.7 | 硬超时 10 分钟 |
123
+ | FR-5.8 | cwd 固定为 Bot 工作目录 |
124
+ | FR-5.9 | `prepare_command_set` 动作写入事件流(可审计) |
125
+
126
+ **验收**:设 prepare 后派活,prepare 成功则 claim 成功,失败则返回 `PREPARE_FAILED`。
127
+
128
+ ---
129
+
130
+ ## 3. 非功能需求
131
+
132
+ | 编号 | 需求 | 验收 |
133
+ |---|---|---|
134
+ | NFR-1 | 零第三方运行时依赖 | `bash test/ci-zero-dep.sh` 通过 |
135
+ | NFR-2 | 全部既有测试通过 | 1108 项测试 0 失败 |
136
+ | NFR-3 | 零 `window.prompt/confirm/alert` | CI 检查 5 通过 |
137
+ | NFR-4 | 所有失败可读 | 每个错误有 code + 人话 |
138
+ | NFR-5 | 移动端可用 | 页签横向滚动、穿透面板全屏抽屉 |
139
+ | NFR-6 | 向后兼容 | 旧页签 id 自动映射 |
140
+
141
+ ---
142
+
143
+ ## 4. 约束
144
+
145
+ | 约束 | 说明 |
146
+ |---|---|
147
+ | C-1 | 不改动既有 38 个工具的契约 |
148
+ | C-2 | 新增工具走 `bot_` 前缀 |
149
+ | C-3 | 新增模块走独立文件,复用 `store.js` |
150
+ | C-4 | 事件流是真相源,先落盘再改内存 |
151
+ | C-5 | 所有变更带 CAS |
152
+ | C-6 | 单一入口 `bash test/run-all.sh` 判定交付 |
153
+
154
+ ---
155
+
156
+ ## 5. 交付物清单
157
+
158
+ | 交付物 | 路径 | 状态 |
159
+ |---|---|---|
160
+ | 架构文档 | `docs/01-架构文档.md` | ✅ |
161
+ | 需求规格书 | `docs/02-需求规格书.md` | ✅ |
162
+ | 详细设计文档 | `docs/03-详细设计.md` | ⏳ |
163
+ | 用户操作手册 | `docs/04-操作手册.md` | ⏳ |
164
+ | 实现代码 | `src/stage.js`、`src/subscription.js` 等 | ✅ |
165
+ | 测试 | `test/stage.test.mjs`、`test/subscription.test.mjs` 等 | ✅ |
166
+
167
+ ---
168
+
169
+ ## 6. 需求追溯矩阵
170
+
171
+ | 需求 | 实现文件 | 测试 |
172
+ |---|---|---|
173
+ | FR-1 分层导航 | `src/client.js` TABS | `test/client.test.mjs` B1 |
174
+ | FR-2 穿透面板 | `src/api.js` deepdive、`src/client.js` DeepDivePanel | `test/api.test.mjs` 改造07 穿透×8 |
175
+ | FR-3 Subscription | `src/subscription.js` | `test/subscription.test.mjs` ×17 |
176
+ | FR-4 阶段机 | `src/stage.js` | `test/stage.test.mjs` ×30 |
177
+ | FR-5 prepare | `src/roster.js`、`src/api.js` | `test/roster.test.mjs` 改造07 prepare×8 |
178
+ | NFR-1 零依赖 | - | `test/ci-zero-dep.sh` |
179
+
180
+ ---
181
+
182
+ *需求规格书完。*
183
+ ---
184
+
185
+ ## 改造08 · 需求 1–5(2026-11-09)
186
+
187
+ > 这一节的每一条都对应你原话里的一条要求,写完当天就上了线(0.7.3 已部署重启,启动图校验 PASS)。
188
+
189
+ ### 需求1 · 任务页只展示人建的任务,智能体任务单独一页
190
+
191
+ | | 改前 | 改后 |
192
+ |---|---|---|
193
+ | 「我的任务」页 | 人和智能体的任务混在一起 | 只显示 `source=human`(你自建的任务) |
194
+ | 智能体任务 | 混在同一个列表里翻 | 单独的「智能体任务」页签,按状态分类 |
195
+
196
+ - 后端 `GET /tasks?source=human|ai` 早已支持(`src/board.js` 里 `source` 字段),这次是**前端把它用起来**。
197
+ - 「我的任务」页保留「只看需要我处理的」开关;「智能体任务」页不显示这个开关(智能体的活不需要你逐条盯)。
198
+
199
+ ### 需求2 · 派活后能追踪进度、看到产出物、看到对话
200
+
201
+ 这一条挖到了一个**真 bug**,不是你操作的问题:
202
+
203
+ > `eventsToMessages` 只读 `ev.content`,而官方会话事件是 `{ type, seq, time, data }`,
204
+ > 内容在 `data.content` / `data.message.content` 里;`tool/call`、`tool/result` 是顶层事件。
205
+ > 结果:**对任何真实会话都恒定返回 0 条** —— 所以你看到的就是「没有对话内容可看」。
206
+
207
+ 实测同一个真实会话(4795 个事件):
208
+
209
+ | | 修前 | 修后 |
210
+ |---|---|---|
211
+ | 对话片段总数 | **0** | **2625** |
212
+ | 你的发言 | 0 | 110 |
213
+ | 执行者正文 | 0 | 74 |
214
+ | 思维链 | 0 | 465 |
215
+ | 工具调用 | 0 | 1306 |
216
+ | 工具结果 | 0 | 670 |
217
+
218
+ 新增/变更:
219
+
220
+ - 后端 `GET /tasks/conversation?id=&limit=` —— 只读打开执行者会话(`persistence.open(id,'read')`,不抢所有权),返回 `{ bot, sessionId, messages[], total, truncated, available }`。
221
+ - 前端任务详情新增**任务对话**面板:显示执行者身份、消息条数;默认只给正文(手机不被思维链淹没),点「看全部」才展开工具调用与思维链;「去对话」直接打开它的会话,宿主不支持就复制会话 ID 兜底。
222
+ - 无执行者时是**空态**(「还没有执行者」+ 下一步),不是报错。
223
+ - 产出物空态改成说清「为什么现在没有」:未完成时正常;已完成却没带证据时提示可以重开补交。
224
+
225
+ ### 需求3 · 团队页只显示你建的团队,负责人有标识,成员可选
226
+
227
+ - 团队页只拉 `GET /teams?type=big`(后端 `type` 字段保留不动,只是 UI 不再暴露「大小团队」概念)。
228
+ - 负责人带 `👑 负责人` 标识,成员列表里负责人加 `👑 ` 前缀;移出负责人会明确警告「移出后团队将没有负责人」。
229
+ - 建团队时负责人用下拉选择,成员用勾选组(可多选,支持新建 Bot 后再来选)。
230
+ - 「看房间」→ 跳房间页并**按团队名定向筛选**:房间页顶部出现「筛选房间:包含「X」→ N 个房间」和「✕ 清筛选」。
231
+ - 你要的「穿透房间看子团队工作内容」:房间页本来就是超级管理员视角,所有房间都能进、都能看长正文(`withBody=1` 一次取回),筛选只是在大列表里做定向。
232
+
233
+ ### 需求4 · PDCA 人机分治(这条改动最大)
234
+
235
+ 你的原话:「pdca 是对用户长任务进行复盘跟进的,人类主导;智能体的 pdca 流程你优化一下」。
236
+
237
+ 结论是**两种周期,两套纪律**:
238
+
239
+ | | `kind=human`(你的) | `kind=agent`(智能体的) |
240
+ |---|---|---|
241
+ | 谁主导 | **你** | 智能体自己 |
242
+ | 用途 | 跟长任务、防漂移 | 定期批量归纳、自我提升 |
243
+ | 阶段纪律 | 计划→执行→检查→改进→完成,**五步不可跳** | 复盘可**一次性提交**,提交即自动闭环 |
244
+ | UI 位置 | 「📋 我的任务周期」(主区) | 「🤖 智能体归纳周期」(折叠在下方) |
245
+ | 复盘后 | 留在「改进」等你显式推进到完成 | 自动 → 完成(`autoClosed: true`) |
246
+ | 产出 | 经验教训 + 标准化建议 | 同左,但**只进建议队列**,你采纳才落库 |
247
+
248
+ 为什么 agent 允许一次性提交:让它假装走 `planned→doing` 是对事实的虚构。你要的是「结论 + 可采纳的标准」,不是看它表演流程。
249
+
250
+ **「定期」怎么落地**:`reviewer` 只做被动回合计数(每回合 +1,到阈值就 `due`),它不自己起定时器(宿主生命周期不可控)。所以:
251
+
252
+ 1. 周期页读 `GET /review/status`,把到期会话列出来(当前线上实测 3 个会话到期,共 111 回合);
253
+ 2. 你点「让它归纳」→ `POST /review/urge` 唤醒它,并给它明确三步指令(开 `kind=agent` 周期 → 一次性复盘 → 建议进队列);
254
+ 3. 归纳出的纪律**不会自动改自己**,走 `bot_suggestion_propose`,你采纳才生效。
255
+
256
+ 这条暗道是被故意堵死的:智能体不能自己给自己立规矩。
257
+
258
+ ### 需求5 · 表述更正
259
+
260
+ 任务详情 5W 区:
261
+
262
+ - 「谁建的」:`source=human` → **用户**;智能体分发 → 显示 Bot 名。
263
+ - 「来源」:`source=human` → **用户自建**;否则 → 智能体分发。
264
+
265
+ 不再把「`ui`」这种平台伪身份暴露给你看。
266
+
267
+ ### 验证证据(可核查)
268
+
269
+ ```
270
+ test/kernel-conversation.test.mjs 8 项 ✅
271
+ test/client-anchor.test.mjs 39 项 ✅
272
+ 全套 node --test test/*.test.mjs → 1108 / 1108 pass, 0 fail
273
+ bash test/run-all.sh → ✅ 全部通过(exit 0)
274
+ dsh-plugins.sh precheck → OK cs-bots -> src/client.js
275
+ dsh web 重启 → 启动图端到端校验 PASS
276
+
277
+ 线上实测(http://150.158.175.241/)
278
+ GET /cs-bots/api/tasks/conversation?id=t-29 → ok=true(无对话时如实 0 条)
279
+ GET /cs-bots/api/review/status → sessions=24, due=true, dueSessions=3
280
+ GET /cs-bots/api/cycles?kind=human → 只返回 human 周期
281
+ GET /cs-bots/api/cycles?kind=agent → items=[](尚无 agent 周期)
282
+ GET /cs-bots/api/teams?type=big → 1 个团队(Myfree改造,leadId 有值)
283
+ 下发 bundle(362 KB) → 含 TaskConversationPanel / roomFilter / 让它归纳
284
+ ```