vibe-coding-master 0.6.19 → 0.6.21
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 +5 -5
- package/dist/backend/api/artifact-routes.js +2 -2
- package/dist/backend/api/gate-review-routes.js +1 -1
- package/dist/backend/api/task-routes.js +1 -1
- package/dist/backend/cli/install-vcm-harness.js +66 -20
- package/dist/backend/services/app-settings-service.js +11 -2
- package/dist/backend/services/artifact-service.js +9 -8
- package/dist/backend/services/gate-review-service.js +319 -24
- package/dist/backend/services/harness-feedback-service.js +8 -3
- package/dist/backend/services/harness-service.js +100 -13
- package/dist/backend/services/job-guard-service.js +2 -2
- package/dist/backend/services/message-service.js +12 -0
- package/dist/backend/services/session-service.js +18 -11
- package/dist/backend/services/status-service.js +1 -4
- package/dist/backend/templates/handoff.js +105 -17
- package/dist/backend/templates/harness/architect-agent.js +51 -27
- package/dist/backend/templates/harness/claude-root.js +43 -15
- package/dist/backend/templates/harness/coder-agent.js +66 -47
- package/dist/backend/templates/harness/coder-worker-agent.js +45 -17
- package/dist/backend/templates/harness/gate-review.js +229 -39
- package/dist/backend/templates/harness/harness-engineer-agent.js +39 -12
- package/dist/backend/templates/harness/project-coding-standards.js +73 -0
- package/dist/backend/templates/harness/project-glossary.js +30 -0
- package/dist/backend/templates/harness/project-known-issues.js +33 -0
- package/dist/backend/templates/harness/project-manager-agent.js +97 -27
- package/dist/backend/templates/harness/pull-request-template.js +6 -4
- package/dist/backend/templates/harness/tester-agent.js +82 -0
- package/dist/backend/templates/harness/vcm-final-acceptance-skill.js +19 -15
- package/dist/backend/templates/harness/vcm-harness-bootstrap-skill.js +19 -2
- package/dist/backend/templates/harness/vcm-long-running-validation-skill.js +1 -1
- package/dist/backend/templates/harness/vcm-report-harness-issue-skill.js +18 -12
- package/dist/backend/templates/harness/vcm-route-message-skill.js +48 -8
- package/dist/backend/templates/message-envelope.js +2 -5
- package/dist/shared/constants.js +3 -3
- package/dist/shared/types/gate-review.js +5 -1
- package/dist/shared/validation/artifact-check.js +64 -10
- package/dist-frontend/assets/{index-C5E5jLp-.js → index-DYBg_qYS.js} +4 -4
- package/dist-frontend/index.html +1 -1
- package/package.json +1 -1
- package/scripts/verify-package.mjs +1 -1
- 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
|
-
-
|
|
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,
|
|
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
|
-
->
|
|
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
|
-
-
|
|
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,
|
|
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 === "
|
|
74
|
-
return paths.
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
60
|
-
description: "VCM
|
|
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
|
|
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/
|
|
119
|
-
title: "
|
|
120
|
-
agentName: "
|
|
141
|
+
path: ".claude/agents/tester.md",
|
|
142
|
+
title: "Tester Agent",
|
|
143
|
+
agentName: "tester",
|
|
121
144
|
commentStyle: "html",
|
|
122
145
|
category: "core-agent",
|
|
123
|
-
content:
|
|
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
|
|
219
|
+
content: renderSkillFile("VCM Final Acceptance Skill", "vcm-final-acceptance", "Use when project-manager is ready to close a complete VCM code-change 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
|
|
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
|
-
|
|
504
|
-
|
|
505
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
206
|
+
const gate = normalizeGateReviewGateValue(value);
|
|
207
|
+
if (!gate || gates.includes(gate)) {
|
|
207
208
|
continue;
|
|
208
209
|
}
|
|
209
|
-
gates.push(
|
|
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,
|
|
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
|
-
["
|
|
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", "
|
|
19
|
+
["project-manager", "tester"],
|
|
20
20
|
["architect", "project-manager"],
|
|
21
21
|
["coder", "project-manager"],
|
|
22
|
-
["
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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) => [
|