vibe-coding-master 0.6.20 → 0.6.22

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 (41) hide show
  1. package/README.md +5 -5
  2. package/dist/backend/api/artifact-routes.js +2 -2
  3. package/dist/backend/api/gate-review-routes.js +1 -1
  4. package/dist/backend/api/task-routes.js +1 -1
  5. package/dist/backend/cli/install-vcm-harness.js +66 -20
  6. package/dist/backend/services/app-settings-service.js +11 -2
  7. package/dist/backend/services/artifact-service.js +9 -8
  8. package/dist/backend/services/gate-review-service.js +322 -24
  9. package/dist/backend/services/harness-feedback-service.js +8 -3
  10. package/dist/backend/services/harness-service.js +100 -13
  11. package/dist/backend/services/job-guard-service.js +2 -2
  12. package/dist/backend/services/message-service.js +12 -0
  13. package/dist/backend/services/session-service.js +18 -11
  14. package/dist/backend/services/status-service.js +1 -4
  15. package/dist/backend/templates/handoff.js +105 -17
  16. package/dist/backend/templates/harness/architect-agent.js +110 -49
  17. package/dist/backend/templates/harness/claude-root.js +45 -15
  18. package/dist/backend/templates/harness/coder-agent.js +66 -47
  19. package/dist/backend/templates/harness/coder-worker-agent.js +45 -17
  20. package/dist/backend/templates/harness/gate-review.js +237 -39
  21. package/dist/backend/templates/harness/harness-engineer-agent.js +39 -12
  22. package/dist/backend/templates/harness/project-coding-standards.js +73 -0
  23. package/dist/backend/templates/harness/project-glossary.js +30 -0
  24. package/dist/backend/templates/harness/project-known-issues.js +33 -0
  25. package/dist/backend/templates/harness/project-manager-agent.js +103 -34
  26. package/dist/backend/templates/harness/pull-request-template.js +6 -4
  27. package/dist/backend/templates/harness/tester-agent.js +82 -0
  28. package/dist/backend/templates/harness/vcm-final-acceptance-skill.js +22 -17
  29. package/dist/backend/templates/harness/vcm-harness-bootstrap-skill.js +19 -2
  30. package/dist/backend/templates/harness/vcm-long-running-validation-skill.js +1 -1
  31. package/dist/backend/templates/harness/vcm-report-harness-issue-skill.js +18 -12
  32. package/dist/backend/templates/harness/vcm-route-message-skill.js +48 -8
  33. package/dist/backend/templates/message-envelope.js +2 -5
  34. package/dist/shared/constants.js +3 -3
  35. package/dist/shared/types/gate-review.js +6 -1
  36. package/dist/shared/validation/artifact-check.js +64 -10
  37. package/dist-frontend/assets/{index-C5E5jLp-.js → index-DYBg_qYS.js} +4 -4
  38. package/dist-frontend/index.html +1 -1
  39. package/package.json +1 -1
  40. package/scripts/verify-package.mjs +1 -1
  41. package/dist/backend/templates/harness/reviewer-agent.js +0 -60
package/README.md CHANGED
@@ -8,7 +8,7 @@ VCM helps you keep one task organized across dedicated roles:
8
8
  - Project Manager
9
9
  - Architect
10
10
  - Coder
11
- - Reviewer
11
+ - Tester
12
12
  - optional Gate Reviewer
13
13
 
14
14
  It runs locally, connects to a local Git repository, creates a task branch and
@@ -133,7 +133,7 @@ If you want VCM app state to survive container rebuilds, set:
133
133
  7. Review the harness/bootstrap commit diff.
134
134
  8. Start the role sessions, or use the saved launch template / one-click start.
135
135
  9. Talk mostly to Project Manager.
136
- 10. Let PM route work to Architect, Coder, Reviewer, and Gate Reviewer when
136
+ 10. Let PM route work to Architect, Coder, Tester, and Gate Reviewer when
137
137
  enabled.
138
138
  11. Review the final result and close the task when finished.
139
139
 
@@ -187,7 +187,7 @@ Typical flow:
187
187
  Project Manager
188
188
  -> Architect
189
189
  -> Coder
190
- -> Reviewer
190
+ -> Tester
191
191
  -> Architect docs sync
192
192
  -> Project Manager final acceptance
