vibe-coding-master 0.0.11 → 0.0.12

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 CHANGED
@@ -207,7 +207,7 @@ Translation settings are local and stored in:
207
207
  ~/.vcm/settings.json
208
208
  ```
209
209
 
210
- The same file stores recent repository paths. The translation API key is stored locally under `translation.secrets.apiKey`; it is not written to the connected repository, `.ai/handoffs`, raw terminal logs, or git diffs.
210
+ The same file stores recent repository paths. The translation API key is stored locally under `translation.secrets.apiKey`; it is not written to the connected repository, `.ai/vcm/handoffs`, raw terminal logs, or git diffs.
211
211
 
212
212
  The sidebar `Settings` section also stores the UI theme preference in this file. The default is `system`, which follows the OS/browser color-scheme preference; users can cycle between `System`, `Light`, and `Dark`.
213
213
 
@@ -283,18 +283,18 @@ Examples that roles can run inside their terminal:
283
283
  ```bash
284
284
  vcmctl send --to coder --type task --body-file /tmp/message.md
285
285
  vcmctl reply --type blocked --body "Need clarification."
286
- vcmctl result --body-file /tmp/result.md --artifact .ai/handoffs/task/implementation-log.md
286
+ vcmctl result --body-file /tmp/result.md --artifact .ai/vcm/handoffs/implementation-log.md
287
287
  vcmctl inbox
288
288
  ```
289
289
 
290
- Durable message and handoff files:
290
+ Runtime message and handoff files:
291
291
 
292
292
  ```text
293
293
  .ai/vcm/messages/<task>.jsonl # under the task runtime repo
294
294
  .ai/vcm/orchestration/<task>.json # under the task runtime repo
295
- .ai/handoffs/<task>/messages/<message-id>.md
296
- .ai/handoffs/<task>/role-commands/
297
- .ai/handoffs/<task>/logs/
295
+ .ai/vcm/handoffs/messages/<message-id>.md
296
+ .ai/vcm/handoffs/role-commands/
297
+ .ai/vcm/handoffs/logs/
298
298
  ```
299
299
 
300
300
  The backend also keeps a compatibility role-command dispatch endpoint, but the primary workflow is PM-mediated `vcmctl` messaging.
@@ -350,17 +350,19 @@ For a connected repository, VCM uses:
350
350
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
351
351
  <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
352
352
  <taskRepoRoot>/.ai/vcm/translation/<task>/
353
- <taskRepoRoot>/.ai/handoffs/<task>/architecture-plan.md
354
- <taskRepoRoot>/.ai/handoffs/<task>/implementation-log.md
355
- <taskRepoRoot>/.ai/handoffs/<task>/validation-log.md
356
- <taskRepoRoot>/.ai/handoffs/<task>/review-report.md
357
- <taskRepoRoot>/.ai/handoffs/<task>/docs-sync-report.md
358
- <taskRepoRoot>/.ai/handoffs/<task>/role-commands/{architect,coder,reviewer}.md
359
- <taskRepoRoot>/.ai/handoffs/<task>/logs/{project-manager,architect,coder,reviewer}.log
353
+ <taskRepoRoot>/.ai/vcm/handoffs/architecture-plan.md
354
+ <taskRepoRoot>/.ai/vcm/handoffs/implementation-log.md
355
+ <taskRepoRoot>/.ai/vcm/handoffs/validation-log.md
356
+ <taskRepoRoot>/.ai/vcm/handoffs/review-report.md
357
+ <taskRepoRoot>/.ai/vcm/handoffs/docs-sync-report.md
358
+ <taskRepoRoot>/.ai/vcm/handoffs/role-commands/{architect,coder,reviewer}.md
359
+ <taskRepoRoot>/.ai/vcm/handoffs/logs/{project-manager,architect,coder,reviewer}.log
360
360
  ```
361
361
 
362
362
  The project config is stored under `~/.vcm` so it is durable local app state and is not hidden inside a Git-ignored repository directory. For worktree-backed tasks, `taskRepoRoot` is `<baseRepoRoot>/.ai/vcm/worktrees/<task>`; for inline tasks, `taskRepoRoot` is the connected base repo.
