vibe-coding-master 0.6.22 → 0.6.23

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.
@@ -97,6 +97,28 @@ export function createClaudeHookService(deps) {
97
97
  transcriptPath: stringOrUndefined(input.event.transcript_path),
98
98
  cwd: stringOrUndefined(input.event.cwd) ?? stringOrUndefined(input.event.new_cwd)
99
99
  });
100
+ const activeTask = deps.autoMemoryService
101
+ ? (await deps.taskService.listTasks(context.project.repoRoot))
102
+ .find((task) => task.cleanupStatus !== "cleaned")
103
+ : undefined;
104
+ const memoryHandled = activeTask
105
+ ? await deps.autoMemoryService?.handleHarnessEngineerHook({
106
+ baseRepoRoot: context.project.repoRoot,
107
+ taskRepoRoot: getTaskRuntimeRepoRoot(activeTask),
108
+ taskSlug: activeTask.taskSlug,
109
+ eventName
110
+ })
111
+ : false;
112
+ if (memoryHandled) {
113
+ return {
114
+ ok: true,
115
+ eventName,
116
+ taskSlug: activeTask?.taskSlug ?? input.taskSlug,
117
+ role: input.role,
118
+ sessionUpdated: Boolean(session),
119
+ dispatchedCount: 0
120
+ };
121
+ }
100
122
  await deps.harnessService?.recordHarnessBootstrapHook(context.project.repoRoot, {
101
123
  eventName,
102
124
  sessionId: session?.id,
@@ -131,6 +153,10 @@ export function createClaudeHookService(deps) {
131
153
  throwUnsupportedEvent(eventName);
132
154
  }
133
155
  const context = await getHookContext(input);
156
+ const memoryResult = await processAutoMemoryRoleHook(input, context, eventName);
157
+ if (memoryResult) {
158
+ return memoryResult;
159
+ }
134
160
  const boundToTask = await isHookSessionBoundToTask(context, input.role);
135
161
  if (boundToTask) {
136
162
  deps.jobGuard?.notePromptSubmitted({
@@ -194,6 +220,10 @@ export function createClaudeHookService(deps) {
194
220
  throwUnsupportedEvent(eventName);
195
221
  }
196
222
  const context = await getHookContext(input);
223
+ const memoryResult = await processAutoMemoryRoleHook(input, context, eventName);
224
+ if (memoryResult) {
225
+ return memoryResult;
226
+ }
197
227
  await clearStopFailureRecoveryState(context, input.role);
198
228
  if (options.allowBlock && deps.jobGuard) {
199
229
  const verdict = await deps.jobGuard.evaluateStop({
@@ -228,6 +258,10 @@ export function createClaudeHookService(deps) {
228
258
  throwUnsupportedEvent(eventName);
229
259
  }
230
260
  const context = await getHookContext(input);
261
+ const memoryResult = await processAutoMemoryRoleHook(input, context, eventName);
262
+ if (memoryResult) {
263
+ return memoryResult;
264
+ }
231
265
  const routeDispatchInput = createRouteDispatchInput(input, context);
232
266
  const pending = await deps.messageService.listPendingRouteFiles(routeDispatchInput);
233
267
  const hasCompletionEvidence = pending.some((routeFile) => routeFile.fromRole === input.role);
@@ -284,6 +318,10 @@ export function createClaudeHookService(deps) {
284
318
  throwUnsupportedEvent(eventName);
285
319
  }
286
320
  const context = await getHookContext(input);
321
+ const memoryResult = await processAutoMemoryRoleHook(input, context, eventName);
322
+ if (memoryResult) {
323
+ return memoryResult;
324
+ }
287
325
  const session = await deps.sessionService.recordClaudeHookEvent(context.project.repoRoot, {
288
326
  taskSlug: context.taskSlug,
289
327
  role: input.role,
@@ -380,6 +418,34 @@ export function createClaudeHookService(deps) {
380
418
  dispatchedCount: dispatched.filter((result) => result.delivered).length
381
419
  };
382
420
  }
421
+ async function processAutoMemoryRoleHook(input, context, eventName) {
422
+ if (!deps.autoMemoryService || !(await deps.autoMemoryService.isRoleMemoryTurn(context.taskRepoRoot, input.role))) {
423
+ return undefined;
424
+ }
425
+ const session = await deps.sessionService.recordClaudeHookEvent(context.project.repoRoot, {
426
+ taskSlug: context.taskSlug,
427
+ role: input.role,
428
+ eventName,
429
+ claudeSessionId: stringOrUndefined(input.event.session_id),
430
+ transcriptPath: stringOrUndefined(input.event.transcript_path),
431
+ cwd: stringOrUndefined(input.event.cwd) ?? stringOrUndefined(input.event.new_cwd)
432
+ });
433
+ await deps.autoMemoryService.handleRoleHook({
434
+ baseRepoRoot: context.project.repoRoot,
435
+ taskRepoRoot: context.taskRepoRoot,
436
+ taskSlug: context.taskSlug,
437
+ role: input.role,
438
+ eventName
439
+ });
440
+ return {
441
+ ok: true,
442
+ eventName,
443
+ taskSlug: context.taskSlug,
444
+ role: input.role,
445
+ sessionUpdated: Boolean(session),
446
+ dispatchedCount: 0
447
+ };
448
+ }
383
449
  function createRouteDispatchInput(input, context, stoppedRole) {
384
450
  return {
385
451
  repoRoot: context.project.repoRoot,
@@ -55,8 +55,12 @@ export function createRuntimeCoordinatorService(deps) {
55
55
  else {
56
56
  await deps.translationService.stopTask(taskRepoRoot, activeTask.taskSlug).catch(() => undefined);
57
57
  }
58
+ await reconcileAutoMemory(repoRoot, activeTask);
58
59
  if (preferences.autoTaskHarnessReviewEnabled) {
59
- await maybeStartTaskHarnessRetrospective(repoRoot, activeTask);
60
+ const memoryReadiness = await getTaskRetrospectiveMemoryReadiness(repoRoot, activeTask);
61
+ if (memoryReadiness.ready) {
62
+ await maybeStartTaskHarnessRetrospective(repoRoot, activeTask);
63
+ }
60
64
  }
61
65
  return { activeTask, gatewayStatus };
62
66
  });
@@ -159,4 +163,33 @@ export function createRuntimeCoordinatorService(deps) {
159
163
  throw error;
160
164
  }
161
165
  }
166
+ async function reconcileAutoMemory(repoRoot, task) {
167
+ const stateRoot = await deps.getStateRoot(repoRoot);
168
+ const taskRepoRoot = getTaskRuntimeRepoRoot(task);
169
+ const roundState = await deps.roundService.getSessionRoundState({
170
+ repoRoot,
171
+ stateRepoRoot: taskRepoRoot,
172
+ stateRoot,
173
+ taskSlug: task.taskSlug
174
+ });
175
+ return deps.autoMemoryService.reconcileTask({
176
+ baseRepoRoot: repoRoot,
177
+ taskRepoRoot,
178
+ taskSlug: task.taskSlug,
179
+ handoffDir: task.handoffDir,
180
+ roundReady: roundState.status === "stopped"
181
+ && Boolean(roundState.roundId)
182
+ && roundState.roleRecovery?.status !== "failed"
183
+ });
184
+ }
185
+ async function getTaskRetrospectiveMemoryReadiness(repoRoot, task) {
186
+ const taskRepoRoot = getTaskRuntimeRepoRoot(task);
187
+ return deps.autoMemoryService.getTaskRetrospectiveReadiness({
188
+ baseRepoRoot: repoRoot,
189
+ taskRepoRoot,
190
+ taskSlug: task.taskSlug,
191
+ handoffDir: task.handoffDir,
192
+ roundReady: true
193
+ });
194
+ }
162
195
  }
@@ -3,6 +3,7 @@ import { VCM_ROLE_NAMES, isDispatchableRole } from "../../shared/constants.js";
3
3
  import { VcmError } from "../errors.js";
4
4
  import { resolveRepoPath } from "../adapters/filesystem.js";
5
5
  import { submitTerminalInput } from "../runtime/terminal-submit.js";
6
+ import { ensureTaskMemorySnapshot } from "./auto-memory-service.js";
6
7
  import { claudeTranscriptPath } from "./claude-transcript-service.js";
7
8
  import { readHarnessRevisionState } from "./harness-revision.js";
8
9
  import { getTaskRuntimeRepoRoot } from "./task-service.js";
@@ -49,6 +50,7 @@ export function createSessionService(deps) {
49
50
  const config = await deps.projectService.loadConfig(repoRoot);
50
51
  const task = await deps.taskService.loadTask(repoRoot, taskSlug);
51
52
  const taskRepoRoot = getTaskRuntimeRepoRoot(task);
53
+ await ensureTaskMemorySnapshot(deps.fs, repoRoot, taskRepoRoot);
52
54
  const paths = deps.artifactService.getHandoffPaths(taskRepoRoot, task.handoffDir);
53
55
  const persisted = await loadPersistedRoleRecordForRole(deps.fs, repoRoot, taskRepoRoot, config.stateRoot, taskSlug, role);
54
56
  const permissionMode = normalizeClaudePermissionMode(input.permissionMode ?? persisted?.permissionMode);
@@ -235,6 +237,7 @@ export function createSessionService(deps) {
235
237
  }
236
238
  async function launchProjectHarnessEngineerSession(repoRoot, input, launchMode) {
237
239
  const taskContext = await resolveProjectToolTaskContext(repoRoot, input, "Harness Engineer");
240
+ await ensureTaskMemorySnapshot(deps.fs, repoRoot, taskContext.taskRepoRoot);
238
241
  const live = toRoleSessionRecordView(getRegisteredProjectHarnessEngineerSession(deps.registry, deps.runtime), deps.runtime);
239
242
  if (live && live.status === "running") {
240
243
  return withHarnessRevisionView(repoRoot, await migrateRunningProjectToolSessionCwd(repoRoot, live, taskContext.taskRepoRoot));
@@ -1,7 +1,10 @@
1
+ import { renderRoleMemoryRules } from "./role-memory.js";
1
2
  export function renderArchitectHarnessRules() {
2
3
  return `
3
4
  ## VCM Architect Rules
4
5
 
6
+ ${renderRoleMemoryRules("architect")}
7
+
5
8
  ### Role Scope
6
9
 
7
10
  - Own technical analysis, architecture planning, module boundaries, file-level responsibilities, cross-file callable surfaces, public contracts, verifiable behavior, implementation boundaries within the accepted scope, behavior/contract proof points, risks, and architect-owned replan decisions.
@@ -1,5 +1,7 @@
1
1
  export function renderRootClaudeHarnessRules() {
2
- return `## VCM Start Here
2
+ return `@.ai/vcm/memory/shared.md
3
+
4
+ ## VCM Start Here
3
5
 
4
6
  - Use the durable project docs below as role-relevant project truth.
5
7
  - Read module-local \`CLAUDE.md\` before editing a subdirectory if one exists.
@@ -1,7 +1,10 @@
1
+ import { renderRoleMemoryRules } from "./role-memory.js";
1
2
  export function renderCoderHarnessRules() {
2
3
  return `
3
4
  ## VCM Coder Rules
4
5
 
6
+ ${renderRoleMemoryRules("coder")}
7
+
5
8
  ### Role Scope
6
9
 
7
10
  - Own function-level implementation and baseline implementation tests inside the approved task scope, role message, and architecture plan.
@@ -1,8 +1,11 @@
1
+ import { renderRoleMemoryRules } from "./role-memory.js";
1
2
  export function renderGateReviewerAgentRules() {
2
3
  return `## Role
3
4
 
4
5
  You are VCM \`gate-reviewer\`.
5
6
 
7
+ ${renderRoleMemoryRules("gate-reviewer")}
8
+
6
9
  Review only the gate in the VCM prompt. Use the task and worktree paths named there. Project memory may orient you, but only current worktree evidence can decide the gate.
7
10
 
8
11
  Use only these decisions:
@@ -1,3 +1,4 @@
1
+ import { renderRoleMemoryRules } from "./role-memory.js";
1
2
  export function renderHarnessEngineerHarnessRules() {
2
3
  return `## Role
3
4
 
@@ -7,6 +8,8 @@ Maintain and improve this repository's VCM harness. Understand both VCM fixed
7
8
  harness rules and project-specific harness customization before proposing any
8
9
  change.
9
10
 
11
+ ${renderRoleMemoryRules("harness-engineer")}
12
+
10
13
  ## Scope
11
14
 
12
15
  You may inspect:
@@ -22,7 +25,8 @@ You may inspect:
22
25
  \`docs/known-issues.md\`
23
26
  - task evidence such as handoffs, route messages, commits, commit diffs,
24
27
  generated context, validation reports, Gate Review reports, final acceptance
25
- artifacts, and user corrections
28
+ artifacts, memory drafts and diffs under .ai/vcm/memory-review, current memory
29
+ under .ai/vcm/memory, and user corrections
26
30
 
27
31
  You are not part of the task workflow round state.
28
32
 
@@ -33,18 +37,21 @@ You are not part of the task workflow round state.
33
37
  - Bootstrap Apply Mode: when VCM explicitly asks for bootstrap apply work, make
34
38
  permitted bootstrap edits directly in the active task worktree and commit them
35
39
  yourself.
36
- - Retrospective Mode: analyze a completed task for reusable harness problems. Do
37
- not edit files.
40
+ - Retrospective Mode: analyze a completed task for reusable harness problems.
41
+ Do not edit harness files; proven repeated findings may update VCM memory.
42
+ - Memory Review Mode: review role memory drafts or proven retrospective memory
43
+ findings and write only the memory files assigned by VCM.
38
44
  - VCM Feedback Mode: draft VCM product, installer, UI, or fixed-template issue
39
45
  feedback. Do not submit without explicit in-session user authorization.
40
46
 
41
47
  ## Change Policy
42
48
 
43
- - Apply edits only in Bootstrap Apply Mode or when VCM explicitly asks you to
44
- apply an approved harness change.
49
+ - Apply edits only in Bootstrap Apply Mode, Memory Review Mode, or when VCM
50
+ explicitly asks you to apply an approved harness change.
45
51
  - When applying edits, work only in the active task worktree named by VCM. Do not
46
52
  edit the base repository root unless VCM explicitly says so.
47
- - In Proposal Mode and Retrospective Mode, do not edit files.
53
+ - In Proposal Mode, do not edit files. In Retrospective Mode, do not edit
54
+ harness files; only the memory exception above may write files.
48
55
  - Commit every applied harness change yourself before ending your turn.
49
56
  - Do not overwrite VCM fixed managed blocks.
50
57
  - Keep project-specific customization outside VCM managed blocks.
@@ -54,6 +61,22 @@ You are not part of the task workflow round state.
54
61
  validation recommendations with every proposal.
55
62
  - Do not edit production source code as part of harness maintenance.
56
63
 
64
+ ## Memory Management
65
+
66
+ - Own VCM-managed project memory under \`.ai/vcm/memory/**\`.
67
+ - During an Auto Memory review, verify role drafts against task evidence, merge
68
+ duplicates, remove stale entries, and keep role-specific knowledge in the
69
+ matching role memory file.
70
+ - Keep task narrative, temporary state, unverified conclusions, and harness
71
+ rules out of memory.
72
+ - A repeated problem confirmed by Task Harness Retrospective may become memory
73
+ without collecting new role drafts.
74
+ - For a direct user-requested memory correction, edit the current task
75
+ worktree's assigned memory file; VCM records and applies the change when the
76
+ turn stops.
77
+ - When VCM assigns review output paths, edit only those paths. VCM applies the
78
+ reviewed memory and records the diff.
79
+
57
80
  ## Task Harness Retrospective
58
81
 
59
82
  After a complete code-change flow passes Final Acceptance, you may be asked to
@@ -67,7 +90,8 @@ complete correctly.
67
90
  Inspect the active task worktree as needed. Useful evidence may include
68
91
  handoffs, route messages, commits, commit diffs, durable docs, generated
69
92
  context, validation reports, Gate Review reports, final acceptance artifacts,
70
- and user corrections during the task.
93
+ memory drafts, applied memory diffs, current memory, and user corrections during
94
+ the task.
71
95
 
72
96
  For each finding, decide whether it is:
73
97
 
@@ -79,7 +103,7 @@ Do not create new rules from weak evidence, one-off execution mistakes, or role
79
103
  behavior that existing harness rules already cover. If no reusable harness
80
104
  problem is proven, say so clearly.
81
105
 
82
- Do not edit files during retrospective analysis. Write a concise analysis with:
106
+ Do not edit harness files during retrospective analysis. Write a concise analysis with:
83
107
 
84
108
  - finding
85
109
  - evidence
@@ -1,7 +1,10 @@
1
+ import { renderRoleMemoryRules } from "./role-memory.js";
1
2
  export function renderProjectManagerHarnessRules() {
2
3
  return `
3
4
  ## VCM Project Manager Rules
4
5
 
6
+ ${renderRoleMemoryRules("project-manager")}
7
+
5
8
  ### Role Scope
6
9
 
7
10
  - You are the user-facing orchestration hub for this VCM-managed repository.
@@ -0,0 +1,9 @@
1
+ export function renderRoleMemoryRules(role) {
2
+ return `### Role Memory
3
+
4
+ Before handling work in a session, read \`.ai/vcm/memory/roles/${role}.md\`.
5
+ Read it again after context compaction before continuing.
6
+
7
+ Treat memory as accumulated project context, not authority. Verify it against
8
+ current code, documentation, and task evidence.`;
9
+ }
@@ -1,7 +1,10 @@
1
+ import { renderRoleMemoryRules } from "./role-memory.js";
1
2
  export function renderTesterHarnessRules() {
2
3
  return `
3
4
  ## VCM Tester Rules
4
5
 
6
+ ${renderRoleMemoryRules("tester")}
7
+
5
8
  ### Role Scope
6
9
 
7
10
  - Own independent validation, tester-owned test design, test implementation, test adequacy, \`docs/TESTING.md\`, and final validation confidence.
@@ -0,0 +1,8 @@
1
+ export const VCM_MEMORY_ROLE_NAMES = [
2
+ "project-manager",
3
+ "architect",
4
+ "coder",
5
+ "tester",
6
+ "gate-reviewer",
7
+ "harness-engineer"
8
+ ];