cc-dev-template 0.1.61 → 0.1.63
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/bin/install.js +22 -2
- package/package.json +1 -1
- package/src/agents/spec-implementer.md +39 -4
- package/src/agents/spec-validator.md +45 -8
- package/src/scripts/block-task-files.sh +23 -0
- package/src/scripts/parse-task-files.js +120 -0
- package/src/scripts/spinner-verbs-factorio.json +27 -0
- package/src/scripts/spinner-verbs-helldivers.json +27 -0
- package/src/skills/execute-spec/SKILL.md +18 -6
- package/src/skills/execute-spec/references/phase-1-hydrate.md +52 -46
- package/src/skills/execute-spec/references/phase-4-triage.md +49 -77
- package/src/skills/execute-spec/references/workflow.md +35 -53
package/bin/install.js
CHANGED
|
@@ -71,7 +71,24 @@ console.log(agentCount ? `✓ ${agentCount} agents installed` : ' No agents to
|
|
|
71
71
|
console.log('\nScripts:');
|
|
72
72
|
const scriptCount = copyFiles('scripts', 'scripts', '.js');
|
|
73
73
|
const jsonCount = copyFiles('scripts', 'scripts', '.json');
|
|
74
|
-
|
|
74
|
+
|
|
75
|
+
// Copy shell scripts and make executable
|
|
76
|
+
const scriptsDir = path.join(SRC_DIR, 'scripts');
|
|
77
|
+
let shellCount = 0;
|
|
78
|
+
if (fs.existsSync(scriptsDir)) {
|
|
79
|
+
const shellScripts = fs.readdirSync(scriptsDir).filter(f => f.endsWith('.sh'));
|
|
80
|
+
shellScripts.forEach(file => {
|
|
81
|
+
const src = path.join(scriptsDir, file);
|
|
82
|
+
const dest = path.join(CLAUDE_DIR, 'scripts', file);
|
|
83
|
+
fs.copyFileSync(src, dest);
|
|
84
|
+
fs.chmodSync(dest, 0o755);
|
|
85
|
+
console.log(` ${file}`);
|
|
86
|
+
shellCount++;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const totalScripts = scriptCount + jsonCount + shellCount;
|
|
91
|
+
console.log(totalScripts ? `✓ ${totalScripts} scripts installed` : ' No scripts to install');
|
|
75
92
|
|
|
76
93
|
// Copy skills (entire directories)
|
|
77
94
|
console.log('\nSkills:');
|
|
@@ -238,7 +255,10 @@ if (fs.existsSync(mergeSettingsPath)) {
|
|
|
238
255
|
{ file: 'read-guard-hook.json', name: 'Context guard for large reads' },
|
|
239
256
|
{ file: 'statusline-config.json', name: 'Custom status line' },
|
|
240
257
|
{ file: 'bash-overflow-hook.json', name: 'Bash overflow guard hook' },
|
|
241
|
-
{ file: 'env-config.json', name: 'Environment variables' }
|
|
258
|
+
{ file: 'env-config.json', name: 'Environment variables' },
|
|
259
|
+
// Spinner verbs - choose one (Helldivers or Factorio)
|
|
260
|
+
{ file: 'spinner-verbs-helldivers.json', name: 'Helldivers spinner verbs' }
|
|
261
|
+
// { file: 'spinner-verbs-factorio.json', name: 'Factorio spinner verbs' }
|
|
242
262
|
];
|
|
243
263
|
|
|
244
264
|
configs.forEach(({ file, name }) => {
|
package/package.json
CHANGED
|
@@ -6,11 +6,46 @@ tools: Read, Grep, Glob, Edit, Write, Bash, LSP
|
|
|
6
6
|
|
|
7
7
|
You implement one task from a spec breakdown.
|
|
8
8
|
|
|
9
|
+
## Process
|
|
10
|
+
|
|
9
11
|
When given a task file path:
|
|
10
12
|
|
|
11
13
|
1. Read the task file at that path
|
|
12
14
|
2. Read the spec file in the parent directory (`../spec.md`)
|
|
13
|
-
3.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
3. Check the **Review Notes** section of the task file:
|
|
16
|
+
- **If issues exist**: Address those specific issues (fix mode)
|
|
17
|
+
- **If empty**: Implement from scratch per the Criterion (initial mode)
|
|
18
|
+
4. Implement the work, touching only files listed in the **Files** section
|
|
19
|
+
5. Append your work summary to **Implementation Notes** (see format below)
|
|
20
|
+
6. Return minimal status (see Output section)
|
|
21
|
+
|
|
22
|
+
## Implementation Notes Format
|
|
23
|
+
|
|
24
|
+
Append a new section with timestamp:
|
|
25
|
+
|
|
26
|
+
```markdown
|
|
27
|
+
### Pass N (YYYY-MM-DD HH:MM)
|
|
28
|
+
|
|
29
|
+
[Brief summary of what you implemented or fixed]
|
|
30
|
+
|
|
31
|
+
Files modified:
|
|
32
|
+
- path/to/file.ts - [what changed]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Do NOT overwrite previous passes. The log provides debugging context.
|
|
36
|
+
|
|
37
|
+
## Output (Critical)
|
|
38
|
+
|
|
39
|
+
Return ONLY a minimal status message. All details go in the task file.
|
|
40
|
+
|
|
41
|
+
**Success:**
|
|
42
|
+
```
|
|
43
|
+
Task complete: T005-variant-selection.md
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Blocked:**
|
|
47
|
+
```
|
|
48
|
+
Blocked: T005 - [one-line reason why you cannot proceed]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Do NOT return tables, code snippets, file listings, or detailed explanations. The orchestrator only needs pass/fail status. All details belong in the task file's Implementation Notes section.
|
|
@@ -6,18 +6,23 @@ tools: Read, Grep, Glob, Bash
|
|
|
6
6
|
|
|
7
7
|
You are a senior QA engineer validating completed work.
|
|
8
8
|
|
|
9
|
+
## Process
|
|
10
|
+
|
|
9
11
|
When given a task file path:
|
|
10
12
|
|
|
11
13
|
1. Read the task file and parent spec (`../spec.md`)
|
|
12
14
|
2. Read the **Implementation Notes** to understand what was built
|
|
15
|
+
3. Perform validation (see steps below)
|
|
16
|
+
4. Append findings to **Review Notes** (see format below)
|
|
17
|
+
5. Return minimal status (see Output section)
|
|
13
18
|
|
|
14
19
|
## Step 1: Code Review + Automated Tests
|
|
15
20
|
|
|
16
21
|
- Run automated tests if they exist (look for test files, run with appropriate test runner)
|
|
17
22
|
- Check for code smells:
|
|
18
|
-
- Files over 300 lines: Can this logically split into multiple files, or does it need to be one file?
|
|
23
|
+
- Files over 300 lines: Can this logically split into multiple files, or does it need to be one file?
|
|
19
24
|
- Missing error handling, unclear naming, other quality issues
|
|
20
|
-
- Note
|
|
25
|
+
- Note concerns for Review Notes
|
|
21
26
|
|
|
22
27
|
## Step 2: E2E Testing with agent-browser
|
|
23
28
|
|
|
@@ -32,11 +37,43 @@ Run `agent-browser --help` if you need to understand its capabilities.
|
|
|
32
37
|
- Does the feature work as a user would expect?
|
|
33
38
|
- Close your session when finished: `agent-browser close --session validator-{task-id}`
|
|
34
39
|
|
|
35
|
-
##
|
|
40
|
+
## Review Notes Format
|
|
41
|
+
|
|
42
|
+
Append a new section with timestamp:
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
### Pass N (YYYY-MM-DD HH:MM)
|
|
46
|
+
|
|
47
|
+
**Result**: PASS | FAIL
|
|
48
|
+
|
|
49
|
+
**Issues** (if any):
|
|
50
|
+
- [critical] one-line description
|
|
51
|
+
- [warning] one-line description
|
|
52
|
+
- [suggestion] one-line description
|
|
53
|
+
|
|
54
|
+
**E2E Tests**:
|
|
55
|
+
- [pass/fail] Test description
|
|
56
|
+
|
|
57
|
+
**Notes**: [Any additional context needed for fix]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Do NOT overwrite previous passes. The log provides debugging context.
|
|
61
|
+
|
|
62
|
+
## Output (Critical)
|
|
63
|
+
|
|
64
|
+
Return ONLY a minimal status message. All details go in the task file.
|
|
65
|
+
|
|
66
|
+
**Pass:**
|
|
67
|
+
```
|
|
68
|
+
Pass: T005
|
|
69
|
+
```
|
|
36
70
|
|
|
37
|
-
|
|
71
|
+
**Issues found:**
|
|
72
|
+
```
|
|
73
|
+
Issues: T005
|
|
74
|
+
- [critical] one-line summary
|
|
75
|
+
- [warning] one-line summary
|
|
76
|
+
Details in Review Notes.
|
|
77
|
+
```
|
|
38
78
|
|
|
39
|
-
|
|
40
|
-
- Files that may need refactoring (with reasoning)
|
|
41
|
-
- E2E test results (what worked, what didn't)
|
|
42
|
-
- Overall pass/fail assessment
|
|
79
|
+
Do NOT return tables, code snippets, detailed logs, or lengthy explanations. The orchestrator only needs pass/fail to decide next action. All details belong in the task file's Review Notes section.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# PreToolUse hook for execute-spec skill
|
|
4
|
+
# Blocks the orchestrator from reading task files directly
|
|
5
|
+
# Task files should only be read by implementer/validator agents
|
|
6
|
+
|
|
7
|
+
INPUT=$(cat)
|
|
8
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
9
|
+
|
|
10
|
+
# Check if this is a task file (pattern: */tasks/T*.md)
|
|
11
|
+
if [[ "$FILE_PATH" =~ /tasks/T[0-9]+.*\.md$ ]]; then
|
|
12
|
+
jq -n '{
|
|
13
|
+
"hookSpecificOutput": {
|
|
14
|
+
"hookEventName": "PreToolUse",
|
|
15
|
+
"permissionDecision": "deny",
|
|
16
|
+
"permissionDecisionReason": "Task files should be read by spec-implementer/spec-validator agents, not the orchestrator. Pass the file path to agents and let them read it."
|
|
17
|
+
}
|
|
18
|
+
}'
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Allow all other reads
|
|
23
|
+
exit 0
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Parses task files from a spec directory and returns structured JSON.
|
|
5
|
+
* Used by execute-spec orchestrator to hydrate tasks without reading full file contents.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node parse-task-files.js <spec-path>
|
|
8
|
+
* Example: node parse-task-files.js docs/specs/kiosk-storefront
|
|
9
|
+
*
|
|
10
|
+
* Output: JSON with task metadata (id, title, depends_on, path)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
function parseYamlFrontmatter(content) {
|
|
17
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
18
|
+
if (!match) return null;
|
|
19
|
+
|
|
20
|
+
const yaml = match[1];
|
|
21
|
+
const result = {};
|
|
22
|
+
|
|
23
|
+
// Simple YAML parsing for our known fields
|
|
24
|
+
const lines = yaml.split('\n');
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
const idMatch = line.match(/^id:\s*(.+)/);
|
|
27
|
+
if (idMatch) result.id = idMatch[1].trim();
|
|
28
|
+
|
|
29
|
+
const titleMatch = line.match(/^title:\s*(.+)/);
|
|
30
|
+
if (titleMatch) result.title = titleMatch[1].trim();
|
|
31
|
+
|
|
32
|
+
const statusMatch = line.match(/^status:\s*(.+)/);
|
|
33
|
+
if (statusMatch) result.status = statusMatch[1].trim();
|
|
34
|
+
|
|
35
|
+
const dependsMatch = line.match(/^depends_on:\s*\[(.*)\]/);
|
|
36
|
+
if (dependsMatch) {
|
|
37
|
+
const deps = dependsMatch[1].trim();
|
|
38
|
+
result.depends_on = deps ? deps.split(',').map(d => d.trim()) : [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Handle multi-line depends_on
|
|
43
|
+
if (!result.depends_on) {
|
|
44
|
+
const depsSection = yaml.match(/depends_on:\s*\n((?:\s+-\s*.+\n?)*)/);
|
|
45
|
+
if (depsSection) {
|
|
46
|
+
result.depends_on = depsSection[1]
|
|
47
|
+
.split('\n')
|
|
48
|
+
.map(line => line.replace(/^\s*-\s*/, '').trim())
|
|
49
|
+
.filter(Boolean);
|
|
50
|
+
} else {
|
|
51
|
+
result.depends_on = [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function main() {
|
|
59
|
+
const specPath = process.argv[2];
|
|
60
|
+
|
|
61
|
+
if (!specPath) {
|
|
62
|
+
console.error(JSON.stringify({ error: 'Usage: parse-task-files.js <spec-path>' }));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const tasksDir = path.join(specPath, 'tasks');
|
|
67
|
+
const specFile = path.join(specPath, 'spec.md');
|
|
68
|
+
|
|
69
|
+
// Validate spec structure
|
|
70
|
+
if (!fs.existsSync(specFile)) {
|
|
71
|
+
console.error(JSON.stringify({ error: `Spec file not found: ${specFile}` }));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(tasksDir)) {
|
|
76
|
+
console.error(JSON.stringify({ error: `Tasks directory not found: ${tasksDir}` }));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Find and parse task files
|
|
81
|
+
const taskFiles = fs.readdirSync(tasksDir)
|
|
82
|
+
.filter(f => f.match(/^T\d+.*\.md$/))
|
|
83
|
+
.sort();
|
|
84
|
+
|
|
85
|
+
if (taskFiles.length === 0) {
|
|
86
|
+
console.error(JSON.stringify({ error: 'No task files found (expected T*.md)' }));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const tasks = [];
|
|
91
|
+
|
|
92
|
+
for (const file of taskFiles) {
|
|
93
|
+
const filePath = path.join(tasksDir, file);
|
|
94
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
95
|
+
const frontmatter = parseYamlFrontmatter(content);
|
|
96
|
+
|
|
97
|
+
if (!frontmatter || !frontmatter.id) {
|
|
98
|
+
console.error(JSON.stringify({ error: `Invalid frontmatter in ${file}` }));
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
tasks.push({
|
|
103
|
+
id: frontmatter.id,
|
|
104
|
+
title: frontmatter.title || file.replace('.md', ''),
|
|
105
|
+
status: frontmatter.status || 'pending',
|
|
106
|
+
depends_on: frontmatter.depends_on || [],
|
|
107
|
+
path: filePath
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Output structured JSON
|
|
112
|
+
console.log(JSON.stringify({
|
|
113
|
+
specPath: specPath,
|
|
114
|
+
specFile: specFile,
|
|
115
|
+
taskCount: tasks.length,
|
|
116
|
+
tasks: tasks
|
|
117
|
+
}, null, 2));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
main();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"spinnerVerbs": {
|
|
3
|
+
"mode": "replace",
|
|
4
|
+
"verbs": [
|
|
5
|
+
"Optimizing ratios",
|
|
6
|
+
"Expanding the factory",
|
|
7
|
+
"Researching technology",
|
|
8
|
+
"Balancing belts",
|
|
9
|
+
"Routing logistics",
|
|
10
|
+
"Smelting ore",
|
|
11
|
+
"Automating production",
|
|
12
|
+
"Deploying blueprints",
|
|
13
|
+
"Scaling throughput",
|
|
14
|
+
"Refining petroleum",
|
|
15
|
+
"Extending rail network",
|
|
16
|
+
"Calculating ratios",
|
|
17
|
+
"Processing resources",
|
|
18
|
+
"Assembling components",
|
|
19
|
+
"Constructing outpost",
|
|
20
|
+
"Launching rockets",
|
|
21
|
+
"Clearing biters",
|
|
22
|
+
"Inserting inserters",
|
|
23
|
+
"Growing the factory",
|
|
24
|
+
"The factory must grow"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"spinnerVerbs": {
|
|
3
|
+
"mode": "replace",
|
|
4
|
+
"verbs": [
|
|
5
|
+
"Spreading democracy",
|
|
6
|
+
"Liberating",
|
|
7
|
+
"Deploying stratagems",
|
|
8
|
+
"Calling in reinforcements",
|
|
9
|
+
"Eliminating hostiles",
|
|
10
|
+
"Securing perimeter",
|
|
11
|
+
"Extracting intel",
|
|
12
|
+
"Suppressing resistance",
|
|
13
|
+
"Dispensing freedom",
|
|
14
|
+
"Neutralizing threats",
|
|
15
|
+
"Conducting reconnaissance",
|
|
16
|
+
"Mobilizing forces",
|
|
17
|
+
"Purging enemies",
|
|
18
|
+
"Defending liberty",
|
|
19
|
+
"Executing orbital strike",
|
|
20
|
+
"Requesting extraction",
|
|
21
|
+
"Fortifying position",
|
|
22
|
+
"Engaging targets",
|
|
23
|
+
"Invoking Super Earth",
|
|
24
|
+
"Upholding managed democracy"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
---
|
|
2
|
-
allowed-tools:
|
|
2
|
+
allowed-tools: Grep, Glob, Task, TaskCreate, TaskList, TaskUpdate, TaskGet, AskUserQuestion, Bash
|
|
3
|
+
hooks:
|
|
4
|
+
PreToolUse:
|
|
5
|
+
- matcher: "Read"
|
|
6
|
+
hooks:
|
|
7
|
+
- type: command
|
|
8
|
+
command: "$HOME/.claude/scripts/block-task-files.sh"
|
|
3
9
|
---
|
|
4
10
|
|
|
5
11
|
# Execute Spec
|
|
6
12
|
|
|
7
13
|
Orchestrates the implementation and validation of a spec's task breakdown.
|
|
8
14
|
|
|
9
|
-
**Important**: This skill is an orchestrator. It
|
|
15
|
+
**Important**: This skill is an orchestrator only. It does NOT read task files or edit code directly. It dispatches agents and receives minimal status responses. All detailed work happens in the agents; all detailed findings live in the task files.
|
|
10
16
|
|
|
11
17
|
## When to Use
|
|
12
18
|
|
|
@@ -23,10 +29,16 @@ Read `references/workflow.md` for the full orchestration flow.
|
|
|
23
29
|
|
|
24
30
|
## Phases
|
|
25
31
|
|
|
26
|
-
1. **Hydrate** -
|
|
27
|
-
2. **Build** - Dispatch spec-implementer agents
|
|
28
|
-
3. **Validate** - Dispatch spec-validator agents
|
|
29
|
-
4. **Triage** -
|
|
32
|
+
1. **Hydrate** - Run parse script, create tasks with dependencies (NO file reading)
|
|
33
|
+
2. **Build** - Dispatch spec-implementer agents, receive minimal status
|
|
34
|
+
3. **Validate** - Dispatch spec-validator agents, receive pass/fail
|
|
35
|
+
4. **Triage** - Re-dispatch implementers for failed tasks, loop until clean
|
|
36
|
+
|
|
37
|
+
## Key Principles
|
|
38
|
+
|
|
39
|
+
- **Never read task files** - Use the parse script for hydration, pass paths to agents
|
|
40
|
+
- **Minimal context** - Agent returns are pass/fail only, details in task files
|
|
41
|
+
- **Delegate everything** - Fixes go to spec-implementer, not done by orchestrator
|
|
30
42
|
|
|
31
43
|
## Requirements
|
|
32
44
|
|
|
@@ -1,65 +1,71 @@
|
|
|
1
1
|
# Phase 1: Hydrate Tasks
|
|
2
2
|
|
|
3
|
-
Load task
|
|
3
|
+
Load task metadata into the Claude Code task system using the parse script.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Important: No File Reading
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The orchestrator does NOT read task files directly. Use the parse script.
|
|
8
8
|
|
|
9
9
|
## Process
|
|
10
10
|
|
|
11
|
+
```bash
|
|
12
|
+
# Run the parse script
|
|
13
|
+
node ~/.claude/scripts/parse-task-files.js {spec-path}
|
|
11
14
|
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
taskId: {claude-task-id},
|
|
36
|
-
addBlockedBy: [mapped-claude-task-ids]
|
|
37
|
-
)
|
|
15
|
+
|
|
16
|
+
This outputs JSON:
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"specPath": "docs/specs/kiosk-storefront",
|
|
20
|
+
"specFile": "docs/specs/kiosk-storefront/spec.md",
|
|
21
|
+
"taskCount": 15,
|
|
22
|
+
"tasks": [
|
|
23
|
+
{
|
|
24
|
+
"id": "T001",
|
|
25
|
+
"title": "Public API endpoints",
|
|
26
|
+
"status": "pending",
|
|
27
|
+
"depends_on": [],
|
|
28
|
+
"path": "docs/specs/kiosk-storefront/tasks/T001-public-api-endpoints.md"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "T002",
|
|
32
|
+
"title": "Kiosk routing",
|
|
33
|
+
"depends_on": ["T001"],
|
|
34
|
+
"path": "..."
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
##
|
|
40
|
+
## Create Tasks
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
For each task in the JSON:
|
|
43
43
|
|
|
44
|
-
Maintain a mapping:
|
|
45
44
|
```
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
TaskCreate(
|
|
46
|
+
subject: "{id}: {title}",
|
|
47
|
+
description: "{path}",
|
|
48
|
+
activeForm: "Implementing {title}"
|
|
49
|
+
)
|
|
51
50
|
```
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
The description is JUST the path. Agents read the file themselves.
|
|
54
53
|
|
|
55
|
-
##
|
|
54
|
+
## Set Dependencies
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
- Dependencies correctly configured
|
|
59
|
-
- Ready for Phase 2: Build
|
|
56
|
+
After creating all tasks, set up blockedBy relationships:
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
```
|
|
59
|
+
TaskUpdate(
|
|
60
|
+
taskId: {claude-task-id},
|
|
61
|
+
addBlockedBy: [mapped IDs from depends_on]
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Maintain a mapping of task IDs (T001, T002) to Claude task system IDs.
|
|
66
|
+
|
|
67
|
+
## Output
|
|
62
68
|
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
69
|
+
- All tasks in Claude Code task system
|
|
70
|
+
- Dependencies configured
|
|
71
|
+
- Ready for Phase 2
|
|
@@ -1,103 +1,75 @@
|
|
|
1
1
|
# Phase 4: Triage
|
|
2
2
|
|
|
3
|
-
Process validation
|
|
3
|
+
Process validation results and iterate until all tasks pass.
|
|
4
4
|
|
|
5
5
|
## Process
|
|
6
6
|
|
|
7
7
|
```
|
|
8
|
-
1. Collect
|
|
9
|
-
|
|
10
|
-
2. Categorize issues:
|
|
11
|
-
|
|
12
|
-
EASY FIXES (dispatch automatically):
|
|
13
|
-
- Missing import
|
|
14
|
-
- Typo in text
|
|
15
|
-
- Small styling fix
|
|
16
|
-
- Test assertion needs update
|
|
17
|
-
- File exists but missing export
|
|
18
|
-
|
|
19
|
-
COMPLEX ISSUES (ask user):
|
|
20
|
-
- Architectural concerns
|
|
21
|
-
- "Should we refactor X into Y?"
|
|
22
|
-
- Unclear requirements
|
|
23
|
-
- Trade-off decisions
|
|
24
|
-
- Performance concerns with multiple valid approaches
|
|
25
|
-
|
|
26
|
-
3. For easy fixes:
|
|
27
|
-
- Dispatch fix agent with specific instructions
|
|
28
|
-
- Agent makes the fix
|
|
29
|
-
- Re-run validator for affected task
|
|
30
|
-
|
|
31
|
-
4. For complex issues:
|
|
32
|
-
- Use AskUserQuestion to discuss with user
|
|
33
|
-
- Present the issue and options
|
|
34
|
-
- Implement based on user decision
|
|
35
|
-
- Or user may defer ("not now, add to backlog")
|
|
36
|
-
|
|
37
|
-
5. Repeat until:
|
|
38
|
-
- No issues remain, OR
|
|
39
|
-
- All remaining issues are deferred by user
|
|
40
|
-
```
|
|
8
|
+
1. Collect failed task IDs from validator returns
|
|
9
|
+
(Returns are minimal: "Issues: T005 - [brief list]")
|
|
41
10
|
|
|
42
|
-
|
|
11
|
+
2. For each failed task:
|
|
12
|
+
- Re-dispatch spec-implementer with the task path
|
|
13
|
+
- Implementer reads Review Notes and addresses issues
|
|
14
|
+
- Returns: "Task complete: T005"
|
|
43
15
|
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
- UI is broken
|
|
47
|
-
- Test failures
|
|
16
|
+
3. Re-run spec-validator on fixed tasks
|
|
17
|
+
- Returns: "Pass: T005" or "Issues: T005 - ..."
|
|
48
18
|
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
|
|
19
|
+
4. Repeat until:
|
|
20
|
+
- All tasks pass, OR
|
|
21
|
+
- User defers remaining issues
|
|
22
|
+
```
|
|
53
23
|
|
|
54
|
-
|
|
55
|
-
- Refactoring opportunities
|
|
56
|
-
- Performance optimizations
|
|
57
|
-
- Style improvements
|
|
24
|
+
## No Separate Fixer Agent
|
|
58
25
|
|
|
59
|
-
|
|
26
|
+
The spec-implementer handles fixes. When it reads the task file:
|
|
27
|
+
- If Review Notes has issues → fix mode (address those issues)
|
|
28
|
+
- If Review Notes is empty → initial mode (implement from scratch)
|
|
60
29
|
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
Task(
|
|
64
|
-
subagent_type: "general-purpose",
|
|
65
|
-
prompt: "Fix this issue in {file}:
|
|
66
|
-
Problem: {issue description}
|
|
67
|
-
Expected: {what it should be}
|
|
68
|
-
|
|
69
|
-
Make the minimal fix needed.",
|
|
70
|
-
run_in_background: true
|
|
71
|
-
)
|
|
72
|
-
```
|
|
30
|
+
The task file's Review Notes section IS the feedback mechanism.
|
|
73
31
|
|
|
74
|
-
##
|
|
32
|
+
## When to Escalate to User
|
|
33
|
+
|
|
34
|
+
Use AskUserQuestion when:
|
|
35
|
+
- Same issue persists after 2+ fix attempts
|
|
36
|
+
- Issue is architectural or unclear how to resolve
|
|
37
|
+
- Trade-off decision needed (performance vs simplicity, etc.)
|
|
75
38
|
|
|
76
39
|
```
|
|
77
40
|
AskUserQuestion(
|
|
78
41
|
questions: [{
|
|
79
|
-
header: "
|
|
80
|
-
question: "
|
|
42
|
+
header: "Fix approach",
|
|
43
|
+
question: "T005 failed twice with: [issue]. How should we proceed?",
|
|
81
44
|
options: [
|
|
82
|
-
{ label: "
|
|
83
|
-
{ label: "
|
|
84
|
-
{ label: "Defer", description: "
|
|
45
|
+
{ label: "Try approach A", description: "..." },
|
|
46
|
+
{ label: "Try approach B", description: "..." },
|
|
47
|
+
{ label: "Defer", description: "Skip for now, add to backlog" }
|
|
85
48
|
]
|
|
86
49
|
}]
|
|
87
50
|
)
|
|
88
51
|
```
|
|
89
52
|
|
|
90
|
-
##
|
|
53
|
+
## Log-Based History
|
|
54
|
+
|
|
55
|
+
Each pass appends to the task file:
|
|
56
|
+
- Implementer appends to Implementation Notes
|
|
57
|
+
- Validator appends to Review Notes
|
|
91
58
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
59
|
+
This creates a debugging trail:
|
|
60
|
+
```
|
|
61
|
+
Implementation Notes:
|
|
62
|
+
Pass 1: Initial implementation...
|
|
63
|
+
Pass 2: Fixed idle timer issue...
|
|
64
|
+
|
|
65
|
+
Review Notes:
|
|
66
|
+
Pass 1: [critical] Timer doesn't pause...
|
|
67
|
+
Pass 2: [pass] All issues resolved
|
|
68
|
+
```
|
|
97
69
|
|
|
98
|
-
##
|
|
70
|
+
## Exit Conditions
|
|
99
71
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
72
|
+
Phase completes when:
|
|
73
|
+
1. All validators return "Pass: TXXX"
|
|
74
|
+
2. User explicitly defers remaining issues
|
|
75
|
+
3. Max retry limit reached (suggest user intervention)
|
|
@@ -4,89 +4,71 @@
|
|
|
4
4
|
|
|
5
5
|
```
|
|
6
6
|
PHASE 1: HYDRATE
|
|
7
|
-
|
|
7
|
+
Run parse script → TaskCreate with dependencies
|
|
8
|
+
(NO file reading by orchestrator)
|
|
8
9
|
|
|
9
10
|
PHASE 2: BUILD
|
|
10
|
-
Loop: find unblocked tasks → dispatch spec-implementer →
|
|
11
|
+
Loop: find unblocked tasks → dispatch spec-implementer → receive minimal status
|
|
11
12
|
Continue until all tasks built
|
|
12
13
|
|
|
13
14
|
PHASE 3: VALIDATE
|
|
14
15
|
Dispatch spec-validator for each task (all in parallel)
|
|
15
|
-
|
|
16
|
+
Receive pass/fail status only
|
|
16
17
|
|
|
17
18
|
PHASE 4: TRIAGE
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Complex → AskUserQuestion, discuss with user
|
|
21
|
-
Re-validate affected tasks
|
|
19
|
+
For failed tasks: re-dispatch spec-implementer
|
|
20
|
+
Re-validate
|
|
22
21
|
Loop until clean or user defers
|
|
23
22
|
```
|
|
24
23
|
|
|
24
|
+
## Critical: Minimal Context
|
|
25
|
+
|
|
26
|
+
**Agent returns are pass/fail only.** All details go in task files.
|
|
27
|
+
|
|
28
|
+
- Implementer returns: `Task complete: T005` or `Blocked: T005 - reason`
|
|
29
|
+
- Validator returns: `Pass: T005` or `Issues: T005 - [brief list]`
|
|
30
|
+
|
|
31
|
+
The orchestrator never reads task files. It dispatches paths and receives status.
|
|
32
|
+
|
|
25
33
|
## Phase 1: Hydrate
|
|
26
34
|
|
|
27
35
|
Read `phase-1-hydrate.md` for details.
|
|
28
36
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
4. Output: All tasks loaded into the task system with proper dependency graph
|
|
37
|
+
Use the parse script to get task metadata:
|
|
38
|
+
```bash
|
|
39
|
+
node ~/.claude/scripts/parse-task-files.js {spec-path}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This returns JSON with task IDs, titles, dependencies, and paths. Create tasks from this output without reading any files.
|
|
36
43
|
|
|
37
44
|
## Phase 2: Build
|
|
38
45
|
|
|
39
46
|
Read `phase-2-build.md` for details.
|
|
40
47
|
|
|
41
|
-
1.
|
|
42
|
-
2.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Task(
|
|
46
|
-
subagent_type: "spec-implementer",
|
|
47
|
-
prompt: "{full-path-to-task-file}",
|
|
48
|
-
run_in_background: true
|
|
49
|
-
)
|
|
50
|
-
```
|
|
51
|
-
3. Monitor for completions (agents will mark tasks complete)
|
|
52
|
-
4. As tasks complete, check for newly unblocked tasks
|
|
53
|
-
5. Repeat until all build tasks are complete
|
|
48
|
+
1. Find unblocked tasks via TaskList
|
|
49
|
+
2. Dispatch spec-implementer with just the file path
|
|
50
|
+
3. Receive minimal status (pass/fail)
|
|
51
|
+
4. Repeat until all built
|
|
54
52
|
|
|
55
53
|
## Phase 3: Validate
|
|
56
54
|
|
|
57
55
|
Read `phase-3-validate.md` for details.
|
|
58
56
|
|
|
59
|
-
1.
|
|
60
|
-
2.
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
Task(
|
|
64
|
-
subagent_type: "spec-validator",
|
|
65
|
-
prompt: "{full-path-to-task-file}",
|
|
66
|
-
run_in_background: true
|
|
67
|
-
)
|
|
68
|
-
```
|
|
69
|
-
3. Validators run in parallel (they create isolated browser sessions)
|
|
70
|
-
4. Wait for all validators to complete
|
|
71
|
-
5. Collect findings from Review Notes sections
|
|
57
|
+
1. Dispatch spec-validator for each task (parallel)
|
|
58
|
+
2. Receive pass/fail status
|
|
59
|
+
3. Collect list of failed task IDs
|
|
72
60
|
|
|
73
61
|
## Phase 4: Triage
|
|
74
62
|
|
|
75
63
|
Read `phase-4-triage.md` for details.
|
|
76
64
|
|
|
77
|
-
1.
|
|
78
|
-
2.
|
|
79
|
-
3.
|
|
80
|
-
- **Easy fixes**: Clear problem, obvious solution → dispatch fix agent
|
|
81
|
-
- **Complex issues**: Ambiguous, architectural, needs discussion → AskUserQuestion
|
|
82
|
-
4. After fixes, re-run validation on affected tasks
|
|
83
|
-
5. Loop until:
|
|
84
|
-
- No issues remain, OR
|
|
85
|
-
- User explicitly defers remaining issues
|
|
65
|
+
1. For failed tasks: re-dispatch spec-implementer (it reads Review Notes and fixes)
|
|
66
|
+
2. Re-run spec-validator on fixed tasks
|
|
67
|
+
3. Loop until all pass or user defers remaining issues
|
|
86
68
|
|
|
87
69
|
## Key Principles
|
|
88
70
|
|
|
89
|
-
- **
|
|
90
|
-
- **
|
|
91
|
-
- **
|
|
92
|
-
- **
|
|
71
|
+
- **No file reading by orchestrator** - Hook blocks task file reads
|
|
72
|
+
- **Minimal returns** - Agents return status only, details in task files
|
|
73
|
+
- **Task file is source of truth** - Implementation Notes and Review Notes track all history
|
|
74
|
+
- **Parallelism** - Use `run_in_background: true` where possible
|