vibe-coding-master 0.7.37 → 0.7.39
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 +7 -3
- package/dist/backend/adapters/claude-adapter.js +6 -0
- package/dist/backend/cli/install-vcm-harness.js +64 -5
- package/dist/backend/services/code-intelligence-service.js +5 -5
- package/dist/backend/services/harness-service.js +63 -9
- package/dist/backend/templates/harness/architect-agent.js +10 -4
- package/dist/backend/templates/harness/coder-agent.js +8 -1
- package/dist/backend/templates/harness/gate-review.js +12 -9
- package/dist/backend/templates/harness/vcm-code-navigation-skill.js +10 -8
- package/dist-frontend/assets/{index-VillnFRo.js → index-DkM0mnQD.js} +1 -1
- package/dist-frontend/index.html +1 -1
- package/package.json +1 -1
- package/scripts/harness-tools/vcm-bash-guard +52 -17
package/README.md
CHANGED
|
@@ -455,7 +455,7 @@ Harness Studio is the UI for VCM harness maintenance.
|
|
|
455
455
|
Use it to:
|
|
456
456
|
|
|
457
457
|
- inspect fixed harness status
|
|
458
|
-
- inspect detected project languages and
|
|
458
|
+
- inspect detected project languages and language-server availability
|
|
459
459
|
- run bootstrap
|
|
460
460
|
- open Harness Engineer
|
|
461
461
|
- review harness files
|
|
@@ -471,8 +471,12 @@ VCM bundles the Claude Code LSP bridge and loads it for Architect, Coder, and
|
|
|
471
471
|
Reviewer sessions, including CCR launches. The project environment must still
|
|
472
472
|
provide the language server for each detected language: `rust-analyzer`,
|
|
473
473
|
`typescript-language-server`, `pyright-langserver`, `gopls`, `clangd`, or
|
|
474
|
-
`jdtls`.
|
|
475
|
-
|
|
474
|
+
`jdtls`. Their Agent definitions preload `vcm-code-navigation`, and their
|
|
475
|
+
launches explicitly enable Glob while leaving Grep unavailable. The Harness
|
|
476
|
+
guard also rejects shell text-search commands for those roles so unresolved
|
|
477
|
+
semantic relationships cannot be hidden by textual fallback. Harness Studio
|
|
478
|
+
reports whether the server executable and plugin can run; the role Session
|
|
479
|
+
performs the real workspace warm-up and semantic query retries.
|
|
476
480
|
|
|
477
481
|
Harness Engineer is task-scoped and runs from the active task worktree. The
|
|
478
482
|
backend automatically starts a fresh Harness Engineer for each active task or
|
|
@@ -20,6 +20,7 @@ export function createClaudeAdapter(runner) {
|
|
|
20
20
|
},
|
|
21
21
|
buildRoleStartCommand(role, command = "claude", permissionMode = "default", claudeSessionId, resume = false, model = "default", effort = "default", settingsOverride, appendSystemPrompt, pluginDirs = []) {
|
|
22
22
|
const args = pluginDirs.flatMap((pluginDir) => ["--plugin-dir", pluginDir]);
|
|
23
|
+
args.push("--allowedTools", roleSearchToolOptIns(role).join(","));
|
|
23
24
|
args.push("--agent", role);
|
|
24
25
|
const sessionSettings = { ...settingsOverride };
|
|
25
26
|
if (claudeSessionId) {
|
|
@@ -51,6 +52,11 @@ export function createClaudeAdapter(runner) {
|
|
|
51
52
|
}
|
|
52
53
|
};
|
|
53
54
|
}
|
|
55
|
+
function roleSearchToolOptIns(role) {
|
|
56
|
+
return role === "architect" || role === "coder" || role === "reviewer"
|
|
57
|
+
? ["Glob"]
|
|
58
|
+
: ["Glob", "Grep"];
|
|
59
|
+
}
|
|
54
60
|
function formatDisplayArg(value) {
|
|
55
61
|
if (/^[A-Za-z0-9_./:=@+-]+$/.test(value)) {
|
|
56
62
|
return value;
|
|
@@ -53,6 +53,7 @@ const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
|
|
|
53
53
|
const VCM_AUTO_MEMORY_ENABLED = false;
|
|
54
54
|
const VCM_HOOK_DEFINITIONS = [
|
|
55
55
|
{ eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
56
|
+
{ eventName: "PreToolUse", matcher: "Grep", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
56
57
|
{ eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
57
58
|
{ eventName: "Stop", command: VCM_STOP_HOOK_COMMAND, timeout: 10 },
|
|
58
59
|
{ eventName: "StopFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
@@ -65,18 +66,21 @@ const AGENT_FRONTMATTER = {
|
|
|
65
66
|
},
|
|
66
67
|
architect: {
|
|
67
68
|
description: "VCM architecture role for plans, module boundaries, public contracts, verifiable behavior, and docs sync.",
|
|
68
|
-
tools: "Read,
|
|
69
|
+
tools: "Read, Glob, Bash, Edit, Write, Agent, LSP",
|
|
70
|
+
skills: ["vcm-code-navigation"]
|
|
69
71
|
},
|
|
70
72
|
coder: {
|
|
71
73
|
description: "VCM implementation role for scoped code changes and focused tests.",
|
|
72
|
-
tools: "Read,
|
|
74
|
+
tools: "Read, Glob, Bash, Edit, Write, Agent, LSP",
|
|
75
|
+
skills: ["vcm-code-navigation"]
|
|
73
76
|
},
|
|
74
77
|
tester: {
|
|
75
78
|
description: "VCM testing role for validation, test adequacy, approved-scope validation, and risk findings."
|
|
76
79
|
},
|
|
77
80
|
reviewer: {
|
|
78
81
|
description: "VCM independent gate review role for architecture plans, validation adequacy, and code diffs.",
|
|
79
|
-
tools: "Read,
|
|
82
|
+
tools: "Read, Glob, Bash, Write, LSP",
|
|
83
|
+
skills: ["vcm-code-navigation"]
|
|
80
84
|
},
|
|
81
85
|
translator: {
|
|
82
86
|
description: "VCM task-scoped translation tool role for conversation translation, file translation, bootstrap, and memory updates."
|
|
@@ -99,6 +103,16 @@ const REQUIRED_AGENT_TOOLS = {
|
|
|
99
103
|
coder: ["Agent", "LSP"],
|
|
100
104
|
reviewer: ["LSP"]
|
|
101
105
|
};
|
|
106
|
+
const FORBIDDEN_AGENT_TOOLS = {
|
|
107
|
+
architect: ["Grep"],
|
|
108
|
+
coder: ["Grep"],
|
|
109
|
+
reviewer: ["Grep"]
|
|
110
|
+
};
|
|
111
|
+
const REQUIRED_AGENT_SKILLS = {
|
|
112
|
+
architect: ["vcm-code-navigation"],
|
|
113
|
+
coder: ["vcm-code-navigation"],
|
|
114
|
+
reviewer: ["vcm-code-navigation"]
|
|
115
|
+
};
|
|
102
116
|
const MANAGED_FILES = [
|
|
103
117
|
{
|
|
104
118
|
path: "CLAUDE.md",
|
|
@@ -266,7 +280,7 @@ const WHOLE_FILES = [
|
|
|
266
280
|
path: ".claude/skills/vcm-code-navigation/SKILL.md",
|
|
267
281
|
category: "skill",
|
|
268
282
|
mode: 0o644,
|
|
269
|
-
content: renderSkillFile("VCM Code Navigation Skill", "vcm-code-navigation", "Use when Architect or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths.", renderVcmCodeNavigationSkillRules())
|
|
283
|
+
content: renderSkillFile("VCM Code Navigation Skill", "vcm-code-navigation", "Use when Architect, Coder, or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths.", renderVcmCodeNavigationSkillRules())
|
|
270
284
|
},
|
|
271
285
|
{
|
|
272
286
|
path: ".claude/skills/vcm-final-acceptance/SKILL.md",
|
|
@@ -672,6 +686,12 @@ async function installManagedFile({ projectRoot, definition, dryRun, operations
|
|
|
672
686
|
for (const requiredTool of REQUIRED_AGENT_TOOLS[definition.agentName] ?? []) {
|
|
673
687
|
nextContent = ensureAgentTool(nextContent, requiredTool);
|
|
674
688
|
}
|
|
689
|
+
for (const forbiddenTool of FORBIDDEN_AGENT_TOOLS[definition.agentName] ?? []) {
|
|
690
|
+
nextContent = removeAgentTool(nextContent, forbiddenTool);
|
|
691
|
+
}
|
|
692
|
+
for (const requiredSkill of REQUIRED_AGENT_SKILLS[definition.agentName] ?? []) {
|
|
693
|
+
nextContent = ensureAgentSkill(nextContent, requiredSkill);
|
|
694
|
+
}
|
|
675
695
|
await writeIfChanged({
|
|
676
696
|
targetPath,
|
|
677
697
|
relativePath: definition.path,
|
|
@@ -714,7 +734,10 @@ function renderNewManagedFile(definition, block) {
|
|
|
714
734
|
const tools = frontmatter.tools ?? "Read, Grep, Glob, Bash, Edit, Write";
|
|
715
735
|
const model = frontmatter.model ? `\nmodel: ${frontmatter.model}` : "";
|
|
716
736
|
const effort = frontmatter.effort ? `\neffort: ${frontmatter.effort}` : "";
|
|
717
|
-
|
|
737
|
+
const skills = frontmatter.skills?.length
|
|
738
|
+
? `\nskills:\n${frontmatter.skills.map((skill) => ` - ${skill}`).join("\n")}`
|
|
739
|
+
: "";
|
|
740
|
+
return `---\nname: ${definition.agentName}\ndescription: ${frontmatter.description}\ntools: ${tools}${model}${effort}${skills}\n---\n\n# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
|
|
718
741
|
}
|
|
719
742
|
return `# ${definition.title}\n\n${block}${suffix ? `\n\n${suffix}` : ""}\n`;
|
|
720
743
|
}
|
|
@@ -734,6 +757,42 @@ function ensureAgentTool(content, requiredTool) {
|
|
|
734
757
|
const nextTools = [...tools, requiredTool].join(", ");
|
|
735
758
|
return content.replace(frontmatterMatch[0], frontmatterMatch[0].replace(toolsMatch[0], `tools: ${nextTools}`));
|
|
736
759
|
}
|
|
760
|
+
function removeAgentTool(content, forbiddenTool) {
|
|
761
|
+
const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
|
|
762
|
+
if (!frontmatterMatch) {
|
|
763
|
+
return content;
|
|
764
|
+
}
|
|
765
|
+
const toolsMatch = frontmatterMatch[0].match(/^tools:\s*(.*)$/m);
|
|
766
|
+
if (!toolsMatch) {
|
|
767
|
+
return content;
|
|
768
|
+
}
|
|
769
|
+
const tools = toolsMatch[1].split(",").map((tool) => tool.trim()).filter(Boolean);
|
|
770
|
+
const nextTools = tools.filter((tool) => tool !== forbiddenTool);
|
|
771
|
+
if (nextTools.length === tools.length) {
|
|
772
|
+
return content;
|
|
773
|
+
}
|
|
774
|
+
return content.replace(frontmatterMatch[0], frontmatterMatch[0].replace(toolsMatch[0], `tools: ${nextTools.join(", ")}`));
|
|
775
|
+
}
|
|
776
|
+
function ensureAgentSkill(content, requiredSkill) {
|
|
777
|
+
const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
|
|
778
|
+
if (!frontmatterMatch) {
|
|
779
|
+
return content;
|
|
780
|
+
}
|
|
781
|
+
const frontmatter = frontmatterMatch[0];
|
|
782
|
+
const skillsMatch = frontmatter.match(/^skills:[ \t]*(?:\r?\n((?:\s+-\s+[^\r\n]+\r?\n?)*))?/m);
|
|
783
|
+
if (!skillsMatch) {
|
|
784
|
+
return content.replace(frontmatter, frontmatter.replace(/\r?\n---$/, `\nskills:\n - ${requiredSkill}\n---`));
|
|
785
|
+
}
|
|
786
|
+
const listedSkills = (skillsMatch[1] ?? "")
|
|
787
|
+
.split(/\r?\n/)
|
|
788
|
+
.map((line) => line.match(/^\s+-\s+(.+)$/)?.[1]?.trim())
|
|
789
|
+
.filter(Boolean);
|
|
790
|
+
if (listedSkills.includes(requiredSkill)) {
|
|
791
|
+
return content;
|
|
792
|
+
}
|
|
793
|
+
const nextSkills = `${skillsMatch[0].trimEnd()}\n - ${requiredSkill}`;
|
|
794
|
+
return content.replace(frontmatter, frontmatter.replace(skillsMatch[0], nextSkills));
|
|
795
|
+
}
|
|
737
796
|
function migrateLegacyManagedFile(definition, currentContent, block) {
|
|
738
797
|
const legacyContent = definition.legacyWholeFile?.trimEnd();
|
|
739
798
|
if (!legacyContent) {
|
|
@@ -127,13 +127,13 @@ async function detectCodeIntelligence(fs, repoRoot, options, probe) {
|
|
|
127
127
|
return status;
|
|
128
128
|
}));
|
|
129
129
|
const languages = detectedLanguages.filter((language) => language !== undefined);
|
|
130
|
-
const
|
|
130
|
+
const runnableCount = languages.filter((language) => language.state === "server_runnable").length;
|
|
131
131
|
return {
|
|
132
132
|
state: languages.length === 0
|
|
133
133
|
? "not_detected"
|
|
134
|
-
:
|
|
135
|
-
? "
|
|
136
|
-
:
|
|
134
|
+
: runnableCount === languages.length
|
|
135
|
+
? "available"
|
|
136
|
+
: runnableCount === 0
|
|
137
137
|
? "missing"
|
|
138
138
|
: "partial",
|
|
139
139
|
languages
|
|
@@ -149,7 +149,7 @@ function languageState(pluginReady, serverFound, serverRunnable, probeCompleted)
|
|
|
149
149
|
if (!probeCompleted) {
|
|
150
150
|
return "server_unverified";
|
|
151
151
|
}
|
|
152
|
-
return serverRunnable ? "
|
|
152
|
+
return serverRunnable ? "server_runnable" : "server_failed";
|
|
153
153
|
}
|
|
154
154
|
function languageError(state, command, probeResult) {
|
|
155
155
|
if (state === "plugin_missing") {
|
|
@@ -53,6 +53,7 @@ const VCM_BASH_DEFAULT_TIMEOUT_MS = "600000";
|
|
|
53
53
|
const VCM_AUTO_MEMORY_ENABLED = false;
|
|
54
54
|
const VCM_HOOK_DEFINITIONS = [
|
|
55
55
|
{ eventName: "PreToolUse", matcher: "Bash", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
56
|
+
{ eventName: "PreToolUse", matcher: "Grep", command: VCM_BASH_GUARD_HOOK_COMMAND, timeout: 10 },
|
|
56
57
|
{ eventName: "UserPromptSubmit", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
57
58
|
{ eventName: "Stop", command: VCM_STOP_HOOK_COMMAND, timeout: 10 },
|
|
58
59
|
{ eventName: "StopFailure", command: VCM_HOOK_COMMAND, timeout: 5 },
|
|
@@ -116,7 +117,7 @@ const HARNESS_FILES = [
|
|
|
116
117
|
kind: "skill-vcm-code-navigation",
|
|
117
118
|
path: ".claude/skills/vcm-code-navigation/SKILL.md",
|
|
118
119
|
title: "VCM Code Navigation Skill",
|
|
119
|
-
frontmatter: renderSkillFrontmatter("vcm-code-navigation", "Use when Architect or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths."),
|
|
120
|
+
frontmatter: renderSkillFrontmatter("vcm-code-navigation", "Use when Architect, Coder, or Reviewer must resolve code symbols, references, implementations, call hierarchies, or bounded dependency paths."),
|
|
120
121
|
ownership: "whole-file",
|
|
121
122
|
renderRules: renderVcmCodeNavigationSkillRules
|
|
122
123
|
},
|
|
@@ -198,7 +199,9 @@ const HARNESS_FILES = [
|
|
|
198
199
|
title: "Reviewer Agent",
|
|
199
200
|
memoryBlock: true,
|
|
200
201
|
requiredTools: ["LSP"],
|
|
201
|
-
|
|
202
|
+
forbiddenTools: ["Grep"],
|
|
203
|
+
requiredSkills: ["vcm-code-navigation"],
|
|
204
|
+
frontmatter: renderAgentFrontmatter("reviewer", "VCM independent gate review role for architecture plans, validation adequacy, and code diffs.", { tools: "Read, Glob, Bash, Write, LSP", skills: ["vcm-code-navigation"] }),
|
|
202
205
|
renderRules: renderReviewerAgentRules
|
|
203
206
|
},
|
|
204
207
|
{
|
|
@@ -272,8 +275,10 @@ const HARNESS_FILES = [
|
|
|
272
275
|
title: "Architect Agent",
|
|
273
276
|
memoryBlock: true,
|
|
274
277
|
requiredTools: ["Agent", "LSP"],
|
|
278
|
+
forbiddenTools: ["Grep"],
|
|
279
|
+
requiredSkills: ["vcm-code-navigation"],
|
|
275
280
|
blankLineBeforeEnd: true,
|
|
276
|
-
frontmatter: renderAgentFrontmatter("architect", "VCM architecture role for plans, module boundaries, public contracts, verifiable behavior, and docs sync.", { tools: "Read,
|
|
281
|
+
frontmatter: renderAgentFrontmatter("architect", "VCM architecture role for plans, module boundaries, public contracts, verifiable behavior, and docs sync.", { tools: "Read, Glob, Bash, Edit, Write, Agent, LSP", skills: ["vcm-code-navigation"] }),
|
|
277
282
|
renderRules: renderArchitectHarnessRules
|
|
278
283
|
},
|
|
279
284
|
{
|
|
@@ -282,7 +287,9 @@ const HARNESS_FILES = [
|
|
|
282
287
|
title: "Coder Agent",
|
|
283
288
|
memoryBlock: true,
|
|
284
289
|
requiredTools: ["Agent", "LSP"],
|
|
285
|
-
|
|
290
|
+
forbiddenTools: ["Grep"],
|
|
291
|
+
requiredSkills: ["vcm-code-navigation"],
|
|
292
|
+
frontmatter: renderAgentFrontmatter("coder", "VCM implementation role for scoped code changes and focused tests.", { tools: "Read, Glob, Bash, Edit, Write, Agent, LSP", skills: ["vcm-code-navigation"] }),
|
|
286
293
|
renderRules: renderCoderHarnessRules
|
|
287
294
|
},
|
|
288
295
|
{
|
|
@@ -1220,7 +1227,7 @@ async function analyzeHarnessFile(fs, repoRoot, definition) {
|
|
|
1220
1227
|
const migratedContent = migrateLegacyHarnessFile(definition, currentContent, expectedBlock);
|
|
1221
1228
|
if (migratedContent) {
|
|
1222
1229
|
const memoryUpdatedContent = definition.memoryBlock ? ensureVcmMemoryBlock(migratedContent) : migratedContent;
|
|
1223
|
-
const nextContent =
|
|
1230
|
+
const nextContent = normalizeAgentFrontmatter(memoryUpdatedContent, definition);
|
|
1224
1231
|
return {
|
|
1225
1232
|
definition,
|
|
1226
1233
|
status: {
|
|
@@ -1239,7 +1246,7 @@ async function analyzeHarnessFile(fs, repoRoot, definition) {
|
|
|
1239
1246
|
};
|
|
1240
1247
|
}
|
|
1241
1248
|
const insertedContent = `${currentContent.trimEnd()}\n\n${expectedBlock}\n`;
|
|
1242
|
-
const nextContent =
|
|
1249
|
+
const nextContent = normalizeAgentFrontmatter(insertedContent, definition);
|
|
1243
1250
|
return {
|
|
1244
1251
|
definition,
|
|
1245
1252
|
status: {
|
|
@@ -1261,7 +1268,7 @@ async function analyzeHarnessFile(fs, repoRoot, definition) {
|
|
|
1261
1268
|
const currentBlock = match[0];
|
|
1262
1269
|
const blockUpdatedContent = currentContent.replace(managedBlockPattern, expectedBlock);
|
|
1263
1270
|
const memoryUpdatedContent = definition.memoryBlock ? ensureVcmMemoryBlock(blockUpdatedContent) : blockUpdatedContent;
|
|
1264
|
-
const nextContent =
|
|
1271
|
+
const nextContent = normalizeAgentFrontmatter(memoryUpdatedContent, definition);
|
|
1265
1272
|
const action = currentContent === nextContent ? "ok" : "update";
|
|
1266
1273
|
return {
|
|
1267
1274
|
definition,
|
|
@@ -1392,6 +1399,50 @@ function ensureAgentTool(content, requiredTool) {
|
|
|
1392
1399
|
function ensureAgentTools(content, requiredTools) {
|
|
1393
1400
|
return (requiredTools ?? []).reduce(ensureAgentTool, content);
|
|
1394
1401
|
}
|
|
1402
|
+
function removeAgentTool(content, forbiddenTool) {
|
|
1403
|
+
const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
|
|
1404
|
+
if (!frontmatterMatch) {
|
|
1405
|
+
return content;
|
|
1406
|
+
}
|
|
1407
|
+
const toolsMatch = frontmatterMatch[0].match(/^tools:\s*(.*)$/m);
|
|
1408
|
+
if (!toolsMatch) {
|
|
1409
|
+
return content;
|
|
1410
|
+
}
|
|
1411
|
+
const tools = toolsMatch[1].split(",").map((tool) => tool.trim()).filter(Boolean);
|
|
1412
|
+
const nextTools = tools.filter((tool) => tool !== forbiddenTool);
|
|
1413
|
+
if (nextTools.length === tools.length) {
|
|
1414
|
+
return content;
|
|
1415
|
+
}
|
|
1416
|
+
return content.replace(frontmatterMatch[0], frontmatterMatch[0].replace(toolsMatch[0], `tools: ${nextTools.join(", ")}`));
|
|
1417
|
+
}
|
|
1418
|
+
function normalizeAgentTools(content, requiredTools, forbiddenTools) {
|
|
1419
|
+
const required = ensureAgentTools(content, requiredTools);
|
|
1420
|
+
return (forbiddenTools ?? []).reduce(removeAgentTool, required);
|
|
1421
|
+
}
|
|
1422
|
+
function normalizeAgentFrontmatter(content, definition) {
|
|
1423
|
+
const toolsUpdated = normalizeAgentTools(content, definition.requiredTools, definition.forbiddenTools);
|
|
1424
|
+
return (definition.requiredSkills ?? []).reduce(ensureAgentSkill, toolsUpdated);
|
|
1425
|
+
}
|
|
1426
|
+
function ensureAgentSkill(content, requiredSkill) {
|
|
1427
|
+
const frontmatterMatch = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
|
|
1428
|
+
if (!frontmatterMatch) {
|
|
1429
|
+
return content;
|
|
1430
|
+
}
|
|
1431
|
+
const frontmatter = frontmatterMatch[0];
|
|
1432
|
+
const skillsMatch = frontmatter.match(/^skills:[ \t]*(?:\r?\n((?:\s+-\s+[^\r\n]+\r?\n?)*))?/m);
|
|
1433
|
+
if (!skillsMatch) {
|
|
1434
|
+
return content.replace(frontmatter, frontmatter.replace(/\r?\n---$/, `\nskills:\n - ${requiredSkill}\n---`));
|
|
1435
|
+
}
|
|
1436
|
+
const listedSkills = (skillsMatch[1] ?? "")
|
|
1437
|
+
.split(/\r?\n/)
|
|
1438
|
+
.map((line) => line.match(/^\s+-\s+(.+)$/)?.[1]?.trim())
|
|
1439
|
+
.filter((skill) => Boolean(skill));
|
|
1440
|
+
if (listedSkills.includes(requiredSkill)) {
|
|
1441
|
+
return content;
|
|
1442
|
+
}
|
|
1443
|
+
const nextSkills = `${skillsMatch[0].trimEnd()}\n - ${requiredSkill}`;
|
|
1444
|
+
return content.replace(frontmatter, frontmatter.replace(skillsMatch[0], nextSkills));
|
|
1445
|
+
}
|
|
1395
1446
|
function migrateLegacyHarnessFile(definition, currentContent, block) {
|
|
1396
1447
|
const legacyContent = definition.legacyWholeFile?.trimEnd();
|
|
1397
1448
|
if (!legacyContent) {
|
|
@@ -1479,7 +1530,7 @@ function withVcmClaudeHooks(settings) {
|
|
|
1479
1530
|
? hooks[definition.eventName]
|
|
1480
1531
|
: [];
|
|
1481
1532
|
hooks[definition.eventName] = [
|
|
1482
|
-
...existingMatchers
|
|
1533
|
+
...existingMatchers,
|
|
1483
1534
|
{
|
|
1484
1535
|
...(definition.matcher ? { matcher: definition.matcher } : {}),
|
|
1485
1536
|
hooks: [
|
|
@@ -1524,7 +1575,10 @@ function renderAgentFrontmatter(name, description, options = {}) {
|
|
|
1524
1575
|
const tools = options.tools ?? "Read, Grep, Glob, Bash, Edit, Write";
|
|
1525
1576
|
const model = options.model ? `\nmodel: ${options.model}` : "";
|
|
1526
1577
|
const effort = options.effort ? `\neffort: ${options.effort}` : "";
|
|
1527
|
-
|
|
1578
|
+
const skills = options.skills?.length
|
|
1579
|
+
? `\nskills:\n${options.skills.map((skill) => ` - ${skill}`).join("\n")}`
|
|
1580
|
+
: "";
|
|
1581
|
+
return `---\nname: ${name}\ndescription: ${description}\ntools: ${tools}${model}${effort}${skills}\n---`;
|
|
1528
1582
|
}
|
|
1529
1583
|
function renderSkillFrontmatter(name, description) {
|
|
1530
1584
|
return `---\nname: ${name}\ndescription: ${description}\n---`;
|
|
@@ -19,6 +19,13 @@ ${renderRoleMemoryRules("architect")}
|
|
|
19
19
|
- In Debug Mode and Architecture Diagnosis Mode, writing baseline unit tests for changed code and running required L0/L1 plus applicable L2/L3 checks are part of the implementation duty; tester still owns final validation.
|
|
20
20
|
- Do not make product priority or approval decisions; route those questions back to project-manager.
|
|
21
21
|
|
|
22
|
+
### Semantic Code Navigation
|
|
23
|
+
|
|
24
|
+
- Follow the preloaded \`vcm-code-navigation\` skill whenever work requires code definitions, implementations, references, callers, callees, or behavior paths. This applies in every Architect mode and in direct user communication.
|
|
25
|
+
- Use LSP for semantic relationships. Use Glob to locate files, Read to inspect complete code, and generated context, architecture documents, or runtime evidence for boundaries LSP does not model.
|
|
26
|
+
- Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
|
|
27
|
+
- If LSP cannot resolve a required project-owned relationship, record it as unresolved. Do not replace semantic evidence with text matches.
|
|
28
|
+
|
|
22
29
|
### Work Persistence
|
|
23
30
|
|
|
24
31
|
- Treat Architect artifacts, not Session memory, as continuation state.
|
|
@@ -45,9 +52,8 @@ ${renderRoleMemoryRules("architect")}
|
|
|
45
52
|
### Planning Code Reading
|
|
46
53
|
|
|
47
54
|
- Do not plan from session memory, architecture docs, generated context, or code comments alone. Re-read current-worktree source and verify actual behavior from implementation.
|
|
48
|
-
- Use \`vcm-code-navigation\` for symbol definitions, implementations, references, call hierarchies, and bounded behavior paths. Start from generated indexes, use LSP semantic navigation
|
|
49
|
-
-
|
|
50
|
-
- If LSP is unavailable or cannot resolve a required relationship, record the limitation and exact fallback evidence in \`architecture-evidence.md\`; do not claim compiler-accurate completeness from text search alone.
|
|
55
|
+
- Use \`vcm-code-navigation\` for symbol definitions, implementations, references, call hierarchies, and bounded behavior paths. Start from generated indexes, use LSP semantic navigation, then read every resolved callable unit in full.
|
|
56
|
+
- If LSP cannot resolve a required project-owned relationship, record the limitation in \`architecture-evidence.md\` and leave it unresolved.
|
|
51
57
|
- Define the planning boundary as the affected feature or module and identify every existing or intended observable entry point for the behavior being changed.
|
|
52
58
|
- Read the complete implementation of each relevant existing entry point.
|
|
53
59
|
- Follow every project-owned call path the plan will change through cross-module calls, state reads and writes, persistence, side effects, completion and failure signals, and consumers.
|
|
@@ -202,7 +208,7 @@ The code-reading phase is complete only when:
|
|
|
202
208
|
- every indirect callback, event, hook, queue, route, and dynamic dispatch path has been resolved
|
|
203
209
|
- every relevant state reader and writer has been read
|
|
204
210
|
- every relevant cross-file surface caller and consumer has been read
|
|
205
|
-
- every semantic relationship records LSP,
|
|
211
|
+
- every semantic relationship records LSP, runtime, external-boundary, or generated-boundary evidence
|
|
206
212
|
- no unresolved project-owned symbol remains
|
|
207
213
|
|
|
208
214
|
Do not diagnose the root cause or choose a fix before the Code Reading Closure is complete.
|
|
@@ -12,6 +12,13 @@ ${renderRoleMemoryRules("coder")}
|
|
|
12
12
|
- Implement assigned file/function-level scaffold items; do not analyze, review, dispute, or redesign architecture, module boundaries, public contracts, dependency direction, durable docs strategy, validation strategy, or final test adequacy.
|
|
13
13
|
- Treat the architecture plan and scaffold as execution instructions, not review targets. Do not critique, reinterpret, or challenge them during Coder work.
|
|
14
14
|
|
|
15
|
+
### Semantic Code Navigation
|
|
16
|
+
|
|
17
|
+
- Follow the preloaded \`vcm-code-navigation\` skill whenever implementation requires code definitions, implementations, references, callers, callees, or behavior paths.
|
|
18
|
+
- Use LSP for semantic relationships. Use Glob to locate files and Read to inspect complete code.
|
|
19
|
+
- Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
|
|
20
|
+
- If LSP cannot resolve a required project-owned relationship, record it as unresolved in the completion evidence. Do not replace semantic evidence with text matches.
|
|
21
|
+
|
|
15
22
|
### Shared Coding Standards
|
|
16
23
|
|
|
17
24
|
- Before editing production code or tests, read and follow \`docs/CODING_STANDARDS.md\`.
|
|
@@ -26,7 +33,7 @@ ${renderRoleMemoryRules("coder")}
|
|
|
26
33
|
- Do not stop before editing because of predicted architecture, design, contract, validation, or test failure; implement the assigned scaffold first.
|
|
27
34
|
- Use \`.ai/generated/module-index.json\` to locate approved module source and test files.
|
|
28
35
|
- Use \`.ai/generated/public-surface.json\` to avoid accidental public API drift.
|
|
29
|
-
-
|
|
36
|
+
- Use LSP definitions and references to locate assigned callable surfaces precisely.
|
|
30
37
|
|
|
31
38
|
### Implementation
|
|
32
39
|
|
|
@@ -15,20 +15,23 @@ Use only these decisions:
|
|
|
15
15
|
- \`approve\`: required gate evidence is present, current, internally consistent, sufficient for that gate, and has no gate-blocking finding.
|
|
16
16
|
- \`request_changes\`: evidence is missing, stale, contradictory, incomplete, insufficient, not reviewable, or unsafe.
|
|
17
17
|
|
|
18
|
+
## Semantic Code Navigation
|
|
19
|
+
|
|
20
|
+
Follow the preloaded \`vcm-code-navigation\` skill whenever a gate requires code definitions,
|
|
21
|
+
implementations, references, callers, callees, or behavior paths. Use LSP for
|
|
22
|
+
semantic relationships, Glob to locate files, Read to inspect complete code,
|
|
23
|
+
and generated context, architecture documents, or runtime evidence for
|
|
24
|
+
boundaries LSP does not model. Do not use the Grep tool or shell text-search
|
|
25
|
+
commands such as \`grep\`, \`rg\`, or \`git grep\`. If LSP cannot resolve
|
|
26
|
+
a required project-owned relationship, treat that evidence as unresolved and
|
|
27
|
+
return \`request_changes\`; do not replace semantic evidence with text matches.
|
|
28
|
+
|
|
18
29
|
Every Gate Review is a complete review of the current gate inputs. Review all
|
|
19
30
|
required evidence and rerun every required mechanical check before deciding.
|
|
20
31
|
Do not carry forward prior conclusions, closed checks, or partial verification.
|
|
21
32
|
Resolving prior findings does not replace the complete review. Return \`approve\`
|
|
22
33
|
or \`request_changes\` only after the review is complete.
|
|
23
34
|
|
|
24
|
-
Use \`vcm-code-navigation\` whenever a gate requires definitions, implementations,
|
|
25
|
-
references, call hierarchies, or a bounded behavior path. Use LSP semantic
|
|
26
|
-
navigation when available and read every resolved callable unit in full. Use
|
|
27
|
-
structural search when available and Grep for dynamic or textual edges and
|
|
28
|
-
explicit fallback discovery. Do not treat Grep as proof of a complete symbol,
|
|
29
|
-
caller, implementation, or reference set when LSP is available. If LSP cannot
|
|
30
|
-
resolve required evidence, record the limitation and exact fallback basis.
|
|
31
|
-
|
|
32
35
|
## Architecture Plan Gate
|
|
33
36
|
|
|
34
37
|
Format is necessary but not sufficient. Do not approve an architecture plan
|
|
@@ -469,7 +472,7 @@ If there are no findings, write:
|
|
|
469
472
|
None.
|
|
470
473
|
\`\`\`
|
|
471
474
|
|
|
472
|
-
Use Bash only for read-only inspection such as \`git diff\`, \`git status\`, \`git show\`, \`ls\`, \`
|
|
475
|
+
Use Bash only for read-only inspection such as \`git diff\`, \`git status\`, \`git show\`, \`ls\`, \`sed\`, or \`cat\`. Do not run shell text-search commands, tests, builds, formatters, generators, package managers, or commands that modify files.
|
|
473
476
|
|
|
474
477
|
Review only code, architecture, and documents; do not perform validation. Do not edit code, tests, durable docs, role files, route files, or handoff artifacts. Do not assign findings or remediation work to VCM roles, choose fixes, decide Replan, or decide whether user intervention is needed.
|
|
475
478
|
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
export function renderVcmCodeNavigationSkillRules() {
|
|
2
2
|
return `## Purpose
|
|
3
3
|
|
|
4
|
-
Use this skill when Architect or Reviewer must establish symbol definitions, implementations, references, callers, callees, or a bounded behavior path from current-worktree evidence.
|
|
4
|
+
Use this skill when Architect, Coder, or Reviewer must establish symbol definitions, implementations, references, callers, callees, or a bounded behavior path from current-worktree evidence.
|
|
5
5
|
|
|
6
6
|
## Navigation Order
|
|
7
7
|
|
|
8
8
|
1. Define the affected feature or module boundary and locate entry symbols with \`.ai/generated/module-index.json\` and \`.ai/generated/public-surface.json\` when available.
|
|
9
|
-
2.
|
|
10
|
-
3.
|
|
11
|
-
4.
|
|
12
|
-
5.
|
|
9
|
+
2. Start each navigation run with LSP \`documentSymbol\` on a known affected project source file. This initializes the actual role-session language server and proves that it can parse that file; an executable version probe is not workspace readiness.
|
|
10
|
+
3. Use LSP workspace or file symbols, definitions, implementations, references, and incoming or outgoing call hierarchy to resolve project-owned relationships.
|
|
11
|
+
4. If an initial workspace-symbol request is empty or reports indexing, do not conclude that the symbol is absent. After a successful file-symbol request, retry the same bounded workspace query at most two more times. If it still cannot resolve, record the operation and result as unresolved.
|
|
12
|
+
5. Read the complete project-owned callable unit at every resolved location.
|
|
13
|
+
6. Expand one project-owned dependency hop at a time until the required behavior path has no unresolved symbol.
|
|
14
|
+
7. Use Glob, generated context, architecture documents, and runtime evidence to locate dynamic registrations, configuration or string edges, macros, documentation, and external boundaries that LSP does not model.
|
|
13
15
|
|
|
14
16
|
## Evidence
|
|
15
17
|
|
|
16
|
-
- Record each resolved relationship and whether it came from LSP,
|
|
17
|
-
- Do not treat a Grep result as proof of a complete definition, caller, implementation, or reference set when LSP is available.
|
|
18
|
+
- Record each resolved relationship and whether it came from LSP, runtime evidence, an external boundary, or a generated boundary.
|
|
18
19
|
- When an empty LSP result contradicts a direct call in the code, another LSP result, or runtime evidence, treat the relationship as unresolved. Record the contradiction and use exact fallback evidence.
|
|
19
|
-
- If LSP is unavailable or cannot resolve a relationship, record that limitation and the
|
|
20
|
+
- If LSP is unavailable or cannot resolve a required project-owned relationship, record that limitation and leave the relationship unresolved. Do not substitute text search for semantic navigation.
|
|
21
|
+
- Do not use the Grep tool or shell text-search commands such as \`grep\`, \`rg\`, or \`git grep\`.
|
|
20
22
|
- Generated indexes and architecture docs locate likely code; reading current-worktree implementation establishes behavior.
|
|
21
23
|
|
|
22
24
|
## Context Boundary
|