flow-cc 0.1.0
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 +66 -0
- package/VERSION +1 -0
- package/bin/install.js +149 -0
- package/hooks/flow-check-update.js +53 -0
- package/hooks/flow-statusline.js +112 -0
- package/package.json +15 -0
- package/skills/flow-done.md +117 -0
- package/skills/flow-go.md +132 -0
- package/skills/flow-init.md +218 -0
- package/skills/flow-intro.md +92 -0
- package/skills/flow-spec.md +235 -0
- package/skills/flow-status.md +72 -0
- package/skills/flow-task.md +125 -0
- package/skills/flow-update.md +79 -0
- package/templates/CLAUDE.md.template +31 -0
- package/templates/ROADMAP.md.template +15 -0
- package/templates/STATE.md.template +23 -0
- package/templates/lessons.md.template +12 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Flow Plugin
|
|
2
|
+
|
|
3
|
+
**Formalized workflow skills for Claude Code. Turns a proven spec-interview, agent-team-execution, session-handoff pattern into reusable `/flow:*` commands.**
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
- `/flow:intro` -- Walkthrough of the system — **start here**
|
|
8
|
+
- `/flow:init` -- Initialize a new project or milestone with planning scaffolding
|
|
9
|
+
- `/flow:spec` -- Run a spec interview that produces an executable PRD with wave-based phases
|
|
10
|
+
- `/flow:task` -- Lightweight task execution — bug fixes, cleanup, small features without a PRD
|
|
11
|
+
- `/flow:go` -- Execute the next phase from the PRD using agent teams
|
|
12
|
+
- `/flow:done` -- Session-end docs, lessons refinement, and handoff prompt generation
|
|
13
|
+
- `/flow:status` -- Quick "where am I?" orientation
|
|
14
|
+
- `/flow:update` -- Pull latest and re-install skills from any session
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Mac/Linux
|
|
20
|
+
git clone https://github.com/troyhoffman/flow-plugin.git && cd flow-plugin && bash setup.sh
|
|
21
|
+
|
|
22
|
+
# Windows (PowerShell)
|
|
23
|
+
git clone https://github.com/troyhoffman/flow-plugin.git; cd flow-plugin; .\setup.ps1
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Update:** Run `/flow:update` in any Claude Code session
|
|
27
|
+
|
|
28
|
+
## Getting Started
|
|
29
|
+
|
|
30
|
+
After installing, run `/flow:intro` in any Claude Code session. It explains the full lifecycle, what each command does, and typical usage patterns.
|
|
31
|
+
|
|
32
|
+
## How It Works
|
|
33
|
+
|
|
34
|
+
Skills install to `~/.claude/commands/flow/` and are immediately available in any Claude Code session. The workflow:
|
|
35
|
+
|
|
36
|
+
1. `/flow:init` -- Creates `.planning/` directory structure, CLAUDE.md, and initial docs
|
|
37
|
+
2. `/flow:spec` -- Interviews you about the milestone, produces PRD.md with wave-based phases
|
|
38
|
+
3. `/flow:go` -- Reads PRD, spawns agent teams per wave structure, verifies, commits
|
|
39
|
+
4. `/flow:task` -- Quick fixes and small features — executes, verifies, commits (no PRD needed)
|
|
40
|
+
5. `/flow:done` -- Updates STATE.md, ROADMAP.md, lessons.md, generates handoff prompt
|
|
41
|
+
6. `/flow:status` -- Read-only orientation check
|
|
42
|
+
|
|
43
|
+
## Lifecycle
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
/flow:init -> /flow:spec -> /flow:go (repeat per phase) -> /flow:done
|
|
47
|
+
|
|
|
48
|
+
handoff prompt for next session
|
|
49
|
+
|
|
50
|
+
/flow:task ← standalone path for bug fixes, cleanup, small features (no PRD needed)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Compatible with GSD
|
|
54
|
+
|
|
55
|
+
Uses the same `.planning/` directory structure. You can still use `/gsd:debug`, `/gsd:map-codebase`, etc. alongside Flow commands.
|
|
56
|
+
|
|
57
|
+
## Philosophy
|
|
58
|
+
|
|
59
|
+
- Front-load decisions into the spec interview, making execution simple
|
|
60
|
+
- Knowledge compounds through lessons.md to CLAUDE.md promotion lifecycle
|
|
61
|
+
- Fresh context per session; memory lives in the repo, not the conversation
|
|
62
|
+
- PRD is the execution contract -- agents execute what was specified
|
|
63
|
+
|
|
64
|
+
## Requirements
|
|
65
|
+
|
|
66
|
+
Claude Code CLI with skills support.
|
package/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Flow plugin installer for Claude Code
|
|
3
|
+
// Usage: npx flow-cc [--uninstall]
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
const homeDir = os.homedir();
|
|
10
|
+
const claudeDir = path.join(homeDir, '.claude');
|
|
11
|
+
const commandsDir = path.join(claudeDir, 'commands', 'flow');
|
|
12
|
+
const hooksDir = path.join(claudeDir, 'hooks');
|
|
13
|
+
const cacheDir = path.join(claudeDir, 'cache');
|
|
14
|
+
const settingsPath = path.join(claudeDir, 'settings.json');
|
|
15
|
+
|
|
16
|
+
// Source directories (relative to package root, one level up from bin/)
|
|
17
|
+
const pkgRoot = path.resolve(__dirname, '..');
|
|
18
|
+
const skillsDir = path.join(pkgRoot, 'skills');
|
|
19
|
+
const srcHooksDir = path.join(pkgRoot, 'hooks');
|
|
20
|
+
const templatesDir = path.join(pkgRoot, 'templates');
|
|
21
|
+
const versionFile = path.join(pkgRoot, 'VERSION');
|
|
22
|
+
|
|
23
|
+
const uninstall = process.argv.includes('--uninstall') || process.argv.includes('-u');
|
|
24
|
+
|
|
25
|
+
// ---------- Uninstall ----------
|
|
26
|
+
if (uninstall) {
|
|
27
|
+
console.log('Uninstalling Flow plugin...\n');
|
|
28
|
+
|
|
29
|
+
// Remove flow commands directory
|
|
30
|
+
if (fs.existsSync(commandsDir)) {
|
|
31
|
+
fs.rmSync(commandsDir, { recursive: true });
|
|
32
|
+
console.log(' Removed ~/.claude/commands/flow/');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Remove flow hooks
|
|
36
|
+
const hookFiles = ['flow-check-update.js', 'flow-statusline.js'];
|
|
37
|
+
for (const hook of hookFiles) {
|
|
38
|
+
const hookPath = path.join(hooksDir, hook);
|
|
39
|
+
if (fs.existsSync(hookPath)) {
|
|
40
|
+
fs.unlinkSync(hookPath);
|
|
41
|
+
console.log(` Removed ~/.claude/hooks/${hook}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Remove update cache
|
|
46
|
+
const cacheFile = path.join(cacheDir, 'flow-update-check.json');
|
|
47
|
+
if (fs.existsSync(cacheFile)) {
|
|
48
|
+
fs.unlinkSync(cacheFile);
|
|
49
|
+
console.log(' Removed ~/.claude/cache/flow-update-check.json');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Remove statusLine from settings.json if it points to flow
|
|
53
|
+
if (fs.existsSync(settingsPath)) {
|
|
54
|
+
try {
|
|
55
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
56
|
+
if (settings.statusLine && typeof settings.statusLine.command === 'string' &&
|
|
57
|
+
settings.statusLine.command.includes('flow-statusline')) {
|
|
58
|
+
delete settings.statusLine;
|
|
59
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
60
|
+
console.log(' Removed statusLine from ~/.claude/settings.json');
|
|
61
|
+
}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
// settings.json parse error — leave it alone
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log('\nFlow plugin uninstalled.');
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ---------- Install ----------
|
|
72
|
+
console.log('Installing Flow plugin...\n');
|
|
73
|
+
|
|
74
|
+
// 1. Create directories
|
|
75
|
+
for (const dir of [commandsDir, hooksDir, cacheDir]) {
|
|
76
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 2. Copy skills: skills/flow-*.md → commands/flow/*.md (strip "flow-" prefix)
|
|
80
|
+
const skillFiles = fs.readdirSync(skillsDir).filter(f => f.startsWith('flow-') && f.endsWith('.md'));
|
|
81
|
+
for (const file of skillFiles) {
|
|
82
|
+
const dest = file.replace(/^flow-/, '');
|
|
83
|
+
fs.copyFileSync(path.join(skillsDir, file), path.join(commandsDir, dest));
|
|
84
|
+
}
|
|
85
|
+
console.log(` Installed ${skillFiles.length} skills → ~/.claude/commands/flow/`);
|
|
86
|
+
|
|
87
|
+
// 3. Copy hooks
|
|
88
|
+
const hookFiles = ['flow-check-update.js', 'flow-statusline.js'];
|
|
89
|
+
for (const hook of hookFiles) {
|
|
90
|
+
const src = path.join(srcHooksDir, hook);
|
|
91
|
+
if (fs.existsSync(src)) {
|
|
92
|
+
fs.copyFileSync(src, path.join(hooksDir, hook));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
console.log(' Installed hooks → ~/.claude/hooks/');
|
|
96
|
+
|
|
97
|
+
// 4. Copy VERSION
|
|
98
|
+
fs.copyFileSync(versionFile, path.join(commandsDir, 'VERSION'));
|
|
99
|
+
console.log(' Installed VERSION → ~/.claude/commands/flow/VERSION');
|
|
100
|
+
|
|
101
|
+
// 5. Copy templates
|
|
102
|
+
const destTemplatesDir = path.join(commandsDir, 'templates');
|
|
103
|
+
fs.mkdirSync(destTemplatesDir, { recursive: true });
|
|
104
|
+
if (fs.existsSync(templatesDir)) {
|
|
105
|
+
const templateFiles = fs.readdirSync(templatesDir);
|
|
106
|
+
for (const file of templateFiles) {
|
|
107
|
+
fs.copyFileSync(path.join(templatesDir, file), path.join(destTemplatesDir, file));
|
|
108
|
+
}
|
|
109
|
+
console.log(` Installed ${templateFiles.length} templates → ~/.claude/commands/flow/templates/`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 6. Merge statusLine into settings.json
|
|
113
|
+
let settings = {};
|
|
114
|
+
if (fs.existsSync(settingsPath)) {
|
|
115
|
+
try {
|
|
116
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
117
|
+
} catch (e) {
|
|
118
|
+
// Corrupted settings — start fresh but warn
|
|
119
|
+
console.log(' Warning: could not parse existing settings.json, preserving as backup');
|
|
120
|
+
fs.copyFileSync(settingsPath, settingsPath + '.bak');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
settings.statusLine = {
|
|
124
|
+
type: 'command',
|
|
125
|
+
command: `node "${path.join(hooksDir, 'flow-statusline.js')}"`
|
|
126
|
+
};
|
|
127
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
128
|
+
console.log(' Configured statusLine in ~/.claude/settings.json');
|
|
129
|
+
|
|
130
|
+
// 7. Write .source breadcrumb (for dev/setup.sh compat)
|
|
131
|
+
fs.writeFileSync(path.join(commandsDir, '.source'), pkgRoot + '\n');
|
|
132
|
+
|
|
133
|
+
// Done
|
|
134
|
+
const version = fs.readFileSync(versionFile, 'utf8').trim();
|
|
135
|
+
console.log(`
|
|
136
|
+
Flow v${version} installed successfully!
|
|
137
|
+
|
|
138
|
+
Commands available:
|
|
139
|
+
/flow:intro — Learn the Flow workflow
|
|
140
|
+
/flow:init — Start a new project or milestone
|
|
141
|
+
/flow:spec — Spec interview → executable PRD
|
|
142
|
+
/flow:go — Execute next phase with agent teams
|
|
143
|
+
/flow:done — Session-end documentation
|
|
144
|
+
/flow:status — Quick orientation
|
|
145
|
+
/flow:task — Lightweight task execution
|
|
146
|
+
/flow:update — Update Flow to latest version
|
|
147
|
+
|
|
148
|
+
Get started: run /flow:intro in any Claude Code session.
|
|
149
|
+
`);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Check for Flow updates in background, write result to cache
|
|
3
|
+
// Called by flow-statusline.js when cache is stale or missing
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const { spawn } = require('child_process');
|
|
9
|
+
|
|
10
|
+
const homeDir = os.homedir();
|
|
11
|
+
const cacheDir = path.join(homeDir, '.claude', 'cache');
|
|
12
|
+
const cacheFile = path.join(cacheDir, 'flow-update-check.json');
|
|
13
|
+
const versionFile = path.join(homeDir, '.claude', 'commands', 'flow', 'VERSION');
|
|
14
|
+
|
|
15
|
+
// Ensure cache directory exists
|
|
16
|
+
if (!fs.existsSync(cacheDir)) {
|
|
17
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Run check in background (spawn detached process, windowsHide prevents console flash)
|
|
21
|
+
const child = spawn(process.execPath, ['-e', `
|
|
22
|
+
const fs = require('fs');
|
|
23
|
+
const { execSync } = require('child_process');
|
|
24
|
+
|
|
25
|
+
const cacheFile = ${JSON.stringify(cacheFile)};
|
|
26
|
+
const versionFile = ${JSON.stringify(versionFile)};
|
|
27
|
+
|
|
28
|
+
let installed = '0.0.0';
|
|
29
|
+
try {
|
|
30
|
+
if (fs.existsSync(versionFile)) {
|
|
31
|
+
installed = fs.readFileSync(versionFile, 'utf8').trim();
|
|
32
|
+
}
|
|
33
|
+
} catch (e) {}
|
|
34
|
+
|
|
35
|
+
let latest = null;
|
|
36
|
+
try {
|
|
37
|
+
latest = execSync('npm view flow-cc version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
|
|
38
|
+
} catch (e) {}
|
|
39
|
+
|
|
40
|
+
const result = {
|
|
41
|
+
update_available: latest && installed !== latest,
|
|
42
|
+
installed,
|
|
43
|
+
latest: latest || 'unknown',
|
|
44
|
+
checked: Math.floor(Date.now() / 1000)
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
fs.writeFileSync(cacheFile, JSON.stringify(result));
|
|
48
|
+
`], {
|
|
49
|
+
stdio: 'ignore',
|
|
50
|
+
windowsHide: true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
child.unref();
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code Statusline — Flow Edition
|
|
3
|
+
// Shows: [update notification] | model | current task | directory | context usage
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
const homeDir = os.homedir();
|
|
10
|
+
|
|
11
|
+
// Read JSON from stdin (Claude Code statusline protocol)
|
|
12
|
+
let input = '';
|
|
13
|
+
process.stdin.setEncoding('utf8');
|
|
14
|
+
process.stdin.on('data', chunk => input += chunk);
|
|
15
|
+
process.stdin.on('end', () => {
|
|
16
|
+
try {
|
|
17
|
+
const data = JSON.parse(input);
|
|
18
|
+
const model = data.model?.display_name || 'Claude';
|
|
19
|
+
const dir = data.workspace?.current_dir || process.cwd();
|
|
20
|
+
const session = data.session_id || '';
|
|
21
|
+
const remaining = data.context_window?.remaining_percentage;
|
|
22
|
+
|
|
23
|
+
// --- Context window bar (scaled to 80% limit) ---
|
|
24
|
+
let ctx = '';
|
|
25
|
+
if (remaining != null) {
|
|
26
|
+
const rem = Math.round(remaining);
|
|
27
|
+
const rawUsed = Math.max(0, Math.min(100, 100 - rem));
|
|
28
|
+
const used = Math.min(100, Math.round((rawUsed / 80) * 100));
|
|
29
|
+
|
|
30
|
+
const filled = Math.floor(used / 10);
|
|
31
|
+
const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(10 - filled);
|
|
32
|
+
|
|
33
|
+
if (used < 63) {
|
|
34
|
+
ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`;
|
|
35
|
+
} else if (used < 81) {
|
|
36
|
+
ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`;
|
|
37
|
+
} else if (used < 95) {
|
|
38
|
+
ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
|
|
39
|
+
} else {
|
|
40
|
+
ctx = ` \x1b[5;31m\uD83D\uDC80 ${bar} ${used}%\x1b[0m`;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// --- Current task from todos ---
|
|
45
|
+
let task = '';
|
|
46
|
+
const todosDir = path.join(homeDir, '.claude', 'todos');
|
|
47
|
+
if (session && fs.existsSync(todosDir)) {
|
|
48
|
+
try {
|
|
49
|
+
const files = fs.readdirSync(todosDir)
|
|
50
|
+
.filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
|
|
51
|
+
.map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
|
|
52
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
53
|
+
|
|
54
|
+
if (files.length > 0) {
|
|
55
|
+
try {
|
|
56
|
+
const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
|
|
57
|
+
const inProgress = todos.find(t => t.status === 'in_progress');
|
|
58
|
+
if (inProgress) task = inProgress.activeForm || '';
|
|
59
|
+
} catch (e) {}
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// --- Flow update notification ---
|
|
65
|
+
let flowUpdate = '';
|
|
66
|
+
const cacheFile = path.join(homeDir, '.claude', 'cache', 'flow-update-check.json');
|
|
67
|
+
let shouldCheck = false;
|
|
68
|
+
|
|
69
|
+
if (fs.existsSync(cacheFile)) {
|
|
70
|
+
try {
|
|
71
|
+
const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
|
72
|
+
if (cache.update_available) {
|
|
73
|
+
flowUpdate = '\x1b[33m\u2B06 /flow:update\x1b[0m \u2502 ';
|
|
74
|
+
}
|
|
75
|
+
// Trigger background re-check if cache is older than 6 hours
|
|
76
|
+
const sixHours = 6 * 60 * 60;
|
|
77
|
+
if (!cache.checked || (Math.floor(Date.now() / 1000) - cache.checked) > sixHours) {
|
|
78
|
+
shouldCheck = true;
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
shouldCheck = true;
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
shouldCheck = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Spawn background update check if needed
|
|
88
|
+
if (shouldCheck) {
|
|
89
|
+
try {
|
|
90
|
+
const checkScript = path.join(homeDir, '.claude', 'hooks', 'flow-check-update.js');
|
|
91
|
+
if (fs.existsSync(checkScript)) {
|
|
92
|
+
const { spawn } = require('child_process');
|
|
93
|
+
const child = spawn(process.execPath, [checkScript], {
|
|
94
|
+
stdio: 'ignore',
|
|
95
|
+
windowsHide: true
|
|
96
|
+
});
|
|
97
|
+
child.unref();
|
|
98
|
+
}
|
|
99
|
+
} catch (e) {}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// --- Output ---
|
|
103
|
+
const dirname = path.basename(dir);
|
|
104
|
+
if (task) {
|
|
105
|
+
process.stdout.write(`${flowUpdate}\x1b[2m${model}\x1b[0m \u2502 \x1b[1m${task}\x1b[0m \u2502 \x1b[2m${dirname}\x1b[0m${ctx}`);
|
|
106
|
+
} else {
|
|
107
|
+
process.stdout.write(`${flowUpdate}\x1b[2m${model}\x1b[0m \u2502 \x1b[2m${dirname}\x1b[0m${ctx}`);
|
|
108
|
+
}
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// Silent fail — statusline must never crash
|
|
111
|
+
}
|
|
112
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow:done
|
|
3
|
+
description: Session-end documentation — updates STATE.md, ROADMAP.md, lessons.md, generates handoff prompt
|
|
4
|
+
user_invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /flow:done — Session End + Handoff
|
|
8
|
+
|
|
9
|
+
You are executing the `/flow:done` skill. This finalizes the current session by updating all planning documents and generating a handoff prompt for the next session.
|
|
10
|
+
|
|
11
|
+
**This is the most important skill for sustainability.** Without proper session-end docs, the next session starts blind.
|
|
12
|
+
|
|
13
|
+
## Steps
|
|
14
|
+
|
|
15
|
+
### 1. Gather Context
|
|
16
|
+
|
|
17
|
+
Read these files (in parallel where possible):
|
|
18
|
+
- `.planning/STATE.md` — current state
|
|
19
|
+
- `.planning/ROADMAP.md` — milestone/phase progress
|
|
20
|
+
- `tasks/lessons.md` — existing lessons
|
|
21
|
+
- `CLAUDE.md` — project rules
|
|
22
|
+
- `PRD.md` — current spec (if exists)
|
|
23
|
+
|
|
24
|
+
Also gather:
|
|
25
|
+
- Run `git log --oneline -20` to see commits this session
|
|
26
|
+
- Run `git diff --stat` to check for uncommitted changes
|
|
27
|
+
- If uncommitted changes exist, warn the user before proceeding
|
|
28
|
+
|
|
29
|
+
### 2. Update STATE.md
|
|
30
|
+
|
|
31
|
+
**REPLACE the entire file** (do NOT append). Keep under 80 lines.
|
|
32
|
+
|
|
33
|
+
Structure:
|
|
34
|
+
```
|
|
35
|
+
# [Project Name] — Project State
|
|
36
|
+
|
|
37
|
+
## Current Position
|
|
38
|
+
- **Milestone:** [name] (vX)
|
|
39
|
+
- **Phase:** [current phase status]
|
|
40
|
+
- **Branch:** [current branch]
|
|
41
|
+
- **Last Session:** [today's date]
|
|
42
|
+
|
|
43
|
+
## Milestone Progress
|
|
44
|
+
|
|
45
|
+
| Phase | Name | Status |
|
|
46
|
+
|-------|------|--------|
|
|
47
|
+
| 1 | [name] | Complete (date) |
|
|
48
|
+
| 2 | [name] | Complete (date) |
|
|
49
|
+
| 3 | [name] | In Progress |
|
|
50
|
+
| 4 | [name] | Pending |
|
|
51
|
+
|
|
52
|
+
## What Was Built (This Session)
|
|
53
|
+
- [Bullet list of what was accomplished]
|
|
54
|
+
- [Include file counts, key components, commit SHAs]
|
|
55
|
+
|
|
56
|
+
## Key Decisions
|
|
57
|
+
- [Any architectural or design decisions made]
|
|
58
|
+
|
|
59
|
+
## Next Actions
|
|
60
|
+
1. [Specific next step — usually "Run /flow:go for Phase N"]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 3. Update ROADMAP.md
|
|
64
|
+
|
|
65
|
+
- Mark completed phases with completion date
|
|
66
|
+
- Ensure pending phases have enough detail that the next session can start with a one-line prompt
|
|
67
|
+
- **Archive check:** If the current milestone is fully complete:
|
|
68
|
+
- Move milestone phase details to `.planning/archive/milestones-vX.md`
|
|
69
|
+
- Keep only the summary row in the ROADMAP milestone table
|
|
70
|
+
- Move `PRD.md` to `.planning/archive/PRD-vX.md`
|
|
71
|
+
|
|
72
|
+
### 4. Update lessons.md
|
|
73
|
+
|
|
74
|
+
- Review the session for mistakes, corrections, or discovered issues
|
|
75
|
+
- Auto-suggest lessons based on errors encountered (if any)
|
|
76
|
+
- Ask the user: "Any lessons from this session?" using AskUserQuestion with options:
|
|
77
|
+
- "No new lessons"
|
|
78
|
+
- "Yes, let me add some" (user types them)
|
|
79
|
+
- "Use your suggestions" (if you auto-suggested any)
|
|
80
|
+
- Add new lessons in PATTERN/CAUSE/FIX/RULE format
|
|
81
|
+
- **Refine existing lessons:** merge duplicates, sharpen vague rules, delete obvious ones
|
|
82
|
+
- **Promote check:** For lessons that seem universal (not project-specific), ask: "This lesson seems universal. Promote to global lessons (~/.claude/lessons.md)?"
|
|
83
|
+
|
|
84
|
+
### 5. Commit Doc Updates
|
|
85
|
+
|
|
86
|
+
- Stage only the planning docs: STATE.md, ROADMAP.md, lessons.md, and any archived files
|
|
87
|
+
- Commit with message: `docs: session-end updates — [brief summary]`
|
|
88
|
+
- Do NOT push unless the user asks
|
|
89
|
+
|
|
90
|
+
### 6. Generate Handoff Prompt
|
|
91
|
+
|
|
92
|
+
Determine the next action and generate a copyable handoff prompt:
|
|
93
|
+
|
|
94
|
+
- If next phase exists in PRD:
|
|
95
|
+
```
|
|
96
|
+
Phase [N]: [Name] — [short description]. Read STATE.md, ROADMAP.md, and PRD.md (US-X).
|
|
97
|
+
[One sentence of context]. [One sentence of what NOT to do if relevant].
|
|
98
|
+
```
|
|
99
|
+
- If milestone is complete:
|
|
100
|
+
```
|
|
101
|
+
Milestone [name] complete. Run /flow:init to start the next milestone.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Print the handoff prompt in a fenced code block so the user can copy it.
|
|
105
|
+
|
|
106
|
+
### 7. Print Summary
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
Session complete.
|
|
110
|
+
- STATE.md: updated
|
|
111
|
+
- ROADMAP.md: [N] phases marked complete
|
|
112
|
+
- lessons.md: [N] lessons added, [N] refined
|
|
113
|
+
- Committed: [SHA]
|
|
114
|
+
|
|
115
|
+
Handoff prompt:
|
|
116
|
+
[the prompt in a code block]
|
|
117
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: flow:go
|
|
3
|
+
description: Execute the next phase from PRD using wave-based agent teams
|
|
4
|
+
user_invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /flow:go — Execute Next Phase
|
|
8
|
+
|
|
9
|
+
You are executing the `/flow:go` skill. This reads the PRD, identifies the next unstarted phase, and executes it using wave-based agent teams.
|
|
10
|
+
|
|
11
|
+
**Core principle:** The PRD is the execution contract. You execute what it specifies. Do not freelance.
|
|
12
|
+
|
|
13
|
+
## Step 1 — Orient
|
|
14
|
+
|
|
15
|
+
Read these files (in parallel):
|
|
16
|
+
- `.planning/STATE.md` — current position
|
|
17
|
+
- `.planning/ROADMAP.md` — phase progress
|
|
18
|
+
- `PRD.md` — the execution spec
|
|
19
|
+
- `tasks/lessons.md` — anti-patterns to avoid
|
|
20
|
+
- `CLAUDE.md` — execution rules and verification commands
|
|
21
|
+
|
|
22
|
+
**Identify the next phase:** Find the first phase in ROADMAP.md with status "Pending" or the first unstarted phase in the PRD.
|
|
23
|
+
|
|
24
|
+
## Step 2 — Pre-flight Checks
|
|
25
|
+
|
|
26
|
+
Run these checks before executing. If any fail, stop and tell the user what to do:
|
|
27
|
+
|
|
28
|
+
1. **PRD exists?** If `PRD.md` is missing: "No PRD found. Run `/flow:spec` first."
|
|
29
|
+
2. **Phase detailed enough?** The phase section in the PRD must have:
|
|
30
|
+
- Wave structure with agent assignments
|
|
31
|
+
- Explicit file lists per agent
|
|
32
|
+
- Verification commands
|
|
33
|
+
- If missing: "PRD phase section is too vague. Add wave structure + file lists, or run `/flow:spec`."
|
|
34
|
+
3. **Branch check:** Verify you're on the correct feature branch (from PRD header). If not, warn the user.
|
|
35
|
+
4. **All phases done?** If no pending phases remain: "All phases complete! Run `/flow:done` to wrap up, or `/flow:init` for the next milestone."
|
|
36
|
+
|
|
37
|
+
## Step 3 — Staleness Check
|
|
38
|
+
|
|
39
|
+
Compare this phase's PRD section against the actual codebase:
|
|
40
|
+
- Do the files it references still exist / have the expected structure?
|
|
41
|
+
- Were files created/deleted/significantly changed by prior phases that affect this phase?
|
|
42
|
+
- If stale references found: fix them in the PRD (update file paths, note structural changes) before proceeding. Print what you corrected.
|
|
43
|
+
|
|
44
|
+
Do NOT rewrite the phase — just fix stale references so agents get accurate context.
|
|
45
|
+
|
|
46
|
+
## Step 4 — Execute Waves
|
|
47
|
+
|
|
48
|
+
For each wave defined in the PRD phase section:
|
|
49
|
+
|
|
50
|
+
### 4a. Prepare Agent Prompts
|
|
51
|
+
|
|
52
|
+
For each agent in the wave, build a prompt containing:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
You are [agent-name] working on Phase [N]: [Phase Name].
|
|
56
|
+
|
|
57
|
+
## Your Task
|
|
58
|
+
[Task description from PRD wave structure]
|
|
59
|
+
|
|
60
|
+
## Files to Create/Modify
|
|
61
|
+
[Exact file list from PRD — absolute paths]
|
|
62
|
+
|
|
63
|
+
## Acceptance Criteria
|
|
64
|
+
[Relevant criteria from the user stories this phase covers]
|
|
65
|
+
|
|
66
|
+
## Existing Code to Reuse
|
|
67
|
+
[Inline the actual code/types/signatures from the "Key Existing Code" PRD section.
|
|
68
|
+
Do NOT just reference file paths — READ the files and INLINE the relevant code
|
|
69
|
+
so agents have it in their context without needing to search.]
|
|
70
|
+
|
|
71
|
+
## Rules
|
|
72
|
+
- Only modify files in your list. Do not touch anything else.
|
|
73
|
+
- Run verification after your work: [commands from CLAUDE.md]
|
|
74
|
+
- Stage only your files when committing (never `git add .` or `git add -A`)
|
|
75
|
+
- If you need output from another agent that isn't available yet, create a temporary stub and continue. Delete the stub before your final commit.
|
|
76
|
+
|
|
77
|
+
## Anti-Patterns to Avoid
|
|
78
|
+
[Relevant lessons from tasks/lessons.md — filter to lessons that apply to this agent's work]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 4b. Spawn Wave
|
|
82
|
+
|
|
83
|
+
- Use TeamCreate or Task tool to spawn all agents in the wave simultaneously
|
|
84
|
+
- Each agent runs with `mode: "bypassPermissions"` for autonomous execution
|
|
85
|
+
- Wait for all agents in the wave to complete before moving to the next wave
|
|
86
|
+
|
|
87
|
+
### 4c. Between Waves
|
|
88
|
+
|
|
89
|
+
After each wave completes:
|
|
90
|
+
1. Run verification commands from CLAUDE.md (e.g., `npx tsc --noEmit`, `npx biome check`)
|
|
91
|
+
2. Check for integration issues between agents' output
|
|
92
|
+
3. Fix any issues before proceeding to the next wave
|
|
93
|
+
4. If verification fails and you can fix it quickly (< 2 minutes of work), fix it. Otherwise, stop and report.
|
|
94
|
+
|
|
95
|
+
### 4d. Final Verification
|
|
96
|
+
|
|
97
|
+
After ALL waves complete:
|
|
98
|
+
1. Run full verification suite
|
|
99
|
+
2. Check all acceptance criteria for this phase's user stories
|
|
100
|
+
3. If anything fails, fix it or report to the user
|
|
101
|
+
|
|
102
|
+
## Step 5 — Commit
|
|
103
|
+
|
|
104
|
+
Create an atomic commit for this phase:
|
|
105
|
+
- Stage only the files created/modified by this phase's agents
|
|
106
|
+
- Commit message: `feat: [phase description] (Phase N)`
|
|
107
|
+
- Do NOT push unless the user asks
|
|
108
|
+
|
|
109
|
+
## Step 6 — Update Docs
|
|
110
|
+
|
|
111
|
+
**STATE.md:** Update "What Was Built" section with:
|
|
112
|
+
- Files created/modified (count + key names)
|
|
113
|
+
- Commit SHA
|
|
114
|
+
- Phase completion note
|
|
115
|
+
|
|
116
|
+
**ROADMAP.md:** Mark this phase as "Complete ([today's date])"
|
|
117
|
+
|
|
118
|
+
## Step 7 — Route Next Action
|
|
119
|
+
|
|
120
|
+
Print phase summary:
|
|
121
|
+
```
|
|
122
|
+
Phase [N]: [Name] — Complete
|
|
123
|
+
- [X] files created, [Y] modified
|
|
124
|
+
- Commit: [SHA]
|
|
125
|
+
- Verification: passed
|
|
126
|
+
|
|
127
|
+
Next:
|
|
128
|
+
- /flow:go for Phase [N+1]: [Next Phase Name]
|
|
129
|
+
- /flow:done to end session
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
If this was the last phase: "All phases complete! Run `/flow:done` to finalize."
|