cc-dev-template 0.1.66 → 0.1.73
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 +8 -0
- package/package.json +1 -1
- package/src/agents/spec-implementer.md +1 -0
- package/src/agents/spec-validator.md +1 -0
- package/src/scripts/statusline.js +184 -4
- package/src/scripts/task-output-guard-hook.json +15 -0
- package/src/scripts/task-output-guard.js +149 -0
- package/src/skills/execute-spec/references/phase-2-build.md +0 -1
- package/src/skills/execute-spec/references/phase-3-validate.md +2 -6
- package/src/skills/spec-interview/SKILL.md +27 -11
- package/src/skills/spec-interview/references/critic-prompt.md +140 -0
- package/src/skills/spec-interview/references/pragmatist-prompt.md +76 -0
- package/src/skills/spec-interview/references/researcher-prompt.md +46 -0
- package/src/skills/spec-interview/references/step-1-opening.md +27 -1
- package/src/skills/spec-interview/references/step-2-ideation.md +16 -2
- package/src/skills/spec-interview/references/step-3-ui-ux.md +10 -0
- package/src/skills/spec-interview/references/step-4-deep-dive.md +21 -13
- package/src/skills/spec-interview/references/step-5-research-needs.md +9 -6
- package/src/skills/spec-interview/references/step-6-verification.md +15 -0
- package/src/skills/spec-interview/references/step-7-finalize.md +16 -10
- package/src/skills/spec-review/SKILL.md +5 -0
- package/src/skills/task-review/references/checklist.md +17 -0
package/bin/install.js
CHANGED
|
@@ -253,6 +253,7 @@ const settingsFile = path.join(CLAUDE_DIR, 'settings.json');
|
|
|
253
253
|
if (fs.existsSync(mergeSettingsPath)) {
|
|
254
254
|
const configs = [
|
|
255
255
|
{ file: 'read-guard-hook.json', name: 'Context guard for large reads' },
|
|
256
|
+
{ file: 'task-output-guard-hook.json', name: 'TaskOutput context guard' },
|
|
256
257
|
{ file: 'statusline-config.json', name: 'Custom status line' },
|
|
257
258
|
// Spinner verbs - choose one (Helldivers or Factorio)
|
|
258
259
|
{ file: 'spinner-verbs-helldivers.json', name: 'Helldivers spinner verbs' }
|
|
@@ -393,6 +394,13 @@ if (fs.existsSync(settingsFile)) {
|
|
|
393
394
|
settingsModified = true;
|
|
394
395
|
}
|
|
395
396
|
|
|
397
|
+
// Enable agent teams (required for spec-interview team workflow)
|
|
398
|
+
if (settings.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS !== '1') {
|
|
399
|
+
settings.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = '1';
|
|
400
|
+
console.log('✓ Set CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1');
|
|
401
|
+
settingsModified = true;
|
|
402
|
+
}
|
|
403
|
+
|
|
396
404
|
if (settingsModified) {
|
|
397
405
|
fs.writeFileSync(settingsFile, JSON.stringify(settings, null, 2));
|
|
398
406
|
}
|
package/package.json
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: spec-implementer
|
|
3
3
|
description: Implements a single criterion from a spec task file. Only use when explicitly assigned a task file path from the execute-spec workflow.
|
|
4
4
|
tools: Read, Grep, Glob, Edit, Write, Bash, LSP
|
|
5
|
+
memory: project
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
You implement one task from a spec breakdown.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: spec-validator
|
|
3
3
|
description: Validates a completed task through code review and E2E testing. Only use when explicitly assigned a task file path from the execute-spec workflow.
|
|
4
4
|
tools: Read, Grep, Glob, Bash
|
|
5
|
+
memory: project
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
You are a senior QA engineer validating completed work.
|
|
@@ -3,18 +3,31 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Custom Status Line for Claude Code
|
|
5
5
|
*
|
|
6
|
-
* Displays project status in
|
|
6
|
+
* Displays project status in a bordered box:
|
|
7
7
|
* - Line 0: Directory name
|
|
8
8
|
* - Line 1: Git branch + status
|
|
9
9
|
* - Line 2: Context window usage bar with percentage and tokens
|
|
10
|
+
* - Line 3: Plan usage limits (5-hour session + 7-day weekly)
|
|
10
11
|
*
|
|
11
12
|
* Input: JSON on stdin with context_window data
|
|
12
13
|
* Output: Formatted status to stdout
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
|
-
const { readFileSync, readdirSync, statSync } = require('fs');
|
|
16
|
+
const { readFileSync, writeFileSync, readdirSync, statSync } = require('fs');
|
|
16
17
|
const { join, basename } = require('path');
|
|
17
|
-
const { execSync } = require('child_process');
|
|
18
|
+
const { execSync, spawnSync, spawn } = require('child_process');
|
|
19
|
+
const { homedir } = require('os');
|
|
20
|
+
|
|
21
|
+
// Usage API cache
|
|
22
|
+
const USAGE_CACHE_PATH = join(homedir(), '.claude', '.usage-cache.json');
|
|
23
|
+
const USAGE_CACHE_TTL = 45000; // 45 seconds
|
|
24
|
+
const USAGE_HISTORY_MAX = 20; // ~15 min of readings at 45s intervals
|
|
25
|
+
|
|
26
|
+
// Background refresh mode: fetch usage data and write cache, then exit
|
|
27
|
+
if (process.argv.includes('--refresh')) {
|
|
28
|
+
refreshUsageCache();
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
18
31
|
|
|
19
32
|
/**
|
|
20
33
|
* Format number as K (e.g., 84000 -> "084K")
|
|
@@ -60,6 +73,50 @@ function getContextGreyscale(percentage) {
|
|
|
60
73
|
return '\x1b[38;5;240m'; // Dark grey - safe
|
|
61
74
|
}
|
|
62
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Compute burn rate (percent per minute) from usage history
|
|
78
|
+
* Returns null if insufficient data
|
|
79
|
+
*/
|
|
80
|
+
function getUsageBurnRate(history, key) {
|
|
81
|
+
if (!history || history.length < 2) return null;
|
|
82
|
+
|
|
83
|
+
const oldest = history[0];
|
|
84
|
+
const newest = history[history.length - 1];
|
|
85
|
+
const minutesElapsed = (newest.t - oldest.t) / 60000;
|
|
86
|
+
|
|
87
|
+
// Need at least 2 minutes of data for a stable reading
|
|
88
|
+
if (minutesElapsed < 2) return null;
|
|
89
|
+
|
|
90
|
+
const deltaUtilization = newest[key] - oldest[key];
|
|
91
|
+
return deltaUtilization / minutesElapsed;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get color for usage bar based on current level and burn rate trend
|
|
96
|
+
* Returns red/yellow for danger, or greyscale for safe
|
|
97
|
+
*/
|
|
98
|
+
function getUsageColor(utilization, burnRate, windowType) {
|
|
99
|
+
const RED = '\x1b[38;5;196m';
|
|
100
|
+
const YELLOW = '\x1b[38;5;220m';
|
|
101
|
+
|
|
102
|
+
// Thresholds differ by window type
|
|
103
|
+
const redMinutes = windowType === '5h' ? 30 : 240; // 30min / 4hr
|
|
104
|
+
const yellowMinutes = windowType === '5h' ? 90 : 720; // 90min / 12hr
|
|
105
|
+
|
|
106
|
+
// Hard thresholds on current utilization
|
|
107
|
+
if (utilization >= 90) return RED;
|
|
108
|
+
if (utilization >= 75) return YELLOW;
|
|
109
|
+
|
|
110
|
+
// Trend-based: project time to hit 100%
|
|
111
|
+
if (burnRate && burnRate > 0) {
|
|
112
|
+
const minutesToLimit = (100 - utilization) / burnRate;
|
|
113
|
+
if (minutesToLimit <= redMinutes) return RED;
|
|
114
|
+
if (minutesToLimit <= yellowMinutes) return YELLOW;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return getContextGreyscale(utilization);
|
|
118
|
+
}
|
|
119
|
+
|
|
63
120
|
/**
|
|
64
121
|
* Count files in a directory recursively
|
|
65
122
|
*/
|
|
@@ -226,6 +283,108 @@ function getModulesWithChanges(projectDir) {
|
|
|
226
283
|
return modules;
|
|
227
284
|
}
|
|
228
285
|
|
|
286
|
+
/**
|
|
287
|
+
* Get OAuth access token from system credentials
|
|
288
|
+
*/
|
|
289
|
+
function getOAuthToken() {
|
|
290
|
+
if (process.platform === 'darwin') {
|
|
291
|
+
const credJson = execSync(
|
|
292
|
+
'security find-generic-password -s "Claude Code-credentials" -w',
|
|
293
|
+
{ encoding: 'utf-8', timeout: 3000, stdio: ['pipe', 'pipe', 'ignore'] }
|
|
294
|
+
).trim();
|
|
295
|
+
const creds = JSON.parse(credJson);
|
|
296
|
+
return creds.claudeAiOauth?.accessToken || null;
|
|
297
|
+
}
|
|
298
|
+
// Linux fallback
|
|
299
|
+
const credPath = join(homedir(), '.claude', '.credentials.json');
|
|
300
|
+
try {
|
|
301
|
+
const creds = JSON.parse(readFileSync(credPath, 'utf-8'));
|
|
302
|
+
return creds.claudeAiOauth?.accessToken || null;
|
|
303
|
+
} catch {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Fetch usage data from API and write to cache (runs in background)
|
|
310
|
+
*/
|
|
311
|
+
function refreshUsageCache() {
|
|
312
|
+
try {
|
|
313
|
+
const token = getOAuthToken();
|
|
314
|
+
if (!token) return;
|
|
315
|
+
|
|
316
|
+
const result = spawnSync('curl', [
|
|
317
|
+
'-s', '--max-time', '3',
|
|
318
|
+
'https://api.anthropic.com/api/oauth/usage',
|
|
319
|
+
'-H', `Authorization: Bearer ${token}`,
|
|
320
|
+
'-H', 'anthropic-beta: oauth-2025-04-20',
|
|
321
|
+
'-H', 'Content-Type: application/json',
|
|
322
|
+
], { encoding: 'utf-8', timeout: 5000 });
|
|
323
|
+
|
|
324
|
+
if (result.status === 0 && result.stdout) {
|
|
325
|
+
const data = JSON.parse(result.stdout.trim());
|
|
326
|
+
if (data.five_hour && data.seven_day) {
|
|
327
|
+
// Load existing history and append new reading
|
|
328
|
+
let history = [];
|
|
329
|
+
try {
|
|
330
|
+
const existing = JSON.parse(readFileSync(USAGE_CACHE_PATH, 'utf-8'));
|
|
331
|
+
if (Array.isArray(existing.history)) history = existing.history;
|
|
332
|
+
} catch {}
|
|
333
|
+
|
|
334
|
+
const now = Date.now();
|
|
335
|
+
history.push({
|
|
336
|
+
t: now,
|
|
337
|
+
five_hour: data.five_hour.utilization,
|
|
338
|
+
seven_day: data.seven_day.utilization,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// Keep only the last N readings
|
|
342
|
+
if (history.length > USAGE_HISTORY_MAX) {
|
|
343
|
+
history = history.slice(-USAGE_HISTORY_MAX);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
writeFileSync(USAGE_CACHE_PATH, JSON.stringify({
|
|
347
|
+
timestamp: now,
|
|
348
|
+
data,
|
|
349
|
+
history,
|
|
350
|
+
}));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
} catch {
|
|
354
|
+
// Silently fail - stale cache will be used on next render
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Read cached usage data, trigger background refresh if stale
|
|
360
|
+
*/
|
|
361
|
+
function getUsageData() {
|
|
362
|
+
let cacheData = null;
|
|
363
|
+
let cacheHistory = null;
|
|
364
|
+
let cacheAge = Infinity;
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
const raw = readFileSync(USAGE_CACHE_PATH, 'utf-8');
|
|
368
|
+
const cache = JSON.parse(raw);
|
|
369
|
+
cacheData = cache.data;
|
|
370
|
+
cacheHistory = cache.history || null;
|
|
371
|
+
cacheAge = Date.now() - cache.timestamp;
|
|
372
|
+
} catch {}
|
|
373
|
+
|
|
374
|
+
// Trigger background refresh if cache is stale
|
|
375
|
+
if (cacheAge > USAGE_CACHE_TTL) {
|
|
376
|
+
try {
|
|
377
|
+
const child = spawn(process.execPath, [__filename, '--refresh'], {
|
|
378
|
+
detached: true,
|
|
379
|
+
stdio: 'ignore',
|
|
380
|
+
});
|
|
381
|
+
child.unref();
|
|
382
|
+
} catch {}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return { data: cacheData, history: cacheHistory };
|
|
386
|
+
}
|
|
387
|
+
|
|
229
388
|
/**
|
|
230
389
|
* Main function
|
|
231
390
|
*/
|
|
@@ -380,11 +539,32 @@ function main() {
|
|
|
380
539
|
// Context bar line
|
|
381
540
|
const ctxLine = makeBoxLine(ctxDisplay);
|
|
382
541
|
|
|
542
|
+
// Usage limits line (5-hour session + 7-day weekly)
|
|
543
|
+
const usageLines = [];
|
|
544
|
+
const { data: usageApiData, history: usageHistory } = getUsageData();
|
|
545
|
+
if (usageApiData && usageApiData.five_hour && usageApiData.seven_day) {
|
|
546
|
+
const pct5h = Math.round(usageApiData.five_hour.utilization);
|
|
547
|
+
const pct7d = Math.round(usageApiData.seven_day.utilization);
|
|
548
|
+
const bar5h = generateBar(pct5h, 12);
|
|
549
|
+
const bar7d = generateBar(pct7d, 12);
|
|
550
|
+
|
|
551
|
+
// Compute burn rates from history for trend-based coloring
|
|
552
|
+
const rate5h = getUsageBurnRate(usageHistory, 'five_hour');
|
|
553
|
+
const rate7d = getUsageBurnRate(usageHistory, 'seven_day');
|
|
554
|
+
const color5h = getUsageColor(pct5h, rate5h, '5h');
|
|
555
|
+
const color7d = getUsageColor(pct7d, rate7d, '7d');
|
|
556
|
+
|
|
557
|
+
const str5h = pct5h.toString().padStart(3, ' ');
|
|
558
|
+
const str7d = pct7d.toString().padStart(3, ' ');
|
|
559
|
+
const usageDisplay = `5HR: ${color5h}[${bar5h}]${str5h}%${DIM_GREY} 7D: ${color7d}[${bar7d}]${str7d}%${DIM_GREY}`;
|
|
560
|
+
usageLines.push(makeBoxLine(usageDisplay));
|
|
561
|
+
}
|
|
562
|
+
|
|
383
563
|
// Bottom border (add 2 to match content line width)
|
|
384
564
|
const bottomBorder = `${DIM_GREY}╚${'═'.repeat(width + 2)}╝${RESET}`;
|
|
385
565
|
|
|
386
566
|
// Combine all lines
|
|
387
|
-
const allLines = [topBorder, line0, ...branchLines, ctxLine, bottomBorder];
|
|
567
|
+
const allLines = [topBorder, line0, ...branchLines, ctxLine, ...usageLines, bottomBorder];
|
|
388
568
|
console.log(allLines.join('\n'));
|
|
389
569
|
} catch (error) {
|
|
390
570
|
// Log error for debugging (goes to stderr, not visible in status line)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* task-output-guard.js - Intercept TaskOutput to prevent context bloat
|
|
5
|
+
*
|
|
6
|
+
* TaskOutput returns the full JSONL transcript of a background agent,
|
|
7
|
+
* including every tool call, tool result, and file contents the agent read.
|
|
8
|
+
* Each poll dumps the entire transcript (not a delta) into the orchestrator's
|
|
9
|
+
* context, causing severe bloat with background agents.
|
|
10
|
+
*
|
|
11
|
+
* This hook intercepts TaskOutput calls, reads the output file directly,
|
|
12
|
+
* extracts only the last few assistant messages, and returns those as the
|
|
13
|
+
* deny reason. The orchestrator gets useful status without the full transcript.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
|
|
19
|
+
const MAX_ASSISTANT_MESSAGES = 3;
|
|
20
|
+
const MAX_CHARS_PER_MESSAGE = 500;
|
|
21
|
+
|
|
22
|
+
async function readStdin() {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
let data = '';
|
|
25
|
+
process.stdin.setEncoding('utf8');
|
|
26
|
+
process.stdin.on('data', chunk => { data += chunk; });
|
|
27
|
+
process.stdin.on('end', () => {
|
|
28
|
+
try { resolve(JSON.parse(data)); }
|
|
29
|
+
catch { resolve(null); }
|
|
30
|
+
});
|
|
31
|
+
process.stdin.on('error', () => resolve(null));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Find the output file for a given task ID.
|
|
37
|
+
* Output files live at /private/tmp/claude-{uid}/{cwd-dashed}/tasks/{taskId}.output
|
|
38
|
+
*/
|
|
39
|
+
function findOutputFile(taskId, cwd) {
|
|
40
|
+
try {
|
|
41
|
+
const uid = process.getuid();
|
|
42
|
+
const cwdDashed = cwd.replace(/\//g, '-');
|
|
43
|
+
const outputPath = path.join('/private/tmp', `claude-${uid}`, cwdDashed, 'tasks', `${taskId}.output`);
|
|
44
|
+
if (fs.existsSync(outputPath)) return outputPath;
|
|
45
|
+
|
|
46
|
+
// Fallback: search common locations
|
|
47
|
+
const tmpBase = path.join('/private/tmp', `claude-${uid}`);
|
|
48
|
+
if (fs.existsSync(tmpBase)) {
|
|
49
|
+
const dirs = fs.readdirSync(tmpBase);
|
|
50
|
+
for (const dir of dirs) {
|
|
51
|
+
const candidate = path.join(tmpBase, dir, 'tasks', `${taskId}.output`);
|
|
52
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
// Ignore errors in file search
|
|
57
|
+
}
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Parse JSONL output file and extract the last N assistant text messages.
|
|
63
|
+
*/
|
|
64
|
+
function extractAssistantMessages(filePath) {
|
|
65
|
+
try {
|
|
66
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
67
|
+
const lines = content.trim().split('\n');
|
|
68
|
+
|
|
69
|
+
const assistantMessages = [];
|
|
70
|
+
|
|
71
|
+
for (const line of lines) {
|
|
72
|
+
try {
|
|
73
|
+
const entry = JSON.parse(line);
|
|
74
|
+
if (entry.type !== 'assistant' || !entry.message) continue;
|
|
75
|
+
if (entry.message.role !== 'assistant' || !entry.message.content) continue;
|
|
76
|
+
|
|
77
|
+
// Extract text blocks only (skip tool_use blocks)
|
|
78
|
+
const textParts = [];
|
|
79
|
+
const contentArr = Array.isArray(entry.message.content)
|
|
80
|
+
? entry.message.content
|
|
81
|
+
: [entry.message.content];
|
|
82
|
+
|
|
83
|
+
for (const block of contentArr) {
|
|
84
|
+
if (typeof block === 'string' && block.trim()) {
|
|
85
|
+
textParts.push(block.trim());
|
|
86
|
+
} else if (block.type === 'text' && block.text && block.text.trim()) {
|
|
87
|
+
textParts.push(block.text.trim());
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (textParts.length > 0) {
|
|
92
|
+
assistantMessages.push(textParts.join('\n'));
|
|
93
|
+
}
|
|
94
|
+
} catch {
|
|
95
|
+
// Skip malformed lines
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return assistantMessages.slice(-MAX_ASSISTANT_MESSAGES);
|
|
100
|
+
} catch {
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async function main() {
|
|
106
|
+
const input = await readStdin();
|
|
107
|
+
if (!input) process.exit(0);
|
|
108
|
+
|
|
109
|
+
const taskId = input.tool_input?.task_id;
|
|
110
|
+
const cwd = input.cwd;
|
|
111
|
+
|
|
112
|
+
if (!taskId || !cwd) process.exit(0);
|
|
113
|
+
|
|
114
|
+
const outputFile = findOutputFile(taskId, cwd);
|
|
115
|
+
|
|
116
|
+
if (!outputFile) {
|
|
117
|
+
// Can't find output file — let the call through so Claude gets the
|
|
118
|
+
// "not found" error naturally rather than a confusing deny
|
|
119
|
+
process.exit(0);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const messages = extractAssistantMessages(outputFile);
|
|
123
|
+
|
|
124
|
+
let summary;
|
|
125
|
+
if (messages.length === 0) {
|
|
126
|
+
summary = `Agent ${taskId} is running but has no assistant messages yet. Wait for the blocking return instead of polling.`;
|
|
127
|
+
} else {
|
|
128
|
+
const trimmed = messages.map((msg, i) => {
|
|
129
|
+
const truncated = msg.length > MAX_CHARS_PER_MESSAGE
|
|
130
|
+
? msg.slice(0, MAX_CHARS_PER_MESSAGE) + '...'
|
|
131
|
+
: msg;
|
|
132
|
+
return `[${i + 1}] ${truncated}`;
|
|
133
|
+
});
|
|
134
|
+
summary = `Last ${messages.length} assistant message(s) from agent ${taskId}:\n\n${trimmed.join('\n\n')}`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const output = {
|
|
138
|
+
hookSpecificOutput: {
|
|
139
|
+
hookEventName: "PreToolUse",
|
|
140
|
+
permissionDecision: "deny",
|
|
141
|
+
permissionDecisionReason: summary
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
console.log(JSON.stringify(output));
|
|
146
|
+
process.exit(0);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main().catch(() => process.exit(0));
|
|
@@ -35,7 +35,6 @@ Loop until all tasks complete:
|
|
|
35
35
|
## Parallelism Strategy
|
|
36
36
|
|
|
37
37
|
- Dispatch ALL ready tasks simultaneously
|
|
38
|
-
- Don't wait for one to finish before starting another
|
|
39
38
|
- The dependency graph controls what can run in parallel
|
|
40
39
|
- Example: If T002, T003, T004 all depend only on T001, they all start when T001 completes
|
|
41
40
|
|
|
@@ -44,20 +44,16 @@ Each validator:
|
|
|
44
44
|
|
|
45
45
|
## Browser Session Isolation
|
|
46
46
|
|
|
47
|
-
Validators use isolated sessions:
|
|
47
|
+
Validators use isolated sessions to prevent conflicts when running in parallel:
|
|
48
48
|
```
|
|
49
49
|
--session validator-T001
|
|
50
50
|
--session validator-T002
|
|
51
51
|
...
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
This prevents conflicts when multiple validators test simultaneously.
|
|
55
|
-
|
|
56
54
|
## Collecting Results
|
|
57
55
|
|
|
58
|
-
After all validators complete,
|
|
59
|
-
|
|
60
|
-
Structure findings:
|
|
56
|
+
After all validators complete, structure findings:
|
|
61
57
|
```
|
|
62
58
|
Validation Results:
|
|
63
59
|
T001: PASS
|
|
@@ -6,22 +6,38 @@ argument-hint: <spec-name>
|
|
|
6
6
|
|
|
7
7
|
# Spec Interview
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Team-Based Approach
|
|
10
10
|
|
|
11
|
-
**IMPORTANT:**
|
|
11
|
+
**IMPORTANT:** This skill uses an agent team for collaborative spec development. You are the **Lead** — you interview the user, write the spec, and curate team input. Three persistent teammates handle research, critique, and complexity assessment.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- Explorer uses a faster, cheaper model
|
|
15
|
-
- Explorer works better with focused tasks
|
|
16
|
-
- Explorer returns only relevant findings, keeping your context clean
|
|
13
|
+
### Team Composition
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
All teammates run on Opus:
|
|
16
|
+
- **Researcher** (researcher): Continuously explores the codebase, maps file landscape, integration points, data model. Drafts technical sections.
|
|
17
|
+
- **Critic** (critic): Reviews the emerging spec for gaps, bad assumptions, edge cases. Absorbs the spec-review completeness checklist and spec-sanity-check logic framework.
|
|
18
|
+
- **Pragmatist** (pragmatist): Evaluates complexity, pushes back on over-engineering, identifies the simplest buildable path.
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
### Working Directory
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
The team shares `{spec_dir}/working/`:
|
|
23
|
+
- `context.md` — You (the Lead) write interview updates here. Append-only — each update is a new section with a heading (e.g., `## Step 1: Feature Overview`). This replaces broadcasting — teammates read this file to stay current.
|
|
24
|
+
- Teammates write their findings to `working/` with descriptive filenames. Read these at checkpoints.
|
|
25
|
+
- `spec.md` (parent dir) — The living spec. You own this file. Teammates read it but never write to it.
|
|
26
|
+
|
|
27
|
+
### Checkpoint Pattern
|
|
28
|
+
|
|
29
|
+
Surface team input at step transitions, not continuously. This keeps the user conversation clean:
|
|
30
|
+
- **After Step 2** (approach selected): Read all working files, curate team findings for user
|
|
31
|
+
- **During Step 4** (deep dive): Read Researcher findings for each subsection, read Critic/Pragmatist feedback
|
|
32
|
+
- **At Step 7** (finalize): Request final assessments from all three, compile and present to user
|
|
33
|
+
|
|
34
|
+
At each checkpoint: read the working files, identify findings that are relevant and actionable, summarize them for the user as "Before we continue, my research team surfaced a few things..." Skip trivial items.
|
|
35
|
+
|
|
36
|
+
### Team Lifecycle
|
|
37
|
+
|
|
38
|
+
1. **Spawn** — After Step 1 (once the feature is understood), create the working directory, read the three prompt templates from `references/`, substitute `{spec_dir}` and `{feature_name}`, use TeamCreate to create a team named `spec-{feature-name}`, then spawn the three teammates via the Task tool
|
|
39
|
+
2. **Communicate** — Update context.md after each step. Message teammates for specific questions. Read their working files at checkpoints.
|
|
40
|
+
3. **Shutdown** — After Step 7 (user approves the spec), send shutdown requests to all three teammates, then use TeamDelete. Leave the `working/` directory in place as reference for implementation.
|
|
25
41
|
|
|
26
42
|
## What To Do Now
|
|
27
43
|
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
You are the Critic on a spec-interview team producing a feature specification for **{feature_name}**.
|
|
2
|
+
|
|
3
|
+
<role>
|
|
4
|
+
Provide continuous quality review of the emerging spec. You catch issues as they emerge — with full context of the conversation and decisions that produced each section. You replace end-of-pipe reviews with ongoing, informed critique.
|
|
5
|
+
</role>
|
|
6
|
+
|
|
7
|
+
<team>
|
|
8
|
+
- Lead (team-lead): Interviews the user, writes the spec, curates team input
|
|
9
|
+
- Researcher (researcher): Explores the codebase, maps the technical landscape
|
|
10
|
+
- Pragmatist (pragmatist): Evaluates complexity, advocates for simplicity
|
|
11
|
+
- You (critic): Find gaps, challenge assumptions, identify risks
|
|
12
|
+
</team>
|
|
13
|
+
|
|
14
|
+
<working-directory>
|
|
15
|
+
The team shares: `{spec_dir}/working/`
|
|
16
|
+
|
|
17
|
+
- `{spec_dir}/working/context.md` — The Lead writes interview context here. Read this for the "why" behind decisions.
|
|
18
|
+
- `{spec_dir}/spec.md` — The living spec. This is what you review.
|
|
19
|
+
- Read the Researcher's working files for technical grounding.
|
|
20
|
+
- Write your analysis to `{spec_dir}/working/` (e.g., `critic-gaps.md`, `critic-assumptions.md`, `critic-review.md`).
|
|
21
|
+
</working-directory>
|
|
22
|
+
|
|
23
|
+
<responsibilities>
|
|
24
|
+
1. Read the spec as it evolves. Challenge every section:
|
|
25
|
+
- Does this flow actually work end-to-end?
|
|
26
|
+
- What assumptions are unstated or unverified?
|
|
27
|
+
- What edge cases are missing?
|
|
28
|
+
- What happens when things fail?
|
|
29
|
+
- Are acceptance criteria actually testable?
|
|
30
|
+
2. Draft proposed content for **Edge Cases** and **Error Handling** sections
|
|
31
|
+
3. Ask the Researcher to verify claims against the codebase when something seems off
|
|
32
|
+
4. Ensure verification methods are concrete and executable
|
|
33
|
+
5. Flag issues by severity: **blocking** (must fix), **gap** (should address), **suggestion** (nice to have)
|
|
34
|
+
6. Check for conflicts with CLAUDE.md project constraints (read all CLAUDE.md files in the project)
|
|
35
|
+
7. Review the File Landscape for new files with overlapping purposes. When multiple new components share similar structure, data, or behavior, flag them for consolidation into a shared abstraction. Ask the Researcher to compare the proposed components.
|
|
36
|
+
</responsibilities>
|
|
37
|
+
|
|
38
|
+
<completeness-checklist>
|
|
39
|
+
Before the spec is finalized, all of these must be true:
|
|
40
|
+
|
|
41
|
+
**Must Have (Blocking if missing)**
|
|
42
|
+
- Clear intent — what and why is unambiguous
|
|
43
|
+
- Data model — entities, relationships, constraints are explicit
|
|
44
|
+
- Integration points — what existing code this touches is documented
|
|
45
|
+
- Core behavior — main flows are step-by-step clear
|
|
46
|
+
- Acceptance criteria — testable requirements with verification methods
|
|
47
|
+
- No ambiguities — nothing requires interpretation
|
|
48
|
+
- No unknowns — all information needed for implementation is present
|
|
49
|
+
- CLAUDE.md alignment — no conflicts with project constraints
|
|
50
|
+
- No internal duplication — new components with similar structure or purpose are consolidated into shared abstractions
|
|
51
|
+
|
|
52
|
+
**Should Have (Gaps that cause implementation friction)**
|
|
53
|
+
- Edge cases — error conditions and boundaries addressed
|
|
54
|
+
- External dependencies — APIs, libraries, services documented
|
|
55
|
+
- Blockers section — missing credentials, pending decisions called out
|
|
56
|
+
- UI/UX wireframes — if feature has a user interface
|
|
57
|
+
- Design direction — if feature has UI, visual approach is explicit
|
|
58
|
+
|
|
59
|
+
**Flag these problems:**
|
|
60
|
+
- Vague language ("should handle errors appropriately" — HOW?)
|
|
61
|
+
- Missing details ("integrates with auth" — WHERE? HOW?)
|
|
62
|
+
- Unstated assumptions ("uses the standard pattern" — WHICH pattern?)
|
|
63
|
+
- Blocking dependencies ("needs API access" — DO WE HAVE IT?)
|
|
64
|
+
- Unverifiable criteria ("dashboard works correctly" — HOW DO WE CHECK?)
|
|
65
|
+
- Missing verification ("loads fast" — WHAT COMMAND PROVES IT?)
|
|
66
|
+
- Implicit knowledge ("depends on how X works" — SPECIFY IT)
|
|
67
|
+
- Unverified claims ("the API returns..." — HAS THIS BEEN CONFIRMED?)
|
|
68
|
+
- CLAUDE.md conflicts (spec proposes X but CLAUDE.md requires Y — WHICH IS IT?)
|
|
69
|
+
- Near-duplicate new components (three similar cards, two similar forms, repeated layout patterns — CONSOLIDATE into shared components with configuration)
|
|
70
|
+
</completeness-checklist>
|
|
71
|
+
|
|
72
|
+
<sanity-check-framework>
|
|
73
|
+
For each section of the spec, challenge it through these lenses:
|
|
74
|
+
|
|
75
|
+
**Logic Gaps**
|
|
76
|
+
- Does the described flow actually work end-to-end?
|
|
77
|
+
- Are there steps that assume a previous step succeeded without checking?
|
|
78
|
+
- Are there circular dependencies?
|
|
79
|
+
|
|
80
|
+
**Incorrect Assumptions**
|
|
81
|
+
- Are there assumptions about how existing systems work that might be wrong?
|
|
82
|
+
- Are there assumptions about external APIs or data formats?
|
|
83
|
+
- Use Grep, Glob, Read to verify assumptions against the actual codebase
|
|
84
|
+
|
|
85
|
+
**Unconsidered Scenarios**
|
|
86
|
+
- What happens if external dependencies fail?
|
|
87
|
+
- What happens if data is malformed or missing?
|
|
88
|
+
- What happens at unexpected scale?
|
|
89
|
+
|
|
90
|
+
**Implementation Pitfalls**
|
|
91
|
+
- Common bugs this approach would likely introduce?
|
|
92
|
+
- Security implications not addressed?
|
|
93
|
+
- Race conditions or timing issues?
|
|
94
|
+
|
|
95
|
+
**The "What If" Test**
|
|
96
|
+
- What if [key assumption] is wrong?
|
|
97
|
+
- What if [external dependency] changes?
|
|
98
|
+
</sanity-check-framework>
|
|
99
|
+
|
|
100
|
+
<final-review-format>
|
|
101
|
+
When the Lead asks for a final review, write your findings to `{spec_dir}/working/critic-final-review.md` using this format:
|
|
102
|
+
|
|
103
|
+
```markdown
|
|
104
|
+
## Spec Review: {feature_name}
|
|
105
|
+
|
|
106
|
+
### Status: [READY | NEEDS WORK]
|
|
107
|
+
|
|
108
|
+
### Blocking Issues
|
|
109
|
+
- [Issue]: [Why this blocks implementation]
|
|
110
|
+
|
|
111
|
+
### CLAUDE.md Conflicts
|
|
112
|
+
- [Constraint]: [How the spec conflicts]
|
|
113
|
+
|
|
114
|
+
### Gaps (Non-blocking)
|
|
115
|
+
- [Item]: [What's unclear or incomplete]
|
|
116
|
+
|
|
117
|
+
### Logic Issues
|
|
118
|
+
- [Issue]: [Why this is a problem]
|
|
119
|
+
|
|
120
|
+
### Questionable Assumptions
|
|
121
|
+
- [Assumption]: [Why this might be wrong]
|
|
122
|
+
|
|
123
|
+
### Duplication Concerns
|
|
124
|
+
- [Group of similar new components]: [How they overlap and consolidation recommendation]
|
|
125
|
+
|
|
126
|
+
### Unconsidered Scenarios
|
|
127
|
+
- [Scenario]: [What could go wrong]
|
|
128
|
+
|
|
129
|
+
### Recommendation
|
|
130
|
+
[Specific items to address, or "Spec is implementation-ready"]
|
|
131
|
+
```
|
|
132
|
+
</final-review-format>
|
|
133
|
+
|
|
134
|
+
<communication>
|
|
135
|
+
- Details go in working files. Messages are concise summaries.
|
|
136
|
+
- Message the Lead when issues need user input to resolve.
|
|
137
|
+
- Message the Researcher to request codebase verification.
|
|
138
|
+
- Engage the Pragmatist when you disagree on scope — this tension is productive and improves the spec.
|
|
139
|
+
- Never interact with the user directly. All user communication goes through the Lead.
|
|
140
|
+
</communication>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
You are the Pragmatist on a spec-interview team producing a feature specification for **{feature_name}**.
|
|
2
|
+
|
|
3
|
+
<role>
|
|
4
|
+
Evaluate implementation complexity and keep the spec grounded in reality. You are the counterbalance to scope creep and over-engineering. Your question is always: "What is the simplest approach that meets the actual requirements?"
|
|
5
|
+
</role>
|
|
6
|
+
|
|
7
|
+
<team>
|
|
8
|
+
- Lead (team-lead): Interviews the user, writes the spec, curates team input
|
|
9
|
+
- Researcher (researcher): Explores the codebase, maps the technical landscape
|
|
10
|
+
- Critic (critic): Reviews the spec for gaps, assumptions, edge cases
|
|
11
|
+
- You (pragmatist): Evaluate complexity, advocate for simplicity
|
|
12
|
+
</team>
|
|
13
|
+
|
|
14
|
+
<working-directory>
|
|
15
|
+
The team shares: `{spec_dir}/working/`
|
|
16
|
+
|
|
17
|
+
- `{spec_dir}/working/context.md` — The Lead writes interview context here.
|
|
18
|
+
- `{spec_dir}/spec.md` — The living spec. Assess its complexity.
|
|
19
|
+
- Read the Researcher's findings for what already exists in the codebase.
|
|
20
|
+
- Read the Critic's analysis to understand proposed additions and edge cases.
|
|
21
|
+
- Write your assessments to `{spec_dir}/working/` (e.g., `pragmatist-complexity.md`, `pragmatist-simplification.md`).
|
|
22
|
+
</working-directory>
|
|
23
|
+
|
|
24
|
+
<responsibilities>
|
|
25
|
+
1. Assess implementation complexity as the spec takes shape:
|
|
26
|
+
- How many files need to change?
|
|
27
|
+
- How many new concepts or patterns are introduced?
|
|
28
|
+
- What's the dependency chain depth?
|
|
29
|
+
- Where are the riskiest parts?
|
|
30
|
+
2. Identify simpler alternatives when the spec over-engineers a solution
|
|
31
|
+
3. Push back on the Critic when edge case handling would add disproportionate complexity — flag what can be deferred to a later iteration
|
|
32
|
+
4. Identify what can be reused from the existing codebase (ask the Researcher about existing patterns). Also identify duplication within the spec's own new components — when two or more new files could share a common implementation, flag it. Fewer new things means lower complexity.
|
|
33
|
+
5. Assess whether the task dependency ordering makes practical sense for implementation
|
|
34
|
+
6. Flag requirements that should be split into "must have now" vs. "iterate later"
|
|
35
|
+
</responsibilities>
|
|
36
|
+
|
|
37
|
+
<evaluation-criteria>
|
|
38
|
+
For each major spec section, assess and write:
|
|
39
|
+
- **Relative complexity**: low / medium / high
|
|
40
|
+
- **Simpler alternative**: does one exist?
|
|
41
|
+
- **Deferral candidate**: could this be cut without losing the core value?
|
|
42
|
+
- **Reuse opportunity**: does an existing pattern cover this, or are we building new? Also: are multiple new things in this spec similar enough to consolidate into one shared abstraction?
|
|
43
|
+
</evaluation-criteria>
|
|
44
|
+
|
|
45
|
+
<final-assessment-format>
|
|
46
|
+
When the Lead asks for a final complexity assessment, write to `{spec_dir}/working/pragmatist-final-assessment.md`:
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
## Complexity Assessment: {feature_name}
|
|
50
|
+
|
|
51
|
+
### Overall Complexity: [Low | Medium | High]
|
|
52
|
+
|
|
53
|
+
### Critical Path (minimum buildable set)
|
|
54
|
+
- [Requirement]: [Why it's essential]
|
|
55
|
+
|
|
56
|
+
### Recommended Deferrals
|
|
57
|
+
- [Requirement]: [Why it can wait, estimated complexity saved]
|
|
58
|
+
|
|
59
|
+
### Reuse Opportunities
|
|
60
|
+
- [Existing pattern/component]: [How it applies]
|
|
61
|
+
|
|
62
|
+
### Risk Areas
|
|
63
|
+
- [Area]: [Why it's risky, suggested mitigation]
|
|
64
|
+
|
|
65
|
+
### Summary
|
|
66
|
+
[One paragraph: is this spec practically buildable as written? What would you change?]
|
|
67
|
+
```
|
|
68
|
+
</final-assessment-format>
|
|
69
|
+
|
|
70
|
+
<communication>
|
|
71
|
+
- Details go in working files. Messages are concise summaries.
|
|
72
|
+
- Message the Lead when simplification opportunities need user input (e.g., "This requirement triples complexity — worth discussing with user").
|
|
73
|
+
- Engage the Critic directly when you disagree on scope — this tension is productive.
|
|
74
|
+
- Ask the Researcher about existing patterns that could simplify the approach.
|
|
75
|
+
- Never interact with the user directly. All user communication goes through the Lead.
|
|
76
|
+
</communication>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
You are the Researcher on a spec-interview team producing a feature specification for **{feature_name}**.
|
|
2
|
+
|
|
3
|
+
<role>
|
|
4
|
+
Explore the codebase and provide technical grounding for the spec. You accumulate context across the entire interview — unlike disposable subagents, you build a deepening understanding of the relevant codebase as the conversation progresses.
|
|
5
|
+
</role>
|
|
6
|
+
|
|
7
|
+
<team>
|
|
8
|
+
- Lead (team-lead): Interviews the user, writes the spec, curates team input
|
|
9
|
+
- Critic (critic): Reviews the spec for gaps, assumptions, edge cases
|
|
10
|
+
- Pragmatist (pragmatist): Evaluates complexity, advocates for simplicity
|
|
11
|
+
- You (researcher): Explore the codebase, map the technical landscape
|
|
12
|
+
</team>
|
|
13
|
+
|
|
14
|
+
<working-directory>
|
|
15
|
+
The team shares: `{spec_dir}/working/`
|
|
16
|
+
|
|
17
|
+
- `{spec_dir}/working/context.md` — The Lead writes interview context here. Read this to stay current on what the user has discussed. It is append-only with section headings per step.
|
|
18
|
+
- `{spec_dir}/spec.md` — The living spec. Read it to understand what has been decided.
|
|
19
|
+
- Write your findings to `{spec_dir}/working/` with descriptive filenames (e.g., `file-landscape.md`, `integration-points.md`, `data-model.md`, `existing-patterns.md`).
|
|
20
|
+
</working-directory>
|
|
21
|
+
|
|
22
|
+
<responsibilities>
|
|
23
|
+
1. When you learn what feature is being built, immediately start mapping the relevant codebase areas — existing patterns, conventions, related components
|
|
24
|
+
2. Map concrete file paths: files to create, files to modify, directory conventions this project follows
|
|
25
|
+
3. Document how existing systems work that the feature will integrate with
|
|
26
|
+
4. Draft proposed content for these spec sections: **File Landscape**, **Integration Points**, **Data Model**. Structure your working files to match the spec's section headings so the Lead can incorporate them directly.
|
|
27
|
+
5. Respond to codebase questions from any teammate via SendMessage
|
|
28
|
+
6. When you discover something that affects the spec, write details to a working file and message the Lead with a concise summary pointing to the file
|
|
29
|
+
</responsibilities>
|
|
30
|
+
|
|
31
|
+
<communication>
|
|
32
|
+
- Details go in working files. Messages are summaries with a pointer to the file (e.g., "Findings on auth patterns ready — see working/integration-points.md").
|
|
33
|
+
- Message the Lead when findings are ready to incorporate into the spec.
|
|
34
|
+
- Message teammates directly when findings affect their analysis.
|
|
35
|
+
- Read context.md and spec.md regularly to stay aligned with interview progress.
|
|
36
|
+
</communication>
|
|
37
|
+
|
|
38
|
+
<tools>
|
|
39
|
+
Use Glob, Grep, Read, and LSP for all codebase exploration. You have full read access. For very broad searches that might flood your context, use the Task tool with an Explorer subagent to get curated results back.
|
|
40
|
+
</tools>
|
|
41
|
+
|
|
42
|
+
<boundaries>
|
|
43
|
+
- Write only to `{spec_dir}/working/`. Never write to spec.md directly — the Lead owns the spec.
|
|
44
|
+
- Never create or modify source code files. Your role is research only.
|
|
45
|
+
- Never interact with the user directly. All user communication goes through the Lead.
|
|
46
|
+
</boundaries>
|
|
@@ -16,6 +16,32 @@ Then explore:
|
|
|
16
16
|
|
|
17
17
|
## When to Move On
|
|
18
18
|
|
|
19
|
-
Move
|
|
19
|
+
Move on when:
|
|
20
20
|
- The core problem and user goal are clear
|
|
21
21
|
- Success criteria are understood at a high level
|
|
22
|
+
|
|
23
|
+
## Initialize the Team
|
|
24
|
+
|
|
25
|
+
Before proceeding to Step 2, set up the agent team:
|
|
26
|
+
|
|
27
|
+
1. Create the spec directory at `docs/specs/<feature-name>/` if not already created
|
|
28
|
+
2. Create `docs/specs/<feature-name>/working/` subdirectory
|
|
29
|
+
3. Read the three prompt templates:
|
|
30
|
+
- `references/researcher-prompt.md`
|
|
31
|
+
- `references/critic-prompt.md`
|
|
32
|
+
- `references/pragmatist-prompt.md`
|
|
33
|
+
4. In all three templates, substitute `{spec_dir}` with the actual spec directory path (e.g., `docs/specs/my-feature`) and `{feature_name}` with the feature name
|
|
34
|
+
5. Use TeamCreate to create a team named `spec-<feature-name>`
|
|
35
|
+
6. Spawn three teammates in parallel using the Task tool with `subagent_type: "general-purpose"` and `model: "opus"`:
|
|
36
|
+
- Name: `researcher`, prompt: substituted researcher-prompt.md content
|
|
37
|
+
- Name: `critic`, prompt: substituted critic-prompt.md content
|
|
38
|
+
- Name: `pragmatist`, prompt: substituted pragmatist-prompt.md content
|
|
39
|
+
- Set `team_name` to the team you just created
|
|
40
|
+
7. Send the Researcher an initial message via SendMessage summarizing the feature: problem, user, success criteria — so it can begin exploring immediately
|
|
41
|
+
8. Write initial context to `{spec_dir}/working/context.md`:
|
|
42
|
+
```
|
|
43
|
+
## Step 1: Feature Overview
|
|
44
|
+
[Problem, user, success criteria as discussed with the user]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Now proceed to `references/step-2-ideation.md`.
|
|
@@ -52,8 +52,22 @@ Document the chosen approach and why before proceeding.
|
|
|
52
52
|
|
|
53
53
|
## When to Move On
|
|
54
54
|
|
|
55
|
-
Proceed
|
|
55
|
+
Proceed when:
|
|
56
56
|
- An approach has been selected (or user chose to skip brainstorming)
|
|
57
57
|
- The rationale for the choice is understood
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
## Team Checkpoint: Post-Ideation
|
|
60
|
+
|
|
61
|
+
Before proceeding to the next step:
|
|
62
|
+
|
|
63
|
+
1. Update `{spec_dir}/working/context.md` — append:
|
|
64
|
+
```
|
|
65
|
+
## Step 2: Approach Selected
|
|
66
|
+
[Chosen approach, rationale, alternatives considered]
|
|
67
|
+
```
|
|
68
|
+
2. Message all three teammates individually (not broadcast) informing them of the chosen approach: "We chose [approach] because [rationale]. Read context.md for full details."
|
|
69
|
+
3. Read all files in `{spec_dir}/working/` to see what the team has found so far
|
|
70
|
+
4. Curate findings for the user — summarize anything noteworthy from the Researcher's codebase exploration, the Critic's early concerns, or the Pragmatist's complexity notes. Present as: "Before we go deeper, my research team surfaced a few things..." Only surface findings that are relevant and actionable. Skip trivial items.
|
|
71
|
+
5. If team findings raise concerns that affect the approach, discuss with the user via AskUserQuestion before proceeding
|
|
72
|
+
|
|
73
|
+
If the feature has no user interface, skip to `references/step-4-deep-dive.md`. Otherwise proceed to `references/step-3-ui-ux.md`.
|
|
@@ -71,3 +71,13 @@ Proceed to `references/step-4-deep-dive.md` when:
|
|
|
71
71
|
- Design direction is agreed upon
|
|
72
72
|
- Wireframes exist for primary screens
|
|
73
73
|
- User has confirmed the layout approach
|
|
74
|
+
|
|
75
|
+
## Update Team Context
|
|
76
|
+
|
|
77
|
+
After design decisions are confirmed, update `{spec_dir}/working/context.md` — append:
|
|
78
|
+
```
|
|
79
|
+
## Step 3: Design Decisions
|
|
80
|
+
[Design direction chosen, layout approach, key wireframe descriptions, user flow summaries]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
No team checkpoint at this step — design is user-driven. Teammates will read the updated context.md on their own.
|
|
@@ -15,23 +15,15 @@ Use AskUserQuestion whenever requirements are ambiguous or multiple approaches e
|
|
|
15
15
|
- External services, APIs, or libraries
|
|
16
16
|
- Data flows in and out
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
The Researcher has been exploring the codebase since Step 1. Read the Researcher's working files (especially any `integration-points.md` or related files). If the Researcher has already mapped integration points, incorporate them into the spec.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
1. First Explorer: "How does [system] work at a high level?"
|
|
22
|
-
2. Parallel Explorers: Deep dive into specific components identified in step 1
|
|
20
|
+
If specific questions remain, message the Researcher via SendMessage with targeted questions like "How does authentication work in this codebase?" or "What middleware handles protected routes?" and wait for a response.
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
- Explorer 1: "How does authentication work in this codebase?"
|
|
26
|
-
- Then parallel: "How are auth tokens validated?", "Where is the user session stored?", "What middleware handles protected routes?"
|
|
27
|
-
|
|
28
|
-
No assumptions. If you don't know how something works, send an Explorer to find out.
|
|
22
|
+
No assumptions. If something is unclear, ask the Researcher to investigate.
|
|
29
23
|
|
|
30
24
|
### File Landscape
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
> "To implement [this feature], what files would need to be created or modified? Give me concrete file paths."
|
|
26
|
+
Read the Researcher's `file-landscape.md` working file. The Researcher should have identified concrete file paths by now. If the file landscape is incomplete, message the Researcher: "To implement [this feature], what files would need to be created or modified? Give me concrete file paths."
|
|
35
27
|
|
|
36
28
|
Capture:
|
|
37
29
|
- **Files to create**: New files with full paths (e.g., `src/models/notification.ts`)
|
|
@@ -106,6 +98,22 @@ Write to `docs/specs/<name>/spec.md` with this structure:
|
|
|
106
98
|
- [ ] [Blocker]: [what's needed]
|
|
107
99
|
```
|
|
108
100
|
|
|
101
|
+
## Team Checkpoint: Deep Dive
|
|
102
|
+
|
|
103
|
+
After completing all deep dive subsections:
|
|
104
|
+
|
|
105
|
+
1. Update `{spec_dir}/working/context.md` — append:
|
|
106
|
+
```
|
|
107
|
+
## Step 4: Deep Dive Complete
|
|
108
|
+
[Summary of what was covered: integration points, file landscape, data model, behaviors, edge cases, blockers]
|
|
109
|
+
```
|
|
110
|
+
2. Read all working files from the Critic and Pragmatist
|
|
111
|
+
3. Present curated findings to the user:
|
|
112
|
+
- Critic's identified gaps, bad assumptions, or logic issues
|
|
113
|
+
- Pragmatist's complexity assessment and simplification suggestions
|
|
114
|
+
4. Use AskUserQuestion to discuss significant findings. If the Critic found gaps, address them. If the Pragmatist suggests simplifications, let the user decide.
|
|
115
|
+
5. Update spec.md with any changes from this discussion
|
|
116
|
+
|
|
109
117
|
## When to Move On
|
|
110
118
|
|
|
111
|
-
Move to `references/step-5-research-needs.md` when all areas have been covered and the spec document is substantially complete.
|
|
119
|
+
Move to `references/step-5-research-needs.md` when all areas have been covered, team findings have been addressed, and the spec document is substantially complete.
|
|
@@ -12,14 +12,11 @@ This is not about whether Claude knows how to do something in general. It's abou
|
|
|
12
12
|
|
|
13
13
|
Review the spec's integration points, data model, and behavior sections.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The Researcher has been exploring the codebase throughout the interview and already knows what patterns exist. For each significant implementation element, message the Researcher: "Does this codebase have an existing example of [pattern]? If yes, where and how does it work?"
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
- "Does this codebase have an existing example of [pattern]? If yes, where and how does it work?"
|
|
17
|
+
You can ask about multiple patterns in a single message. The Researcher will respond based on accumulated knowledge — faster and more informed than spawning fresh subagents.
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Based on Explorer findings:
|
|
19
|
+
Based on Researcher findings:
|
|
23
20
|
- If pattern exists → paradigm is established, no research needed
|
|
24
21
|
- If not found → this is a new paradigm requiring research
|
|
25
22
|
|
|
@@ -48,3 +45,9 @@ Proceed to `references/step-6-verification.md` when:
|
|
|
48
45
|
- All new paradigms have been researched, OR
|
|
49
46
|
- User confirmed no research is needed, OR
|
|
50
47
|
- All patterns have existing codebase examples
|
|
48
|
+
|
|
49
|
+
Update `{spec_dir}/working/context.md` — append:
|
|
50
|
+
```
|
|
51
|
+
## Step 5: Research Needs
|
|
52
|
+
[Which paradigms are established, which required research, research outcomes]
|
|
53
|
+
```
|
|
@@ -69,6 +69,21 @@ Use AskUserQuestion to review verification methods with the user:
|
|
|
69
69
|
|
|
70
70
|
The standard: if the agent executes the verification and it passes, the feature is done. No human checking required.
|
|
71
71
|
|
|
72
|
+
## Team Validation
|
|
73
|
+
|
|
74
|
+
After defining verification methods and before confirming with the user:
|
|
75
|
+
|
|
76
|
+
1. Message the Critic: "Review the verification methods in spec.md. Are they concrete and executable? Will each one actually prove its criterion works?"
|
|
77
|
+
2. Message the Pragmatist: "Review the verification methods in spec.md. Are any over-complex? Could simpler verification achieve the same confidence?"
|
|
78
|
+
3. Read their responses (via working files or SendMessage)
|
|
79
|
+
4. Adjust verification methods based on valid feedback before presenting to the user
|
|
80
|
+
|
|
72
81
|
## When to Move On
|
|
73
82
|
|
|
74
83
|
Proceed to `references/step-7-finalize.md` when every acceptance criterion has a verification method and the user agrees each method proves the criterion works.
|
|
84
|
+
|
|
85
|
+
Update `{spec_dir}/working/context.md` — append:
|
|
86
|
+
```
|
|
87
|
+
## Step 6: Verification Methods Defined
|
|
88
|
+
[Summary of verification approach and any team feedback incorporated]
|
|
89
|
+
```
|
|
@@ -2,23 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
Review the spec for completeness and soundness, then hand off.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Request Final Team Reviews
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- `spec-review` — checks completeness, format, and implementation readiness
|
|
9
|
-
- `spec-sanity-check` — checks logic, assumptions, and unconsidered scenarios
|
|
7
|
+
Message both the Critic and Pragmatist requesting final assessments:
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
1. Message the Critic: "The spec is substantially complete. Please do a final review against your completeness checklist and sanity check framework. Write your complete findings to `{spec_dir}/working/critic-final-review.md` using the format in your prompt."
|
|
10
|
+
2. Message the Pragmatist: "The spec is substantially complete. Please do a final complexity assessment. Write your findings to `{spec_dir}/working/pragmatist-final-assessment.md` using the format in your prompt."
|
|
11
|
+
3. Wait for both to respond (they will message you when their files are ready)
|
|
12
|
+
4. Read their working files: `critic-final-review.md` and `pragmatist-final-assessment.md`
|
|
12
13
|
|
|
13
14
|
## Curate the Findings
|
|
14
15
|
|
|
15
|
-
Synthesize findings from
|
|
16
|
+
Synthesize findings from the Critic's review and the Pragmatist's assessment. Some findings may be:
|
|
16
17
|
- Critical issues that must be addressed
|
|
17
18
|
- Valid suggestions worth considering
|
|
18
19
|
- Pedantic or irrelevant items to skip
|
|
19
20
|
|
|
20
21
|
For each finding, form a recommendation: address it or skip it, and why.
|
|
21
22
|
|
|
23
|
+
The Critic and Pragmatist have had full context of the entire interview — their findings are more informed than cold reviews. Weight their input accordingly.
|
|
24
|
+
|
|
22
25
|
## Walk Through With User
|
|
23
26
|
|
|
24
27
|
Use AskUserQuestion to present findings in batches (2-3 at a time). For each finding:
|
|
@@ -36,10 +39,9 @@ After walking through all findings, make the approved changes to the spec.
|
|
|
36
39
|
|
|
37
40
|
Use AskUserQuestion: "Do you want to run the reviews again?"
|
|
38
41
|
|
|
39
|
-
If yes,
|
|
40
|
-
- "We already ran a review. These changes were made: [list]. These findings were intentionally skipped: [list]. Look for anything new we haven't considered."
|
|
42
|
+
If yes, message the Critic and Pragmatist again with additional context: "We already ran a review. These changes were made: [list]. These findings were intentionally skipped: [list]. Look for anything new we haven't considered."
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
Read their updated working files and repeat the curate → walk through → offer another pass cycle until user is satisfied.
|
|
43
45
|
|
|
44
46
|
## Complete the Interview
|
|
45
47
|
|
|
@@ -48,5 +50,9 @@ Once user confirms no more review passes needed:
|
|
|
48
50
|
1. Show the user the final spec
|
|
49
51
|
2. Use AskUserQuestion to confirm they are satisfied
|
|
50
52
|
3. Ask if they want to proceed to task breakdown
|
|
53
|
+
4. Shutdown the team:
|
|
54
|
+
- Send shutdown requests to all three teammates (researcher, critic, pragmatist) via SendMessage with type "shutdown_request"
|
|
55
|
+
- After all teammates confirm shutdown, use TeamDelete to clean up team resources
|
|
56
|
+
- The `{spec_dir}/working/` directory remains on disk as reference for implementation
|
|
51
57
|
|
|
52
|
-
If yes, invoke `spec-to-tasks` and specify which spec to break down.
|
|
58
|
+
If yes to task breakdown, invoke `spec-to-tasks` and specify which spec to break down.
|
|
@@ -31,6 +31,7 @@ A spec is implementation-ready when ALL of these are satisfied:
|
|
|
31
31
|
- [ ] **No ambiguities** - Nothing requires interpretation; all requirements are explicit
|
|
32
32
|
- [ ] **No unknowns** - All information needed for implementation is present; nothing left to discover
|
|
33
33
|
- [ ] **CLAUDE.md alignment** - Spec does not conflict with constraints in any CLAUDE.md file
|
|
34
|
+
- [ ] **No internal duplication** - File Landscape contains no sets of new files that serve similar purposes and could share a common implementation
|
|
34
35
|
|
|
35
36
|
### Should Have (Gaps that cause implementation friction)
|
|
36
37
|
|
|
@@ -54,6 +55,7 @@ Flag these problems:
|
|
|
54
55
|
- Implicit knowledge ("depends on how X works" — SPECIFY IT)
|
|
55
56
|
- Unverified claims ("the API returns..." — HAS THIS BEEN CONFIRMED?)
|
|
56
57
|
- CLAUDE.md conflicts (spec proposes X but CLAUDE.md requires Y — WHICH IS IT?)
|
|
58
|
+
- Near-duplicate new components (three card components for different pages — CONSOLIDATE into one shared component with props/configuration)
|
|
57
59
|
|
|
58
60
|
## Output Format
|
|
59
61
|
|
|
@@ -73,6 +75,9 @@ Return the review as:
|
|
|
73
75
|
### Gaps (Non-blocking but should address)
|
|
74
76
|
- [Item]: [What's unclear or incomplete]
|
|
75
77
|
|
|
78
|
+
### Duplication Concerns
|
|
79
|
+
- [Group of similar new files/components]: [How they overlap and consolidation recommendation]
|
|
80
|
+
|
|
76
81
|
### Blocking Dependencies
|
|
77
82
|
- [Dependency]: [What's needed before implementation can start]
|
|
78
83
|
|
|
@@ -113,6 +113,23 @@ Cross-check task files against each other and the spec.
|
|
|
113
113
|
- [ ] Frontmatter format is consistent across all task files
|
|
114
114
|
- [ ] Implementation Notes and Review Notes sections exist (empty is fine)
|
|
115
115
|
|
|
116
|
+
## 9. Component Consolidation
|
|
117
|
+
|
|
118
|
+
Scan for tasks that create structurally similar files.
|
|
119
|
+
|
|
120
|
+
**Check:**
|
|
121
|
+
- [ ] No two tasks create components with similar names, purposes, or overlapping structure
|
|
122
|
+
- [ ] Shared patterns (cards, forms, list items, layout sections) use a single shared component with configuration, not separate implementations
|
|
123
|
+
- [ ] Utility functions or services with similar logic are consolidated
|
|
124
|
+
|
|
125
|
+
**How to verify:**
|
|
126
|
+
Compare files-to-create across all tasks. Group by similarity (naming patterns, structural role, data shape). When two or more tasks create similar files, flag for consolidation.
|
|
127
|
+
|
|
128
|
+
**Common issues:**
|
|
129
|
+
- Three "card" components for different pages that differ only by displayed fields
|
|
130
|
+
- Two form components with nearly identical validation and submission logic
|
|
131
|
+
- Repeated layout patterns that could be a shared template with slots/children
|
|
132
|
+
|
|
116
133
|
---
|
|
117
134
|
|
|
118
135
|
## Output Format
|