193
193
  ```
@@ -264,7 +264,7 @@ Available gates:
264
264
 
265
265
  - Architecture plan
266
266
  - Validation adequacy
267
- - Final diff
267
+ - Code diff
268
268
 
269
269
  When a gate is enabled, VCM uses Gate Reviewer as an independent review role.
270
270
  Gate Reviewer reviews artifacts and diffs, writes a gate report, and returns
@@ -337,7 +337,7 @@ Gateway can:
337
337
  - translate mobile messages when Gateway translation is enabled
338
338
 
339
339
  Gateway does not expose the embedded terminal and does not send directly to
340
- Architect, Coder, Reviewer, or Gate Reviewer.
340
+ Architect, Coder, Tester, or Gate Reviewer.
341
341
 
342
342
  Common commands:
343
343
 
@@ -70,8 +70,8 @@ function artifactNameToPath(paths, artifactName) {
70
70
  if (artifactName === "known-issues.md") {
71
71
  return paths.knownIssuesPath;
72
72
  }
73
- if (artifactName === "review-report.md") {
74
- return paths.reviewReportPath;
73
+ if (artifactName === "test-report.md") {
74
+ return paths.testReportPath;
75
75
  }
76
76
  if (artifactName === "docs-sync-report.md") {
77
77
  return paths.docsSyncReportPath;
@@ -12,7 +12,7 @@ export function registerGateReviewRoutes(app, deps) {
12
12
  app.post("/api/tasks/:taskSlug/gate-review/:gate/request", async (request) => {
13
13
  const project = await requireCurrentProject(deps.projectService);
14
14
  const gate = parseGate(request.params.gate);
15
- return deps.gateReviewService.requestReviewGate(project.repoRoot, request.params.taskSlug, gate);
15
+ return deps.gateReviewService.requestReviewGate(project.repoRoot, request.params.taskSlug, gate, request.body);
16
16
  });
17
17
  app.post("/api/tasks/:taskSlug/gate-review/:gate/retry", async (request) => {
18
18
  const project = await requireCurrentProject(deps.projectService);
@@ -196,7 +196,7 @@ function degradedArtifactSummary(handoffDir) {
196
196
  messageRoutePaths: {},
197
197
  architecturePlanPath: `${handoffDir}/architecture-plan.md`,
198
198
  knownIssuesPath: `${handoffDir}/known-issues.md`,
199
- reviewReportPath: `${handoffDir}/review-report.md`,
199
+ testReportPath: `${handoffDir}/test-report.md`,
200
200
  docsSyncReportPath: `${handoffDir}/docs-sync-report.md`,
201
201
  finalAcceptancePath: `${handoffDir}/final-acceptance.md`
202
202
  },
@@ -11,9 +11,12 @@ import { renderGateReviewerAgentRules, renderRequestGateReviewTool, renderTransl
11
11
  import { renderHarnessEngineerHarnessRules } from "../templates/harness/harness-engineer-agent.js";
12
12
  import { renderRootClaudeHarnessRules } from "../templates/harness/claude-root.js";
13
13
  import { renderGitignoreHarnessRules } from "../templates/harness/gitignore.js";
14
+ import { renderLegacyProjectCodingStandardsTemplate, renderProjectCodingStandardsProjectSection, renderProjectCodingStandardsRules } from "../templates/harness/project-coding-standards.js";
15
+ import { renderProjectGlossaryTemplate } from "../templates/harness/project-glossary.js";
16
+ import { renderLegacyProjectKnownIssuesTemplate, renderProjectKnownIssuesRules, renderProjectKnownIssuesSection } from "../templates/harness/project-known-issues.js";
14
17
  import { renderProjectManagerHarnessRules } from "../templates/harness/project-manager-agent.js";
15
18
  import { renderPullRequestTemplateHarnessRules } from "../templates/harness/pull-request-template.js";
16
- import { renderReviewerHarnessRules } from "../templates/harness/reviewer-agent.js";
19
+ import { renderTesterHarnessRules } from "../templates/harness/tester-agent.js";
17
20
  import { renderVcmFinalAcceptanceSkillRules } from "../templates/harness/vcm-final-acceptance-skill.js";
18
21
  import { renderVcmHarnessBootstrapSkillRules } from "../templates/harness/vcm-harness-bootstrap-skill.js";
19
22
  import { renderVcmLongRunningValidationSkillRules } from "../templates/harness/vcm-long-running-validation-skill.js";
@@ -37,6 +40,7 @@ const VCM_STOP_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\
37
40
  const VCM_PERMISSION_REQUEST_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ] || [ -z "\${VCM_API_URL:-}" ]; then exit 0; fi; node -e '"'"'let s="";process.stdin.setEncoding("utf8");process.stdin.on("data",d=>s+=d);process.stdin.on("end",()=>{let event={};try{event=s.trim()?JSON.parse(s):{};}catch{event={raw:s};}process.stdout.write(JSON.stringify({taskSlug:process.env.VCM_TASK_SLUG,role:process.env.VCM_ROLE,event}));});'"'"' | curl -fsS --max-time 5 -X POST "\${VCM_API_URL}/api/hooks/claude-code/permission-request" -H "content-type: application/json" --data-binary @- || true'`;
