vibe-coding-master 0.0.16 → 0.2.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.
Files changed (47) hide show
  1. package/README.md +74 -41
  2. package/dist/backend/api/artifact-routes.js +5 -5
  3. package/dist/backend/api/harness-routes.js +8 -0
  4. package/dist/backend/api/message-routes.js +4 -4
  5. package/dist/backend/api/round-routes.js +4 -2
  6. package/dist/backend/server.js +8 -2
  7. package/dist/backend/services/artifact-service.js +12 -12
  8. package/dist/backend/services/claude-hook-service.js +1 -1
  9. package/dist/backend/services/harness-service.js +579 -5
  10. package/dist/backend/services/message-service.js +71 -137
  11. package/dist/backend/services/project-service.js +4 -1
  12. package/dist/backend/services/round-service.js +14 -52
  13. package/dist/backend/services/session-service.js +1 -3
  14. package/dist/backend/services/task-service.js +16 -17
  15. package/dist/backend/templates/handoff.js +64 -26
  16. package/dist/backend/templates/harness/architect-agent.js +42 -12
  17. package/dist/backend/templates/harness/claude-root.js +42 -18
  18. package/dist/backend/templates/harness/coder-agent.js +15 -11
  19. package/dist/backend/templates/harness/known-issues-doc.js +22 -0
  20. package/dist/backend/templates/harness/project-manager-agent.js +66 -15
  21. package/dist/backend/templates/harness/pull-request-template.js +29 -0
  22. package/dist/backend/templates/harness/reviewer-agent.js +40 -12
  23. package/dist/backend/templates/harness/vcm-final-acceptance-skill.js +105 -0
  24. package/dist/backend/templates/harness/vcm-harness-bootstrap-skill.js +78 -0
  25. package/dist/backend/templates/harness/vcm-long-running-validation-skill.js +50 -0
  26. package/dist/backend/templates/harness/vcm-route-message-skill.js +86 -0
  27. package/dist/backend/templates/message-envelope.js +1 -0
  28. package/dist/backend/templates/role-command.js +7 -1
  29. package/dist/shared/validation/artifact-check.js +14 -9
  30. package/dist-frontend/assets/index-CrY5Ryps.js +90 -0
  31. package/dist-frontend/assets/index-CvvtrrCN.css +32 -0
  32. package/dist-frontend/index.html +2 -2
  33. package/docs/cc-best-practices.md +434 -192
  34. package/docs/full-harness-baseline.md +254 -0
  35. package/docs/product-design.md +31 -28
  36. package/docs/v0.2-implementation-plan.md +379 -0
  37. package/docs/vcm-cc-best-practices.md +449 -0
  38. package/package.json +3 -1
  39. package/scripts/harness-tools/generate-module-index +298 -0
  40. package/scripts/harness-tools/generate-public-surface +692 -0
  41. package/scripts/install-vcm-harness.mjs +1607 -0
  42. package/scripts/uninstall-vcm-harness.mjs +490 -0
  43. package/scripts/verify-package.mjs +4 -0
  44. package/dist-frontend/assets/index-CvtyKEfS.js +0 -89
  45. package/dist-frontend/assets/index-jEkUTnIY.css +0 -32
  46. package/docs/v1-architecture-design.md +0 -1009
  47. package/docs/v1-implementation-plan.md +0 -1376