363
363
 
364
+ Because handoffs are scoped to `taskRepoRoot` without an extra task-name directory, VCM allows only one active inline task per connected repository. Use the default worktree mode for parallel tasks.
365
+
364
366
  ## Packaging
365
367
 
366
368
  The npm package publishes built output, not raw TypeScript entry files. `package.json` includes:
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { ROLE_NAMES } from "../../shared/constants.js";
3
3
  import { VcmError } from "../errors.js";
4
- const DEFAULT_HANDOFF_ROOT = ".ai/handoffs";
4
+ const DEFAULT_HANDOFF_ROOT = ".ai/vcm/handoffs";
5
5
  const DEFAULT_STATE_ROOT = ".ai/vcm";
6
6
  export function createProjectService(deps) {
7
7
  let currentProject = null;
@@ -116,7 +116,7 @@ function normalizeProjectConfig(input, repoRoot) {
116
116
  version: 1,
117
117
  repoRoot,
118
118
  defaultRoles: input.defaultRoles?.length ? input.defaultRoles : fallback.defaultRoles,
119
- handoffRoot: input.handoffRoot || fallback.handoffRoot,
119
+ handoffRoot: DEFAULT_HANDOFF_ROOT,
120
120
  stateRoot: DEFAULT_STATE_ROOT,
121
121
  terminalBackend: "node-pty",
122
122
  claudeCommand: input.claudeCommand || fallback.claudeCommand
@@ -30,6 +30,17 @@ export function createTaskService(deps) {
30
30
  hint: "Apply VCM Harness first so .gitignore contains the VCM managed block."
31
31
  });
32
32
  }