38
41
  const VCM_BASH_GUARD_HOOK_COMMAND = `sh -c 'if [ -z "\${VCM_TASK_SLUG:-}" ] || [ -z "\${VCM_ROLE:-}" ]; then exit 0; fi; guard=""; repo="$(git rev-parse --show-toplevel 2>/dev/null || true)"; if [ -n "$repo" ] && [ -f "$repo/.ai/tools/vcm-bash-guard" ]; then guard="$repo/.ai/tools/vcm-bash-guard"; else cwd="$(pwd -P 2>/dev/null || pwd)"; dir="$cwd"; while [ -n "$dir" ] && [ "$dir" != "/" ]; do if [ -f "$dir/.ai/tools/vcm-bash-guard" ]; then guard="$dir/.ai/tools/vcm-bash-guard"; break; fi; dir="$(dirname "$dir")"; done; if [ -z "$guard" ] && [ -n "\${CLAUDE_PROJECT_DIR:-}" ] && [ -f "\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-bash-guard" ]; then guard="\${CLAUDE_PROJECT_DIR}/.ai/tools/vcm-bash-guard"; fi; fi; [ -n "$guard" ] || exit 0; python3 "$guard" || exit 0'`;
39
42
  const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
43
+ const VCM_AUTO_MEMORY_ENABLED = false;
40
44
  const VCM_HOOK_DEFINITIONS = [
41
45
  { eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
42
46
  { eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
@@ -56,11 +60,12 @@ const AGENT_FRONTMATTER = {
56
60
  description: "VCM implementation role for scoped code changes and focused tests.",
57
61
  tools: "Read, Grep, Glob, Bash, Edit, Write, Agent"
58
62
  },
59
- reviewer: {
60
- description: "VCM independent review role for acceptance, test adequacy, scope checks, and risk findings."
63
+ tester: {
64
+ description: "VCM testing role for validation, test adequacy, approved-scope validation, and risk findings."
61
65
  },
62
66
  "gate-reviewer": {
63
- description: "VCM independent gate review role for architecture plans, validation adequacy, and final diffs."
67
+ description: "VCM independent gate review role for architecture plans, validation adequacy, and code diffs.",
68
+ tools: "Read, Grep, Glob, Bash, Write"
64
69
  },
65
70
  translator: {
66
71
  description: "VCM project translation tool role for conversation translation, file translation, bootstrap, and memory updates."
@@ -82,6 +87,24 @@ const MANAGED_FILES = [
82
87
  blankLineBeforeEnd: true,
83
88
  content: renderRootClaudeHarnessRules()
84
89
  },
90
+ {
91
+ path: "docs/CODING_STANDARDS.md",
92
+ title: "Coding Standards",
93
+ commentStyle: "html",
94
+ category: "project-coding-standards",
95
+ content: renderProjectCodingStandardsRules(),
96
+ contentAfterBlock: renderProjectCodingStandardsProjectSection(),
97
+ legacyWholeFile: renderLegacyProjectCodingStandardsTemplate()
98
+ },
99
+ {
100
+ path: "docs/known-issues.md",
101
+ title: "Known Issues",
102
+ commentStyle: "html",
103
+ category: "project-known-issues",
104
+ content: renderProjectKnownIssuesRules(),
105
+ contentAfterBlock: renderProjectKnownIssuesSection(),
106
+ legacyWholeFile: renderLegacyProjectKnownIssuesTemplate()
107
+ },
85
108
  {
86
109
  path: ".gitignore",
87
110
  title: ".gitignore",
@@ -115,12 +138,12 @@ const MANAGED_FILES = [
115
138
  content: renderCoderHarnessRules()
116
139
  },
117
140
  {
118
- path: ".claude/agents/reviewer.md",
119
- title: "Reviewer Agent",
120
- agentName: "reviewer",
141
+ path: ".claude/agents/tester.md",
142
+ title: "Tester Agent",
143
+ agentName: "tester",
121
144
  commentStyle: "html",
122
145
  category: "core-agent",
123
- content: renderReviewerHarnessRules()
146
+ content: renderTesterHarnessRules()
124
147
  },
125
148
  {
126
149
  path: ".github/pull_request_template.md",
@@ -163,6 +186,10 @@ const MANAGED_FILES = [
163
186
  }
164
187
  ];
165
188
  const DURABLE_DOC_TEMPLATES = [
189
+ {
190
+ path: "docs/GLOSSARY.md",
191
+ content: renderProjectGlossaryTemplate()
192
+ },
166
193
  {
167
194
  path: "docs/ARCHITECTURE.md",
168
195
  content: "# Architecture\n"
@@ -171,10 +198,6 @@ const DURABLE_DOC_TEMPLATES = [
171
198
  path: "docs/TESTING.md",
172
199
  content: "# Testing\n"
173
200
  },
174
- {
175
- path: "docs/known-issues.md",
176
- content: "# Known Issues\n"
177
- }
178
201
  ];
179
202
  const WHOLE_FILES = [
180
203
  {
@@ -193,7 +216,7 @@ const WHOLE_FILES = [
193
216
  path: ".claude/skills/vcm-final-acceptance/SKILL.md",
194
217
  category: "skill",
195
218
  mode: 0o644,
196
- content: renderSkillFile("VCM Final Acceptance Skill", "vcm-final-acceptance", "Use when project-manager is ready to decide whether a VCM-managed task can be accepted, returned for follow-up, or blocked for a decision.", renderVcmFinalAcceptanceSkillRules())
219
+ content: renderSkillFile("VCM Final Acceptance Skill", "vcm-final-acceptance", "Use when project-manager is ready to close a complete VCM code-delivery flow.", renderVcmFinalAcceptanceSkillRules())
197
220
  },
198
221
  {
199
222
  path: ".claude/skills/vcm-harness-bootstrap/SKILL.md",
@@ -211,7 +234,7 @@ const WHOLE_FILES = [
211
234
  path: ".claude/skills/vcm-route-message/SKILL.md",
212
235
  category: "skill",
213
236
  mode: 0o644,
214
- content: renderSkillFile("VCM Route Message Skill", "vcm-route-message", "Use when a VCM role needs to hand off work, ask a question, report a result, report a blocker, or raise a finding to another VCM role.", renderVcmRouteMessageSkillRules())
237
+ content: renderSkillFile("VCM Route Message Skill", "vcm-route-message", "Use when project-manager dispatches a VCM role or when a VCM role reports a question, result, blocker, or finding back to project-manager.", renderVcmRouteMessageSkillRules())
215
238
  },
216
239
  {
217
240
  path: ".claude/skills/vcm-gate-review/SKILL.md",
@@ -381,6 +404,8 @@ async function buildManifest(projectRoot) {
381
404
  }
382
405
  },
383
406
  ...fixedDirectories().map((directory) => manifestEntry(directory, "directory", directoryCategory(directory), "vcm-created")),
407
+ manifestEntry("docs/GLOSSARY.md", "file", "project-glossary", "project-owned"),
408
+ manifestEntry("docs/CODING_STANDARDS.md", "file", "project-coding-standards", "project-owned"),
384
409
  ...WHOLE_FILES.map((file) => ({
385
410
  path: file.path,
386
411
  entryType: "file",
@@ -500,9 +525,13 @@ async function installManagedFile({ projectRoot, definition, dryRun, operations
500
525
  }
501
526
  else {
502
527
  const pattern = definition.commentStyle === "hash" ? HASH_BLOCK_PATTERN : HTML_BLOCK_PATTERN;
503
- nextContent = pattern.test(currentContent)
504
- ? currentContent.replace(pattern, block)
505
- : `${currentContent.trimEnd()}\n\n${block}\n`;
528
+ if (pattern.test(currentContent)) {
529
+ nextContent = currentContent.replace(pattern, block);
530
+ }
531
+ else {
532
+ nextContent = migrateLegacyManagedFile(definition, currentContent, block)
533
+ ?? `${currentContent.trimEnd()}\n\n${block}\n`;
534
+ }
506
535
  }
507
536
  await writeIfChanged({
508
537
  targetPath,
@@ -540,13 +569,29 @@ function renderManagedBlock(definition) {
540
569
  return `<!-- VCM:BEGIN version=1 -->\n${body}${endSpacing}<!-- VCM:END -->`;
541
570
  }
542
571
  function renderNewManagedFile(definition, block) {
572
+ const suffix = definition.contentAfterBlock?.trim();
543
573
  if (definition.agentName) {
544
574
  const frontmatter = AGENT_FRONTMATTER[definition.agentName];
545
575
  const tools = frontmatter.tools ?? "Read, Grep, Glob, Bash, Edit, Write";
546
576
  const model = frontmatter.model ? `\nmodel: ${frontmatter.model}` : "";
547
- return `---\nname: ${definition.agentName}\ndescription: ${frontmatter.description}\ntools: ${tools}${model}\n---\n\n# ${definition.title}\n\n${block}\n`;
577
+ return `---\nname: ${definition.agentName}\ndescription: ${frontmatter.description}\ntools: ${tools}${model}\n---\n\n# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
578
+ }
579
+ return `# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
580
+ }
581
+ function migrateLegacyManagedFile(definition, currentContent, block) {
582
+ const legacyContent = definition.legacyWholeFile?.trimEnd();
583
+ if (!legacyContent) {
584
+ return undefined;
585
+ }
586
+ const current = currentContent.trimEnd();
587
+ if (current !== legacyContent && !current.startsWith(`${legacyContent}\n`)) {
588
+ return undefined;
548
589
  }
549
- return `# ${definition.title}\n\n${block}\n`;
590
+ const projectContent = current.slice(legacyContent.length).trim();
591
+ return renderNewManagedFile({
592
+ ...definition,
593
+ contentAfterBlock: projectContent || definition.contentAfterBlock
594
+ }, block);
550
595
  }
551
596
  function renderSkillFile(title, name, description, body) {
552
597
  return `---\nname: ${name}\ndescription: ${description}\n---\n\n# ${title}\n\n${body.trimEnd()}\n`;
@@ -565,7 +610,7 @@ async function installClaudeSettings({ projectRoot, dryRun, operations }) {
565
610
  mode: 0o644,
566
611
  dryRun,
567
612
  operations,
568
- action: "merge VCM Claude hooks"
613
+ action: "merge VCM Claude settings"
569
614
  });
570
615
  }
571
616
  function mergeVcmHooks(settings) {
@@ -602,6 +647,7 @@ function mergeVcmHooks(settings) {
602
647
  const env = isPlainObject(next.env) ? { ...next.env } : {};
603
648
  env.BASH_DEFAULT_TIMEOUT_MS = VCM_BASH_DEFAULT_TIMEOUT_MS;
604
649
  next.env = env;
650
+ next.autoMemoryEnabled = VCM_AUTO_MEMORY_ENABLED;
605
651
  return next;
606
652
  }
607
653
  function isOwnedHookMatcher(matcher) {
@@ -203,13 +203,22 @@ function normalizeGateReviewGates(input) {
203
203
  }
204
204
  const gates = [];
205
205
  for (const value of input) {
206
- if (!GATE_REVIEW_GATES.includes(value) || gates.includes(value)) {
206
+ const gate = normalizeGateReviewGateValue(value);
207
+ if (!gate || gates.includes(gate)) {
207
208
  continue;
208
209
  }
209
- gates.push(value);
210
+ gates.push(gate);
210
211
  }
211
212
  return GATE_REVIEW_GATES.filter((gate) => gates.includes(gate));
212
213
  }
214
+ function normalizeGateReviewGateValue(value) {
215
+ if (value === "final-diff") {
216
+ return "code-diff";
217
+ }
218
+ return GATE_REVIEW_GATES.includes(value)
219
+ ? value
220
+ : undefined;
221
+ }
213
222
  function normalizeSettingsFile(input) {
214
223
  const settings = {
215
224
  version: 1,
@@ -3,12 +3,12 @@ import { DISPATCHABLE_ROLES } from "../../shared/constants.js";
3
3
  import { checkMarkdownArtifact } from "../../shared/validation/artifact-check.js";
4
4
  import { VcmError } from "../errors.js";
5
5
  import { resolveRepoPath } from "../adapters/filesystem.js";
6
- import { renderArchitecturePlanTemplate, renderDocsSyncReportTemplate, renderFinalAcceptanceTemplate, renderKnownIssuesTemplate, renderMessageRouteTemplate, renderReviewReportTemplate } from "../templates/handoff.js";
6
+ import { renderArchitecturePlanTemplate, renderCoderCompletionTemplate, renderDocsSyncReportTemplate, renderFinalAcceptanceTemplate, renderKnownIssuesTemplate, renderMessageRouteTemplate, renderTestReportTemplate } from "../templates/handoff.js";
7
7
  import { renderRoleCommandTemplate } from "../templates/role-command.js";
8
8
  const ARTIFACT_PATH_KEYS = [
9
9
  ["architecture-plan", "architecturePlanPath"],
10
10
  ["known-issues", "knownIssuesPath"],
11
- ["review-report", "reviewReportPath"],
11
+ ["test-report", "testReportPath"],
12
12
  ["docs-sync-report", "docsSyncReportPath"],
13
13
  ["final-acceptance", "finalAcceptancePath"]
14
14
  ];
@@ -16,10 +16,10 @@ const ROLE_COMMAND_PLACEHOLDER_PATTERN = /(^|\n)\s*(TBD|status:\s*draft)\s*(\n|$
16
16
  const DEFAULT_MESSAGE_ROUTES = [
17
17
  ["project-manager", "architect"],
18
18
  ["project-manager", "coder"],
19
- ["project-manager", "reviewer"],
19
+ ["project-manager", "tester"],
20
20
  ["architect", "project-manager"],
21
21
  ["coder", "project-manager"],
22
- ["reviewer", "project-manager"]
22
+ ["tester", "project-manager"]
23
23
  ];
24
24
  export function createArtifactService(fs) {
25
25
  return {
@@ -33,12 +33,12 @@ export function createArtifactService(fs) {
33
33
  roleCommandPaths: {
34
34
  architect: path.posix.join(roleCommandsDir, "architect.md"),
35
35
  coder: path.posix.join(roleCommandsDir, "coder.md"),
36
- reviewer: path.posix.join(roleCommandsDir, "reviewer.md")
36
+ tester: path.posix.join(roleCommandsDir, "tester.md")
37
37
  },
38
38
  messageRoutePaths: getDefaultMessageRoutePaths(messagesDir),
39
39
  architecturePlanPath: path.posix.join(handoffDir, "architecture-plan.md"),
40
40
  knownIssuesPath: path.posix.join(handoffDir, "known-issues.md"),
41
- reviewReportPath: path.posix.join(handoffDir, "review-report.md"),
41
+ testReportPath: path.posix.join(handoffDir, "test-report.md"),
42
42
  docsSyncReportPath: path.posix.join(handoffDir, "docs-sync-report.md"),
43
43
  finalAcceptancePath: path.posix.join(handoffDir, "final-acceptance.md")
44
44
  };
@@ -58,10 +58,11 @@ export function createArtifactService(fs) {
58
58
  const files = [
59
59
  [paths.roleCommandPaths.architect, renderRoleCommandTemplate(input.taskSlug, "architect", input.repoRoot, input.branch)],
60
60
  [paths.roleCommandPaths.coder, renderRoleCommandTemplate(input.taskSlug, "coder", input.repoRoot, input.branch)],
61
- [paths.roleCommandPaths.reviewer, renderRoleCommandTemplate(input.taskSlug, "reviewer", input.repoRoot, input.branch)],
61
+ [paths.roleCommandPaths.tester, renderRoleCommandTemplate(input.taskSlug, "tester", input.repoRoot, input.branch)],
62
62
  [paths.architecturePlanPath, renderArchitecturePlanTemplate(input.taskSlug)],
63
63
  [paths.knownIssuesPath, renderKnownIssuesTemplate(input.taskSlug)],
64
- [paths.reviewReportPath, renderReviewReportTemplate(input.taskSlug)],
64
+ [path.posix.join(paths.handoffDir, "coder-completion.md"), renderCoderCompletionTemplate(input.taskSlug)],
65
+ [paths.testReportPath, renderTestReportTemplate(input.taskSlug)],
65
66
  [paths.docsSyncReportPath, renderDocsSyncReportTemplate(input.taskSlug)],
66
67
  [paths.finalAcceptancePath, renderFinalAcceptanceTemplate(input.taskSlug)],
67
68
  ...Object.values(paths.messageRoutePaths).map((messagePath) => [