vibe-coding-master 0.0.17 → 0.2.1

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