vibe-coding-master 0.0.6 → 0.0.8
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 +207 -66
- package/dist/backend/adapters/filesystem.js +13 -0
- package/dist/backend/adapters/git-adapter.js +79 -1
- package/dist/backend/adapters/translation-provider.js +145 -0
- package/dist/backend/api/artifact-routes.js +16 -7
- package/dist/backend/api/harness-routes.js +22 -0
- package/dist/backend/api/message-routes.js +2 -0
- package/dist/backend/api/project-routes.js +3 -8
- package/dist/backend/api/task-routes.js +14 -0
- package/dist/backend/api/translation-routes.js +70 -0
- package/dist/backend/runtime/node-pty-runtime.js +20 -18
- package/dist/backend/server.js +33 -2
- package/dist/backend/services/app-settings-service.js +128 -0
- package/dist/backend/services/artifact-service.js +7 -4
- package/dist/backend/services/claude-transcript-service.js +509 -0
- package/dist/backend/services/command-dispatcher.js +4 -2
- package/dist/backend/services/harness-service.js +196 -0
- package/dist/backend/services/message-service.js +1 -1
- package/dist/backend/services/project-service.js +50 -9
- package/dist/backend/services/session-service.js +13 -9
- package/dist/backend/services/status-service.js +79 -1
- package/dist/backend/services/task-service.js +118 -4
- package/dist/backend/services/translation-prompts.js +173 -0
- package/dist/backend/services/translation-queue.js +39 -0
- package/dist/backend/services/translation-service.js +546 -0
- package/dist/backend/templates/handoff.js +32 -0
- package/dist/backend/templates/harness/architect-agent.js +12 -0
- package/dist/backend/templates/harness/claude-root.js +14 -0
- package/dist/backend/templates/harness/coder-agent.js +11 -0
- package/dist/backend/templates/harness/gitignore.js +9 -0
- package/dist/backend/templates/harness/project-manager-agent.js +14 -0
- package/dist/backend/templates/harness/reviewer-agent.js +13 -0
- package/dist/backend/ws/translation-ws.js +35 -0
- package/dist/shared/types/harness.js +1 -0
- package/dist/shared/types/translation.js +5 -0
- package/dist/shared/validation/artifact-check.js +15 -1
- package/dist/shared/validation/language-detect.js +46 -0
- package/dist-frontend/assets/index-CuiNNOzj.css +32 -0
- package/dist-frontend/assets/index-D59GuHCR.js +58 -0
- package/dist-frontend/index.html +2 -2
- package/docs/cc-best-practices.md +109 -40
- package/docs/product-design.md +370 -1374
- package/docs/v1-architecture-design.md +595 -1114
- package/docs/v1-implementation-plan.md +898 -1603
- package/package.json +1 -1
- package/scripts/verify-package.mjs +8 -0
- package/dist/backend/templates/role-messaging-context.js +0 -44
- package/dist-frontend/assets/index-Bah6k-Ix.css +0 -32
- package/dist-frontend/assets/index-EMaQuIB6.js +0 -58
- package/docs/v1-message-bus-orchestration-design.md +0 -534
|
@@ -1,1949 +1,1244 @@
|
|
|
1
|
-
#
|
|
1
|
+
# V1 Implementation Plan And File Map
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
日期:2026-05-29
|
|
5
|
-
状态:实施计划草案
|
|
6
|
-
依据:
|
|
3
|
+
Last updated: 2026-05-31
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
- `docs/v1-architecture-design.md`
|
|
10
|
-
- `docs/cc-best-practices.md`
|
|
5
|
+
This document is the current implementation map for VCM V1.
|
|
11
6
|
|
|
12
|
-
## 1.
|
|
7
|
+
## 1. Current Status
|
|
13
8
|
|
|
14
|
-
V1
|
|
9
|
+
V1 is implemented as a local GUI app with:
|
|
15
10
|
|
|
16
|
-
|
|
11
|
+
- Fastify backend.
|
|
12
|
+
- React frontend.
|
|
13
|
+
- `node-pty` embedded terminals.
|
|
14
|
+
- `xterm.js` terminal rendering.
|
|
15
|
+
- Four Claude Code role sessions.
|
|
16
|
+
- VCM harness installer.
|
|
17
|
+
- API-driven message bus.
|
|
18
|
+
- Translation panel based on Claude transcript JSONL tailing.
|
|
19
|
+
- npm packaging with built `dist` and `dist-frontend` output.
|
|
20
|
+
- Task creation creates one `feature/<task>` branch and one `.ai/vcm/worktrees/<task>` git worktree.
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
Open VibeCodingMaster
|
|
20
|
-
-> Select repo
|
|
21
|
-
-> New task
|
|
22
|
-
-> Start project-manager session
|
|
23
|
-
-> Start architect session
|
|
24
|
-
-> Switch between role sessions
|
|
25
|
-
-> Type directly into embedded Claude Code terminals
|
|
26
|
-
-> View role commands, logs, and handoff artifacts
|
|
27
|
-
-> Send role command to target session from GUI
|
|
28
|
-
-> Restart / stop role sessions
|
|
29
|
-
```
|
|
22
|
+
## 2. Package And Build
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
File:
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
- `package.json`
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
- 自动识别 public contract / test contract。
|
|
37
|
-
- 自动执行 validation commands。
|
|
38
|
-
- 自动 Cross-Model Review。
|
|
39
|
-
- 自动创建 PR。
|
|
40
|
-
- SaaS 多用户协作。
|
|
41
|
-
- 完整 Desktop 打包和自动更新。
|
|
42
|
-
- 多 worktree 自动管理。
|
|
28
|
+
Current package facts:
|
|
43
29
|
|
|
44
|
-
|
|
30
|
+
- package name: `vibe-coding-master`
|
|
31
|
+
- current version: `0.0.7`
|
|
32
|
+
- type: ESM
|
|
33
|
+
- `bin.vcm`: `dist/main.js`
|
|
34
|
+
- `bin.vcmctl`: `dist/cli/vcmctl.js`
|
|
35
|
+
- published files: `dist`, `dist-frontend`, `docs`, `scripts`, `README.md`
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
2. Claude Code role session 必须在 embedded terminal 中可见、可输入、可重启。
|
|
48
|
-
3. Project Manager 不直接无限制控制其他 role sessions。
|
|
49
|
-
4. Role command 必须先落盘到 `.ai/handoffs/<task-slug>/role-commands/<role>.md`。
|
|
50
|
-
5. GUI 读取 role command,用户点击发送后,backend 只向目标 terminal 写入短指令。
|
|
51
|
-
6. Backend 可以程序化写入和监听 embedded terminal,但 V1 只允许用户触发的 command dispatch,不自动确认权限,不自动串联驱动角色。
|
|
52
|
-
7. Terminal output 只作为调试信息;长期事实源是 handoff artifacts。
|
|
53
|
-
8. Raw terminal stream 必须持续写入 `.ai/handoffs/<task-slug>/logs/<role>.log`。
|
|
54
|
-
9. V1 只做 artifact 存在性和标题完整性检查,不判断内容质量。
|
|
55
|
-
10. 状态必须能从 backend session registry、terminal process state、repo artifacts、`.vcm` metadata 恢复。
|
|
56
|
-
11. V1 不把每个 role 放到独立 worktree。同一任务默认共享当前 repo working directory。
|
|
57
|
-
12. V1 默认遵守 single-writer rule,但主要通过流程提示、role status 和 review gate 实现,不做强制 sandbox。
|
|
37
|
+
Scripts:
|
|
58
38
|
|
|
59
|
-
|
|
39
|
+
- `clean`: remove build output.
|
|
40
|
+
- `fix:node-pty`: fix packaged `node-pty` spawn helper.
|
|
41
|
+
- `postinstall`: run `fix:node-pty`.
|
|
42
|
+
- `verify:package`: verify required package files.
|
|
43
|
+
- `prepack`: run build and package verification.
|
|
44
|
+
- `dev`: start backend plus Vite dev server.
|
|
45
|
+
- `build`: clean, compile Node TypeScript, build frontend.
|
|
46
|
+
- `start`: run built backend.
|
|
47
|
+
- `typecheck`: TypeScript no-emit checks for browser and Node configs.
|
|
48
|
+
- `test`: Vitest.
|
|
49
|
+
- `e2e`: Playwright.
|
|
60
50
|
|
|
61
|
-
|
|
62
|
-
Language: TypeScript
|
|
63
|
-
Runtime: Node.js LTS
|
|
64
|
-
Frontend: React + Vite
|
|
65
|
-
Terminal UI: xterm.js
|
|
66
|
-
Backend: Fastify + ws
|
|
67
|
-
Terminal runtime: node-pty
|
|
68
|
-
Process execution: execa
|
|
69
|
-
State storage: JSON files
|
|
70
|
-
Test runner: Vitest + Playwright
|
|
71
|
-
Module format: ESM / NodeNext
|
|
72
|
-
```
|
|
51
|
+
Packaging guard:
|
|
73
52
|
|
|
74
|
-
|
|
53
|
+
- `scripts/verify-package.mjs`
|
|
54
|
+
|
|
55
|
+
It verifies required files, shebangs, packaged static path behavior, and frontend built assets.
|
|
56
|
+
|
|
57
|
+
## 3. Source Tree
|
|
75
58
|
|
|
76
59
|
```text
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
role.ts
|
|
102
|
-
session.ts
|
|
103
|
-
task.ts
|
|
104
|
-
terminal.ts
|
|
105
|
-
validation/
|
|
106
|
-
artifact-check.ts
|
|
107
|
-
slug-check.ts
|
|
108
|
-
|
|
109
|
-
frontend/
|
|
110
|
-
app.tsx
|
|
111
|
-
main.tsx
|
|
112
|
-
styles.css
|
|
113
|
-
routes/
|
|
114
|
-
project-dashboard.tsx
|
|
115
|
-
task-workspace.tsx
|
|
116
|
-
components/
|
|
117
|
-
app-shell.tsx
|
|
118
|
-
event-log.tsx
|
|
119
|
-
repo-connect-form.tsx
|
|
120
|
-
role-session-tabs.tsx
|
|
121
|
-
session-console.tsx
|
|
122
|
-
session-toolbar.tsx
|
|
123
|
-
status-badge.tsx
|
|
124
|
-
task-nav.tsx
|
|
125
|
-
terminal/
|
|
126
|
-
terminal-client.ts
|
|
127
|
-
xterm-view.tsx
|
|
128
|
-
state/
|
|
129
|
-
api-client.ts
|
|
130
|
-
app-store.ts
|
|
131
|
-
session-store.ts
|
|
132
|
-
|
|
133
|
-
backend/
|
|
134
|
-
server.ts
|
|
135
|
-
api/
|
|
136
|
-
artifact-routes.ts
|
|
137
|
-
project-routes.ts
|
|
138
|
-
session-routes.ts
|
|
139
|
-
task-routes.ts
|
|
140
|
-
ws/
|
|
141
|
-
terminal-ws.ts
|
|
142
|
-
runtime/
|
|
143
|
-
node-pty-runtime.ts
|
|
144
|
-
session-registry.ts
|
|
145
|
-
terminal-runtime.ts
|
|
146
|
-
services/
|
|
147
|
-
artifact-service.ts
|
|
148
|
-
command-dispatcher.ts
|
|
149
|
-
project-service.ts
|
|
150
|
-
session-service.ts
|
|
151
|
-
status-service.ts
|
|
152
|
-
task-service.ts
|
|
153
|
-
adapters/
|
|
154
|
-
claude-adapter.ts
|
|
155
|
-
command-runner.ts
|
|
156
|
-
filesystem.ts
|
|
157
|
-
git-adapter.ts
|
|
158
|
-
templates/
|
|
159
|
-
handoff.ts
|
|
160
|
-
role-command.ts
|
|
161
|
-
validation/
|
|
162
|
-
environment-check.ts
|
|
163
|
-
|
|
164
|
-
tests/
|
|
165
|
-
unit/
|
|
166
|
-
shared/
|
|
167
|
-
backend/
|
|
168
|
-
frontend/
|
|
169
|
-
integration/
|
|
170
|
-
api/
|
|
171
|
-
runtime/
|
|
172
|
-
e2e/
|
|
173
|
-
task-workspace.spec.ts
|
|
60
|
+
src/
|
|
61
|
+
main.ts
|
|
62
|
+
cli/
|
|
63
|
+
vcmctl.ts
|
|
64
|
+
shared/
|
|
65
|
+
constants.ts
|
|
66
|
+
types/
|
|
67
|
+
validation/
|
|
68
|
+
backend/
|
|
69
|
+
server.ts
|
|
70
|
+
adapters/
|
|
71
|
+
api/
|
|
72
|
+
runtime/
|
|
73
|
+
services/
|
|
74
|
+
templates/
|
|
75
|
+
ws/
|
|
76
|
+
frontend/
|
|
77
|
+
app.tsx
|
|
78
|
+
main.tsx
|
|
79
|
+
routes/
|
|
80
|
+
components/
|
|
81
|
+
state/
|
|
82
|
+
terminal/
|
|
83
|
+
styles.css
|
|
174
84
|
```
|
|
175
85
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
### 5.1 `package.json`
|
|
179
|
-
|
|
180
|
-
职责:
|
|
181
|
-
|
|
182
|
-
- 声明本地开发命令。
|
|
183
|
-
- 声明 build、test、typecheck、e2e 命令。
|
|
184
|
-
- 保留 `vcm` binary 用于启动本地 GUI dev/prod server。
|
|
185
|
-
|
|
186
|
-
计划字段:
|
|
187
|
-
|
|
188
|
-
```json
|
|
189
|
-
{
|
|
190
|
-
"type": "module",
|
|
191
|
-
"bin": {
|
|
192
|
-
"vcm": "./dist/main.js"
|
|
193
|
-
},
|
|
194
|
-
"scripts": {
|
|
195
|
-
"dev": "tsx src/main.ts --dev",
|
|
196
|
-
"build": "tsc -p tsconfig.node.json && vite build",
|
|
197
|
-
"start": "node dist/main.js",
|
|
198
|
-
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.node.json --noEmit",
|
|
199
|
-
"test": "vitest run",
|
|
200
|
-
"test:watch": "vitest",
|
|
201
|
-
"e2e": "playwright test"
|
|
202
|
-
},
|
|
203
|
-
"dependencies": {
|
|
204
|
-
"@fastify/static": "^7.0.0",
|
|
205
|
-
"@xterm/addon-fit": "^0.10.0",
|
|
206
|
-
"@xterm/addon-web-links": "^0.11.0",
|
|
207
|
-
"@xterm/xterm": "^5.5.0",
|
|
208
|
-
"execa": "^9.0.0",
|
|
209
|
-
"fastify": "^5.0.0",
|
|
210
|
-
"node-pty": "^1.0.0",
|
|
211
|
-
"react": "^19.0.0",
|
|
212
|
-
"react-dom": "^19.0.0",
|
|
213
|
-
"ws": "^8.0.0",
|
|
214
|
-
"zod": "^3.0.0"
|
|
215
|
-
},
|
|
216
|
-
"devDependencies": {
|
|
217
|
-
"@playwright/test": "^1.0.0",
|
|
218
|
-
"@types/node": "^22.0.0",
|
|
219
|
-
"@types/react": "^19.0.0",
|
|
220
|
-
"@types/react-dom": "^19.0.0",
|
|
221
|
-
"@types/ws": "^8.0.0",
|
|
222
|
-
"@vitejs/plugin-react": "^4.0.0",
|
|
223
|
-
"tsx": "^4.0.0",
|
|
224
|
-
"typescript": "^5.0.0",
|
|
225
|
-
"vite": "^6.0.0",
|
|
226
|
-
"vitest": "^2.0.0"
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
```
|
|
86
|
+
Removed/obsolete files that must not be documented as active:
|
|
230
87
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- 类型检查前端和 shared 代码。
|
|
236
|
-
- 使用 JSX。
|
|
237
|
-
- 不输出文件。
|
|
238
|
-
|
|
239
|
-
关键配置:
|
|
240
|
-
|
|
241
|
-
```json
|
|
242
|
-
{
|
|
243
|
-
"compilerOptions": {
|
|
244
|
-
"target": "ES2022",
|
|
245
|
-
"module": "ESNext",
|
|
246
|
-
"moduleResolution": "Bundler",
|
|
247
|
-
"jsx": "react-jsx",
|
|
248
|
-
"strict": true,
|
|
249
|
-
"esModuleInterop": true,
|
|
250
|
-
"skipLibCheck": true,
|
|
251
|
-
"types": ["vite/client"]
|
|
252
|
-
},
|
|
253
|
-
"include": ["src/frontend/**/*.ts", "src/frontend/**/*.tsx", "src/shared/**/*.ts"]
|
|
254
|
-
}
|
|
255
|
-
```
|
|
88
|
+
- `src/shared/validation/translation-classifier.ts`
|
|
89
|
+
- `src/frontend/state/translation-store.ts`
|
|
90
|
+
- `src/frontend/components/translation-entry-row.tsx`
|
|
91
|
+
- `src/frontend/state/task-store.ts`
|
|
256
92
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
职责:
|
|
260
|
-
|
|
261
|
-
- 编译 backend、main 和 shared 代码到 `dist/`。
|
|
262
|
-
- 使用 NodeNext ESM。
|
|
263
|
-
|
|
264
|
-
关键配置:
|
|
265
|
-
|
|
266
|
-
```json
|
|
267
|
-
{
|
|
268
|
-
"compilerOptions": {
|
|
269
|
-
"target": "ES2022",
|
|
270
|
-
"module": "NodeNext",
|
|
271
|
-
"moduleResolution": "NodeNext",
|
|
272
|
-
"rootDir": "src",
|
|
273
|
-
"outDir": "dist",
|
|
274
|
-
"strict": true,
|
|
275
|
-
"esModuleInterop": true,
|
|
276
|
-
"skipLibCheck": true
|
|
277
|
-
},
|
|
278
|
-
"include": ["src/main.ts", "src/backend/**/*.ts", "src/shared/**/*.ts"]
|
|
279
|
-
}
|
|
280
|
-
```
|
|
93
|
+
## 4. Entry Points
|
|
281
94
|
|
|
282
|
-
###
|
|
283
|
-
|
|
284
|
-
职责:
|
|
285
|
-
|
|
286
|
-
- 构建 React frontend。
|
|
287
|
-
- 开发时代理 API 和 WebSocket 到 local backend。
|
|
288
|
-
|
|
289
|
-
导出定义:
|
|
290
|
-
|
|
291
|
-
```ts
|
|
292
|
-
export default defineConfig({
|
|
293
|
-
plugins: [react()],
|
|
294
|
-
root: ".",
|
|
295
|
-
build: {
|
|
296
|
-
outDir: "dist-frontend"
|
|
297
|
-
},
|
|
298
|
-
server: {
|
|
299
|
-
port: 5173,
|
|
300
|
-
proxy: {
|
|
301
|
-
"/api": "http://localhost:4173",
|
|
302
|
-
"/ws": {
|
|
303
|
-
target: "ws://localhost:4173",
|
|
304
|
-
ws: true
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
```
|
|
95
|
+
### `src/main.ts`
|
|
310
96
|
|
|
311
|
-
|
|
97
|
+
Exports:
|
|
312
98
|
|
|
313
|
-
|
|
99
|
+
- `MainOptions`
|
|
100
|
+
- `parseMainArgs(argv): MainOptions`
|
|
101
|
+
- `main(argv): Promise<void>`
|
|
314
102
|
|
|
315
|
-
|
|
316
|
-
- 使用 node environment。
|
|
103
|
+
Responsibilities:
|
|
317
104
|
|
|
318
|
-
|
|
105
|
+
- parse `--dev`, `--open`, `--host=`, `--port=`
|
|
106
|
+
- start backend on port `4173` by default
|
|
107
|
+
- start Vite on port `5173` in dev mode
|
|
108
|
+
- serve `dist-frontend` through backend in production mode
|
|
109
|
+
- close backend/Vite on `SIGINT`
|
|
319
110
|
|
|
320
|
-
|
|
321
|
-
export default defineConfig({
|
|
322
|
-
test: {
|
|
323
|
-
environment: "node",
|
|
324
|
-
include: ["tests/unit/**/*.test.ts", "tests/integration/**/*.test.ts"]
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
```
|
|
111
|
+
### `src/cli/vcmctl.ts`
|
|
328
112
|
|
|
329
|
-
|
|
113
|
+
CLI commands:
|
|
330
114
|
|
|
331
|
-
|
|
115
|
+
- `vcmctl send`
|
|
116
|
+
- `vcmctl reply`
|
|
117
|
+
- `vcmctl result`
|
|
118
|
+
- `vcmctl inbox`
|
|
119
|
+
- `vcmctl ready`
|
|
332
120
|
|
|
333
|
-
|
|
334
|
-
- 启动 `npm run dev` 作为 webServer。
|
|
121
|
+
Environment required in role sessions:
|
|
335
122
|
|
|
336
|
-
|
|
123
|
+
- `VCM_API_URL`
|
|
124
|
+
- `VCM_TASK_SLUG`
|
|
125
|
+
- `VCM_ROLE`
|
|
337
126
|
|
|
338
|
-
|
|
339
|
-
export default defineConfig({
|
|
340
|
-
testDir: "tests/e2e",
|
|
341
|
-
webServer: {
|
|
342
|
-
command: "npm run dev",
|
|
343
|
-
url: "http://localhost:5173",
|
|
344
|
-
reuseExistingServer: true
|
|
345
|
-
}
|
|
346
|
-
});
|
|
347
|
-
```
|
|
127
|
+
Role sessions receive these env vars from `SessionService`.
|
|
348
128
|
|
|
349
|
-
|
|
129
|
+
## 5. Shared Layer
|
|
350
130
|
|
|
351
|
-
|
|
131
|
+
### `src/shared/constants.ts`
|
|
352
132
|
|
|
353
|
-
|
|
354
|
-
- 在 dev 模式提示 Vite URL。
|
|
355
|
-
- 在 prod 模式 serve frontend static assets。
|
|
133
|
+
Exports:
|
|
356
134
|
|
|
357
|
-
|
|
135
|
+
- `DEFAULT_BACKEND_PORT`
|
|
136
|
+
- `DEFAULT_FRONTEND_PORT`
|
|
137
|
+
- `ROLE_DEFINITIONS`
|
|
138
|
+
- `ROLE_NAMES`
|
|
139
|
+
- `DISPATCHABLE_ROLES`
|
|
140
|
+
- `isRoleName(value)`
|
|
141
|
+
- `isDispatchableRole(value)`
|
|
142
|
+
- `getRoleDefinition(role)`
|
|
358
143
|
|
|
359
|
-
|
|
360
|
-
export interface MainOptions {
|
|
361
|
-
dev?: boolean;
|
|
362
|
-
host?: string;
|
|
363
|
-
port?: number;
|
|
364
|
-
open?: boolean;
|
|
365
|
-
}
|
|
144
|
+
Roles:
|
|
366
145
|
|
|
367
|
-
|
|
146
|
+
- `project-manager`
|
|
147
|
+
- `architect`
|
|
148
|
+
- `coder`
|
|
149
|
+
- `reviewer`
|
|
368
150
|
|
|
369
|
-
|
|
370
|
-
```
|
|
151
|
+
Dispatchable roles:
|
|
371
152
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
职责:
|
|
377
|
-
|
|
378
|
-
- 定义 V1 role 集合和状态。
|
|
379
|
-
|
|
380
|
-
导出定义:
|
|
381
|
-
|
|
382
|
-
```ts
|
|
383
|
-
export type RoleName =
|
|
384
|
-
| "project-manager"
|
|
385
|
-
| "architect"
|
|
386
|
-
| "coder"
|
|
387
|
-
| "reviewer";
|
|
388
|
-
|
|
389
|
-
export type DispatchableRole =
|
|
390
|
-
| "architect"
|
|
391
|
-
| "coder"
|
|
392
|
-
| "reviewer";
|
|
393
|
-
|
|
394
|
-
export type RoleStatus =
|
|
395
|
-
| "not_started"
|
|
396
|
-
| "starting"
|
|
397
|
-
| "running"
|
|
398
|
-
| "waiting"
|
|
399
|
-
| "blocked"
|
|
400
|
-
| "done"
|
|
401
|
-
| "resumable"
|
|
402
|
-
| "crashed"
|
|
403
|
-
| "exited"
|
|
404
|
-
| "missing"
|
|
405
|
-
| "unknown";
|
|
406
|
-
|
|
407
|
-
export interface RoleDefinition {
|
|
408
|
-
name: RoleName;
|
|
409
|
-
label: string;
|
|
410
|
-
commandAgent: string;
|
|
411
|
-
dispatchable: boolean;
|
|
412
|
-
}
|
|
413
|
-
```
|
|
153
|
+
- `architect`
|
|
154
|
+
- `coder`
|
|
155
|
+
- `reviewer`
|
|
414
156
|
|
|
415
|
-
###
|
|
157
|
+
### `src/shared/types/role.ts`
|
|
416
158
|
|
|
417
|
-
|
|
159
|
+
Defines:
|
|
418
160
|
|
|
419
|
-
-
|
|
161
|
+
- `RoleName`
|
|
162
|
+
- `DispatchableRole`
|
|
163
|
+
- `RoleStatus`
|
|
164
|
+
- `RoleDefinition`
|
|
420
165
|
|
|
421
|
-
|
|
166
|
+
### `src/shared/types/project.ts`
|
|
422
167
|
|
|
423
|
-
|
|
424
|
-
export const DEFAULT_BACKEND_PORT = 4173;
|
|
425
|
-
export const DEFAULT_FRONTEND_PORT = 5173;
|
|
168
|
+
Defines:
|
|
426
169
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
170
|
+
- `ProjectConfig`
|
|
171
|
+
- `ProjectSummary`
|
|
172
|
+
- `ConnectProjectRequest`
|
|
430
173
|
|
|
431
|
-
|
|
432
|
-
export function isDispatchableRole(value: string): value is DispatchableRole;
|
|
433
|
-
export function getRoleDefinition(role: RoleName): RoleDefinition;
|
|
434
|
-
```
|
|
174
|
+
Important fields:
|
|
435
175
|
|
|
436
|
-
|
|
176
|
+
- `handoffRoot`
|
|
177
|
+
- `stateRoot`
|
|
178
|
+
- `terminalBackend`
|
|
179
|
+
- `claudeCommand`
|
|
180
|
+
- `isDirty`
|
|
437
181
|
|
|
438
|
-
|
|
182
|
+
### `src/shared/types/task.ts`
|
|
439
183
|
|
|
440
|
-
|
|
184
|
+
Defines:
|
|
441
185
|
|
|
442
|
-
|
|
186
|
+
- `TaskStatus`
|
|
187
|
+
- `TaskRecord`
|
|
188
|
+
- `CreateTaskRequest`
|
|
443
189
|
|
|
444
|
-
|
|
445
|
-
export interface ProjectConfig {
|
|
446
|
-
version: 1;
|
|
447
|
-
repoRoot: string;
|
|
448
|
-
defaultRoles: RoleName[];
|
|
449
|
-
handoffRoot: string;
|
|
450
|
-
stateRoot: string;
|
|
451
|
-
terminalBackend: "node-pty";
|
|
452
|
-
claudeCommand: string;
|
|
453
|
-
}
|
|
190
|
+
Current UI sends only `taskSlug`, although the API type still permits optional `title` and `specPath`.
|
|
454
191
|
|
|
455
|
-
|
|
456
|
-
repoRoot: string;
|
|
457
|
-
branch: string;
|
|
458
|
-
isDirty: boolean;
|
|
459
|
-
config: ProjectConfig;
|
|
460
|
-
warnings: string[];
|
|
461
|
-
}
|
|
192
|
+
Worktree fields:
|
|
462
193
|
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
194
|
+
- `worktreePath: string`
|
|
195
|
+
- `branch: feature/<taskSlug>`
|
|
196
|
+
- `cleanupStatus?: "active" | "cleaned"`
|
|
197
|
+
- `cleanedAt?: string`
|
|
467
198
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
职责:
|
|
471
|
-
|
|
472
|
-
- 定义 task metadata。
|
|
473
|
-
|
|
474
|
-
导出定义:
|
|
475
|
-
|
|
476
|
-
```ts
|
|
477
|
-
export type TaskStatus =
|
|
478
|
-
| "created"
|
|
479
|
-
| "planning"
|
|
480
|
-
| "running"
|
|
481
|
-
| "blocked"
|
|
482
|
-
| "stopped"
|
|
483
|
-
| "done";
|
|
484
|
-
|
|
485
|
-
export interface TaskRecord {
|
|
486
|
-
version: 1;
|
|
487
|
-
taskSlug: string;
|
|
488
|
-
title?: string;
|
|
489
|
-
createdAt: string;
|
|
490
|
-
updatedAt: string;
|
|
491
|
-
repoRoot: string;
|
|
492
|
-
branch: string;
|
|
493
|
-
handoffDir: string;
|
|
494
|
-
status: TaskStatus;
|
|
495
|
-
specPath?: string;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
export interface CreateTaskRequest {
|
|
499
|
-
taskSlug: string;
|
|
500
|
-
title?: string;
|
|
501
|
-
specPath?: string;
|
|
502
|
-
}
|
|
503
|
-
```
|
|
199
|
+
`CreateTaskRequest` creates a worktree and branch by default. The UI shows a checked `Create worktree and branch` indicator, but task worktree creation is the normal VCM task path and does not require a separate later action or a user-visible off switch.
|
|
504
200
|
|
|
505
|
-
###
|
|
506
|
-
|
|
507
|
-
职责:
|
|
508
|
-
|
|
509
|
-
- 定义 role session metadata 和 task session summary。
|
|
510
|
-
|
|
511
|
-
导出定义:
|
|
512
|
-
|
|
513
|
-
```ts
|
|
514
|
-
export type ClaudePermissionMode =
|
|
515
|
-
| "default"
|
|
516
|
-
| "bypassPermissions"
|
|
517
|
-
| "dangerously-skip-permissions";
|
|
518
|
-
|
|
519
|
-
export interface RoleSessionRecord {
|
|
520
|
-
id: string;
|
|
521
|
-
claudeSessionId: string;
|
|
522
|
-
taskSlug: string;
|
|
523
|
-
role: RoleName;
|
|
524
|
-
status: RoleStatus;
|
|
525
|
-
command: string;
|
|
526
|
-
permissionMode: ClaudePermissionMode;
|
|
527
|
-
cwd: string;
|
|
528
|
-
terminalBackend: "node-pty";
|
|
529
|
-
pid?: number;
|
|
530
|
-
logPath: string;
|
|
531
|
-
roleCommandPath?: string;
|
|
532
|
-
handoffArtifactPath?: string;
|
|
533
|
-
startedAt?: string;
|
|
534
|
-
updatedAt: string;
|
|
535
|
-
lastOutputAt?: string;
|
|
536
|
-
exitCode?: number | null;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
export interface TaskSessionRecord {
|
|
540
|
-
version: 1;
|
|
541
|
-
taskSlug: string;
|
|
542
|
-
updatedAt: string;
|
|
543
|
-
roles: Record<RoleName, RoleSessionPointer>;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
export interface RoleSessionPointer {
|
|
547
|
-
id: string | null;
|
|
548
|
-
claudeSessionId?: string;
|
|
549
|
-
status: RoleStatus;
|
|
550
|
-
record?: RoleSessionRecord;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
export interface StartRoleSessionRequest {
|
|
554
|
-
cols?: number;
|
|
555
|
-
rows?: number;
|
|
556
|
-
permissionMode?: ClaudePermissionMode;
|
|
557
|
-
}
|
|
558
|
-
```
|
|
201
|
+
### `src/shared/types/session.ts`
|
|
559
202
|
|
|
560
|
-
|
|
203
|
+
Defines:
|
|
561
204
|
|
|
562
|
-
|
|
205
|
+
- `ClaudePermissionMode`
|
|
206
|
+
- `RoleSessionRecord`
|
|
207
|
+
- `TaskSessionRecord`
|
|
208
|
+
- `RoleSessionPointer`
|
|
209
|
+
- `StartRoleSessionRequest`
|
|
563
210
|
|
|
564
|
-
|
|
211
|
+
`RoleSessionRecord` includes `claudeSessionId` and `transcriptPath`, which are required for resume and translation transcript lookup.
|
|
565
212
|
|
|
566
|
-
|
|
213
|
+
### `src/shared/types/message.ts`
|
|
567
214
|
|
|
568
|
-
|
|
569
|
-
export type ClientTerminalMessage =
|
|
570
|
-
| { type: "input"; data: string }
|
|
571
|
-
| { type: "resize"; cols: number; rows: number };
|
|
215
|
+
Defines:
|
|
572
216
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
217
|
+
- `VcmMessageActor`
|
|
218
|
+
- `VcmMessageType`
|
|
219
|
+
- `VcmMessageStatus`
|
|
220
|
+
- `VcmOrchestrationMode`
|
|
221
|
+
- `VcmRoleMessage`
|
|
222
|
+
- `VcmOrchestrationState`
|
|
223
|
+
- `SendRoleMessageRequest`
|
|
224
|
+
- `SendRoleMessageResult`
|
|
578
225
|
|
|
579
|
-
|
|
580
|
-
id: string;
|
|
581
|
-
sessionId: string;
|
|
582
|
-
taskSlug: string;
|
|
583
|
-
role: RoleName;
|
|
584
|
-
type: "input" | "output" | "status" | "exit" | "error" | "dispatch";
|
|
585
|
-
timestamp: string;
|
|
586
|
-
data?: string;
|
|
587
|
-
status?: RoleStatus;
|
|
588
|
-
exitCode?: number | null;
|
|
589
|
-
}
|
|
590
|
-
```
|
|
226
|
+
The state type includes `paused` for backend/API compatibility. The current GUI only exposes manual/auto.
|
|
591
227
|
|
|
592
|
-
###
|
|
593
|
-
|
|
594
|
-
职责:
|
|
595
|
-
|
|
596
|
-
- 定义 handoff artifact paths 和 schema check。
|
|
597
|
-
|
|
598
|
-
导出定义:
|
|
599
|
-
|
|
600
|
-
```ts
|
|
601
|
-
export type ArtifactKind =
|
|
602
|
-
| "architecture-plan"
|
|
603
|
-
| "implementation-log"
|
|
604
|
-
| "validation-log"
|
|
605
|
-
| "review-report";
|
|
606
|
-
|
|
607
|
-
export interface HandoffPaths {
|
|
608
|
-
handoffDir: string;
|
|
609
|
-
roleCommandsDir: string;
|
|
610
|
-
logsDir: string;
|
|
611
|
-
roleCommandPaths: Record<DispatchableRole, string>;
|
|
612
|
-
roleLogPaths: Record<RoleName, string>;
|
|
613
|
-
architecturePlanPath: string;
|
|
614
|
-
implementationLogPath: string;
|
|
615
|
-
validationLogPath: string;
|
|
616
|
-
reviewReportPath: string;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
export interface ArtifactCheckResult {
|
|
620
|
-
kind: ArtifactKind;
|
|
621
|
-
path: string;
|
|
622
|
-
exists: boolean;
|
|
623
|
-
isEmpty: boolean;
|
|
624
|
-
missingHeadings: string[];
|
|
625
|
-
status: "missing" | "empty" | "incomplete" | "ok";
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
export interface ArtifactSummary {
|
|
629
|
-
paths: HandoffPaths;
|
|
630
|
-
checks: ArtifactCheckResult[];
|
|
631
|
-
}
|
|
632
|
-
```
|
|
228
|
+
### `src/shared/types/translation.ts`
|
|
633
229
|
|
|
634
|
-
|
|
230
|
+
Defines:
|
|
635
231
|
|
|
636
|
-
|
|
232
|
+
- `TranslationProviderType`
|
|
233
|
+
- `TranslationDirection`
|
|
234
|
+
- `TranslationInputMode`
|
|
235
|
+
- `TranslationPromptKey`
|
|
236
|
+
- `TRANSLATION_PROMPT_KEYS`
|
|
237
|
+
- `TranslationSourceKind`
|
|
238
|
+
- `TranslationStatus`
|
|
239
|
+
- `TranslationSettings`
|
|
240
|
+
- `TranslationSecretSettings`
|
|
241
|
+
- `TranslationEntry`
|
|
242
|
+
- `TranslateUserInputRequest`
|
|
243
|
+
- `TranslateUserInputResult`
|
|
244
|
+
- `SendTranslatedInputRequest`
|
|
245
|
+
- `TranslationProviderTestResult`
|
|
246
|
+
- `TranslationPromptPreview`
|
|
247
|
+
- `TranslationWsMessage`
|
|
637
248
|
|
|
638
|
-
|
|
249
|
+
Prompt keys:
|
|
639
250
|
|
|
640
|
-
|
|
251
|
+
- `zh-to-en`
|
|
252
|
+
- `zh-to-en-with-context`
|
|
253
|
+
- `en-to-zh`
|
|
641
254
|
|
|
642
|
-
|
|
643
|
-
export interface ApiSuccess<T> {
|
|
644
|
-
ok: true;
|
|
645
|
-
data: T;
|
|
646
|
-
}
|
|
255
|
+
Source kinds:
|
|
647
256
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
error: {
|
|
651
|
-
code: string;
|
|
652
|
-
message: string;
|
|
653
|
-
hint?: string;
|
|
654
|
-
};
|
|
655
|
-
}
|
|
257
|
+
- `prose`
|
|
258
|
+
- `tool-output`
|
|
656
259
|
|
|
657
|
-
|
|
658
|
-
```
|
|
260
|
+
Statuses:
|
|
659
261
|
|
|
660
|
-
|
|
262
|
+
- `queued`
|
|
263
|
+
- `translating`
|
|
264
|
+
- `translated`
|
|
265
|
+
- `failed`
|
|
266
|
+
- `preserved`
|
|
661
267
|
|
|
662
|
-
###
|
|
268
|
+
### `src/shared/types/api.ts`
|
|
663
269
|
|
|
664
|
-
|
|
270
|
+
Defines:
|
|
665
271
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
272
|
+
- `ApiErrorResponse`
|
|
273
|
+
- `TaskStatusReport`
|
|
274
|
+
- `TaskWorkflowStepId`
|
|
275
|
+
- `TaskWorkflowStepStatus`
|
|
276
|
+
- `TaskWorkflowStep`
|
|
277
|
+
- `TaskWorkflowReport`
|
|
278
|
+
- `DispatchRoleCommandResult`
|
|
279
|
+
- `BootstrapState`
|
|
672
280
|
|
|
673
|
-
|
|
674
|
-
export function validateTaskSlug(value: string): SlugValidationResult;
|
|
675
|
-
export function assertValidTaskSlug(value: string): string;
|
|
676
|
-
export function suggestTaskSlug(value: string): string;
|
|
677
|
-
```
|
|
281
|
+
### `src/shared/types/artifact.ts`
|
|
678
282
|
|
|
679
|
-
|
|
283
|
+
Defines:
|
|
680
284
|
|
|
681
|
-
|
|
285
|
+
- `ArtifactKind`
|
|
286
|
+
- `HandoffPaths`
|
|
287
|
+
- `ArtifactCheckResult`
|
|
288
|
+
- `ArtifactSummary`
|
|
682
289
|
|
|
683
|
-
|
|
684
|
-
export const REQUIRED_ARCHITECTURE_PLAN_HEADINGS: readonly string[];
|
|
685
|
-
export const REQUIRED_IMPLEMENTATION_LOG_HEADINGS: readonly string[];
|
|
686
|
-
export const REQUIRED_REVIEW_REPORT_HEADINGS: readonly string[];
|
|
290
|
+
Artifact kinds:
|
|
687
291
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
```
|
|
292
|
+
- `architecture-plan`
|
|
293
|
+
- `implementation-log`
|
|
294
|
+
- `validation-log`
|
|
295
|
+
- `review-report`
|
|
296
|
+
- `docs-sync-report`
|
|
694
297
|
|
|
695
|
-
|
|
298
|
+
### `src/shared/types/harness.ts`
|
|
696
299
|
|
|
697
|
-
|
|
300
|
+
Defines:
|
|
698
301
|
|
|
699
|
-
|
|
302
|
+
- `HarnessFileKind`
|
|
303
|
+
- `HarnessFileAction`
|
|
304
|
+
- `HarnessFileStatus`
|
|
305
|
+
- `HarnessPlannedChange`
|
|
306
|
+
- `HarnessStatusReport`
|
|
307
|
+
- `HarnessApplyResult`
|
|
700
308
|
|
|
701
|
-
|
|
702
|
-
- 供 git / claude check 使用。
|
|
309
|
+
### `src/shared/types/terminal.ts`
|
|
703
310
|
|
|
704
|
-
|
|
311
|
+
Defines:
|
|
705
312
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
reject?: boolean;
|
|
710
|
-
env?: NodeJS.ProcessEnv;
|
|
711
|
-
}
|
|
313
|
+
- `ClientTerminalMessage`
|
|
314
|
+
- `ServerTerminalMessage`
|
|
315
|
+
- `TerminalEvent`
|
|
712
316
|
|
|
713
|
-
|
|
714
|
-
stdout: string;
|
|
715
|
-
stderr: string;
|
|
716
|
-
exitCode: number;
|
|
717
|
-
}
|
|
317
|
+
### `src/shared/validation/slug-check.ts`
|
|
718
318
|
|
|
719
|
-
|
|
720
|
-
run(command: string, args: string[], options?: RunCommandOptions): Promise<RunCommandResult>;
|
|
721
|
-
}
|
|
319
|
+
Exports:
|
|
722
320
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
```
|
|
321
|
+
- `validateTaskSlug(taskSlug)`
|
|
322
|
+
- `assertValidTaskSlug(taskSlug)`
|
|
726
323
|
|
|
727
|
-
|
|
324
|
+
Current rule:
|
|
728
325
|
|
|
729
|
-
|
|
326
|
+
- lowercase slug-style task names
|
|
327
|
+
- safe for local paths and URLs
|
|
730
328
|
|
|
731
|
-
-
|
|
329
|
+
### `src/shared/validation/artifact-check.ts`
|
|
732
330
|
|
|
733
|
-
|
|
331
|
+
Exports:
|
|
734
332
|
|
|
735
|
-
|
|
736
|
-
export interface FileSystemAdapter {
|
|
737
|
-
pathExists(path: string): Promise<boolean>;
|
|
738
|
-
ensureDir(path: string): Promise<void>;
|
|
739
|
-
readText(path: string): Promise<string>;
|
|
740
|
-
writeText(path: string, content: string): Promise<void>;
|
|
741
|
-
appendText(path: string, content: string): Promise<void>;
|
|
742
|
-
readJson<T>(path: string): Promise<T>;
|
|
743
|
-
writeJsonAtomic<T>(path: string, value: T): Promise<void>;
|
|
744
|
-
ensureFile(path: string, content: string, options?: EnsureFileOptions): Promise<boolean>;
|
|
745
|
-
}
|
|
333
|
+
- `checkMarkdownArtifact(kind, path, content)`
|
|
746
334
|
|
|
747
|
-
|
|
748
|
-
overwrite?: boolean;
|
|
749
|
-
}
|
|
335
|
+
Current checks are title/placeholder oriented and do not judge semantic quality.
|
|
750
336
|
|
|
751
|
-
|
|
752
|
-
export function resolveRepoPath(repoRoot: string, repoRelativePath: string): string;
|
|
753
|
-
export function toRepoRelativePath(repoRoot: string, absolutePath: string): string;
|
|
754
|
-
```
|
|
337
|
+
### `src/shared/validation/language-detect.ts`
|
|
755
338
|
|
|
756
|
-
|
|
339
|
+
Exports:
|
|
757
340
|
|
|
758
|
-
|
|
341
|
+
- `cjkRatio(value)`
|
|
342
|
+
- `isProbablyCjk(value, threshold)`
|
|
343
|
+
- `shouldSkipForTargetLanguage(value, targetLanguage)`
|
|
759
344
|
|
|
760
|
-
-
|
|
345
|
+
These helpers remain available, but current Claude-output translation no longer uses a classifier to skip assistant prose.
|
|
761
346
|
|
|
762
|
-
|
|
347
|
+
## 6. Backend Adapters
|
|
763
348
|
|
|
764
|
-
|
|
765
|
-
export interface GitAdapter {
|
|
766
|
-
isGitRepo(cwd: string): Promise<boolean>;
|
|
767
|
-
getRepoRoot(cwd: string): Promise<string>;
|
|
768
|
-
getCurrentBranch(repoRoot: string): Promise<string>;
|
|
769
|
-
isDirty(repoRoot: string): Promise<boolean>;
|
|
770
|
-
getDiffSummary(repoRoot: string): Promise<string>;
|
|
771
|
-
}
|
|
349
|
+
### `src/backend/adapters/filesystem.ts`
|
|
772
350
|
|
|
773
|
-
|
|
774
|
-
```
|
|
351
|
+
Exports:
|
|
775
352
|
|
|
776
|
-
|
|
353
|
+
- `FileSystemAdapter`
|
|
354
|
+
- `EnsureFileOptions`
|
|
355
|
+
- `createNodeFileSystemAdapter()`
|
|
356
|
+
- `resolveRepoPath(repoRoot, repoRelativePath)`
|
|
357
|
+
- `toRepoRelativePath(repoRoot, absolutePath)`
|
|
777
358
|
|
|
778
|
-
|
|
359
|
+
Used by all services that touch repo/app files.
|
|
779
360
|
|
|
780
|
-
-
|
|
781
|
-
- 生成 role session 启动命令。
|
|
361
|
+
### `src/backend/adapters/command-runner.ts`
|
|
782
362
|
|
|
783
|
-
|
|
363
|
+
Exports:
|
|
784
364
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
buildRoleStartCommand(
|
|
790
|
-
role: RoleName,
|
|
791
|
-
command?: string,
|
|
792
|
-
permissionMode?: ClaudePermissionMode
|
|
793
|
-
): { command: string; args: string[]; display: string };
|
|
794
|
-
}
|
|
365
|
+
- `CommandResult`
|
|
366
|
+
- `CommandRunner`
|
|
367
|
+
- `CommandRunnerOptions`
|
|
368
|
+
- `createCommandRunner()`
|
|
795
369
|
|
|
796
|
-
|
|
797
|
-
```
|
|
370
|
+
Used by Git and Claude adapters.
|
|
798
371
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
args: string[];
|
|
816
|
-
cwd: string;
|
|
817
|
-
env?: NodeJS.ProcessEnv;
|
|
818
|
-
cols?: number;
|
|
819
|
-
rows?: number;
|
|
820
|
-
logPath: string;
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
export interface TerminalSession {
|
|
824
|
-
id: string;
|
|
825
|
-
taskSlug: string;
|
|
826
|
-
role: RoleName;
|
|
827
|
-
status: RoleStatus;
|
|
828
|
-
pid?: number;
|
|
829
|
-
startedAt: string;
|
|
830
|
-
lastOutputAt?: string;
|
|
831
|
-
exitCode?: number | null;
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
export type TerminalEventListener = (event: TerminalEvent) => void;
|
|
835
|
-
export type Unsubscribe = () => void;
|
|
836
|
-
|
|
837
|
-
export interface TerminalRuntime {
|
|
838
|
-
createSession(input: CreateTerminalSessionInput): Promise<TerminalSession>;
|
|
839
|
-
getSession(sessionId: string): TerminalSession | undefined;
|
|
840
|
-
getSessionByRole(taskSlug: string, role: RoleName): TerminalSession | undefined;
|
|
841
|
-
listSessions(taskSlug?: string): TerminalSession[];
|
|
842
|
-
write(sessionId: string, data: string): void;
|
|
843
|
-
resize(sessionId: string, cols: number, rows: number): void;
|
|
844
|
-
stop(sessionId: string): Promise<void>;
|
|
845
|
-
restart(sessionId: string): Promise<TerminalSession>;
|
|
846
|
-
subscribe(sessionId: string, listener: TerminalEventListener): Unsubscribe;
|
|
847
|
-
}
|
|
848
|
-
```
|
|
372
|
+
### `src/backend/adapters/git-adapter.ts`
|
|
373
|
+
|
|
374
|
+
Exports:
|
|
375
|
+
|
|
376
|
+
- `GitRepoCheck`
|
|
377
|
+
- `GitAdapter`
|
|
378
|
+
- `createGitAdapter(runner)`
|
|
379
|
+
|
|
380
|
+
Important behavior:
|
|
381
|
+
|
|
382
|
+
- checks `.git` directly
|
|
383
|
+
- accepts normal `.git` directories
|
|
384
|
+
- accepts `.git` pointer files
|
|
385
|
+
- passes per-command `safe.directory`
|
|
386
|
+
|
|
387
|
+
Worktree methods:
|
|
849
388
|
|
|
850
|
-
|
|
389
|
+
- `branchExists(repoRoot, branch): Promise<boolean>`
|
|
390
|
+
- `createWorktree(input): Promise<void>`
|
|
391
|
+
- `removeWorktree(repoRoot, worktreePath, options): Promise<void>`
|
|
392
|
+
- `deleteBranch(repoRoot, branch, options): Promise<void>`
|
|
393
|
+
- `getStatusPorcelain(repoRoot): Promise<string>`
|
|
394
|
+
- `isIgnored(repoRoot, repoRelativePath): Promise<boolean>`
|
|
851
395
|
|
|
852
|
-
|
|
396
|
+
Required safety:
|
|
853
397
|
|
|
854
|
-
-
|
|
855
|
-
-
|
|
856
|
-
-
|
|
398
|
+
- all Git commands keep command-scoped `safe.directory`
|
|
399
|
+
- refuse worktree paths outside `<baseRepoRoot>/.ai/vcm/worktrees/`
|
|
400
|
+
- refuse branch names that do not match `feature/<taskSlug>` for VCM-created tasks
|
|
857
401
|
|
|
858
|
-
|
|
402
|
+
### `src/backend/adapters/claude-adapter.ts`
|
|
859
403
|
|
|
860
|
-
|
|
861
|
-
export interface NodePtyRuntimeDeps {
|
|
862
|
-
fs: FileSystemAdapter;
|
|
863
|
-
now?: () => string;
|
|
864
|
-
id?: () => string;
|
|
865
|
-
}
|
|
404
|
+
Exports:
|
|
866
405
|
|
|
867
|
-
|
|
406
|
+
- `ClaudeAdapter`
|
|
407
|
+
- `createClaudeAdapter(runner)`
|
|
408
|
+
|
|
409
|
+
Builds role commands:
|
|
410
|
+
|
|
411
|
+
```text
|
|
412
|
+
claude --agent <role> --session-id <uuid>
|
|
413
|
+
claude --agent <role> --resume <uuid>
|
|
868
414
|
```
|
|
869
415
|
|
|
870
|
-
|
|
416
|
+
Adds permission flags for `bypassPermissions` and `dangerously-skip-permissions`.
|
|
871
417
|
|
|
872
|
-
|
|
873
|
-
- 监听 `onData`:
|
|
874
|
-
- append 到 log。
|
|
875
|
-
- emit `TerminalEvent`。
|
|
876
|
-
- 更新 `lastOutputAt`。
|
|
877
|
-
- 监听 `onExit`:
|
|
878
|
-
- 更新 `status` 为 `exited` 或 `crashed`。
|
|
879
|
-
- emit `exit` event。
|
|
880
|
-
- `write` 写入 pty。
|
|
881
|
-
- `resize` 调用 pty resize。
|
|
882
|
-
- `stop` kill pty 并更新状态。
|
|
418
|
+
### `src/backend/adapters/translation-provider.ts`
|
|
883
419
|
|
|
884
|
-
|
|
420
|
+
Exports:
|
|
885
421
|
|
|
886
|
-
|
|
422
|
+
- `TranslationProviderRequest`
|
|
423
|
+
- `TranslationProviderResult`
|
|
424
|
+
- `TranslationProvider`
|
|
425
|
+
- `TranslationProviderError`
|
|
426
|
+
- `createOpenAiCompatibleTranslationProvider(fetchImpl)`
|
|
427
|
+
- `buildChatCompletionsUrl(baseUrl)`
|
|
428
|
+
- `parseOpenAiUsage(raw)`
|
|
887
429
|
|
|
888
|
-
-
|
|
889
|
-
- `runtime.subscribe(sessionId, listener)`:监听 terminal output、status、exit 和 error event。
|
|
890
|
-
- `terminal-ws`:把用户在 GUI terminal 中输入的内容转发给 runtime。
|
|
891
|
-
- `command-dispatcher`:在用户点击 Send Command 后,向目标 session 写入短指令。
|
|
430
|
+
Implements OpenAI-compatible chat completions.
|
|
892
431
|
|
|
893
|
-
|
|
432
|
+
## 7. Backend Runtime
|
|
894
433
|
|
|
895
|
-
|
|
896
|
-
- 用户点击 Send Command 后,backend 可以写入 `Please read and execute the role command at: <path>`。
|
|
897
|
-
- Backend 可以监听 output 并写入 raw log。
|
|
898
|
-
- Backend 可以根据 output/exit event 更新轻量状态和 GUI 提示。
|
|
434
|
+
### `src/backend/runtime/terminal-runtime.ts`
|
|
899
435
|
|
|
900
|
-
|
|
436
|
+
Defines the runtime interface:
|
|
901
437
|
|
|
902
|
-
-
|
|
903
|
-
-
|
|
904
|
-
-
|
|
905
|
-
-
|
|
906
|
-
-
|
|
438
|
+
- `CreateTerminalSessionInput`
|
|
439
|
+
- `TerminalSession`
|
|
440
|
+
- `TerminalEventListener`
|
|
441
|
+
- `Unsubscribe`
|
|
442
|
+
- `SubscribeTerminalOptions`
|
|
443
|
+
- `TerminalRuntime`
|
|
907
444
|
|
|
908
|
-
###
|
|
445
|
+
### `src/backend/runtime/node-pty-runtime.ts`
|
|
909
446
|
|
|
910
|
-
|
|
447
|
+
Exports:
|
|
911
448
|
|
|
912
|
-
-
|
|
913
|
-
-
|
|
449
|
+
- `NodePtyRuntimeDeps`
|
|
450
|
+
- `createNodePtyTerminalRuntime(deps)`
|
|
451
|
+
- `buildPtyEnvironment(baseEnv, inputEnv)`
|
|
914
452
|
|
|
915
|
-
|
|
453
|
+
Responsibilities:
|
|
916
454
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
updateStatus(sessionId: string, status: RoleStatus, patch?: Partial<RoleSessionRecord>): void;
|
|
924
|
-
remove(sessionId: string): void;
|
|
925
|
-
}
|
|
455
|
+
- spawn Claude Code with `node-pty`
|
|
456
|
+
- append raw output to role log file
|
|
457
|
+
- emit terminal output/input/exit events
|
|
458
|
+
- replay logs on subscribe
|
|
459
|
+
- handle writes, resize, stop
|
|
460
|
+
- set color-friendly terminal env vars
|
|
926
461
|
|
|
927
|
-
|
|
928
|
-
```
|
|
462
|
+
### `src/backend/runtime/session-registry.ts`
|
|
929
463
|
|
|
930
|
-
|
|
464
|
+
Exports:
|
|
931
465
|
|
|
932
|
-
|
|
466
|
+
- `SessionRegistry`
|
|
467
|
+
- `createSessionRegistry()`
|
|
933
468
|
|
|
934
|
-
|
|
469
|
+
In-memory index for live/persisted role records by runtime session id and role.
|
|
935
470
|
|
|
936
|
-
|
|
937
|
-
- 创建 `.vcm/config.json`。
|
|
938
|
-
- 检查 Claude Code、branch、dirty state。
|
|
471
|
+
## 8. Backend Services
|
|
939
472
|
|
|
940
|
-
|
|
473
|
+
### `src/backend/services/project-service.ts`
|
|
941
474
|
|
|
942
|
-
|
|
943
|
-
export interface ProjectService {
|
|
944
|
-
connectProject(input: ConnectProjectInput): Promise<ProjectSummary>;
|
|
945
|
-
getCurrentProject(): Promise<ProjectSummary | null>;
|
|
946
|
-
loadConfig(repoRoot: string): Promise<ProjectConfig>;
|
|
947
|
-
saveConfig(config: ProjectConfig, force?: boolean): Promise<void>;
|
|
948
|
-
getConfigPath(repoRoot: string): string;
|
|
949
|
-
}
|
|
475
|
+
Exports:
|
|
950
476
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
}
|
|
477
|
+
- `ProjectService`
|
|
478
|
+
- `ProjectServiceDeps`
|
|
479
|
+
- `createProjectService(deps)`
|
|
480
|
+
- `buildDefaultProjectConfig(repoRoot)`
|
|
956
481
|
|
|
957
|
-
|
|
958
|
-
export function buildDefaultProjectConfig(repoRoot: string): ProjectConfig;
|
|
959
|
-
```
|
|
482
|
+
Responsibilities:
|
|
960
483
|
|
|
961
|
-
|
|
484
|
+
- connect repo
|
|
485
|
+
- store current project in process memory
|
|
486
|
+
- record recent repo paths in app settings
|
|
487
|
+
- create `.ai/vcm/config.json`
|
|
488
|
+
- ensure base state directories
|
|
489
|
+
- ensure `.ai/vcm/` is ignored by Git before task-worktree creation
|
|
490
|
+
- expose base repo as the project control root
|
|
962
491
|
|
|
963
|
-
|
|
492
|
+
Repository connect should keep connecting to the base repo. Task worktrees are managed under that base repo and should not be treated as separate projects in the normal task list.
|
|
964
493
|
|
|
965
|
-
-
|
|
966
|
-
- 创建 handoff structure。
|
|
967
|
-
- 读取任务列表和单个任务。
|
|
494
|
+
### `src/backend/services/task-service.ts`
|
|
968
495
|
|
|
969
|
-
|
|
496
|
+
Exports:
|
|
970
497
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
listTasks(repoRoot: string): Promise<TaskRecord[]>;
|
|
975
|
-
loadTask(repoRoot: string, taskSlug: string): Promise<TaskRecord>;
|
|
976
|
-
saveTask(repoRoot: string, task: TaskRecord): Promise<void>;
|
|
977
|
-
updateTaskStatus(repoRoot: string, taskSlug: string, status: TaskStatus): Promise<TaskRecord>;
|
|
978
|
-
}
|
|
498
|
+
- `TaskService`
|
|
499
|
+
- `TaskServiceDeps`
|
|
500
|
+
- `createTaskService(deps)`
|
|
979
501
|
|
|
980
|
-
|
|
981
|
-
fs: FileSystemAdapter;
|
|
982
|
-
git: GitAdapter;
|
|
983
|
-
artifactService: ArtifactService;
|
|
984
|
-
projectService: Pick<ProjectService, "loadConfig">;
|
|
985
|
-
}
|
|
502
|
+
Responsibilities:
|
|
986
503
|
|
|
987
|
-
|
|
988
|
-
|
|
504
|
+
- create task
|
|
505
|
+
- list tasks
|
|
506
|
+
- load task
|
|
507
|
+
- save task
|
|
508
|
+
- update task status
|
|
509
|
+
- create task branch and worktree
|
|
510
|
+
- clean up completed task worktree and task metadata
|
|
511
|
+
|
|
512
|
+
Task files:
|
|
989
513
|
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
职责:
|
|
993
|
-
|
|
994
|
-
- 创建 handoff 目录结构。
|
|
995
|
-
- 创建 artifact 模板。
|
|
996
|
-
- 读写 role command。
|
|
997
|
-
- 检查 artifact 状态。
|
|
998
|
-
- 追加 raw logs。
|
|
999
|
-
|
|
1000
|
-
导出定义:
|
|
1001
|
-
|
|
1002
|
-
```ts
|
|
1003
|
-
export interface ArtifactService {
|
|
1004
|
-
getHandoffPaths(repoRoot: string, handoffDir: string): HandoffPaths;
|
|
1005
|
-
ensureHandoffStructure(input: EnsureHandoffStructureInput): Promise<HandoffPaths>;
|
|
1006
|
-
createArtifactTemplates(input: CreateArtifactTemplatesInput): Promise<string[]>;
|
|
1007
|
-
listArtifacts(input: ListArtifactsInput): Promise<ArtifactSummary>;
|
|
1008
|
-
readArtifact(input: ReadArtifactInput): Promise<string>;
|
|
1009
|
-
readRoleCommand(input: ReadRoleCommandInput): Promise<string>;
|
|
1010
|
-
saveRoleCommand(input: SaveRoleCommandInput): Promise<void>;
|
|
1011
|
-
appendRoleLog(input: AppendRoleLogInput): Promise<void>;
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
export interface EnsureHandoffStructureInput {
|
|
1015
|
-
repoRoot: string;
|
|
1016
|
-
taskSlug: string;
|
|
1017
|
-
handoffDir: string;
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
export interface CreateArtifactTemplatesInput {
|
|
1021
|
-
repoRoot: string;
|
|
1022
|
-
taskSlug: string;
|
|
1023
|
-
handoffDir: string;
|
|
1024
|
-
overwrite?: boolean;
|
|
1025
|
-
}
|
|
1026
|
-
|
|
1027
|
-
export interface ListArtifactsInput {
|
|
1028
|
-
repoRoot: string;
|
|
1029
|
-
taskSlug: string;
|
|
1030
|
-
handoffDir: string;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
export interface ReadArtifactInput {
|
|
1034
|
-
repoRoot: string;
|
|
1035
|
-
path: string;
|
|
1036
|
-
}
|
|
1037
|
-
|
|
1038
|
-
export interface ReadRoleCommandInput {
|
|
1039
|
-
repoRoot: string;
|
|
1040
|
-
handoffDir: string;
|
|
1041
|
-
role: DispatchableRole;
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
export interface SaveRoleCommandInput {
|
|
1045
|
-
repoRoot: string;
|
|
1046
|
-
handoffDir: string;
|
|
1047
|
-
role: DispatchableRole;
|
|
1048
|
-
content: string;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
export interface AppendRoleLogInput {
|
|
1052
|
-
repoRoot: string;
|
|
1053
|
-
handoffDir: string;
|
|
1054
|
-
role: RoleName;
|
|
1055
|
-
content: string;
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
export function createArtifactService(fs: FileSystemAdapter): ArtifactService;
|
|
514
|
+
```text
|
|
515
|
+
<baseRepoRoot>/.ai/vcm/tasks/<task>.json
|
|
1059
516
|
```
|
|
1060
517
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
export interface StopRoleSessionInput {
|
|
1094
|
-
repoRoot: string;
|
|
1095
|
-
taskSlug: string;
|
|
1096
|
-
role: RoleName;
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
export interface RestartRoleSessionInput extends StopRoleSessionInput {
|
|
1100
|
-
cols?: number;
|
|
1101
|
-
rows?: number;
|
|
1102
|
-
}
|
|
1103
|
-
|
|
1104
|
-
export interface SessionServiceDeps {
|
|
1105
|
-
claude: ClaudeAdapter;
|
|
1106
|
-
runtime: TerminalRuntime;
|
|
1107
|
-
registry: SessionRegistry;
|
|
1108
|
-
taskService: TaskService;
|
|
1109
|
-
artifactService: ArtifactService;
|
|
1110
|
-
projectService: Pick<ProjectService, "loadConfig">;
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
export function createSessionService(deps: SessionServiceDeps): SessionService;
|
|
518
|
+
Create flow:
|
|
519
|
+
|
|
520
|
+
```text
|
|
521
|
+
createTask(baseRepoRoot, { taskSlug })
|
|
522
|
+
-> assertValidTaskSlug(taskSlug)
|
|
523
|
+
-> branch = feature/<taskSlug>
|
|
524
|
+
-> worktreePath = <baseRepoRoot>/.ai/vcm/worktrees/<taskSlug>
|
|
525
|
+
-> assert .ai/vcm/ is ignored
|
|
526
|
+
-> assert base repo has no uncommitted changes
|
|
527
|
+
-> assert branch does not exist
|
|
528
|
+
-> assert worktree path does not exist
|
|
529
|
+
-> git.createWorktree({ baseRepoRoot, branch, worktreePath, baseRef: HEAD })
|
|
530
|
+
-> artifactService.ensureHandoffStructure({ repoRoot: worktreePath, handoffDir })
|
|
531
|
+
-> artifactService.createArtifactTemplates({ repoRoot: worktreePath, handoffDir })
|
|
532
|
+
-> write central task record under <baseRepoRoot>/.ai/vcm/tasks/<task>.json
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Cleanup flow:
|
|
536
|
+
|
|
537
|
+
```text
|
|
538
|
+
cleanupTask(baseRepoRoot, taskSlug, options)
|
|
539
|
+
-> require all role sessions stopped
|
|
540
|
+
-> load central task record
|
|
541
|
+
-> verify worktreePath is under <baseRepoRoot>/.ai/vcm/worktrees/
|
|
542
|
+
-> inspect git status in worktree
|
|
543
|
+
-> refuse uncommitted changes unless options.force
|
|
544
|
+
-> git.removeWorktree(baseRepoRoot, worktreePath)
|
|
545
|
+
-> delete .ai/vcm/tasks/<task>.json
|
|
546
|
+
-> delete .ai/vcm/sessions/<task>.json
|
|
547
|
+
-> delete .ai/vcm/messages/<task>.jsonl
|
|
548
|
+
-> delete .ai/vcm/orchestration/<task>.json
|
|
1114
549
|
```
|
|
1115
550
|
|
|
1116
|
-
|
|
551
|
+
Branch cleanup:
|
|
1117
552
|
|
|
1118
|
-
|
|
553
|
+
- keep `feature/<taskSlug>` by default
|
|
554
|
+
- optional `deleteBranch` only with explicit confirmation
|
|
555
|
+
- prefer requiring merged branch unless force-confirmed
|
|
1119
556
|
|
|
1120
|
-
|
|
1121
|
-
- 将短指令写入目标 role terminal。
|
|
1122
|
-
- 记录 dispatch event。
|
|
557
|
+
### `src/backend/services/artifact-service.ts`
|
|
1123
558
|
|
|
1124
|
-
|
|
559
|
+
Exports:
|
|
1125
560
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
}
|
|
561
|
+
- `ArtifactService`
|
|
562
|
+
- input interfaces for handoff, artifacts, role commands, logs
|
|
563
|
+
- `createArtifactService(fs)`
|
|
1130
564
|
|
|
1131
|
-
|
|
1132
|
-
repoRoot: string;
|
|
1133
|
-
taskSlug: string;
|
|
1134
|
-
role: DispatchableRole;
|
|
1135
|
-
}
|
|
565
|
+
Responsibilities:
|
|
1136
566
|
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
567
|
+
- compute handoff paths
|
|
568
|
+
- create handoff directory structure
|
|
569
|
+
- create artifact templates
|
|
570
|
+
- list artifact checks
|
|
571
|
+
- read artifacts
|
|
572
|
+
- read/save role commands
|
|
573
|
+
- append role logs
|
|
1144
574
|
|
|
1145
|
-
|
|
1146
|
-
runtime: TerminalRuntime;
|
|
1147
|
-
sessionService: SessionService;
|
|
1148
|
-
taskService: TaskService;
|
|
1149
|
-
artifactService: ArtifactService;
|
|
1150
|
-
}
|
|
575
|
+
In task-worktree mode, artifact paths are still repo-relative, but `repoRoot` must be the task worktree path, not the base repo path.
|
|
1151
576
|
|
|
1152
|
-
|
|
1153
|
-
```
|
|
577
|
+
Primary role command path:
|
|
1154
578
|
|
|
1155
|
-
|
|
579
|
+
```text
|
|
580
|
+
.ai/handoffs/<task>/role-commands/<role>.md
|
|
581
|
+
```
|
|
1156
582
|
|
|
1157
|
-
|
|
1158
|
-
- role command 文件为空时失败。
|
|
1159
|
-
- role command 文件仍是模板或包含 `TBD` / `status: draft` 时失败。
|
|
1160
|
-
- role command 必须使用当前 VCM task 的 canonical path:`.ai/handoffs/<task-slug>/role-commands/<role>.md`。
|
|
1161
|
-
- Project Manager 启动时,backend 必须向 session 注入 task context,明确 `taskSlug`、`handoffDir` 和三个 role command 路径。
|
|
1162
|
-
- 目标 role session 未运行时失败并提示启动 session。
|
|
1163
|
-
- `instruction` 必须是短文本:
|
|
1164
|
-
- 只有用户通过 GUI 点击 Send Command 时才调用 dispatch。
|
|
1165
|
-
- dispatch 不解析 Claude Code 输出,不自动重试,不自动确认权限。
|
|
1166
|
-
- dispatch 成功后只记录 event,不继续触发下一个 role。
|
|
583
|
+
Legacy fallback:
|
|
1167
584
|
|
|
1168
585
|
```text
|
|
1169
|
-
|
|
586
|
+
.ai/handoffs/<task>/role-commands/<role>-command.md
|
|
1170
587
|
```
|
|
1171
588
|
|
|
1172
|
-
###
|
|
589
|
+
### `src/backend/services/status-service.ts`
|
|
590
|
+
|
|
591
|
+
Exports:
|
|
592
|
+
|
|
593
|
+
- `StatusService`
|
|
594
|
+
- `StatusServiceDeps`
|
|
595
|
+
- `createStatusService(deps)`
|
|
1173
596
|
|
|
1174
|
-
|
|
597
|
+
Responsibilities:
|
|
1175
598
|
|
|
1176
|
-
-
|
|
599
|
+
- assemble `TaskStatusReport`
|
|
600
|
+
- list sessions
|
|
601
|
+
- list artifact checks
|
|
602
|
+
- compute workflow report
|
|
1177
603
|
|
|
1178
|
-
|
|
604
|
+
### `src/backend/services/session-service.ts`
|
|
1179
605
|
|
|
1180
|
-
|
|
1181
|
-
export interface TaskStatusReport {
|
|
1182
|
-
task: TaskRecord;
|
|
1183
|
-
sessions: RoleSessionRecord[];
|
|
1184
|
-
artifacts: ArtifactSummary;
|
|
1185
|
-
warnings: string[];
|
|
1186
|
-
}
|
|
606
|
+
Exports:
|
|
1187
607
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
608
|
+
- `SessionService`
|
|
609
|
+
- `SessionServiceDeps`
|
|
610
|
+
- `createSessionService(deps)`
|
|
1191
611
|
|
|
1192
|
-
|
|
1193
|
-
taskService: TaskService;
|
|
1194
|
-
sessionService: SessionService;
|
|
1195
|
-
artifactService: ArtifactService;
|
|
1196
|
-
}
|
|
612
|
+
Responsibilities:
|
|
1197
613
|
|
|
1198
|
-
|
|
614
|
+
- start role session
|
|
615
|
+
- resume role session
|
|
616
|
+
- restart role session
|
|
617
|
+
- stop role session
|
|
618
|
+
- get role session
|
|
619
|
+
- list role sessions
|
|
620
|
+
|
|
621
|
+
Persistence:
|
|
622
|
+
|
|
623
|
+
```text
|
|
624
|
+
<baseRepoRoot>/.ai/vcm/sessions/<task>.json
|
|
1199
625
|
```
|
|
1200
626
|
|
|
1201
|
-
|
|
627
|
+
Environment passed to Claude Code:
|
|
1202
628
|
|
|
1203
|
-
|
|
629
|
+
- `VCM_API_URL`
|
|
630
|
+
- `VCM_CTL_COMMAND`
|
|
631
|
+
- `VCM_TASK_SLUG`
|
|
632
|
+
- `VCM_ROLE`
|
|
1204
633
|
|
|
1205
|
-
|
|
634
|
+
In task-worktree mode:
|
|
1206
635
|
|
|
1207
|
-
-
|
|
1208
|
-
-
|
|
1209
|
-
-
|
|
1210
|
-
- Serve frontend assets。
|
|
636
|
+
- session cwd is `task.worktreePath`
|
|
637
|
+
- session persistence remains central under `baseRepoRoot/.ai/vcm/sessions`
|
|
638
|
+
- raw logs and handoff artifacts are written under the task worktree
|
|
1211
639
|
|
|
1212
|
-
|
|
640
|
+
### `src/backend/services/message-service.ts`
|
|
1213
641
|
|
|
1214
|
-
|
|
1215
|
-
export interface CreateServerOptions {
|
|
1216
|
-
host?: string;
|
|
1217
|
-
port?: number;
|
|
1218
|
-
staticDir?: string;
|
|
1219
|
-
dev?: boolean;
|
|
1220
|
-
}
|
|
642
|
+
Exports:
|
|
1221
643
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
sessionService: SessionService;
|
|
1226
|
-
artifactService: ArtifactService;
|
|
1227
|
-
commandDispatcher: CommandDispatcher;
|
|
1228
|
-
statusService: StatusService;
|
|
1229
|
-
runtime: TerminalRuntime;
|
|
1230
|
-
}
|
|
644
|
+
- `MessageService`
|
|
645
|
+
- input interfaces
|
|
646
|
+
- `createMessageService(deps)`
|
|
1231
647
|
|
|
1232
|
-
|
|
1233
|
-
export async function startServer(options?: CreateServerOptions): Promise<{ url: string; close(): Promise<void> }>;
|
|
1234
|
-
```
|
|
648
|
+
Responsibilities:
|
|
1235
649
|
|
|
1236
|
-
|
|
650
|
+
- list messages
|
|
651
|
+
- send messages
|
|
652
|
+
- stage/approve/reject messages
|
|
653
|
+
- get/update orchestration state
|
|
654
|
+
- enforce message policy
|
|
655
|
+
- persist message snapshots
|
|
656
|
+
- write message body markdown
|
|
657
|
+
- write staged or delivered messages to target terminal
|
|
1237
658
|
|
|
1238
|
-
|
|
659
|
+
In task-worktree mode:
|
|
1239
660
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
GET /api/projects/current
|
|
1244
|
-
GET /api/projects/harness
|
|
1245
|
-
```
|
|
661
|
+
- message snapshots remain central under `baseRepoRoot/.ai/vcm/messages`
|
|
662
|
+
- message body files live under `task.worktreePath/.ai/handoffs/<task>/messages`
|
|
663
|
+
- terminal delivery uses the runtime session for the role, whose cwd is the task worktree
|
|
1246
664
|
|
|
1247
|
-
|
|
665
|
+
### `src/backend/services/command-dispatcher.ts`
|
|
1248
666
|
|
|
1249
|
-
|
|
1250
|
-
export function registerProjectRoutes(app: FastifyInstance, deps: ProjectRouteDeps): void;
|
|
667
|
+
Exports:
|
|
1251
668
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
669
|
+
- `CommandDispatcher`
|
|
670
|
+
- `DispatchRoleCommandInput`
|
|
671
|
+
- `CommandDispatcherDeps`
|
|
672
|
+
- `createCommandDispatcher(deps)`
|
|
1256
673
|
|
|
1257
|
-
|
|
674
|
+
Compatibility role-command dispatch only. Preferred orchestration is `MessageService` plus `vcmctl`.
|
|
1258
675
|
|
|
1259
|
-
|
|
676
|
+
### `src/backend/services/harness-service.ts`
|
|
1260
677
|
|
|
1261
|
-
|
|
1262
|
-
GET /api/tasks
|
|
1263
|
-
POST /api/tasks
|
|
1264
|
-
GET /api/tasks/:taskSlug
|
|
1265
|
-
GET /api/tasks/:taskSlug/status
|
|
1266
|
-
```
|
|
678
|
+
Exports:
|
|
1267
679
|
|
|
1268
|
-
|
|
680
|
+
- `HarnessService`
|
|
681
|
+
- `HarnessServiceDeps`
|
|
682
|
+
- `VCM_HARNESS_VERSION`
|
|
683
|
+
- `createHarnessService(deps)`
|
|
1269
684
|
|
|
1270
|
-
|
|
1271
|
-
export function registerTaskRoutes(app: FastifyInstance, deps: TaskRouteDeps): void;
|
|
685
|
+
Responsibilities:
|
|
1272
686
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
687
|
+
- inspect harness files
|
|
688
|
+
- manage `.gitignore` entries for VCM local state
|
|
689
|
+
- plan create/insert/update/ok
|
|
690
|
+
- apply VCM managed blocks
|
|
691
|
+
- preserve user content outside managed blocks
|
|
692
|
+
|
|
693
|
+
### `src/backend/services/app-settings-service.ts`
|
|
1279
694
|
|
|
1280
|
-
|
|
695
|
+
Exports:
|
|
1281
696
|
|
|
1282
|
-
|
|
697
|
+
- `StoredTranslationConfig`
|
|
698
|
+
- `AppSettingsFile`
|
|
699
|
+
- `AppSettingsService`
|
|
700
|
+
- `AppSettingsServiceDeps`
|
|
701
|
+
- `createAppSettingsService(deps)`
|
|
702
|
+
|
|
703
|
+
Storage:
|
|
1283
704
|
|
|
1284
705
|
```text
|
|
1285
|
-
|
|
1286
|
-
POST /api/tasks/:taskSlug/sessions/:role/start
|
|
1287
|
-
POST /api/tasks/:taskSlug/sessions/:role/stop
|
|
1288
|
-
POST /api/tasks/:taskSlug/sessions/:role/resume
|
|
1289
|
-
POST /api/tasks/:taskSlug/sessions/:role/restart
|
|
1290
|
-
POST /api/tasks/:taskSlug/sessions/:role/dispatch
|
|
706
|
+
~/.vcm/settings.json
|
|
1291
707
|
```
|
|
1292
708
|
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
```ts
|
|
1296
|
-
export function registerSessionRoutes(app: FastifyInstance, deps: SessionRouteDeps): void;
|
|
709
|
+
Also migrates legacy:
|
|
1297
710
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
commandDispatcher: CommandDispatcher;
|
|
1302
|
-
}
|
|
711
|
+
```text
|
|
712
|
+
~/.vibe-coding-master/settings.json
|
|
713
|
+
~/.vibe-coding-master/translation.json
|
|
1303
714
|
```
|
|
1304
715
|
|
|
1305
|
-
###
|
|
716
|
+
### `src/backend/services/translation-prompts.ts`
|
|
1306
717
|
|
|
1307
|
-
|
|
718
|
+
Exports:
|
|
1308
719
|
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
720
|
+
- `TranslationPromptInput`
|
|
721
|
+
- `BuiltTranslationPrompt`
|
|
722
|
+
- `buildTranslationPrompt(input)`
|
|
723
|
+
- `getTranslationPromptKey(input)`
|
|
724
|
+
- `getBaseTranslationPrompt(key, settings)`
|
|
725
|
+
- `resolveTranslationSystemPrompt(key, settings)`
|
|
726
|
+
- `getTranslationPromptPreviews(settings)`
|
|
1316
727
|
|
|
1317
|
-
|
|
728
|
+
Owns default prompts and user overrides.
|
|
1318
729
|
|
|
1319
|
-
|
|
1320
|
-
export function registerArtifactRoutes(app: FastifyInstance, deps: ArtifactRouteDeps): void;
|
|
730
|
+
### `src/backend/services/translation-queue.ts`
|
|
1321
731
|
|
|
1322
|
-
|
|
1323
|
-
projectService: ProjectService;
|
|
1324
|
-
taskService: TaskService;
|
|
1325
|
-
artifactService: ArtifactService;
|
|
1326
|
-
}
|
|
1327
|
-
```
|
|
732
|
+
Exports:
|
|
1328
733
|
|
|
1329
|
-
|
|
734
|
+
- `SerialTranslationQueue`
|
|
735
|
+
- `TranslationQueueRegistry`
|
|
736
|
+
- `createSerialTranslationQueue()`
|
|
737
|
+
- `createTranslationQueueRegistry()`
|
|
1330
738
|
|
|
1331
|
-
|
|
739
|
+
Ensures translations for one session run serially.
|
|
1332
740
|
|
|
1333
|
-
|
|
1334
|
-
- 将 runtime events 推送给前端。
|
|
1335
|
-
- 将前端 input/resize 写回 runtime。
|
|
741
|
+
### `src/backend/services/claude-transcript-service.ts`
|
|
1336
742
|
|
|
1337
|
-
|
|
743
|
+
Exports:
|
|
1338
744
|
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
745
|
+
- transcript event types
|
|
746
|
+
- `ClaudeTranscriptService`
|
|
747
|
+
- `TranscriptTail`
|
|
748
|
+
- `createClaudeTranscriptService()`
|
|
749
|
+
- `resolveExistingClaudeTranscriptPath(session)`
|
|
750
|
+
- `findClaudeTranscriptPathBySessionId(claudeSessionId)`
|
|
751
|
+
- `claudeProjectsRoot()`
|
|
752
|
+
- `projectHash(projectDir)`
|
|
753
|
+
- `projectsTranscriptDir(projectDir)`
|
|
754
|
+
- `claudeTranscriptPath(projectDir, claudeSessionId)`
|
|
755
|
+
- `parseAssistantContent(line)`
|
|
1345
756
|
|
|
1346
|
-
|
|
757
|
+
Responsibilities:
|
|
1347
758
|
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
759
|
+
- tail Claude JSONL transcript files
|
|
760
|
+
- resolve transcript path after start/resume/restart
|
|
761
|
+
- parse assistant messages, tool uses, tool results, questions, todos, and agent calls
|
|
1351
762
|
|
|
1352
|
-
|
|
763
|
+
### `src/backend/services/translation-service.ts`
|
|
1353
764
|
|
|
1354
|
-
|
|
765
|
+
Exports:
|
|
1355
766
|
|
|
1356
|
-
|
|
767
|
+
- `TranslationService`
|
|
768
|
+
- `TranslateUserInputServiceInput`
|
|
769
|
+
- `SendTranslatedInputServiceInput`
|
|
770
|
+
- `TranslationEventListener`
|
|
771
|
+
- `TranslationServiceDeps`
|
|
772
|
+
- `createTranslationService(deps)`
|
|
773
|
+
- `formatTerminalSubmit(text)`
|
|
1357
774
|
|
|
1358
|
-
|
|
775
|
+
Responsibilities:
|
|
1359
776
|
|
|
1360
|
-
|
|
777
|
+
- load/update translation settings
|
|
778
|
+
- expose prompt previews
|
|
779
|
+
- test provider
|
|
780
|
+
- translate user input
|
|
781
|
+
- send English text to active terminal
|
|
782
|
+
- subscribe to session translation events
|
|
783
|
+
- clear session entries
|
|
784
|
+
- retry failed output translation
|
|
785
|
+
- subscribe to Claude transcript service
|
|
786
|
+
- translate prose output and preserve tool output
|
|
1361
787
|
|
|
1362
|
-
|
|
1363
|
-
export function bootstrap(): void;
|
|
1364
|
-
```
|
|
788
|
+
## 9. Backend API
|
|
1365
789
|
|
|
1366
|
-
###
|
|
790
|
+
### `src/backend/server.ts`
|
|
1367
791
|
|
|
1368
|
-
|
|
792
|
+
Exports:
|
|
1369
793
|
|
|
1370
|
-
-
|
|
794
|
+
- `CreateServerOptions`
|
|
795
|
+
- `ServerDeps`
|
|
796
|
+
- `createServer(deps, options)`
|
|
797
|
+
- `startServer(options)`
|
|
798
|
+
- `CreateDefaultServerDepsOptions`
|
|
799
|
+
- `createDefaultServerDeps(options)`
|
|
800
|
+
- `getDefaultStaticDir()`
|
|
1371
801
|
|
|
1372
|
-
|
|
802
|
+
Registers all routes and WebSockets.
|
|
1373
803
|
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
804
|
+
### Route files
|
|
805
|
+
|
|
806
|
+
- `src/backend/api/project-routes.ts`: health, recent paths, connect/current project
|
|
807
|
+
- `src/backend/api/harness-routes.ts`: harness status/apply
|
|
808
|
+
- `src/backend/api/task-routes.ts`: tasks, task status, task cleanup
|
|
809
|
+
- `src/backend/api/session-routes.ts`: session lifecycle and dispatch compatibility endpoint
|
|
810
|
+
- `src/backend/api/artifact-routes.ts`: artifact, role command, and log reads/writes
|
|
811
|
+
- `src/backend/api/message-routes.ts`: messages and orchestration
|
|
812
|
+
- `src/backend/api/translation-routes.ts`: settings, prompt previews, provider test, input/send, clear/retry
|
|
813
|
+
|
|
814
|
+
Worktree task API:
|
|
1377
815
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
职责:
|
|
1381
|
-
|
|
1382
|
-
- 封装 REST API。
|
|
1383
|
-
|
|
1384
|
-
导出定义:
|
|
1385
|
-
|
|
1386
|
-
```ts
|
|
1387
|
-
export interface ApiClient {
|
|
1388
|
-
connectProject(input: ConnectProjectRequest): Promise<ProjectSummary>;
|
|
1389
|
-
getCurrentProject(): Promise<ProjectSummary | null>;
|
|
1390
|
-
listTasks(): Promise<TaskRecord[]>;
|
|
1391
|
-
createTask(input: CreateTaskRequest): Promise<TaskRecord>;
|
|
1392
|
-
getTask(taskSlug: string): Promise<TaskRecord>;
|
|
1393
|
-
getTaskStatus(taskSlug: string): Promise<TaskStatusReport>;
|
|
1394
|
-
listSessions(taskSlug: string): Promise<RoleSessionRecord[]>;
|
|
1395
|
-
startRoleSession(taskSlug: string, role: RoleName, input?: StartRoleSessionRequest): Promise<RoleSessionRecord>;
|
|
1396
|
-
stopRoleSession(taskSlug: string, role: RoleName): Promise<RoleSessionRecord>;
|
|
1397
|
-
restartRoleSession(taskSlug: string, role: RoleName, input?: StartRoleSessionRequest): Promise<RoleSessionRecord>;
|
|
1398
|
-
dispatchRoleCommand(taskSlug: string, role: DispatchableRole): Promise<DispatchRoleCommandResult>;
|
|
1399
|
-
listArtifacts(taskSlug: string): Promise<ArtifactSummary>;
|
|
1400
|
-
readRoleCommand(taskSlug: string, role: DispatchableRole): Promise<string>;
|
|
1401
|
-
saveRoleCommand(taskSlug: string, role: DispatchableRole, content: string): Promise<void>;
|
|
1402
|
-
readLog(taskSlug: string, role: RoleName): Promise<string>;
|
|
1403
|
-
}
|
|
1404
|
-
|
|
1405
|
-
export function createApiClient(baseUrl?: string): ApiClient;
|
|
816
|
+
```text
|
|
817
|
+
POST /api/tasks/:taskSlug/cleanup
|
|
1406
818
|
```
|
|
1407
819
|
|
|
1408
|
-
|
|
820
|
+
Do not add a "switch task worktree" endpoint. Worktree assignment happens only during task creation.
|
|
1409
821
|
|
|
1410
|
-
|
|
822
|
+
### WebSocket files
|
|
1411
823
|
|
|
1412
|
-
-
|
|
824
|
+
- `src/backend/ws/terminal-ws.ts`
|
|
825
|
+
- `src/backend/ws/translation-ws.ts`
|
|
1413
826
|
|
|
1414
|
-
|
|
827
|
+
Terminal WebSocket forwards PTY output/input/resize.
|
|
1415
828
|
|
|
1416
|
-
|
|
1417
|
-
export interface TerminalClient {
|
|
1418
|
-
connect(): void;
|
|
1419
|
-
disconnect(): void;
|
|
1420
|
-
sendInput(data: string): void;
|
|
1421
|
-
resize(cols: number, rows: number): void;
|
|
1422
|
-
onMessage(listener: (message: ServerTerminalMessage) => void): Unsubscribe;
|
|
1423
|
-
}
|
|
829
|
+
Translation WebSocket subscribes to translation entries/status for a runtime session id.
|
|
1424
830
|
|
|
1425
|
-
|
|
831
|
+
## 10. Backend Templates
|
|
1426
832
|
|
|
1427
|
-
|
|
1428
|
-
taskSlug: string;
|
|
1429
|
-
role: RoleName;
|
|
1430
|
-
baseUrl?: string;
|
|
1431
|
-
}
|
|
1432
|
-
```
|
|
833
|
+
### `src/backend/templates/handoff.ts`
|
|
1433
834
|
|
|
1434
|
-
|
|
835
|
+
Exports:
|
|
1435
836
|
|
|
1436
|
-
|
|
837
|
+
- `renderArchitecturePlanTemplate(taskSlug)`
|
|
838
|
+
- `renderImplementationLogTemplate(taskSlug)`
|
|
839
|
+
- `renderValidationLogTemplate(taskSlug)`
|
|
840
|
+
- `renderReviewReportTemplate(taskSlug)`
|
|
841
|
+
- `renderDocsSyncReportTemplate(taskSlug)`
|
|
1437
842
|
|
|
1438
|
-
-
|
|
1439
|
-
- 连接 TerminalClient。
|
|
1440
|
-
- 处理 fit、resize、input、output。
|
|
843
|
+
### `src/backend/templates/role-command.ts`
|
|
1441
844
|
|
|
1442
|
-
|
|
845
|
+
Exports:
|
|
1443
846
|
|
|
1444
|
-
|
|
1445
|
-
export interface XtermViewProps {
|
|
1446
|
-
taskSlug: string;
|
|
1447
|
-
role: RoleName;
|
|
1448
|
-
active: boolean;
|
|
1449
|
-
}
|
|
847
|
+
- `renderRoleCommandTemplate(taskSlug, role)`
|
|
1450
848
|
|
|
1451
|
-
|
|
1452
|
-
```
|
|
849
|
+
### `src/backend/templates/message-envelope.ts`
|
|
1453
850
|
|
|
1454
|
-
|
|
851
|
+
Exports:
|
|
1455
852
|
|
|
1456
|
-
|
|
853
|
+
- `renderMessageEnvelope(message)`
|
|
854
|
+
- `renderManualStagePrompt(message)`
|
|
1457
855
|
|
|
1458
|
-
|
|
1459
|
-
- 在 Start / Restart 上方提供三档权限模式选择。
|
|
1460
|
-
- 未启动时显示 Start。
|
|
1461
|
-
- 已启动时显示 terminal。
|
|
856
|
+
Manual stage prompt does not submit Enter.
|
|
1462
857
|
|
|
1463
|
-
|
|
858
|
+
Auto delivery envelope is submitted with Enter.
|
|
1464
859
|
|
|
1465
|
-
|
|
1466
|
-
export interface SessionConsoleProps {
|
|
1467
|
-
taskSlug: string;
|
|
1468
|
-
role: RoleName;
|
|
1469
|
-
session?: RoleSessionRecord;
|
|
1470
|
-
active: boolean;
|
|
1471
|
-
permissionMode: ClaudePermissionMode;
|
|
1472
|
-
onPermissionModeChange(mode: ClaudePermissionMode): void;
|
|
1473
|
-
onStart(role: RoleName): Promise<void>;
|
|
1474
|
-
onResume(role: RoleName): Promise<void>;
|
|
1475
|
-
onStop(role: RoleName): Promise<void>;
|
|
1476
|
-
onRestart(role: RoleName): Promise<void>;
|
|
1477
|
-
}
|
|
860
|
+
### Harness templates
|
|
1478
861
|
|
|
1479
|
-
|
|
1480
|
-
|
|
862
|
+
- `src/backend/templates/harness/claude-root.ts`
|
|
863
|
+
- `src/backend/templates/harness/gitignore.ts`
|
|
864
|
+
- `src/backend/templates/harness/project-manager-agent.ts`
|
|
865
|
+
- `src/backend/templates/harness/architect-agent.ts`
|
|
866
|
+
- `src/backend/templates/harness/coder-agent.ts`
|
|
867
|
+
- `src/backend/templates/harness/reviewer-agent.ts`
|
|
1481
868
|
|
|
1482
|
-
|
|
869
|
+
Each exports one render function for VCM managed rules.
|
|
1483
870
|
|
|
1484
|
-
|
|
871
|
+
## 11. Frontend State And API Client
|
|
1485
872
|
|
|
1486
|
-
|
|
1487
|
-
- 展示 status badge。
|
|
873
|
+
### `src/frontend/state/api-client.ts`
|
|
1488
874
|
|
|
1489
|
-
|
|
875
|
+
Central browser API wrapper.
|
|
1490
876
|
|
|
1491
|
-
|
|
1492
|
-
export interface RoleSessionTabsProps {
|
|
1493
|
-
activeRole: RoleName;
|
|
1494
|
-
sessions: RoleSessionRecord[];
|
|
1495
|
-
onRoleChange(role: RoleName): void;
|
|
1496
|
-
}
|
|
877
|
+
It calls:
|
|
1497
878
|
|
|
1498
|
-
|
|
1499
|
-
|
|
879
|
+
- project endpoints
|
|
880
|
+
- harness endpoints
|
|
881
|
+
- task endpoints
|
|
882
|
+
- session endpoints
|
|
883
|
+
- artifact endpoints
|
|
884
|
+
- message endpoints
|
|
885
|
+
- orchestration endpoints
|
|
886
|
+
- translation endpoints
|
|
1500
887
|
|
|
1501
|
-
|
|
888
|
+
Target additions:
|
|
1502
889
|
|
|
1503
|
-
|
|
890
|
+
- `listGitWorktrees()`
|
|
891
|
+
- `listGitBranches()`
|
|
892
|
+
- `cleanupTask(taskSlug, options)`
|
|
1504
893
|
|
|
1505
|
-
-
|
|
894
|
+
### `src/frontend/state/app-store.ts`
|
|
1506
895
|
|
|
1507
|
-
|
|
896
|
+
Exports:
|
|
1508
897
|
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
events: TerminalEvent[];
|
|
1512
|
-
}
|
|
898
|
+
- `AppStateSnapshot`
|
|
899
|
+
- `selectActiveTask(tasks, activeTaskSlug)`
|
|
1513
900
|
|
|
1514
|
-
|
|
1515
|
-
```
|
|
901
|
+
### `src/frontend/state/session-store.ts`
|
|
1516
902
|
|
|
1517
|
-
|
|
903
|
+
Exports:
|
|
1518
904
|
|
|
1519
|
-
|
|
905
|
+
- `getSessionForRole(sessions, role)`
|
|
1520
906
|
|
|
1521
|
-
|
|
907
|
+
## 12. Frontend Routes
|
|
1522
908
|
|
|
1523
|
-
|
|
909
|
+
### `src/frontend/app.tsx`
|
|
1524
910
|
|
|
1525
|
-
|
|
1526
|
-
export function ProjectDashboard(): JSX.Element;
|
|
1527
|
-
```
|
|
911
|
+
Exports:
|
|
1528
912
|
|
|
1529
|
-
|
|
913
|
+
- `App()`
|
|
1530
914
|
|
|
1531
|
-
|
|
915
|
+
Responsibilities:
|
|
1532
916
|
|
|
1533
|
-
-
|
|
1534
|
-
-
|
|
1535
|
-
-
|
|
917
|
+
- own top-level app state
|
|
918
|
+
- load current project and recent paths on startup
|
|
919
|
+
- load tasks and harness status after connect
|
|
920
|
+
- pass sidebar props to `ProjectDashboard`
|
|
921
|
+
- pass task props to `TaskWorkspace`
|
|
922
|
+
- keep active workflow/messages/orchestration/events synchronized by task
|
|
1536
923
|
|
|
1537
|
-
|
|
924
|
+
### `src/frontend/routes/project-dashboard.tsx`
|
|
1538
925
|
|
|
1539
|
-
|
|
1540
|
-
export interface TaskWorkspaceProps {
|
|
1541
|
-
taskSlug: string;
|
|
1542
|
-
}
|
|
926
|
+
Exports:
|
|
1543
927
|
|
|
1544
|
-
|
|
1545
|
-
|
|
928
|
+
- `ProjectDashboardProps`
|
|
929
|
+
- `ProjectDashboard(props)`
|
|
1546
930
|
|
|
1547
|
-
|
|
931
|
+
Responsibilities:
|
|
1548
932
|
|
|
1549
|
-
|
|
933
|
+
- collapsible sidebar
|
|
934
|
+
- repository connect form
|
|
935
|
+
- repository summary
|
|
936
|
+
- workflow panel
|
|
937
|
+
- settings section
|
|
938
|
+
- messages modal
|
|
939
|
+
- events modal
|
|
940
|
+
- harness panel
|
|
941
|
+
- task creation with one task-name field, checked non-optional worktree/branch indicator, branch preview, and worktree path preview
|
|
942
|
+
- task navigation
|
|
943
|
+
- completed-task cleanup action
|
|
1550
944
|
|
|
1551
|
-
|
|
945
|
+
### `src/frontend/routes/task-workspace.tsx`
|
|
1552
946
|
|
|
1553
|
-
|
|
1554
|
-
export function renderArchitecturePlanTemplate(taskSlug: string): string;
|
|
1555
|
-
export function renderImplementationLogTemplate(taskSlug: string): string;
|
|
1556
|
-
export function renderValidationLogTemplate(taskSlug: string): string;
|
|
1557
|
-
export function renderReviewReportTemplate(taskSlug: string): string;
|
|
1558
|
-
```
|
|
947
|
+
Exports:
|
|
1559
948
|
|
|
1560
|
-
|
|
949
|
+
- `TaskWorkspaceProps`
|
|
950
|
+
- `TaskWorkspace(props)`
|
|
1561
951
|
|
|
1562
|
-
|
|
952
|
+
Responsibilities:
|
|
1563
953
|
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
954
|
+
- task header with role tabs and refresh
|
|
955
|
+
- show branch and immutable worktree path for the active task
|
|
956
|
+
- status/message/orchestration refresh
|
|
957
|
+
- periodic polling
|
|
958
|
+
- session lifecycle actions
|
|
959
|
+
- per-role permission state
|
|
960
|
+
- runtime event collection for sidebar Events modal
|
|
1568
961
|
|
|
1569
|
-
|
|
962
|
+
## 13. Frontend Components
|
|
1570
963
|
|
|
1571
|
-
|
|
1572
|
-
Please read and execute the role command at: <commandPath>
|
|
1573
|
-
```
|
|
964
|
+
### `src/frontend/components/app-shell.tsx`
|
|
1574
965
|
|
|
1575
|
-
|
|
966
|
+
Exports:
|
|
1576
967
|
|
|
1577
|
-
|
|
968
|
+
- `AppShellProps`
|
|
969
|
+
- `AppShell({ sidebar, children })`
|
|
1578
970
|
|
|
1579
|
-
|
|
1580
|
-
main
|
|
1581
|
-
-> startServer
|
|
1582
|
-
-> create services/adapters/runtime
|
|
1583
|
-
-> register REST routes
|
|
1584
|
-
-> register terminal WebSocket
|
|
1585
|
-
-> serve frontend
|
|
1586
|
-
```
|
|
971
|
+
Two-column page shell.
|
|
1587
972
|
|
|
1588
|
-
###
|
|
973
|
+
### `src/frontend/components/repo-connect-form.tsx`
|
|
1589
974
|
|
|
1590
|
-
|
|
1591
|
-
ProjectDashboard
|
|
1592
|
-
-> api.connectProject
|
|
1593
|
-
-> POST /api/projects/connect
|
|
1594
|
-
-> projectService.connectProject
|
|
1595
|
-
-> git.getRepoRoot
|
|
1596
|
-
-> git.getCurrentBranch
|
|
1597
|
-
-> git.isDirty
|
|
1598
|
-
-> claude.isAvailable
|
|
1599
|
-
-> fs.writeJsonAtomic(.vcm/config.json)
|
|
1600
|
-
```
|
|
975
|
+
Exports:
|
|
1601
976
|
|
|
1602
|
-
|
|
977
|
+
- `RepoConnectFormProps`
|
|
978
|
+
- `RepoConnectForm(props)`
|
|
1603
979
|
|
|
1604
|
-
|
|
1605
|
-
ProjectDashboard / TaskWorkspace
|
|
1606
|
-
-> api.createTask
|
|
1607
|
-
-> POST /api/tasks
|
|
1608
|
-
-> taskService.createTask
|
|
1609
|
-
-> assertValidTaskSlug
|
|
1610
|
-
-> artifactService.ensureHandoffStructure
|
|
1611
|
-
-> artifactService.createArtifactTemplates
|
|
1612
|
-
-> fs.writeJsonAtomic(.vcm/tasks/<task-slug>.json)
|
|
1613
|
-
```
|
|
980
|
+
Layout:
|
|
1614
981
|
|
|
1615
|
-
|
|
982
|
+
- path input row
|
|
983
|
+
- recent select plus connect button row
|
|
1616
984
|
|
|
1617
|
-
|
|
1618
|
-
SessionConsole Start
|
|
1619
|
-
-> api.startRoleSession
|
|
1620
|
-
-> POST /api/tasks/:taskSlug/sessions/:role/start
|
|
1621
|
-
-> sessionService.startRoleSession
|
|
1622
|
-
-> claude.buildRoleStartCommand
|
|
1623
|
-
-> runtime.createSession
|
|
1624
|
-
-> node-pty spawn
|
|
1625
|
-
-> registry.upsert
|
|
1626
|
-
-> write session metadata
|
|
1627
|
-
```
|
|
985
|
+
This form connects the base repository. It is not used to switch an existing task to another worktree.
|
|
1628
986
|
|
|
1629
|
-
###
|
|
987
|
+
### `src/frontend/components/harness-panel.tsx`
|
|
1630
988
|
|
|
1631
|
-
|
|
1632
|
-
XtermView
|
|
1633
|
-
-> TerminalClient WebSocket
|
|
1634
|
-
-> input message
|
|
1635
|
-
-> terminal-ws
|
|
1636
|
-
-> runtime.write
|
|
1637
|
-
-> node-pty
|
|
1638
|
-
-> output event
|
|
1639
|
-
-> append role log
|
|
1640
|
-
-> WebSocket output message
|
|
1641
|
-
-> xterm.write
|
|
1642
|
-
```
|
|
989
|
+
Exports:
|
|
1643
990
|
|
|
1644
|
-
|
|
991
|
+
- `HarnessPanelProps`
|
|
992
|
+
- `HarnessPanel(props)`
|
|
1645
993
|
|
|
1646
|
-
|
|
1647
|
-
Role toolbar Send Command
|
|
1648
|
-
-> api.dispatchRoleCommand
|
|
1649
|
-
-> POST /api/tasks/:taskSlug/sessions/:role/dispatch
|
|
1650
|
-
-> commandDispatcher.dispatchRoleCommand
|
|
1651
|
-
-> artifactService.readRoleCommand
|
|
1652
|
-
-> sessionService.getRoleSession
|
|
1653
|
-
-> runtime.write(short instruction)
|
|
1654
|
-
-> registry event
|
|
1655
|
-
```
|
|
994
|
+
Shows harness status and install/update action.
|
|
1656
995
|
|
|
1657
|
-
###
|
|
996
|
+
### `src/frontend/components/workflow-panel.tsx`
|
|
1658
997
|
|
|
1659
|
-
|
|
998
|
+
Exports:
|
|
1660
999
|
|
|
1661
|
-
|
|
1000
|
+
- `WorkflowPanelProps`
|
|
1001
|
+
- `WorkflowPanel({ workflow })`
|
|
1662
1002
|
|
|
1663
|
-
|
|
1003
|
+
Renders the sidebar workflow steps.
|
|
1664
1004
|
|
|
1665
|
-
`
|
|
1005
|
+
### `src/frontend/components/message-timeline.tsx`
|
|
1666
1006
|
|
|
1667
|
-
|
|
1668
|
-
- rejects uppercase、underscore、space、path traversal。
|
|
1669
|
-
- suggests normalized slugs。
|
|
1007
|
+
Exports:
|
|
1670
1008
|
|
|
1671
|
-
|
|
1009
|
+
- `MessageTimelineProps`
|
|
1010
|
+
- `getMessageCounts(messages)`
|
|
1011
|
+
- `MessageTimeline(props)`
|
|
1672
1012
|
|
|
1673
|
-
-
|
|
1674
|
-
- detects missing headings。
|
|
1675
|
-
- validates handoff templates。
|
|
1676
|
-
- validates `validation-log` not-run reason。
|
|
1013
|
+
Used inside the Messages modal. Can show stage/reject/open-role actions.
|
|
1677
1014
|
|
|
1678
|
-
`
|
|
1015
|
+
### `src/frontend/components/event-log.tsx`
|
|
1679
1016
|
|
|
1680
|
-
|
|
1681
|
-
- creates role command files。
|
|
1682
|
-
- does not overwrite existing files by default。
|
|
1683
|
-
- returns artifact summary statuses。
|
|
1017
|
+
Exports:
|
|
1684
1018
|
|
|
1685
|
-
|
|
1019
|
+
- `EventLogProps`
|
|
1020
|
+
- `EventLog(props)`
|
|
1686
1021
|
|
|
1687
|
-
|
|
1688
|
-
- rejects empty command。
|
|
1689
|
-
- rejects not-started target session。
|
|
1690
|
-
- writes only short instruction to runtime。
|
|
1022
|
+
Used inside the Events modal.
|
|
1691
1023
|
|
|
1692
|
-
`
|
|
1024
|
+
### `src/frontend/components/task-nav.tsx`
|
|
1693
1025
|
|
|
1694
|
-
|
|
1695
|
-
- finds by task + role。
|
|
1696
|
-
- updates status。
|
|
1697
|
-
- removes sessions。
|
|
1026
|
+
Exports:
|
|
1698
1027
|
|
|
1699
|
-
|
|
1028
|
+
- `TaskNavProps`
|
|
1029
|
+
- `TaskNav(props)`
|
|
1700
1030
|
|
|
1701
|
-
|
|
1702
|
-
- throws useful errors for API failures。
|
|
1031
|
+
Task list in sidebar.
|
|
1703
1032
|
|
|
1704
|
-
`
|
|
1033
|
+
### `src/frontend/components/role-session-tabs.tsx`
|
|
1705
1034
|
|
|
1706
|
-
|
|
1707
|
-
- dispatches output/status/exit messages to listeners。
|
|
1035
|
+
Exports:
|
|
1708
1036
|
|
|
1709
|
-
|
|
1037
|
+
- `RoleSessionTabsProps`
|
|
1038
|
+
- `RoleSessionTabs(props)`
|
|
1710
1039
|
|
|
1711
|
-
|
|
1040
|
+
Header role tabs with status badges.
|
|
1712
1041
|
|
|
1713
|
-
-
|
|
1714
|
-
- writes `.vcm/config.json`。
|
|
1715
|
-
- returns branch and dirty warning。
|
|
1042
|
+
### `src/frontend/components/session-console.tsx`
|
|
1716
1043
|
|
|
1717
|
-
|
|
1044
|
+
Exports:
|
|
1718
1045
|
|
|
1719
|
-
-
|
|
1720
|
-
-
|
|
1721
|
-
- creates handoff artifacts。
|
|
1046
|
+
- `SessionConsoleProps`
|
|
1047
|
+
- `SessionConsole(props)`
|
|
1722
1048
|
|
|
1723
|
-
|
|
1049
|
+
Role console and translation split.
|
|
1724
1050
|
|
|
1725
|
-
-
|
|
1726
|
-
- streams output。
|
|
1727
|
-
- writes log file。
|
|
1728
|
-
- handles exit。
|
|
1051
|
+
### `src/frontend/components/session-toolbar.tsx`
|
|
1729
1052
|
|
|
1730
|
-
|
|
1053
|
+
Exports:
|
|
1731
1054
|
|
|
1732
|
-
-
|
|
1733
|
-
-
|
|
1734
|
-
- restarts role session。
|
|
1735
|
-
- dispatches role command.
|
|
1055
|
+
- `SessionToolbarProps`
|
|
1056
|
+
- `SessionToolbar(props)`
|
|
1736
1057
|
|
|
1737
|
-
|
|
1058
|
+
Renders permission select and session lifecycle buttons.
|
|
1738
1059
|
|
|
1739
|
-
`
|
|
1060
|
+
There is no visible primary `Send Command` button in the current toolbar. Role-command dispatch remains backend compatibility.
|
|
1740
1061
|
|
|
1741
|
-
-
|
|
1742
|
-
- connect temp repo。
|
|
1743
|
-
- create task。
|
|
1744
|
-
- see Task Workspace。
|
|
1745
|
-
- start fake project-manager session。
|
|
1746
|
-
- see terminal output。
|
|
1747
|
-
- switch to architect tab。
|
|
1748
|
-
- see Start button。
|
|
1749
|
-
- verify the main workspace has no right-side artifact panel。
|
|
1062
|
+
### `src/frontend/components/translation-panel.tsx`
|
|
1750
1063
|
|
|
1751
|
-
|
|
1064
|
+
Exports:
|
|
1752
1065
|
|
|
1753
|
-
|
|
1066
|
+
- `TranslationPanelProps`
|
|
1067
|
+
- `TranslationPanel(props)`
|
|
1754
1068
|
|
|
1755
|
-
|
|
1069
|
+
Renders output translations, settings actions, auto-send toggle, and composer.
|
|
1756
1070
|
|
|
1757
|
-
|
|
1758
|
-
npm install
|
|
1759
|
-
npm run dev
|
|
1760
|
-
open http://localhost:5173
|
|
1761
|
-
Select repo
|
|
1762
|
-
Create demo-task
|
|
1763
|
-
Start project-manager
|
|
1764
|
-
Start architect
|
|
1765
|
-
Type in PM terminal
|
|
1766
|
-
Send architect command
|
|
1767
|
-
Verify logs/architect.log
|
|
1768
|
-
Verify artifact status
|
|
1769
|
-
Restart coder
|
|
1770
|
-
Refresh browser
|
|
1771
|
-
Verify session state recovers
|
|
1772
|
-
```
|
|
1071
|
+
Important current behavior:
|
|
1773
1072
|
|
|
1774
|
-
|
|
1073
|
+
- panel-level status only
|
|
1074
|
+
- no per-entry status label
|
|
1075
|
+
- no `Original` buttons
|
|
1076
|
+
- tool output is preserved, dim, one-line
|
|
1077
|
+
- prose source is replaced by translated text after completion
|
|
1078
|
+
- no separate translated-English textarea
|
|
1775
1079
|
|
|
1776
|
-
###
|
|
1080
|
+
### `src/frontend/components/translation-settings-modal.tsx`
|
|
1777
1081
|
|
|
1778
|
-
|
|
1082
|
+
Exports:
|
|
1779
1083
|
|
|
1780
|
-
- `
|
|
1781
|
-
- `
|
|
1782
|
-
- `tsconfig.node.json`
|
|
1783
|
-
- `vite.config.ts`
|
|
1784
|
-
- `src/main.ts`
|
|
1785
|
-
- `src/backend/server.ts`
|
|
1786
|
-
- `src/frontend/main.tsx`
|
|
1787
|
-
- `src/frontend/app.tsx`
|
|
1788
|
-
- `src/frontend/routes/project-dashboard.tsx`
|
|
1084
|
+
- `TranslationSettingsModalProps`
|
|
1085
|
+
- `TranslationSettingsModal(props)`
|
|
1789
1086
|
|
|
1790
|
-
|
|
1087
|
+
Settings:
|
|
1791
1088
|
|
|
1792
|
-
-
|
|
1793
|
-
-
|
|
1794
|
-
-
|
|
1089
|
+
- enable translation
|
|
1090
|
+
- base URL
|
|
1091
|
+
- API key as text input
|
|
1092
|
+
- model
|
|
1093
|
+
- target language
|
|
1094
|
+
- input mode
|
|
1095
|
+
- context
|
|
1096
|
+
- translate output
|
|
1097
|
+
- translate user input
|
|
1098
|
+
- timeout
|
|
1099
|
+
- temperature
|
|
1100
|
+
- prompt slot overrides
|
|
1101
|
+
- provider test
|
|
1795
1102
|
|
|
1796
|
-
###
|
|
1103
|
+
### `src/frontend/components/status-badge.tsx`
|
|
1797
1104
|
|
|
1798
|
-
|
|
1105
|
+
Exports:
|
|
1799
1106
|
|
|
1800
|
-
- `
|
|
1801
|
-
- `
|
|
1802
|
-
- `src/backend/templates/*.ts`
|
|
1803
|
-
- `src/backend/services/artifact-service.ts`
|
|
1804
|
-
- `src/backend/services/task-service.ts`
|
|
1805
|
-
- `src/backend/api/task-routes.ts`
|
|
1107
|
+
- `StatusBadgeProps`
|
|
1108
|
+
- `StatusBadge(props)`
|
|
1806
1109
|
|
|
1807
|
-
|
|
1110
|
+
### `src/frontend/terminal/xterm-view.tsx`
|
|
1808
1111
|
|
|
1809
|
-
|
|
1810
|
-
- `.ai/handoffs/<task-slug>/` 被创建。
|
|
1811
|
-
- Handoff artifacts 在任务目录中被创建。
|
|
1112
|
+
Renders `xterm.js`, connects to terminal WebSocket, sends input and resize, and preserves terminal colors.
|
|
1812
1113
|
|
|
1813
|
-
###
|
|
1114
|
+
### `src/frontend/terminal/terminal-client.ts`
|
|
1814
1115
|
|
|
1815
|
-
|
|
1116
|
+
Terminal WebSocket client wrapper.
|
|
1816
1117
|
|
|
1817
|
-
|
|
1818
|
-
- `src/backend/services/project-service.ts`
|
|
1819
|
-
- `src/backend/validation/environment-check.ts`
|
|
1820
|
-
- `src/backend/api/project-routes.ts`
|
|
1821
|
-
- `src/frontend/components/repo-connect-form.tsx`
|
|
1118
|
+
## 14. UI State Details
|
|
1822
1119
|
|
|
1823
|
-
|
|
1120
|
+
Sidebar:
|
|
1824
1121
|
|
|
1825
|
-
-
|
|
1826
|
-
-
|
|
1827
|
-
-
|
|
1828
|
-
- main/master 和 dirty state 显示 warning。
|
|
1122
|
+
- all groups default collapsed
|
|
1123
|
+
- `Repository Path` default open only when no task is selected
|
|
1124
|
+
- `Settings` includes `Messages`, `Events`, and `Auto orchestration`
|
|
1829
1125
|
|
|
1830
|
-
|
|
1126
|
+
Task workspace:
|
|
1831
1127
|
|
|
1832
|
-
|
|
1128
|
+
- role tabs in the first header row
|
|
1129
|
+
- workflow is not in main workspace
|
|
1130
|
+
- messages/events are not in main workspace
|
|
1131
|
+
- active role console fills available space
|
|
1833
1132
|
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
- `
|
|
1837
|
-
- `
|
|
1838
|
-
-
|
|
1839
|
-
-
|
|
1840
|
-
- `
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
### Milestone 6: GUI Role Command Dispatch
|
|
1870
|
-
|
|
1871
|
-
文件:
|
|
1872
|
-
|
|
1873
|
-
- `src/backend/services/command-dispatcher.ts`
|
|
1874
|
-
- `src/frontend/components/event-log.tsx`
|
|
1875
|
-
|
|
1876
|
-
验收:
|
|
1877
|
-
|
|
1878
|
-
- 用户点击目标 role toolbar 的 Send Command。
|
|
1879
|
-
- backend 写入短指令到 architect runtime。
|
|
1880
|
-
- dispatch event 出现在 Event Log。
|
|
1881
|
-
- 不发送未落盘长 prompt。
|
|
1882
|
-
|
|
1883
|
-
### Milestone 7: Acceptance and Hardening
|
|
1884
|
-
|
|
1885
|
-
内容:
|
|
1886
|
-
|
|
1887
|
-
- unit tests。
|
|
1888
|
-
- integration tests。
|
|
1889
|
-
- e2e smoke。
|
|
1890
|
-
- README 更新。
|
|
1891
|
-
- GUI 错误态。
|
|
1892
|
-
- empty/missing/incomplete artifact 状态。
|
|
1893
|
-
- Claude Code 缺失提示。
|
|
1894
|
-
- process crashed 提示。
|
|
1895
|
-
|
|
1896
|
-
验收:
|
|
1897
|
-
|
|
1898
|
-
- `npm run typecheck` 通过。
|
|
1899
|
-
- `npm test` 通过。
|
|
1900
|
-
- `npm run build` 通过。
|
|
1901
|
-
- `npm run e2e` 通过或有明确 fake Claude 限制说明。
|
|
1902
|
-
|
|
1903
|
-
## 17. 最终 V1 验收清单
|
|
1904
|
-
|
|
1905
|
-
- [ ] GUI 可以启动。
|
|
1906
|
-
- [ ] 用户可以连接本地 Git repo。
|
|
1907
|
-
- [ ] GUI 显示 repo path、branch、dirty warning。
|
|
1908
|
-
- [ ] 用户可以创建 task workspace。
|
|
1909
|
-
- [ ] 系统创建 `.vcm/config.json`。
|
|
1910
|
-
- [ ] 系统创建 `.vcm/tasks/<task-slug>.json`。
|
|
1911
|
-
- [ ] 系统创建 `.ai/handoffs/<task-slug>/role-commands/`。
|
|
1912
|
-
- [ ] 系统创建 `.ai/handoffs/<task-slug>/logs/`。
|
|
1913
|
-
- [ ] 系统创建 architecture / implementation / validation / review artifact templates。
|
|
1914
|
-
- [ ] GUI 显示 PM / Architect / Coder / Reviewer tabs。
|
|
1915
|
-
- [ ] 用户可以启动 project-manager session。
|
|
1916
|
-
- [ ] 用户可以启动 architect session。
|
|
1917
|
-
- [ ] embedded terminal 可以显示 Claude Code output。
|
|
1918
|
-
- [ ] 用户可以直接在 embedded terminal 中输入。
|
|
1919
|
-
- [ ] terminal output 被保存到 role log。
|
|
1920
|
-
- [ ] 用户可以从 GUI 发送 role command 到目标 role session。
|
|
1921
|
-
- [ ] backend 只发送短指令,不粘贴完整长 prompt。
|
|
1922
|
-
- [ ] 用户可以 stop / restart role session。
|
|
1923
|
-
- [ ] 页面刷新后可以恢复 task/session 可见状态。
|
|
1924
|
-
- [ ] Claude Code 缺失时 GUI 有清晰提示。
|
|
1925
|
-
- [ ] 进程 crashed/exited 时 GUI 有清晰提示。
|
|
1926
|
-
|
|
1927
|
-
## 18. 需要延后到 V2 的接口
|
|
1928
|
-
|
|
1929
|
-
V1 文件中可以预留类型或接口,但不实现完整功能:
|
|
1930
|
-
|
|
1931
|
-
- `ReviewAdapter`:后续接 Cross-Model Reviewer。
|
|
1932
|
-
- `ValidationRunner`:后续自动运行 validation commands。
|
|
1933
|
-
- `WorktreeManager`:后续实现 one task -> one branch -> one worktree。
|
|
1934
|
-
- `SessionPersistenceService`:后续增强 backend lifecycle、session registry 持久化、raw log replay 和恢复体验。
|
|
1935
|
-
- `DesktopShell`:后续用 Electron 或 Tauri 打包。
|
|
1936
|
-
- `PermissionHookManager`:后续生成 role-specific Claude Code permission hooks。
|
|
1937
|
-
|
|
1938
|
-
V1 的判断标准是:
|
|
1133
|
+
Translation:
|
|
1134
|
+
|
|
1135
|
+
- top role toolbar button label is `✅ Translate` when on and `× Translate` when off
|
|
1136
|
+
- translation panel `Auto-send` label is `✅ Auto-send` when on and `× Auto-send` when off
|
|
1137
|
+
- panel uses terminal-like dark styling
|
|
1138
|
+
- composer height is compact
|
|
1139
|
+
- `Enter` translates/sends, `Shift+Enter` inserts newline
|
|
1140
|
+
|
|
1141
|
+
## 15. Data Persistence Summary
|
|
1142
|
+
|
|
1143
|
+
App settings:
|
|
1144
|
+
|
|
1145
|
+
```text
|
|
1146
|
+
~/.vcm/settings.json
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
Project config:
|
|
1150
|
+
|
|
1151
|
+
```text
|
|
1152
|
+
.ai/vcm/config.json
|
|
1153
|
+
```
|
|
1154
|
+
|
|
1155
|
+
Task state:
|
|
1156
|
+
|
|
1157
|
+
```text
|
|
1158
|
+
.ai/vcm/tasks/<task>.json
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
Session state:
|
|
1162
|
+
|
|
1163
|
+
```text
|
|
1164
|
+
.ai/vcm/sessions/<task>.json
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
Messages:
|
|
1939
1168
|
|
|
1940
1169
|
```text
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
少自动修改代码
|
|
1944
|
-
多沉淀 artifacts
|
|
1945
|
-
少解析终端语义
|
|
1946
|
-
多保留 raw logs
|
|
1947
|
-
少暴露终端编排细节
|
|
1948
|
-
多提供 GUI 操作入口
|
|
1170
|
+
.ai/vcm/messages/<task>.jsonl
|
|
1171
|
+
.ai/handoffs/<task>/messages/<message-id>.md
|
|
1949
1172
|
```
|
|
1173
|
+
|
|
1174
|
+
Orchestration:
|
|
1175
|
+
|
|
1176
|
+
```text
|
|
1177
|
+
.ai/vcm/orchestration/<task>.json
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
Task worktrees:
|
|
1181
|
+
|
|
1182
|
+
```text
|
|
1183
|
+
.ai/vcm/worktrees/<task>/
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
Handoff artifacts:
|
|
1187
|
+
|
|
1188
|
+
```text
|
|
1189
|
+
.ai/handoffs/<task>/
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
Claude transcripts:
|
|
1193
|
+
|
|
1194
|
+
```text
|
|
1195
|
+
~/.claude/projects/<project-hash>/<claude-session-id>.jsonl
|
|
1196
|
+
```
|
|
1197
|
+
|
|
1198
|
+
## 16. Validation Checklist
|
|
1199
|
+
|
|
1200
|
+
Before release or publish:
|
|
1201
|
+
|
|
1202
|
+
```bash
|
|
1203
|
+
npm run typecheck
|
|
1204
|
+
npm test
|
|
1205
|
+
npm run build
|
|
1206
|
+
npm run verify:package
|
|
1207
|
+
```
|
|
1208
|
+
|
|
1209
|
+
For frontend layout changes, also verify manually:
|
|
1210
|
+
|
|
1211
|
+
- connect repository
|
|
1212
|
+
- confirm `.ai/vcm/` is ignored before creating a task worktree
|
|
1213
|
+
- create task and verify branch `feature/<task>` is created
|
|
1214
|
+
- verify worktree path is `<baseRepoRoot>/.ai/vcm/worktrees/<task>`
|
|
1215
|
+
- open task
|
|
1216
|
+
- verify role sessions start with cwd set to the task worktree
|
|
1217
|
+
- role tabs stay in header
|
|
1218
|
+
- sidebar sections collapse/open correctly
|
|
1219
|
+
- embedded terminal remains visible after role switch
|
|
1220
|
+
- translation split is 50/50
|
|
1221
|
+
- Messages modal opens from sidebar Settings
|
|
1222
|
+
- Events modal opens from sidebar Settings
|
|
1223
|
+
- Auto orchestration toggles on/off
|
|
1224
|
+
- `Enter` in translation composer translates/sends
|
|
1225
|
+
- `Shift+Enter` inserts newline
|
|
1226
|
+
- mark task complete and verify cleanup removes the worktree and central task metadata
|
|
1227
|
+
|
|
1228
|
+
## 17. V1 Boundaries To Preserve
|
|
1229
|
+
|
|
1230
|
+
Do not reintroduce these into V1 docs or UI unless the product direction changes:
|
|
1231
|
+
|
|
1232
|
+
- tmux persistence backend
|
|
1233
|
+
- CLI-first task management as the main product mode
|
|
1234
|
+
- main workspace artifact panel
|
|
1235
|
+
- Pause/Resume orchestration buttons in GUI
|
|
1236
|
+
- raw PTY output translation
|
|
1237
|
+
- translation classifier that drops assistant prose
|
|
1238
|
+
- separate translated-English textarea
|
|
1239
|
+
- optional title input in New Task
|
|
1240
|
+
- `Dirty: yes/no` sidebar label
|
|
1241
|
+
- role command dispatch as the primary orchestration path
|
|
1242
|
+
- per-role worktrees
|
|
1243
|
+
- switching a task to another branch/worktree after creation
|
|
1244
|
+
- a separate `Create task worktree` button outside task creation
|