@@ -1,1009 +0,0 @@
1
- # V1 Architecture Design
2
-
3
- Last updated: 2026-05-31
4
-
5
- This document describes the architecture implemented by the current VCM codebase.
6
-
7
- ## 1. System Overview
8
-
9
- VCM is a local Node.js application with:
10
-
11
- - Fastify backend.
12
- - React frontend.
13
- - `node-pty` terminal runtime.
14
- - `xterm.js` terminal view.
15
- - Claude Code role processes.
16
- - API-driven message bus.
17
- - Claude transcript JSONL tailer for translation.
18
-
19
- Runtime shape:
20
-
21
- ```text
22
- browser
23
- -> React GUI
24
- -> HTTP API + terminal WebSocket
25
- -> Fastify backend
26
- -> services
27
- -> node-pty
28
- -> claude --agent <role>
29
- ```
30
-
31
- The app is local-first. It writes project control state under `.ai/vcm/`, handoff artifacts under `.ai/vcm/handoffs/` inside the active task worktree, app settings under `~/.vcm/settings.json`, and reads Claude transcript files under `~/.claude/projects/`.
32
-
33
- ## 2. Processes And Ports
34
-
35
- Default ports:
36
-
37
- - backend / production GUI: `4173`
38
- - Vite dev GUI: `5173`
39
-
40
- Development:
41
-
42
- ```text
43
- npm run dev
44
- -> backend at http://127.0.0.1:4173
45
- -> Vite dev server at http://127.0.0.1:5173
46
- ```
47
-
48
- Production / npm package:
49
-
50
- ```text
51
- vcm
52
- -> backend serves dist-frontend at http://127.0.0.1:4173
53
- ```
54
-
55
- `src/main.ts` starts the backend and optionally starts Vite when `--dev` is passed.
56
-
57
- ## 3. Frontend Architecture
58
-
59
- Entry:
60
-
61
- - `src/frontend/main.tsx`
62
- - `src/frontend/app.tsx`
63
-
64
- Main state lives in `App`:
65
-
66
- - connected project
67
- - recent repository paths
68
- - harness status
69
- - task list
70
- - active task
71
- - active role
72
- - active messages
73
- - active orchestration state
74
- - task-local event list
75
-
76
- Layout:
77
-
78
- ```text
79
- AppShell
80
- sidebar: ProjectDashboard
81
- main: TaskWorkspace or EmptyWorkspace
82
- ```
83
-
84
- ### ProjectDashboard
85
-
86
- File:
87
-
88
- - `src/frontend/routes/project-dashboard.tsx`
89
-
90
- Responsibilities:
91
-
92
- - Render collapsible sidebar sections.
93
- - Render repository connect form.
94
- - Render repository summary.
95
- - Render settings section with Theme, Round alert, Try alert, Messages, and Events.
96
- - Render harness status/actions.
97
- - Render task creation form with one task-name field, a `Create worktree and branch` checkbox selected by default, and generated branch/path previews when selected.
98
- - Render task list.
99
- - Render Messages and Events modals.
100
-
101
- All sections default collapsed. `Repository Path` opens when there is no selected task.
102
-
103
- ### TaskWorkspace
104
-
105
- File:
106
-
107
- - `src/frontend/routes/task-workspace.tsx`
108
-
109
- Responsibilities:
110
-
111
- - Fetch task status, messages, orchestration state, and round state.
112
- - Poll those every three seconds.
113
- - Render compact header with task title, branch, immutable worktree path, role tabs, Refresh, and red `Close Task`.
114
- - Hold per-role permission mode selection.
115
- - Hold task orchestration state and pass its on/off control to the active role console.
116
- - Detect newly submitted auto-orchestration messages from VCM dispatch and switch the active role tab to the target role.
117
- - Emit task round state to `App` so completion alerts can be deduplicated and displayed.
118
- - Render one `SessionConsole` per role but only show the active role.
119
- - Emit messages/orchestration/events back to `App` so sidebar stays synchronized.
120
-
121
- ### SessionConsole
122
-
123
- File:
124
-
125
- - `src/frontend/components/session-console.tsx`
126
-
127
- Responsibilities:
128
-
129
- - Render role session controls and embedded terminal.
130
- - Render `Auto orchestration` immediately to the left of `Translate`, using the same compact toggle styling.
131
- - Render the translation split panel when `Translate` is enabled.
132
-
133
- Responsibilities:
134
-
135
- - Render role toolbar.
136
- - Render embedded terminal for running sessions.
137
- - Render empty/resume state for stopped sessions.
138
- - Toggle translation panel.
139
- - Split terminal and translation into two equal columns when translation is on.
140
-
141
- ### TranslationPanel
142
-
143
- File:
144
-
145
- - `src/frontend/components/translation-panel.tsx`
146
-
147
- Responsibilities:
148
-
149
- - Load translation settings and prompt previews.
150
- - Start backend transcript listening for the current terminal runtime session id.
151
- - Poll backend translation events with a cursor.
152
- - Render dark translation output panel.
153
- - Render translation status: `ready`, `translating <elapsed>`, or `error`.
154
- - Render preserved tool output as dim one-line rows.
155
- - Render prose source while translating, then translated text after completion, using Markdown rendering for prose.
156
- - Render user composer.
157
- - Translate on `Enter`; newline on `Shift+Enter`.
158
- - Replace Chinese input with English draft after translation.
159
- - Send English draft to the active terminal.
160
- - Provide panel-level `Auto-send`, `Settings`, and `Clear`.
161
-
162
- ## 4. Backend Architecture
163
-
164
- Entry:
165
-
166
- - `src/backend/server.ts`
167
-
168
- `createDefaultServerDeps()` wires:
169
-
170
- - filesystem adapter
171
- - command runner
172
- - git adapter
173
- - Claude adapter
174
- - app settings service
175
- - node-pty runtime
176
- - session registry
177
- - artifact service
178
- - harness service
179
- - project service
180
- - task service
181
- - session service
182
- - command dispatcher
183
- - status service
184
- - message service
185
- - translation service
186
-
187
- Fastify registers:
188
-
189
- - app settings routes
190
- - project routes
191
- - harness routes
192
- - task routes
193
- - session routes
194
- - artifact routes
195
- - message routes
196
- - translation routes
197
- - terminal WebSocket
198
-
199
- ## 5. Repository Connection
200
-
201
- File:
202
-
203
- - `src/backend/services/project-service.ts`
204
- - `src/backend/adapters/git-adapter.ts`
205
-
206
- Connect flow:
207
-
208
- ```text
209
- POST /api/projects/connect
210
- -> resolve path
211
- -> check path exists
212
- -> check .git marker directly
213
- -> create ~/.vcm/projects/<project-id>/config.json
214
- -> ensure .ai/vcm state dirs
215
- -> read branch and dirty state
216
- -> record recent repo path in ~/.vcm/settings.json
217
- ```
218
-
219
- Git repository detection:
220
-
221
- - `.git` directory with `HEAD` is accepted.
222
- - `.git` file with `gitdir:` pointer and target `HEAD` is accepted.
223
- - This supports normal repositories and worktrees.
224
-
225
- Git metadata commands use:
226
-
227
- ```text
228
- git -c safe.directory=<repoRoot> -c safe.directory=<realpath(repoRoot)> ...
229
- ```
230
-
231
- VCM does not require global `safe.directory` configuration.
232
-
233
- ## 6. Task Worktree Architecture
234
-
235
- Task-level worktree management is the default architecture for multi-task parallelism.
236
-
237
- Rule:
238
-
239
- ```text
240
- default VCM task = one branch + one git worktree + one handoff directory + one role-session set
241
- ```
242
-
243
- Branch name:
244
-
245
- ```text
246
- feature/<taskSlug>
247
- ```
248
-
249
- Worktree path:
250
-
251
- ```text
252
- <baseRepoRoot>/.claude/worktrees/<taskSlug>
253
- ```
254
-
255
- VCM does not support switching a task to another branch or worktree mode after creation. If the user needs a different branch/worktree choice, they should create a new task.
256
-
257
- When `Create worktree and branch` is cleared, the task uses:
258
-
259
- ```text
260
- branch: current connected-repo branch
261
- runtime repo root: <baseRepoRoot>
262
- worktreePath: undefined
263
- ```
264
-
265
- VCM does not create worktrees by role. All four role sessions for a task share the same task worktree:
266
-
267
- ```text
268
- .claude/worktrees/<taskSlug>/
269
- project-manager session cwd
270
- architect session cwd
271
- coder session cwd
272
- reviewer session cwd
273
- ```
274
-
275
- ### 6.1 Base Repo vs Task Worktree
276
-
277
- VCM distinguishes:
278
-
279
- - `baseRepoRoot`: repository the user connected.
280
- - `taskRepoRoot`: git worktree path for a specific task.
281
- - `branch`: `feature/<taskSlug>`.
282
- - `worktreePath`: same as `taskRepoRoot`.
283
-
284
- Base repo state is the task index plus the Claude-compatible container for nested task worktrees:
285
-
286
- ```text
287
- <baseRepoRoot>/.ai/vcm/tasks/<task>.json
288
- <baseRepoRoot>/.claude/worktrees/<task>/
289
- ```
290
-
291
- Project configuration is app-local and stored outside the repository:
292
-
293
- ```text
294
- ~/.vcm/projects/<project-id>/config.json
295
- ~/.vcm/projects/index.json
296
- ```
297
-
298
- Task runtime state, source changes, and handoff artifacts live in the task runtime repo. For worktree-backed tasks this is the nested task worktree:
299
-
300
- ```text
301
- <baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/sessions/<task>.json
302
- <baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
303
- <baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/orchestration/<task>.json
304
- <baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/translation/<task>/
305
- <baseRepoRoot>/.claude/worktrees/<task>/.ai/vcm/handoffs/
306
- ```
307
-
308
- For inline tasks, `taskRepoRoot` is the connected base repo, so these same runtime paths resolve under the connected repo's `.ai/vcm/`.
309
-
310
- Because the handoff directory is `<taskRepoRoot>/.ai/vcm/handoffs/` without a task slug segment, VCM rejects creating a second active inline task in the same connected repository. Parallel tasks should use the default worktree mode.
311
-
312
- This split lets VCM list tasks from the base repo after worktrees are created, while each task's runtime state follows the same root as the role sessions.
313
-
314
- ### 6.2 Git Ignore Requirement
315
-
316
- The base repository must ignore `.ai/vcm/` and `.claude/worktrees/`.
317
-
318
- Reason:
319
-
320
- - `.claude/worktrees/<task>` is a nested git worktree.
321
- - Without `.claude/worktrees/` in `.gitignore`, the base repo sees worktree files as untracked noise.
322
- - `.ai/vcm` also contains local task/session/message metadata that should not be committed by default.
323
-
324
- The VCM harness manages a `.gitignore` block that ignores `.ai/vcm/` and `.claude/worktrees/` before task worktree creation.
325
-
326
- ### 6.3 Task Creation Flow
327
-
328
- ```text
329
- POST /api/tasks
330
- -> validate taskSlug
331
- -> assert .ai/vcm/ is ignored by Git
332
- -> if createWorktree is not false:
333
- -> assert .claude/worktrees/ is ignored by Git
334
- -> compute branch feature/<taskSlug>
335
- -> compute worktreePath <baseRepoRoot>/.claude/worktrees/<taskSlug>
336
- -> assert branch does not already exist
337
- -> assert worktreePath does not already exist
338
- -> assert base repo has no uncommitted changes
339
- -> git worktree add -b feature/<taskSlug> <worktreePath> <baseRef>
340
- -> otherwise:
341
- -> read current base repo branch
342
- -> leave worktreePath undefined
343
- -> reject when another inline task is already active
344
- -> create handoff structure in taskRepoRoot
345
- -> write central task metadata under baseRepoRoot/.ai/vcm/tasks/<task>.json
346
- ```
347
-
348
- The default `baseRef` is the connected repo's current `HEAD`.
349
-
350
- ### 6.4 Task Close Flow
351
-
352
- ```text
353
- POST /api/tasks/:taskSlug/cleanup
354
- -> load task metadata
355
- -> list role sessions for the task
356
- -> stop each VCM-managed role session whose runtime status is running
357
- -> stop translation tailers and clear task translation cache
358
- -> when worktreePath exists, verify it belongs under <baseRepoRoot>/.claude/worktrees/
359
- -> when worktreePath exists, git worktree remove --force <worktreePath>
360
- -> when worktreePath exists, delete the task branch by default
361
- -> delete base task metadata
362
- -> delete task runtime session/message/orchestration/translation metadata
363
- -> delete task runtime handoff directory
364
- ```
365
-
366
- Close Task is intentionally destructive after user confirmation. It actively stops VCM-managed running role sessions, but it does not preflight running sessions or uncommitted worktree changes. Tasks created without a worktree remove VCM metadata only because there is no VCM-owned branch/worktree to delete.
367
-
368
- ## 7. Task And Artifact Model
369
-
370
- File:
371
-
372
- - `src/backend/services/task-service.ts`
373
- - `src/backend/services/artifact-service.ts`
374
- - `src/shared/types/task.ts`
375
- - `src/shared/types/artifact.ts`
376
-
377
- Task state:
378
-
379
- ```text
380
- <baseRepoRoot>/.ai/vcm/tasks/<task>.json
381
- ```
382
-
383
- Each task stores:
384
-
385
- - `taskSlug`
386
- - optional `title`
387
- - timestamps
388
- - `repoRoot`, which is the connected base repository
389
- - optional `worktreePath`, which is the task runtime repo when present
390
- - branch, always `feature/<taskSlug>` for VCM-created tasks
391
- - handoff directory
392
- - status
393
- - optional spec path
394
-
395
- Task creation:
396
-
397
- ```text
398
- POST /api/tasks
399
- -> validate slug
400
- -> create branch and worktree
401
- -> create handoff directories
402
- -> create artifact templates
403
- -> write base .ai/vcm/tasks/<task>.json
404
- ```
405
-
406
- Task cleanup is orchestrated by `src/backend/api/task-routes.ts` because it coordinates session stopping, translation tailer stopping, and `TaskService.cleanupTask`.
407
-
408
- Handoff directory:
409
-
410
- ```text
411
- <taskRepoRoot>/.ai/vcm/handoffs/
412
- role-commands/
413
- architect.md
414
- coder.md
415
- reviewer.md
416
- logs/
417
- project-manager.log
418
- architect.log
419
- coder.log
420
- reviewer.log
421
- architecture-plan.md
422
- implementation-log.md
423
- validation-log.md
424
- review-report.md
425
- docs-sync-report.md
426
- messages/
427
- ```
428
-
429
- Artifact checks are simple V1 checks:
430
-
431
- - missing
432
- - placeholder / incomplete
433
- - ok
434
-
435
- They are used for missing/incomplete artifact warnings, not content quality judgment.
436
-
437
- ## 8. Task Status Report
438
-
439
- File:
440
-
441
- - `src/backend/services/status-service.ts`
442
-
443
- Endpoint:
444
-
445
- ```text
446
- GET /api/tasks/:taskSlug/status
447
- ```
448
-
449
- The status report returns the task record, role sessions, artifact checks, and warnings. VCM no longer computes or renders a Workflow panel; role sequencing is guided by the injected Claude rules and PM-mediated messages.
450
-
451
- ## 9. Session Runtime
452
-
453
- Files:
454
-
455
- - `src/backend/services/session-service.ts`
456
- - `src/backend/adapters/claude-adapter.ts`
457
- - `src/backend/runtime/node-pty-runtime.ts`
458
- - `src/backend/runtime/session-registry.ts`
459
-
460
- Session service owns role session lifecycle:
461
-
462
- - start
463
- - resume
464
- - restart
465
- - stop
466
- - list
467
- - get
468
-
469
- Runtime session id and Claude session id are different:
470
-
471
- - runtime session id identifies the local `node-pty` process in VCM.
472
- - Claude session id identifies the Claude Code conversation for resume/transcript lookup.
473
-
474
- Start:
475
-
476
- ```text
477
- claude --agent <role> --session-id <uuid>
478
- ```
479
-
480
- Resume:
481
-
482
- ```text
483
- claude --agent <role> --resume <uuid>
484
- ```
485
-
486
- Permission flags:
487
-
488
- ```text
489
- --permission-mode bypassPermissions
490
- --dangerously-skip-permissions
491
- ```
492
-
493
- Session persistence:
494
-
495
- ```text
496
- <taskRepoRoot>/.ai/vcm/sessions/<task>.json
497
- ```
498
-
499
- The persisted record includes:
500
-
501
- - runtime session id
502
- - Claude session id
503
- - transcript path
504
- - role
505
- - status
506
- - command display
507
- - permission mode
508
- - cwd
509
- - pid
510
- - raw log path
511
- - role command path
512
- - handoff artifact path
513
-
514
- If a runtime process is gone but the role has a Claude session id, `getRoleSession` returns a recoverable `resumable` status.
515
-
516
- In task-worktree mode, `cwd` must be the immutable task worktree path. Role sessions must not start in the base repo when a task worktree exists.
517
-
518
- ## 10. Terminal Runtime
519
-
520
- File:
521
-
522
- - `src/backend/runtime/node-pty-runtime.ts`
523
-
524
- The runtime:
525
-
526
- - spawns `node-pty`
527
- - sets `TERM=xterm-256color`
528
- - sets color-friendly env vars
529
- - appends raw PTY output to `<taskRepoRoot>/.ai/vcm/handoffs/logs/<role>.log`
530
- - emits terminal output/input/exit events to WebSocket subscribers
531
- - replays the log on terminal WebSocket subscribe
532
-
533
- Terminal WebSocket:
534
-
535
- ```text
536
- GET /ws/terminal/:sessionId
537
- ```
538
-
539
- Client messages:
540
-
541
- - input
542
- - resize
543
-
544
- Server messages:
545
-
546
- - output
547
- - exit
548
- - error
549
-
550
- ## 11. Message Bus
551
-
552
- Files:
553
-
554
- - `src/backend/services/message-service.ts`
555
- - `src/backend/templates/message-envelope.ts`
556
-
557
- State:
558
-
559
- ```text
560
- <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
561
- <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
562
- <taskRepoRoot>/.ai/vcm/handoffs/messages/<from-role>-<to-role>.md
563
- ```
564
-
565
- Policy:
566
-
567
- - Roles never call a VCM CLI to send messages.
568
- - A role writes or updates exactly one route file for each directed target role.
569
- - File name format is `<from-role>-<to-role>.md`; the filename is the authoritative route.
570
- - Blank route files are not pending.
571
- - Non-empty route files are pending and are dispatched only by VCM.
572
- - Optional YAML frontmatter may provide message type and metadata, but cannot override the route.
573
- - PM-to-role and role-to-PM routes are the default policy. Peer route files are supported only when the task design explicitly allows them.
574
-
575
- Manual mode:
576
-
577
- ```text
578
- role writes route file -> Stop hook -> VCM records pending snapshot -> Messages modal -> Copy/manual action
579
- ```
580
-
581
- The current GUI shows sequence, timestamp, status, route file path, body preview, `Copy`, and `Mark All Done`. VCM leaves the route file non-empty until the user confirms the pending content was handled or auto mode later dispatches it.
582
-
583
- Auto mode:
584
-
585
- ```text
586
- role writes route file
587
- Stop hook -> VCM scans pending route files
588
- target idle and running -> VCM writes envelope + Enter -> delivering
589
- UserPromptSubmit hook -> VCM confirms accepted prompt -> submitted
590
- submitted -> VCM clears source route file if it still contains the same message
591
- target busy/unavailable/failure -> source route file remains non-empty
592
- target Stop hook -> VCM scans again and may deliver next pending route file
593
- ```
594
-
595
- The backend pastes a `[VCM MESSAGE]` envelope into the target terminal, then sends Enter as a separate terminal input event. A successful terminal write creates a `delivering` snapshot. Claude Code `UserPromptSubmit` is the acceptance confirmation that moves the message to `submitted`. VCM snapshots the message body before clearing the source route file so the message history remains auditable. Delivery is serialized per target role; VCM never sends two pending route files into the same target role during one scan.
596
-
597
- VCM Harness owns Claude Code hook injection through `.claude/settings.json`. The target design injects `UserPromptSubmit` and `Stop`. Hooks post directly to a local VCM backend endpoint and do not use `vcmctl`. `UserPromptSubmit` confirms accepted prompts and switches the role activity badge to `running`; `Stop` switches the role activity badge to `idle` and triggers a pending route-file scan. VCM also marks a role `running` immediately after it submits user input or a VCM message to that embedded terminal. VCM does not use Claude Code Subagent hooks for role delegation.
598
-
599
- `Mark All Done` is a manual recovery action for stuck orchestration. It appends `acknowledged` snapshots for open messages and, after user confirmation, clears pending route files that the user already handled manually.
600
-
601
- The message service also serializes message mutations per task inside the VCM process so concurrent API calls cannot bypass the per-role in-flight check.
602
-
603
- The backend should not keep compatibility-only message command paths after this migration. Removing `vcmctl` is part of the target simplification.
604
-
605
- Messages and orchestration snapshots are task runtime state under `taskRepoRoot/.ai/vcm`. Pending route files live in the task worktree handoff directory and are cleared after successful VCM submission.
606
-
607
- ## 12. Round Completion Architecture
608
-
609
- Files:
610
-
611
- - `src/backend/services/round-service.ts`
612
- - `src/backend/api/round-routes.ts`
613
- - `src/shared/types/round.ts`
614
-
615
- API:
616
-
617
- ```text
618
- GET /api/tasks/:taskSlug/round
619
- ```
620
-
621
- The round service reads hook-driven role activity from `RoleSessionRecord`. It does not use transcript tailing as the source of truth for round completion.
622
-
623
- - `unknown`
624
- - `idle`
625
- - `answering`
626
-
627
- Mapping:
628
-
629
- - VCM terminal submit updates the session to `activityStatus: "running"` and the round role state to `answering`
630
- - `Stop` updates the session to `activityStatus: "idle"`, records `lastStopAt`, and the round role state becomes `idle`
631
-
632
- Task-level completion:
633
-
634
- - If a message is currently `delivering` or `submitted`, the latest such message defines the round target.
635
- - In a PM -> role -> PM chain, completion follows the newest active message, so the round completes after PM emits hook `Stop` for the final response.
636
- - Queued or pending messages prevent completion.
637
- - If no VCM message is in the round, the latest direct role `Stop` can still produce a completion state.
638
-
639
- Frontend behavior:
640
-
641
- - `TaskWorkspace` polls the round endpoint with the other task state.
642
- - `App` stores the sidebar `Round alert` preference in `~/.vcm/settings.json`.
643
- - `Try alert` is frontend-only and calls the same round completion notice/sound path without persisting any setting.
644
- - `App` deduplicates `completionId`, then shows a small `Round complete` prompt and plays a short two-note Web Audio chime when alerts are enabled.
645
-
646
- ## 13. Role Command Compatibility
647
-
648
- Files:
649
-
650
- - `src/backend/services/command-dispatcher.ts`
651
- - `src/backend/api/session-routes.ts`
652
- - `src/backend/api/artifact-routes.ts`
653
-
654
- Compatibility endpoint:
655
-
656
- ```text
657
- POST /api/tasks/:taskSlug/sessions/:role/dispatch
658
- ```
659
-
660
- Dispatchable roles:
661
-
662
- - `architect`
663
- - `coder`
664
- - `reviewer`
665
-
666
- The dispatcher:
667
-
668
- 1. Loads the task.
669
- 2. Reads the role command artifact.
670
- 3. Rejects missing, empty, or placeholder role commands.
671
- 4. Resolves primary command path `role-commands/<role>.md`, with legacy fallback `<role>-command.md`.
672
- 5. Pastes `Please read and execute the role command at: <path>` to the target terminal, then sends Enter as a separate terminal input event.
673
-
674
- This is an obsolete compatibility path and should be removed when route-file messaging lands. The preferred V1 coordination path is VCM-dispatched route files under `.ai/vcm/handoffs/messages/`.
675
-
676
- ## 14. Harness Service
677
-
678
- File:
679
-
680
- - `src/backend/services/harness-service.ts`
681
-
682
- Harness files:
683
-
684
- ```text
685
- CLAUDE.md
686
- .gitignore
687
- .claude/settings.json
688
- .claude/agents/project-manager.md
689
- .claude/agents/architect.md
690
- .claude/agents/coder.md
691
- .claude/agents/reviewer.md
692
- ```
693
-
694
- Managed block:
695
-
696
- ```md
697
- <!-- VCM:BEGIN version=1 -->
698
- ...
699
- <!-- VCM:END -->
700
- ```
701
-
702
- `.gitignore` uses the same VCM managed-block concept with hash comments:
703
-
704
- ```gitignore
705
- # VCM:BEGIN version=1
706
- .ai/vcm/
707
- .claude/worktrees/
708
- # VCM:END
709
- ```
710
-
711
- `.claude/settings.json` is JSON-merged by the harness. VCM preserves existing settings and adds `UserPromptSubmit` and `Stop` hooks that post directly to the local VCM backend using the session-provided VCM API URL, task slug, role, and Claude session id. The hooks must not call `vcmctl`.
712
-
713
- The service:
714
-
715
- - checks whether files exist
716
- - checks whether a managed block exists
717
- - compares the managed block with the current template
718
- - plans `create`, `insert`, `update`, or `ok`
719
- - applies only the planned managed-block change
720
-
721
- It must not overwrite user content outside the VCM block.
722
-
723
- ## 15. Translation Architecture
724
-
725
- Files:
726
-
727
- - `src/backend/services/translation-service.ts`
728
- - `src/backend/services/translation-queue.ts`
729
- - `src/backend/services/translation-prompts.ts`
730
- - `src/backend/services/claude-transcript-service.ts`
731
- - `src/backend/adapters/translation-provider.ts`
732
- - `src/backend/api/translation-routes.ts`
733
- - `src/frontend/components/translation-panel.tsx`
734
- - `src/frontend/components/translation-settings-modal.tsx`
735
-
736
- ### Settings
737
-
738
- Settings service:
739
-
740
- - `src/backend/services/app-settings-service.ts`
741
-
742
- Storage:
743
-
744
- ```text
745
- ~/.vcm/settings.json
746
- ```
747
-
748
- Stored data:
749
-
750
- - UI theme preference: `system`, `light`, or `dark`
751
- - translation settings
752
- - translation secrets
753
- - recent repository paths, max 5
754
-
755
- ### Provider
756
-
757
- Provider type:
758
-
759
- ```text
760
- openai-compatible
761
- ```
762
-
763
- It uses chat completions and builds the URL from `baseUrl`.
764
-
765
- Prompt keys:
766
-
767
- - `zh-to-en`
768
- - `zh-to-en-with-context`
769
- - `en-to-zh`
770
-
771
- ### Claude Output Path
772
-
773
- Output translation reads Claude transcript JSONL, not terminal raw output.
774
-
775
- Resolution order:
776
-
777
- 1. persisted `RoleSessionRecord.transcriptPath`
778
- 2. `claudeTranscriptPath(session.cwd, session.claudeSessionId)`
779
- 3. scan `~/.claude/projects/*/<sessionId>.jsonl` and choose newest mtime
780
-
781
- Tailer:
782
-
783
- - validates file exists
784
- - can replay history since session start minus a grace window
785
- - uses `fs.watch`
786
- - also polls every 200ms
787
- - parses only complete newline-delimited JSON records
788
- - is owned by the backend translation service, not the frontend panel
789
- - stays running after the panel closes
790
- - stops only when the role session is stopped/restarted or the task is closed
791
-
792
- Parsed transcript events:
793
-
794
- - `text`
795
- - `thinking`
796
- - `question`
797
- - `todo`
798
- - `agent`
799
- - `tool_use`
800
- - `tool_result`
801
-
802
- Translation service behavior:
803
-
804
- - ignores thinking
805
- - translates text/question/todo/agent as prose
806
- - preserves tool_use/tool_result as tool-output
807
- - queues provider translation per runtime session id
808
- - pushes prose entries before provider translation starts
809
- - pushes tool_use/tool_result immediately without entering the translation queue
810
- - writes translation events to `<taskRepoRoot>/.ai/vcm/translation/<task>/<role>/<session-id>.jsonl`
811
- - exposes HTTP polling for frontend rendering
812
-
813
- Polling protocol:
814
-
815
- - `seq` starts at 1 for each translation session cache.
816
- - the frontend calls `GET /api/translation/sessions/:sessionId/events?after=<cursor>`.
817
- - `after` is the next expected seq, not the last displayed seq.
818
- - `after=18` lets the backend delete cached events with `seq < 18` and return events with `seq >= 18`.
819
- - if `after` is older than the retained cache, the backend returns whatever newer events still exist.
820
- - no snapshot mismatch error is used.
821
- - translated prose replacement is a later `entry` event with the same translation entry id and a newer `seq`.
822
-
823
- ### User Input Path
824
-
825
- ```text
826
- textarea -> POST translation/input -> provider -> English draft in the same textarea -> optional send
827
- ```
828
-
829
- Send path:
830
-
831
- ```text
832
- POST translation/send -> bracketed paste English text -> short delay -> runtime.write(session.id, "\r")
833
- ```
834
-
835
- The backend strips trailing newlines before pasting and sends Enter separately. This avoids Claude Code TUI cases where a single large PTY write containing both text and `\r` fills the input line but does not submit it.
836
-
837
- ## 16. API Surface
838
-
839
- Project:
840
-
841
- ```text
842
- GET /api/health
843
- GET /api/projects/recent
844
- GET /api/projects/current
845
- POST /api/projects/connect
846
- ```
847
-
848
- Harness:
849
-
850
- ```text
851
- GET /api/projects/harness
852
- POST /api/projects/harness/apply
853
- ```
854
-
855
- Tasks:
856
-
857
- ```text
858
- GET /api/tasks
859
- POST /api/tasks
860
- GET /api/tasks/:taskSlug
861
- GET /api/tasks/:taskSlug/status
862
- POST /api/tasks/:taskSlug/cleanup
863
- ```
864
-
865
- There is no task-level "switch worktree" API. Worktree selection happens only at task creation.
866
-
867
- Sessions:
868
-
869
- ```text
870
- GET /api/tasks/:taskSlug/sessions
871
- POST /api/tasks/:taskSlug/sessions/:role/start
872
- POST /api/tasks/:taskSlug/sessions/:role/resume
873
- POST /api/tasks/:taskSlug/sessions/:role/restart
874
- POST /api/tasks/:taskSlug/sessions/:role/stop
875
- POST /api/tasks/:taskSlug/sessions/:role/dispatch
876
- ```
877
-
878
- Artifacts:
879
-
880
- ```text
881
- GET /api/tasks/:taskSlug/artifacts
882
- GET /api/tasks/:taskSlug/artifacts/:artifactName
883
- GET /api/tasks/:taskSlug/role-commands/:role
884
- PUT /api/tasks/:taskSlug/role-commands/:role
885
- GET /api/tasks/:taskSlug/logs/:role
886
- ```
887
-
888
- Messages:
889
-
890
- ```text
891
- GET /api/tasks/:taskSlug/messages
892
- GET /api/tasks/:taskSlug/messages/pending-route-files
893
- POST /api/tasks/:taskSlug/messages/scan
894
- POST /api/tasks/:taskSlug/messages/mark-all-done
895
- GET /api/tasks/:taskSlug/orchestration
896
- PUT /api/tasks/:taskSlug/orchestration
897
- ```
898
-
899
- Claude Code hooks:
900
-
901
- ```text
902
- POST /api/hooks/claude-code
903
- POST /api/hooks/claude-code/stop
904
- ```
905
-
906
- Round:
907
-
908
- ```text
909
- GET /api/tasks/:taskSlug/round
910
- ```
911
-
912
- App settings:
913
-
914
- ```text
915
- GET /api/settings/preferences
916
- PUT /api/settings/preferences
917
- ```
918
-
919
- Translation:
920
-
921
- ```text
922
- GET /api/translation/settings
923
- PUT /api/translation/settings
924
- GET /api/translation/prompts
925
- POST /api/translation/test
926
- POST /api/tasks/:taskSlug/sessions/:role/translation/start
927
- GET /api/translation/sessions/:sessionId/events?after=<cursor>&limit=<n>
928
- POST /api/tasks/:taskSlug/sessions/:role/translation/input
929
- POST /api/tasks/:taskSlug/sessions/:role/translation/send
930
- POST /api/translation/sessions/:sessionId/clear
931
- POST /api/translation/sessions/:sessionId/retry/:translationId
932
- ```
933
-
934
- WebSockets:
935
-
936
- ```text
937
- /ws/terminal/:sessionId
938
- ```
939
-
940
- ## 17. Error Handling
941
-
942
- File:
943
-
944
- - `src/backend/errors.ts`
945
-
946
- Backend services throw `VcmError` with:
947
-
948
- - code
949
- - message
950
- - status code
951
- - optional hint
952
-
953
- Fastify error handler returns:
954
-
955
- ```json
956
- {
957
- "error": {
958
- "code": "CODE",
959
- "message": "Human-readable message",
960
- "hint": "Optional hint"
961
- }
962
- }
963
- ```
964
-
965
- ## 18. Packaging Architecture
966
-
967
- `package.json` publishes built artifacts:
968
-
969
- - `dist`
970
- - `dist-frontend`
971
- - `docs`
972
- - `scripts`
973
- - `README.md`
974
-
975
- Bins:
976
-
977
- - `vcm` -> `dist/main.js`
978
-
979
- Important scripts:
980
-
981
- - `build`: clean, TypeScript build, Vite build
982
- - `verify:package`: verifies required dist files and frontend assets
983
- - `prepack`: build and package verification
984
- - `postinstall`: fixes `node-pty` spawn helper when needed
985
-
986
- ## 19. Security And Safety Boundaries
987
-
988
- Current boundaries:
989
-
990
- - VCM runs local processes with the user's permissions.
991
- - VCM does not auto-confirm Claude Code permission prompts.
992
- - Relaxed Claude permission modes are user-selected per role launch.
993
- - Translation API key is local in `~/.vcm/settings.json`.
994
- - Translation output is UI/runtime state only unless a user or role copies it into a file.
995
- - `.ai/vcm` is local project control state and must be ignored by Git.
996
- - Task handoff artifacts live under `.ai/vcm/handoffs/` as task-local runtime state and are removed by Close Task. Durable conclusions belong in normal project docs, code comments, commit messages, or PR text.
997
- - Task worktrees are created only during task creation; VCM does not expose branch/worktree switching APIs.
998
- - Sandbox isolation should come from a devContainer, Docker container, VM, or other user-controlled environment.
999
-
1000
- ## 20. Known Implementation Boundaries
1001
-
1002
- - No tmux backend.
1003
- - No per-role worktree manager.
1004
- - No branch switching for an existing task.
1005
- - No main-page artifact inspector.
1006
- - No raw PTY output translation.
1007
- - No computed Workflow panel or hard gate enforcement.
1008
- - No durable backend event log for the sidebar Events modal; current events are frontend runtime events for the active task.
1009
- - No hosted multi-user collaboration.