33
+ if (!shouldCreateWorktree) {
34
+ const activeInlineTask = await findActiveInlineTask(deps.fs, repoRoot, config.stateRoot);
35
+ if (activeInlineTask) {
36
+ throw new VcmError({
37
+ code: "INLINE_TASK_EXISTS",
38
+ message: `An inline task already exists: ${activeInlineTask.taskSlug}`,
39
+ statusCode: 409,
40
+ hint: "Close the existing inline task first, or enable Create worktree and branch for this task."
41
+ });
42
+ }
43
+ }
33
44
  if (shouldCreateWorktree && worktreePath) {
34
45
  if (await deps.git.branchExists(repoRoot, taskBranch)) {
35
46
  throw new VcmError({
@@ -75,7 +86,7 @@ export function createTaskService(deps) {
75
86
  repoRoot,
76
87
  worktreePath,
77
88
  branch: taskBranch,
78
- handoffDir: path.posix.join(config.handoffRoot, input.taskSlug),
89
+ handoffDir: config.handoffRoot,
79
90
  status: "created",
80
91
  specPath: input.specPath,
81
92
  cleanupStatus: "active"
@@ -146,7 +157,7 @@ export function createTaskService(deps) {
146
157
  const config = await deps.projectService.loadConfig(repoRoot);
147
158
  const task = await this.loadTask(repoRoot, taskSlug);
148
159
  const taskRepoRoot = getTaskRuntimeRepoRoot(task);
149
- const statePaths = getTaskStatePaths(repoRoot, taskRepoRoot, config.stateRoot, taskSlug);
160
+ const statePaths = getTaskStatePaths(repoRoot, taskRepoRoot, config.stateRoot, config.handoffRoot, taskSlug);
150
161
  const removedStatePaths = [];
151
162
  const cleanedAt = now();
152
163
  if (task.worktreePath) {
@@ -187,13 +198,28 @@ async function ensureTaskRuntimeStateDirs(fs, taskRepoRoot, stateRoot) {
187
198
  await fs.ensureDir(path.join(taskRepoRoot, stateRoot, "orchestration"));
188
199
  await fs.ensureDir(path.join(taskRepoRoot, stateRoot, "translation"));
189
200
  }
190
- function getTaskStatePaths(baseRepoRoot, taskRepoRoot, stateRoot, taskSlug) {
201
+ async function findActiveInlineTask(fs, repoRoot, stateRoot) {
202
+ const tasksDir = path.join(repoRoot, stateRoot, "tasks");
203
+ if (!(await fs.pathExists(tasksDir))) {
204
+ return undefined;
205
+ }
206
+ const entries = await fs.readDir(tasksDir);
207
+ for (const entry of entries.filter((candidate) => candidate.endsWith(".json"))) {
208
+ const task = await fs.readJson(path.join(tasksDir, entry));
209
+ if (!task.worktreePath && task.cleanupStatus !== "cleaned") {
210
+ return task;
211
+ }
212
+ }
213
+ return undefined;
214
+ }
215
+ function getTaskStatePaths(baseRepoRoot, taskRepoRoot, stateRoot, handoffRoot, taskSlug) {
191
216
  return [
192
217
  path.join(baseRepoRoot, stateRoot, "tasks", `${taskSlug}.json`),
193
218
  path.join(taskRepoRoot, stateRoot, "sessions", `${taskSlug}.json`),
194
219
  path.join(taskRepoRoot, stateRoot, "messages", `${taskSlug}.jsonl`),
195
220
  path.join(taskRepoRoot, stateRoot, "orchestration", `${taskSlug}.json`),
196
- path.join(taskRepoRoot, stateRoot, "translation", taskSlug)
221
+ path.join(taskRepoRoot, stateRoot, "translation", taskSlug),
222
+ path.join(taskRepoRoot, handoffRoot)
197
223
  ];
198
224
  }
199
225
  function assertTaskWorktreePath(repoRoot, stateRoot, worktreePath) {
@@ -3,9 +3,9 @@ export function renderRootClaudeHarnessRules() {
3
3
 
4
4
  - This repository uses VibeCodingMaster for multi-session Claude Code work.
5
5
  - User-facing work starts with the project-manager role.
6
- - Canonical task handoffs live under .ai/handoffs/<task-slug>/.
6
+ - Canonical task handoffs live under .ai/vcm/handoffs/ inside the current task runtime repo.
7
7
  - Use only the current task's handoff directory for task-specific artifacts.
8
- - Do not create or write .ai/handoffs/<other-task>/ for the current task.
8
+ - Do not create or write task handoffs outside .ai/vcm/handoffs/ for the current task.
9
9
  - Use vcmctl for role-to-role messaging instead of asking the user to copy prompts.
10
10
  - Non-PM roles only reply to project-manager; they do not message other roles directly.
11
11
  - High-risk decisions involving schema, auth, permissions, payment, billing, security, data deletion, or unclear user intent must stop for project-manager/user approval.
@@ -131,7 +131,7 @@ function printHelp() {
131
131
  Usage:
132
132
  vcmctl send --to coder --type task --body-file /tmp/message.md
133
133
  vcmctl reply --type blocked --body "Need clarification."
134
- vcmctl result --body-file /tmp/result.md --artifact .ai/handoffs/task/implementation-log.md
134
+ vcmctl result --body-file /tmp/result.md --artifact .ai/vcm/handoffs/implementation-log.md
135
135
  vcmctl inbox
136
136
  `);
137
137
  }
@@ -97,13 +97,12 @@ repo/
97
97
 
98
98
  .ai/
99
99
  vcm/ # ignored local VCM control state
100
- task-specs/
101
- handoffs/
102
- <task-slug>/
100
+ handoffs/
103
101
  architecture-plan.md
104
102
  implementation-log.md
105
103
  validation-log.md
106
104
  review-report.md
105
+ task-specs/
107
106
  state/
108
107
  progress.md
109
108
  decisions.md
@@ -213,7 +212,7 @@ Role-specific behavior lives in `.claude/agents/`.
213
212
  - Default core roles are `project-manager`, `architect`, `coder`, and `reviewer`.
214
213
  - The `project-manager` role owns user communication, task routing, role commands, handoff verification, final status reporting, and PR preparation after required gates pass.
215
214
  - Do not let one coding session own architecture/plan decisions, implementation, final testing responsibility, and review.
216
- - Role outputs are exchanged through `.ai/handoffs/<task-slug>/`, not through chat history.
215
+ - Role outputs are exchanged through `.ai/vcm/handoffs/`, not through chat history.
217
216
  - When the required role route includes `architect`, coding must not start until the architecture and plan artifact exists.
218
217
  - If the current session was not started with the required role, stop and ask the user to restart with `claude --agent <role>`; do not pretend to be that role inside the wrong session.
219
218
  - Critical global rules may be repeated in role agent files for defense in depth, but repeated rules must use stable rule IDs and be checked by `tools/check-agent-rules`. Do not maintain untracked manual copies.
@@ -628,7 +627,7 @@ Role command examples:
628
627
  ```text
629
628
  architect command:
630
629
  read the task spec, architecture docs, module map, and relevant module-local CLAUDE.md
631
- produce .ai/handoffs/<task-slug>/architecture-plan.md
630
+ produce .ai/vcm/handoffs/architecture-plan.md
632
631
  define file responsibilities, public contracts, test contracts, phases, validation, and Replan triggers
633
632
  do not edit production code
634
633
 
@@ -726,8 +725,8 @@ architect
726
725
  owns architecture and plan
727
726
  defines module boundaries, file responsibilities, public contracts, dependency direction, risk, and phases
728
727
  owns post-review docs sync and architecture drift checks before PM final acceptance
729
- outputs .ai/handoffs/<task-slug>/architecture-plan.md
730
- outputs .ai/handoffs/<task-slug>/docs-sync-report.md when a post-review docs sync gate is required
728
+ outputs .ai/vcm/handoffs/architecture-plan.md
729
+ outputs .ai/vcm/handoffs/docs-sync-report.md when a post-review docs sync gate is required
731
730
  must not implement production code
732
731
 
733
732
  coder
@@ -743,7 +742,7 @@ reviewer
743
742
  checks, designs, and adds missing tests when needed
744
743
  may directly apply small, local, low-risk review fixes
745
744
  owns complex tests, E2E coverage, regression matrix, and release-level validation recommendations
746
- outputs .ai/handoffs/<task-slug>/review-report.md
745
+ outputs .ai/vcm/handoffs/review-report.md
747
746
  must escalate larger implementation issues to coder
748
747
  must escalate architecture, public contract, design, or documentation drift issues to architect
749
748
  ```
@@ -781,7 +780,7 @@ Role sessions communicate through files, not memory from previous chats.
781
780
  Required handoff directory:
782
781
 
783
782
  ```text
784
- .ai/handoffs/<task-slug>/
783
+ .ai/vcm/handoffs/
785
784
  role-commands/
786
785
  architect.md
787
786
  coder.md
@@ -875,7 +874,7 @@ escalate to architect:
875
874
  the implementation reveals that the architecture plan is invalid
876
875
  ```
877
876
 
878
- For a task with a handoff directory, `.ai/handoffs/<task-slug>/validation-log.md` is the authoritative validation record for that task. `.ai/state/validation-log.md` is only a rolling index of recent validation results across tasks.
877
+ For a task with a handoff directory, `.ai/vcm/handoffs/validation-log.md` is the authoritative validation record for that task. `.ai/state/validation-log.md` is only a rolling index of recent validation results across tasks.
879
878
 
880
879
  For complex or high-risk work, the next role must not start until the required previous artifact exists and is coherent.
881
880
 
@@ -1038,7 +1037,7 @@ You are the architecture and planning role for this project.
1038
1037
 
1039
1038
  # Outputs
1040
1039
 
1041
- - `.ai/handoffs/<task-slug>/architecture-plan.md`
1040
+ - `.ai/vcm/handoffs/architecture-plan.md`
1042
1041
 
1043
1042
  # Do Not
1044
1043
 
@@ -1489,8 +1488,8 @@ Branch rules:
1489
1488
  Close Task rules:
1490
1489
 
1491
1490
  - after task completion, use VCM `Close Task` only when the user is ready to delete task-local state
1492
- - for worktree-backed tasks, `Close Task` deletes the task worktree, deletes the task branch by default, and removes VCM task/session/message/orchestration metadata
1493
- - `Close Task` does not check running role sessions or uncommitted changes; finish, commit, or preserve anything important before using it
1491
+ - for worktree-backed tasks, `Close Task` deletes the task worktree, deletes the task branch by default, and removes VCM task/session/message/orchestration/handoff metadata
1492
+ - `Close Task` stops VCM-managed running role sessions, but it does not check uncommitted changes; finish, commit, or preserve anything important before using it
1494
1493
 
1495
1494
  Small commits:
1496
1495
 
@@ -1613,7 +1612,7 @@ State files:
1613
1612
 
1614
1613
  Validation log authority:
1615
1614
 
1616
- - `.ai/handoffs/<task-slug>/validation-log.md` is authoritative for one task.
1615
+ - `.ai/vcm/handoffs/validation-log.md` is authoritative for one task.
1617
1616
  - `.ai/state/validation-log.md` is a rolling index across tasks and should point to the task-level log when one exists.
1618
1617
  - Final reports and review reports should cite the task-level validation log, not scattered chat output.
1619
1618
 
@@ -1868,7 +1867,7 @@ behavior is correct
1868
1867
  - [ ] For T2+ work, architect performed post-review docs sync / architecture drift check before final PM acceptance.
1869
1868
  - [ ] Docs updates or a docs-sync-report explain why affected architecture/module/testing/security/dependency docs are current.
1870
1869
  - [ ] The project manager prepared final acceptance, commit, and PR only after reviewer and docs-sync gates passed or an exception was approved.
1871
- - [ ] Task-level validation evidence is recorded in `.ai/handoffs/<task-slug>/validation-log.md` when a handoff directory exists.
1870
+ - [ ] Task-level validation evidence is recorded in `.ai/vcm/handoffs/validation-log.md` when a handoff directory exists.
1872
1871
 
1873
1872
  ## Architecture
1874
1873
 
@@ -111,13 +111,14 @@ Task creation flow:
111
111
  New Task submit
112
112
  -> validate task name
113
113
  -> verify .ai/vcm/ is ignored
114
- -> if Create worktree and branch is selected:
115
- -> derive branch feature/<task-name>
116
- -> derive worktree path .ai/vcm/worktrees/<task-name>
117
- -> verify the base repo is clean
118
- -> git worktree add -b feature/<task-name> .ai/vcm/worktrees/<task-name> <base-ref>
119
- -> otherwise:
120
- -> use the connected repo path and current branch
114
+ -> if Create worktree and branch is selected:
115
+ -> derive branch feature/<task-name>
116
+ -> derive worktree path .ai/vcm/worktrees/<task-name>
117
+ -> verify the base repo is clean
118
+ -> git worktree add -b feature/<task-name> .ai/vcm/worktrees/<task-name> <base-ref>
119
+ -> otherwise:
120
+ -> use the connected repo path and current branch
121
+ -> reject if another inline task is already active
121
122
  -> create task metadata
122
123
  -> create handoff structure inside the task runtime repo
123
124
  -> open the task workspace with role session cwd = task runtime repo
@@ -169,8 +170,8 @@ The architect owns:
169
170
 
170
171
  Outputs:
171
172
 
172
- - `.ai/handoffs/<task>/architecture-plan.md`
173
- - `.ai/handoffs/<task>/docs-sync-report.md`
173
+ - `.ai/vcm/handoffs/architecture-plan.md`
174
+ - `.ai/vcm/handoffs/docs-sync-report.md`
174
175
 
175
176
  ### Coder
176
177
 
@@ -183,8 +184,8 @@ The coder owns:
183
184
 
184
185
  Outputs:
185
186
 
186
- - `.ai/handoffs/<task>/implementation-log.md`
187
- - `.ai/handoffs/<task>/validation-log.md`
187
+ - `.ai/vcm/handoffs/implementation-log.md`
188
+ - `.ai/vcm/handoffs/validation-log.md`
188
189
 
189
190
  ### Reviewer
190
191
 
@@ -198,7 +199,7 @@ The reviewer owns:
198
199
 
199
200
  Output:
200
201
 
201
- - `.ai/handoffs/<task>/review-report.md`
202
+ - `.ai/vcm/handoffs/review-report.md`
202
203
 
203
204
  ## 6. Information Architecture
204
205
 
@@ -393,7 +394,7 @@ Role sessions get VCM behavior from `CLAUDE.md` and `.claude/agents/*.md`, not f
393
394
  Each task creates:
394
395
 
395
396
  ```text
396
- .ai/handoffs/<task>/
397
+ .ai/vcm/handoffs/
397
398
  role-commands/
398
399
  architect.md
399
400
  coder.md
@@ -412,7 +413,7 @@ Each task creates:
412
413
  <message-id>.md
413
414
  ```
414
415
 
415
- The product treats handoff files as durable facts. The terminal is useful for live interaction, but handoff files and message history are what survive task handoffs cleanly.
416
+ The product treats handoff files as task-local coordination facts. The terminal is useful for live interaction, but handoff files and message history are the source of truth during a task. They live under `.ai/vcm/`, are ignored by Git, and are removed by `Close Task`; final decisions that should survive must be copied into normal project docs, source, commit messages, or PR text.
416
417
 
417
418
  The main UI no longer has a dedicated artifact panel. Artifact APIs still exist for status checks, role command compatibility, and future UI work.
418
419
 
@@ -584,10 +585,10 @@ Task worktree local files:
584
585
  .ai/vcm/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
585
586
  .ai/vcm/worktrees/<task>/.ai/vcm/orchestration/<task>.json
586
587
  .ai/vcm/worktrees/<task>/.ai/vcm/translation/<task>/
587
- .ai/vcm/worktrees/<task>/.ai/handoffs/<task>/
588
+ .ai/vcm/worktrees/<task>/.ai/vcm/handoffs/
588
589
  ```
589
590
 
590
- For tasks created without a worktree, the task runtime repo is the connected base repo, so the runtime state resolves under the base repo's `.ai/vcm/`.
591
+ For tasks created without a worktree, the task runtime repo is the connected base repo, so the runtime state resolves under the base repo's `.ai/vcm/`. Because `.ai/vcm/handoffs/` has no task-name segment, VCM allows only one active inline task in a connected repo.
591
592
 
592
593
  External Claude transcripts:
593
594
 
@@ -28,7 +28,7 @@ browser
28
28
  -> claude --agent <role>
29
29
  ```
30
30
 
31
- The app is local-first. It writes project control state under `.ai/vcm/`, handoff artifacts under `.ai/handoffs/` inside the active task worktree, app settings under `~/.vcm/settings.json`, and reads Claude transcript files under `~/.claude/projects/`.
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
32
 
33
33
  ## 2. Processes And Ports
34
34
 
@@ -295,11 +295,13 @@ Task runtime state, source changes, and handoff artifacts live in the task runti
295
295
  <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/messages/<task>.jsonl
296
296
  <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/orchestration/<task>.json
297
297
  <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/translation/<task>/
298
- <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/handoffs/<task>/
298
+ <baseRepoRoot>/.ai/vcm/worktrees/<task>/.ai/vcm/handoffs/
299
299
  ```
300
300
 
301
301
  For inline tasks, `taskRepoRoot` is the connected base repo, so these same runtime paths resolve under the connected repo's `.ai/vcm/`.
302
302
 
303
+ 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.
304
+
303
305
  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.
304
306
 
305
307
  ### 6.2 Git Ignore Requirement
@@ -327,9 +329,10 @@ POST /api/tasks
327
329
  -> assert worktreePath does not already exist
328
330
  -> assert base repo has no uncommitted changes
329
331
  -> git worktree add -b feature/<taskSlug> <worktreePath> <baseRef>
330
- -> otherwise:
331
- -> read current base repo branch
332
- -> leave worktreePath undefined
332
+ -> otherwise:
333
+ -> read current base repo branch
334
+ -> leave worktreePath undefined
335
+ -> reject when another inline task is already active
333
336
  -> create handoff structure in taskRepoRoot
334
337
  -> write central task metadata under baseRepoRoot/.ai/vcm/tasks/<task>.json
335
338
  ```
@@ -349,6 +352,7 @@ POST /api/tasks/:taskSlug/cleanup
349
352
  -> when worktreePath exists, delete the task branch by default
350
353
  -> delete base task metadata
351
354
  -> delete task runtime session/message/orchestration/translation metadata
355
+ -> delete task runtime handoff directory
352
356
  ```
353
357
 
354
358
  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.
@@ -396,7 +400,7 @@ Task cleanup is orchestrated by `src/backend/api/task-routes.ts` because it coor
396
400
  Handoff directory:
397
401
 
398
402
  ```text
399
- <taskRepoRoot>/.ai/handoffs/<task>/
403
+ <taskRepoRoot>/.ai/vcm/handoffs/
400
404
  role-commands/
401
405
  architect.md
402
406
  coder.md
@@ -528,7 +532,7 @@ The runtime:
528
532
  - spawns `node-pty`
529
533
  - sets `TERM=xterm-256color`
530
534
  - sets color-friendly env vars
531
- - appends raw PTY output to `<taskRepoRoot>/.ai/handoffs/<task>/logs/<role>.log`
535
+ - appends raw PTY output to `<taskRepoRoot>/.ai/vcm/handoffs/logs/<role>.log`
532
536
  - emits terminal output/input/exit events to WebSocket subscribers
533
537
  - replays the log on terminal WebSocket subscribe
534
538
 
@@ -562,7 +566,7 @@ State:
562
566
  ```text
563
567
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
564
568
  <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
565
- <taskRepoRoot>/.ai/handoffs/<task>/messages/<message-id>.md
569
+ <taskRepoRoot>/.ai/vcm/handoffs/messages/<message-id>.md
566
570
  ```
567
571
 
568
572
  Policy:
@@ -928,7 +932,7 @@ Current boundaries:
928
932
  - Translation API key is local in `~/.vcm/settings.json`.
929
933
  - Translation output is UI/runtime state only unless a user or role copies it into a file.
930
934
  - `.ai/vcm` is local project control state and must be ignored by Git.
931
- - Task handoff artifacts live in the task worktree and users should decide whether those artifacts belong in task commits.
935
+ - 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.
932
936
  - Task worktrees are created only during task creation; VCM does not expose branch/worktree switching APIs.
933
937
  - Sandbox isolation should come from a devContainer, Docker container, VM, or other user-controlled environment.
934
938
 
@@ -17,7 +17,7 @@ V1 is implemented as a local GUI app with:
17
17
  - API-driven message bus.
18
18
  - Translation panel based on Claude transcript JSONL tailing.
19
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 by default; users may clear `Create worktree and branch` to create an inline task in the connected repository/current branch.
20
+ - Task creation creates one `feature/<task>` branch and one `.ai/vcm/worktrees/<task>` git worktree by default; users may clear `Create worktree and branch` to create an inline task in the connected repository/current branch. Because handoffs are scoped as `.ai/vcm/handoffs/` under the task runtime repo, only one active inline task is allowed per connected repository.
21
21
 
22
22
  ## 2. Package And Build
23
23
 
@@ -210,7 +210,7 @@ Worktree fields:
210
210
  - `cleanupStatus?: "active" | "cleaned"`
211
211
  - `cleanedAt?: string`
212
212
 
213
- `CreateTaskRequest` supports `createWorktree?: boolean`. It creates a worktree and branch by default, and skips both when `createWorktree === false`.
213
+ `CreateTaskRequest` supports `createWorktree?: boolean`. It creates a worktree and branch by default, and skips both when `createWorktree === false`. Inline creation rejects a second active inline task in the same connected repository.
214
214
 
215
215
  ### `src/shared/types/session.ts`
216
216
 
@@ -546,10 +546,11 @@ createTask(baseRepoRoot, { taskSlug })
546
546
  -> assert worktree path does not exist
547
547
  -> git.createWorktree({ baseRepoRoot, branch, worktreePath, baseRef: HEAD })
548
548
  -> taskRepoRoot = worktreePath
549
- -> otherwise:
550
- -> branch = current base repo branch
551
- -> worktreePath = undefined
552
- -> taskRepoRoot = baseRepoRoot
549
+ -> otherwise:
550
+ -> branch = current base repo branch
551
+ -> worktreePath = undefined
552
+ -> taskRepoRoot = baseRepoRoot
553
+ -> reject if another inline task is already active
553
554
  -> artifactService.ensureHandoffStructure({ repoRoot: taskRepoRoot, handoffDir })
554
555
  -> artifactService.createArtifactTemplates({ repoRoot: taskRepoRoot, handoffDir })
555
556
  -> ensure task runtime state dirs under <taskRepoRoot>/.ai/vcm/
@@ -567,7 +568,8 @@ cleanupTask(baseRepoRoot, taskSlug, options)
567
568
  -> if worktreePath exists, verify it is under <baseRepoRoot>/.ai/vcm/worktrees/
568
569
  -> if worktreePath exists, git.removeWorktree(baseRepoRoot, worktreePath, force=true)
569
570
  -> if worktreePath exists, git.deleteBranch(baseRepoRoot, task.branch, force=true) by default
570
- -> delete <baseRepoRoot>/.ai/vcm/tasks/<task>.json
571
+ -> delete <baseRepoRoot>/.ai/vcm/tasks/<task>.json
572
+ -> delete <taskRepoRoot>/.ai/vcm/handoffs/
571
573
  -> delete <taskRepoRoot>/.ai/vcm/sessions/<task>.json
572
574
  -> delete <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
573
575
  -> delete <taskRepoRoot>/.ai/vcm/orchestration/<task>.json
@@ -599,13 +601,13 @@ In task-worktree mode, artifact paths are still repo-relative, but `repoRoot` mu
599
601
  Primary role command path:
600
602
 
601
603
  ```text
602
- .ai/handoffs/<task>/role-commands/<role>.md
604
+ .ai/vcm/handoffs/role-commands/<role>.md
603
605
  ```
604
606
 
605
607
  Legacy fallback:
606
608
 
607
609
  ```text
608
- .ai/handoffs/<task>/role-commands/<role>-command.md
610
+ .ai/vcm/handoffs/role-commands/<role>-command.md
609
611
  ```
610
612
 
611
613
  ### `src/backend/services/status-service.ts`
@@ -682,7 +684,7 @@ In task-worktree mode:
682
684
 
683
685
  - message snapshots live under `task.worktreePath/.ai/vcm/messages`
684
686
  - orchestration state lives under `task.worktreePath/.ai/vcm/orchestration`
685
- - message body files live under `task.worktreePath/.ai/handoffs/<task>/messages`
687
+ - message body files live under `task.worktreePath/.ai/vcm/handoffs/messages`
686
688
  - terminal delivery uses the runtime session for the role, whose cwd is the task worktree
687
689
 
688
690
  ### `src/backend/services/command-dispatcher.ts`
@@ -1196,7 +1198,7 @@ Messages:
1196
1198
 
1197
1199
  ```text
1198
1200
  <taskRepoRoot>/.ai/vcm/messages/<task>.jsonl
1199
- <taskRepoRoot>/.ai/handoffs/<task>/messages/<message-id>.md
1201
+ <taskRepoRoot>/.ai/vcm/handoffs/messages/<message-id>.md
1200
1202
  ```
1201
1203
 
1202
1204
  Orchestration:
@@ -1220,7 +1222,7 @@ Task worktrees:
1220
1222
  Handoff artifacts:
1221
1223
 
1222
1224
  ```text
1223
- .ai/handoffs/<task>/
1225
+ .ai/vcm/handoffs/
1224
1226
  ```
1225
1227
 
1226
1228
  Claude transcripts:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-coding-master",
3
- "version": "0.0.11",
3
+ "version": "0.0.12",
4
4
  "description": "Local GUI session cockpit for Claude Code role sessions.",
5
5
  "type": "module",
6
6
  "files": [