agent-step-gate 0.3.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/ARCHITECTURE.md +393 -0
- package/README.md +662 -0
- package/SKILL.md +190 -0
- package/Weaver.md +140 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +573 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/errors.d.ts +16 -0
- package/dist/core/errors.js +32 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/gate.d.ts +20 -0
- package/dist/core/gate.js +82 -0
- package/dist/core/gate.js.map +1 -0
- package/dist/core/keys.d.ts +18 -0
- package/dist/core/keys.js +37 -0
- package/dist/core/keys.js.map +1 -0
- package/dist/core/plan.d.ts +2 -0
- package/dist/core/plan.js +135 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/program.d.ts +69 -0
- package/dist/core/program.js +191 -0
- package/dist/core/program.js.map +1 -0
- package/dist/core/reconcile.d.ts +37 -0
- package/dist/core/reconcile.js +198 -0
- package/dist/core/reconcile.js.map +1 -0
- package/dist/core/session.d.ts +25 -0
- package/dist/core/session.js +88 -0
- package/dist/core/session.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/db.d.ts +3 -0
- package/dist/storage/db.js +117 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/repository.d.ts +24 -0
- package/dist/storage/repository.js +449 -0
- package/dist/storage/repository.js.map +1 -0
- package/dist/tools/activeTask.d.ts +2 -0
- package/dist/tools/activeTask.js +41 -0
- package/dist/tools/activeTask.js.map +1 -0
- package/dist/tools/cancelTask.d.ts +2 -0
- package/dist/tools/cancelTask.js +39 -0
- package/dist/tools/cancelTask.js.map +1 -0
- package/dist/tools/checkpoint.d.ts +2 -0
- package/dist/tools/checkpoint.js +71 -0
- package/dist/tools/checkpoint.js.map +1 -0
- package/dist/tools/current.d.ts +2 -0
- package/dist/tools/current.js +64 -0
- package/dist/tools/current.js.map +1 -0
- package/dist/tools/finalize.d.ts +2 -0
- package/dist/tools/finalize.js +95 -0
- package/dist/tools/finalize.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/startPlan.d.ts +2 -0
- package/dist/tools/startPlan.js +124 -0
- package/dist/tools/startPlan.js.map +1 -0
- package/dist/types/index.d.ts +142 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +48 -0
- package/scripts/interactive-demo.ts +394 -0
- package/scripts/mcp-call.mjs +56 -0
- package/scripts/prompt-check-hook.sh +27 -0
- package/scripts/session-start-hook.sh +47 -0
- package/scripts/stop-hook.mjs +83 -0
- package/scripts/stop-hook.sh +75 -0
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# Agent Step Gate — 完整架构文档
|
|
2
|
+
|
|
3
|
+
**版本**: 0.3.0 | **日期**: 2026-05-30 | **测试**: 116/116
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 四层架构
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Program (pgm_XXXXXX) ← 跨 Session 大计划
|
|
11
|
+
└─ Node (pg-xxx) ← 一个 Session 的工作单元
|
|
12
|
+
└─ Task (tsk_XXXXXX) ← 一个 DAG 计划
|
|
13
|
+
└─ Step ← 最小执行单元
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
每层都有对应的完成凭证:
|
|
17
|
+
```
|
|
18
|
+
stepKey ──→ taskKey ──→ nodeKey ──→ program (自检)
|
|
19
|
+
(出示) (出示) (收据) (自动)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 自底向上传播
|
|
23
|
+
|
|
24
|
+
`finalize` 命令一次调用,自动逐层上浮:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
finalize(taskKey)
|
|
28
|
+
→ task completed
|
|
29
|
+
→ 检查: 同 node 全部 task completed?
|
|
30
|
+
→ 是 → 生成 nodeKey → node completed
|
|
31
|
+
→ 检查: 同 program 全部 node completed?
|
|
32
|
+
→ 是 → program completed
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Agent 不需要判断层级——系统自己知道该传播到哪。
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2. 数据库 — 7 张表
|
|
40
|
+
|
|
41
|
+
### programs
|
|
42
|
+
```sql
|
|
43
|
+
program_id TEXT PK -- pgm_XXXXXX
|
|
44
|
+
title TEXT
|
|
45
|
+
status TEXT -- active | completed
|
|
46
|
+
total_nodes INTEGER
|
|
47
|
+
created_at / updated_at
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### program_nodes
|
|
51
|
+
```sql
|
|
52
|
+
node_id TEXT PK -- user-defined or pg_xxx_N
|
|
53
|
+
program_id TEXT FK
|
|
54
|
+
title / description / order_index
|
|
55
|
+
status TEXT -- pending | in_progress | completed
|
|
56
|
+
session_id TEXT
|
|
57
|
+
node_key_hash TEXT -- SHA-256(6-char nodeKey), system-generated
|
|
58
|
+
completed_at / created_at
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### sessions
|
|
62
|
+
```sql
|
|
63
|
+
session_id TEXT PK -- ses_XXXXXX
|
|
64
|
+
session_secret_hash TEXT -- SHA-256(6-char)
|
|
65
|
+
recovery_token_hash TEXT -- SHA-256(6-char)
|
|
66
|
+
title / workspace
|
|
67
|
+
program_id / program_node_id
|
|
68
|
+
status TEXT -- active | completed | abandoned
|
|
69
|
+
created_by_cli / created_at / updated_at
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### cli_instances
|
|
73
|
+
```sql
|
|
74
|
+
cli_instance_id TEXT PK -- cli_XXXXXX
|
|
75
|
+
session_id / hostname / pid / workspace
|
|
76
|
+
status TEXT -- active | dead | detached
|
|
77
|
+
created_at / last_seen_at
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### tasks
|
|
81
|
+
```sql
|
|
82
|
+
id TEXT PK -- tsk_XXXXXX
|
|
83
|
+
title / status -- active | completed | cancelled
|
|
84
|
+
current_index / total_steps
|
|
85
|
+
final_key_hash TEXT -- SHA-256(taskKey)
|
|
86
|
+
session_id TEXT FK
|
|
87
|
+
created_at / updated_at
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### steps
|
|
91
|
+
```sql
|
|
92
|
+
id TEXT PK -- {taskId}_{nodeId}
|
|
93
|
+
task_id / parent_path / title / path
|
|
94
|
+
order_index / depends_on (JSON)
|
|
95
|
+
status TEXT -- pending | current | completed | skipped
|
|
96
|
+
step_key_hash TEXT -- SHA-256(stepKey), 完成后保留为永久凭证
|
|
97
|
+
completed_at / created_at
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### events
|
|
101
|
+
```sql
|
|
102
|
+
id / task_id / step_id
|
|
103
|
+
event_type TEXT -- plan_created | step_activated | step_completed
|
|
104
|
+
-- all_steps_completed | task_finalized | task_cancelled
|
|
105
|
+
-- skip_key_consumed
|
|
106
|
+
payload / created_at
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 3. 安全模型 — 5 种凭证
|
|
112
|
+
|
|
113
|
+
| 凭证 | 长度 | 用途 | 生成者 | 验证方式 | 生命周期 |
|
|
114
|
+
|------|------|------|--------|---------|---------|
|
|
115
|
+
| **stepKey** | 6位 | 证明单个 step 完成 | 系统(plan/checkpoint) | SHA-256 hash 匹配 | 一次性,checkpoint 后消耗 |
|
|
116
|
+
| **taskKey** | 6位 | 证明全部 step 完成 | 系统(最后一步 checkpoint) | SHA-256 hash 匹配 | 一次性,finalize 后消耗 |
|
|
117
|
+
| **nodeKey** | 6位 | Node 完成凭证(收据) | 系统(finalize 自动传播) | SHA-256 hash 存 DB | 作为完成凭证返回给 Agent |
|
|
118
|
+
| **sessionSecret** | 6位 | Session 身份认证 | 系统(createSession) | SHA-256 hash 匹配 | Session 生命周期 |
|
|
119
|
+
| **recoveryToken** | 6位 | 崩溃恢复 + 管理操作 | 系统(createSession) | SHA-256 hash 匹配 | Session 生命周期 |
|
|
120
|
+
|
|
121
|
+
### 隔离规则
|
|
122
|
+
- Task 写操作:session_id 列强制过滤
|
|
123
|
+
- cancel-task:必须同 session,或出示 recoveryToken (--admin)
|
|
124
|
+
- checkpoint 原子性:`WHERE status='current' + affected rows` 防双消费
|
|
125
|
+
- stepKey 一次性:key_hash 保留作永久凭证,但 step 只能 checkpoint 一次
|
|
126
|
+
|
|
127
|
+
### skipKey 验证 (中断恢复)
|
|
128
|
+
- 旧 task 的 completed step 可作 skipKey 跳过新 task 的重复步骤
|
|
129
|
+
- `verifySkipKey()` 检查:hash 匹配 + status='completed' + events 表无 `skip_key_consumed`
|
|
130
|
+
- 验证通过后立即写入 `skip_key_consumed` 事件——确保一次性使用
|
|
131
|
+
- 跳过步骤标记为 `skipped`(非 `completed`),保留溯源
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 4. DAG 引擎
|
|
136
|
+
|
|
137
|
+
### 输入格式
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"title": "Plan",
|
|
141
|
+
"steps": [
|
|
142
|
+
{"id":"a","title":"A","dependsOn":[]},
|
|
143
|
+
{"id":"b","title":"B","dependsOn":["a"]},
|
|
144
|
+
{"id":"c","title":"C","dependsOn":[],"skipKey":"OLD","skipTaskId":"tsk_OLD"}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 展开规则
|
|
150
|
+
1. `dependsOn: []` → 并行起点,初始即激活
|
|
151
|
+
2. `dependsOn: undefined` → 自动串行,依赖前一个叶子
|
|
152
|
+
3. `dependsOn: ["b","c"]` → b 和 c 都完成后才解锁
|
|
153
|
+
4. `skipKey + skipTaskId` → 验证通过后标记 `skipped`
|
|
154
|
+
5. 嵌套 children → 递归展开为叶子节点
|
|
155
|
+
|
|
156
|
+
### 解锁算法
|
|
157
|
+
```
|
|
158
|
+
checkpoint(stepX):
|
|
159
|
+
1. 标记 stepX = completed (保留 key_hash)
|
|
160
|
+
2. 扫描 pending steps:
|
|
161
|
+
dependsOn 全部 completed/skipped → 标记 current,生成 key
|
|
162
|
+
3. 无新解锁 + 全部 completed/skipped → 生成 taskKey
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 5. CLI 命令全集 (12 个)
|
|
168
|
+
|
|
169
|
+
### Task 级
|
|
170
|
+
| 命令 | 输入 | 输出 |
|
|
171
|
+
|------|------|------|
|
|
172
|
+
| `start-plan '<json>'` | title + steps[] | taskId, session, totalSteps, currentSteps, stepKeys |
|
|
173
|
+
| `checkpoint '<json>'` | taskId + stepId + stepKey | completedStep, nextSteps, nextStepKeys, taskKey |
|
|
174
|
+
| `current '<json>'` | taskId | status, totalSteps, completedSteps, currentSteps |
|
|
175
|
+
| `finalize '<json>'` | taskId + taskKey | level(task/node/program), nodeKey(if), program(if) |
|
|
176
|
+
| `cancel-task '<json>'` | taskId | ok / error(NO_SESSION) |
|
|
177
|
+
| `active-task` | — | activeTasks[] (session-filtered) |
|
|
178
|
+
| `active-task --all` | — | activeTasks[] (跨 session) |
|
|
179
|
+
|
|
180
|
+
### Program 级
|
|
181
|
+
| 命令 | 输入 | 输出 |
|
|
182
|
+
|------|------|------|
|
|
183
|
+
| `program init '<json>'` | title + nodes[] | programId, totalNodes, nodes |
|
|
184
|
+
| `program status '<json>'` | programId | programId, title, nodes[] |
|
|
185
|
+
| `program ready '<json>'` | programId | readyNodes[] |
|
|
186
|
+
| `program start '<json>'` | programId + nodeId | ok, nodeId, sessionId |
|
|
187
|
+
| `program finalize '<json>'` | programId | ok, pending[] |
|
|
188
|
+
|
|
189
|
+
### Session 绑定方式
|
|
190
|
+
- `--session-file <path>` — 显式指定 session 文件
|
|
191
|
+
- `--binding-file <path>` — 通过 binding 文件间接指定
|
|
192
|
+
- `STEP_GATE_SESSION_FILE` / `STEP_GATE_BINDING_FILE` 环境变量
|
|
193
|
+
- 自动发现 `.step-gate/bindings/` 中最新的 binding(回退)
|
|
194
|
+
|
|
195
|
+
### Admin 模式
|
|
196
|
+
- `cancel-task --admin --recovery-token <token>` — 跨 session 取消
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## 6. 核心函数 (20+)
|
|
201
|
+
|
|
202
|
+
### src/core/plan.ts
|
|
203
|
+
| 函数 | 作用 |
|
|
204
|
+
|------|------|
|
|
205
|
+
| `flattenPlan(nodes, taskId) → LeafStep[]` | 嵌套展开 + DAG 依赖解析 |
|
|
206
|
+
|
|
207
|
+
### src/core/keys.ts
|
|
208
|
+
| 函数 | 作用 |
|
|
209
|
+
|------|------|
|
|
210
|
+
| `randomCode(length) → string` | [A-Z0-9] 随机码 |
|
|
211
|
+
| `generateStepKey() → {plaintext, hash}` | 6位 step key |
|
|
212
|
+
| `generateTaskKey() → {plaintext, hash}` | 6位 task key |
|
|
213
|
+
| `generateNodeKey() → {plaintext, hash}` | 6位 node key |
|
|
214
|
+
| `hashKey(plaintext) → string` | SHA-256 |
|
|
215
|
+
|
|
216
|
+
### src/core/gate.ts
|
|
217
|
+
| 函数 | 作用 |
|
|
218
|
+
|------|------|
|
|
219
|
+
| `validateCheckpoint(repo, taskId, stepId, stepKey)` | 5步校验(task存在/active/current匹配/key匹配) |
|
|
220
|
+
| `advanceSteps(repo, task, completedStepId)` | 解锁后继步骤或生成 taskKey |
|
|
221
|
+
| `GateRepository` (interface) | 仓库抽象:getTask/getCurrentSteps/getTaskSteps/completeAndAdvance/updateTaskStatus/verifyTaskKey |
|
|
222
|
+
|
|
223
|
+
### src/core/session.ts
|
|
224
|
+
| 函数 | 作用 |
|
|
225
|
+
|------|------|
|
|
226
|
+
| `createSession(workspace) → SessionInfo` | 创建 session + 写入文件 |
|
|
227
|
+
| `verifySessionSecret(sessionId, secret)` | 校验 session 凭据 |
|
|
228
|
+
| `verifyRecoveryToken(sessionId, token)` | 校验恢复凭据 |
|
|
229
|
+
| `isSessionActive(sessionId)` | 检查状态 |
|
|
230
|
+
| `getCurrentSessionId()` | 进程内共享 sessionId |
|
|
231
|
+
|
|
232
|
+
### src/core/program.ts
|
|
233
|
+
| 函数 | 作用 |
|
|
234
|
+
|------|------|
|
|
235
|
+
| `createProgram(title, nodes[]) → ProgramInfo` | 创建 Program |
|
|
236
|
+
| `getProgramStatus(programId) → ProgramInfo` | 查询状态 |
|
|
237
|
+
| `getReadyNodes(programId) → ProgramNodeInfo[]` | 可开始的 node |
|
|
238
|
+
| `startProgramNode(programId, nodeId, sessionId)` | 绑定 session |
|
|
239
|
+
| `commitProgramNode(sessionId)` | 自动生成 nodeKey + 标记 node 完成 |
|
|
240
|
+
| `finalizeProgram(programId)` | 全局完整性检查 |
|
|
241
|
+
|
|
242
|
+
### src/storage/repository.ts
|
|
243
|
+
| 函数 | 作用 |
|
|
244
|
+
|------|------|
|
|
245
|
+
| `createTask(task, steps[])` | 原子写入 task + steps |
|
|
246
|
+
| `getTask(taskId)` | 查询 task |
|
|
247
|
+
| `getCurrentSteps(taskId)` | 查询活跃步骤 |
|
|
248
|
+
| `getTaskSteps(taskId)` | 查询所有步骤 |
|
|
249
|
+
| `getActiveTasks(sessionId?)` | 活跃 task(可选 session 过滤) |
|
|
250
|
+
| `completeAndAdvance(...)` | 原子完成+推进(事务保护) |
|
|
251
|
+
| `verifyStepKey(taskId, stepId, key)` | 严格校验(status='current') |
|
|
252
|
+
| `verifyTaskKey(taskId, key)` | 校验 taskKey |
|
|
253
|
+
| `verifySkipKey(oldTaskId, stepId, oldKey)` | 验证 skip 凭证 + 检查消费事件 |
|
|
254
|
+
| `recordSkipConsumed(taskId, stepId)` | 写入 skip_key_consumed 事件 |
|
|
255
|
+
| `cancelTask(taskId, sessionId)` | 取消(session 门控) |
|
|
256
|
+
| `updateTaskStatus(taskId, status)` | 更新状态 |
|
|
257
|
+
| `addEvent(taskId, stepId, type, payload?)` | 事件记录 |
|
|
258
|
+
| `getEvents(taskId)` | 查询事件 |
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## 7. Hook 系统
|
|
263
|
+
|
|
264
|
+
### SessionStart (`scripts/session-start-hook.sh`)
|
|
265
|
+
```
|
|
266
|
+
触发: 每次终端启动
|
|
267
|
+
策略: 轻量优先 — 读 data/state.json (1ms),无结果才调 CLI
|
|
268
|
+
行为:
|
|
269
|
+
1. 读 state.json → 有活跃 task → 警告 + 列出进度
|
|
270
|
+
2. state 为空 → active-task --all → 跨 session 检查
|
|
271
|
+
3. 无未完成 → 提醒可用命令
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Stop (`.claude/settings.local.json`)
|
|
275
|
+
```
|
|
276
|
+
触发: Session 结束前
|
|
277
|
+
行为:
|
|
278
|
+
调用 finalize(taskKey) → 系统自动传播到 node/program
|
|
279
|
+
如无 taskKey → 拦截提醒
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### State File (`data/state.json`)
|
|
283
|
+
```
|
|
284
|
+
写入时机: start-plan / checkpoint / finalize / cancel-task 后
|
|
285
|
+
内容: { hasActiveTask, activeTasks: [{taskId, title, completed, total, current}] }
|
|
286
|
+
用途: SessionStart 1ms 快照,跨互动提醒
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 8. 文件布局
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
project/
|
|
295
|
+
src/
|
|
296
|
+
cli.ts ← CLI 入口 (504行, 12命令)
|
|
297
|
+
index.ts ← MCP Server 入口 (备用)
|
|
298
|
+
core/
|
|
299
|
+
plan.ts ← DAG 展开
|
|
300
|
+
keys.ts ← 三层密钥生成
|
|
301
|
+
gate.ts ← 校验 + 解锁状态机
|
|
302
|
+
session.ts ← Session 管理
|
|
303
|
+
program.ts ← Program 层
|
|
304
|
+
errors.ts ← GateError
|
|
305
|
+
storage/
|
|
306
|
+
db.ts ← SQLite (WAL, busy_timeout=5000)
|
|
307
|
+
repository.ts ← 数据层 (20+ 函数)
|
|
308
|
+
tools/ ← MCP 工具 (备用)
|
|
309
|
+
startPlan.ts / checkpoint.ts / current.ts
|
|
310
|
+
finalize.ts / cancelTask.ts / activeTask.ts / index.ts
|
|
311
|
+
types/
|
|
312
|
+
index.ts ← 全部类型定义
|
|
313
|
+
tests/
|
|
314
|
+
core.test.ts ← 36 tests
|
|
315
|
+
storage.test.ts ← 34 tests
|
|
316
|
+
tools.test.ts ← 29 tests (含 A1/B1)
|
|
317
|
+
ci-blackbox.test.ts ← 15 tests (MCP 协议级)
|
|
318
|
+
e2e-smoking-app.test.ts ← E2E 强制回退
|
|
319
|
+
e2e-multi-agent.test.ts ← E2E 多Agent协作
|
|
320
|
+
scripts/
|
|
321
|
+
session-start-hook.sh
|
|
322
|
+
prompt-check-hook.sh
|
|
323
|
+
mcp-backup/ ← MCP 完整备份
|
|
324
|
+
data/
|
|
325
|
+
gate.db ← SQLite 数据库
|
|
326
|
+
state.json ← 轻量快照
|
|
327
|
+
.step-gate/
|
|
328
|
+
sessions/ ← Session 凭据文件
|
|
329
|
+
bindings/ ← CLI 绑定文件
|
|
330
|
+
openspec/changes/ ← 变更文档
|
|
331
|
+
SKILL.md ← Skill 定义
|
|
332
|
+
ARCHITECTURE.md ← 本文档
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## 9. 错误码
|
|
338
|
+
|
|
339
|
+
| 错误码 | 含义 |
|
|
340
|
+
|--------|------|
|
|
341
|
+
| TASK_NOT_FOUND | taskId 不存在 |
|
|
342
|
+
| TASK_ALREADY_COMPLETED | 任务已完成 |
|
|
343
|
+
| NO_STEPS | 计划无步骤 |
|
|
344
|
+
| INVALID_CURRENT_STEP | 步骤不在当前状态 |
|
|
345
|
+
| INVALID_STEP_KEY | stepKey 校验失败 |
|
|
346
|
+
| INVALID_FINAL_KEY | taskKey 校验失败 |
|
|
347
|
+
| INVALID_RECOVERY_TOKEN | recoveryToken 校验失败 |
|
|
348
|
+
| PLAN_SCHEMA_INVALID | 计划格式错误 |
|
|
349
|
+
| SKIP_VERIFY_FAILED | skip 凭证验证失败或已消费 |
|
|
350
|
+
| NO_SESSION | 无 session 绑定 |
|
|
351
|
+
| INTERNAL_ERROR | 数据库/内部错误 |
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 10. 典型流程
|
|
356
|
+
|
|
357
|
+
### 单 Session
|
|
358
|
+
```bash
|
|
359
|
+
start-plan → checkpoint × N → finalize taskKey
|
|
360
|
+
# → 自底向上: task → node → program (如有)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### 中断恢复
|
|
364
|
+
```bash
|
|
365
|
+
start-plan → checkpoint auth ✅
|
|
366
|
+
→ current (查状态) → cancel-task
|
|
367
|
+
→ start-plan (skipKey+skipTaskId 重建,旧 key 被消费)
|
|
368
|
+
→ checkpoint → finalize taskKey
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### 跨 Session Program
|
|
372
|
+
```bash
|
|
373
|
+
program init → program start pg-1
|
|
374
|
+
→ start-plan → checkpoint × N → finalize taskKey
|
|
375
|
+
# ↑ 自动标记 pg-1 completed + nodeKey 生成
|
|
376
|
+
|
|
377
|
+
program start pg-2
|
|
378
|
+
→ start-plan → checkpoint × N → finalize taskKey
|
|
379
|
+
# ↑ 自动标记 pg-2 completed,program completed
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## 11. 技术栈
|
|
385
|
+
|
|
386
|
+
- **Runtime**: Node.js 20+
|
|
387
|
+
- **Language**: TypeScript ESM
|
|
388
|
+
- **Storage**: better-sqlite3 (WAL, synchronous=NORMAL, busy_timeout=5000)
|
|
389
|
+
- **Validation**: Zod v4 (MCP tools)
|
|
390
|
+
- **Test**: vitest (116 tests, 6 suites)
|
|
391
|
+
- **Key**: crypto.randomBytes → [A-Z0-9]{6} → SHA-256
|
|
392
|
+
- **IDs**: 6位 [A-Z0-9] (36^6 ≈ 21亿熵)
|
|
393
|
+
- **MCP SDK**: @modelcontextprotocol/sdk v1.x (备用)
|