declare-cc 1.0.7 → 2.0.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.
Files changed (75) hide show
  1. package/README.md +153 -187
  2. package/dist/client/assets/index-BVuhr02G.css +1 -0
  3. package/dist/client/assets/index-DujGXAYw.js +9 -0
  4. package/dist/client/index.html +23 -0
  5. package/dist/index.js +17459 -0
  6. package/package.json +38 -45
  7. package/src/agents/prompts/00-research.md +90 -0
  8. package/src/agents/prompts/01-vision.md +38 -0
  9. package/src/agents/prompts/02-declarations.md +47 -0
  10. package/src/agents/prompts/03-milestones.md +43 -0
  11. package/src/agents/prompts/04-actions.md +90 -0
  12. package/src/agents/prompts/05-execution.md +63 -0
  13. package/src/agents/prompts/06-verification.md +104 -0
  14. package/LICENSE +0 -21
  15. package/agents/declare-codebase-mapper.md +0 -761
  16. package/agents/declare-debugger.md +0 -1198
  17. package/agents/declare-executor.md +0 -353
  18. package/agents/declare-integration-checker.md +0 -440
  19. package/agents/declare-plan-checker.md +0 -608
  20. package/agents/declare-planner.md +0 -1015
  21. package/agents/declare-research-synthesizer.md +0 -309
  22. package/agents/declare-researcher.md +0 -484
  23. package/agents/declare-roadmapper.md +0 -639
  24. package/agents/declare-verifier.md +0 -555
  25. package/bin/declare.js +0 -16
  26. package/bin/install.js +0 -1907
  27. package/commands/declare/actions.md +0 -113
  28. package/commands/declare/add-todo.md +0 -41
  29. package/commands/declare/audit.md +0 -76
  30. package/commands/declare/check-todos.md +0 -125
  31. package/commands/declare/complete-milestone.md +0 -215
  32. package/commands/declare/dashboard.md +0 -65
  33. package/commands/declare/debug.md +0 -162
  34. package/commands/declare/discuss.md +0 -65
  35. package/commands/declare/execute.md +0 -521
  36. package/commands/declare/future.md +0 -72
  37. package/commands/declare/health.md +0 -92
  38. package/commands/declare/help.md +0 -31
  39. package/commands/declare/init.md +0 -39
  40. package/commands/declare/map-codebase.md +0 -149
  41. package/commands/declare/milestones.md +0 -98
  42. package/commands/declare/new-cycle.md +0 -172
  43. package/commands/declare/new-project.md +0 -565
  44. package/commands/declare/pause.md +0 -138
  45. package/commands/declare/plan.md +0 -320
  46. package/commands/declare/prioritize.md +0 -65
  47. package/commands/declare/progress.md +0 -116
  48. package/commands/declare/quick.md +0 -119
  49. package/commands/declare/reapply-patches.md +0 -178
  50. package/commands/declare/research.md +0 -267
  51. package/commands/declare/resume.md +0 -146
  52. package/commands/declare/set-profile.md +0 -66
  53. package/commands/declare/settings.md +0 -119
  54. package/commands/declare/status.md +0 -65
  55. package/commands/declare/trace.md +0 -81
  56. package/commands/declare/update.md +0 -251
  57. package/commands/declare/verify.md +0 -65
  58. package/commands/declare/visualize.md +0 -74
  59. package/dist/declare-tools.cjs +0 -9428
  60. package/dist/public/app.js +0 -9086
  61. package/dist/public/index.html +0 -4292
  62. package/hooks/declare-activity.js +0 -106
  63. package/hooks/declare-check-update.js +0 -62
  64. package/hooks/declare-server.js +0 -116
  65. package/hooks/declare-statusline.js +0 -91
  66. package/scripts/build-hooks.js +0 -42
  67. package/scripts/release.js +0 -50
  68. package/templates/future.md +0 -4
  69. package/templates/milestones.md +0 -11
  70. package/workflows/actions.md +0 -89
  71. package/workflows/discuss.md +0 -476
  72. package/workflows/future.md +0 -185
  73. package/workflows/milestones.md +0 -87
  74. package/workflows/scope.md +0 -94
  75. package/workflows/verify.md +0 -504
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env node
2
- // Declare activity hook — PreToolUse + PostToolUse
3
- // Writes interesting tool events to .planning/activity.jsonl
4
- // Server watches .planning/ via fs.watch and pushes SSE events to dashboard.
5
- //
6
- // Installed for PreToolUse and PostToolUse hook events.
7
- // Runs fast: read stdin → decide → append one line → exit.
8
-
9
- 'use strict';
10
-
11
- const fs = require('fs');
12
- const path = require('path');
13
- const os = require('os');
14
-
15
- const cwd = process.cwd();
16
- const planningDir = path.join(cwd, '.planning');
17
- const activityFile = path.join(planningDir, 'activity.jsonl');
18
-
19
- // Only write if .planning/ exists (i.e. this is a Declare project)
20
- if (!fs.existsSync(planningDir)) process.exit(0);
21
-
22
- let raw = '';
23
- process.stdin.setEncoding('utf8');
24
- process.stdin.on('data', c => raw += c);
25
- process.stdin.on('end', () => {
26
- try {
27
- const data = JSON.parse(raw);
28
- const event = buildEvent(data);
29
- if (!event) process.exit(0);
30
-
31
- // Ensure file exists
32
- if (!fs.existsSync(activityFile)) fs.writeFileSync(activityFile, '');
33
-
34
- // Append event + trim to last 200 lines
35
- const line = JSON.stringify(event) + '\n';
36
- fs.appendFileSync(activityFile, line);
37
-
38
- // Trim to last 200 lines to avoid unbounded growth
39
- const content = fs.readFileSync(activityFile, 'utf8');
40
- const lines = content.split('\n').filter(Boolean);
41
- if (lines.length > 200) {
42
- fs.writeFileSync(activityFile, lines.slice(-200).join('\n') + '\n');
43
- }
44
- } catch (_) {
45
- // Silent fail — never block Claude
46
- }
47
- process.exit(0);
48
- });
49
-
50
- /**
51
- * Build an activity event from a hook payload, or return null to skip.
52
- * @param {any} data
53
- * @returns {object|null}
54
- */
55
- function buildEvent(data) {
56
- const tool = data.tool_name || '';
57
- const input = data.tool_input || {};
58
- const response = data.tool_response;
59
- const hookEvent = data.hook_event_name || ''; // PreToolUse or PostToolUse
60
- const ts = Date.now();
61
- const phase = hookEvent === 'PostToolUse' ? 'done' : 'start';
62
-
63
- // Task spawns — most important for agent visibility
64
- if (tool === 'Task') {
65
- return {
66
- ts, phase, tool: 'Task',
67
- desc: input.description || '',
68
- agent: input.subagent_type || '',
69
- // truncate prompt to avoid massive payloads
70
- prompt: (input.prompt || '').slice(0, 200),
71
- bg: hookEvent === 'PostToolUse',
72
- };
73
- }
74
-
75
- // Bash commands that involve declare-tools (execution steps)
76
- if (tool === 'Bash') {
77
- const cmd = input.command || '';
78
- if (cmd.includes('declare-tools') || cmd.includes('/declare:')) {
79
- return { ts, phase, tool: 'Bash', cmd: cmd.slice(0, 200) };
80
- }
81
- return null; // skip noisy general bash
82
- }
83
-
84
- // Write tool — track planning file changes + auto-sync on SUMMARY.md writes
85
- if (tool === 'Write' && hookEvent === 'PostToolUse') {
86
- const fp = input.file_path || '';
87
- if (fp.includes('.planning/')) {
88
- // When an executor writes A-XX-SUMMARY.md, auto-run sync-status so
89
- // PLAN.md and MILESTONES.md update immediately without manual intervention
90
- if (fp.includes('-SUMMARY.md')) {
91
- const { execSync } = require('child_process');
92
- try {
93
- execSync(`node "${path.join(cwd, '.claude', 'declare-tools.cjs')}" sync-status`, {
94
- cwd,
95
- timeout: 10000,
96
- stdio: 'ignore',
97
- });
98
- } catch (_) { /* silent — never block Claude */ }
99
- }
100
- return { ts, phase: 'done', tool: 'Write', file: fp.replace(cwd, '.') };
101
- }
102
- return null;
103
- }
104
-
105
- return null;
106
- }
@@ -1,62 +0,0 @@
1
- #!/usr/bin/env node
2
- // Check for Declare updates in background, write result to cache
3
- // Called by SessionStart hook - runs once per session
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 cwd = process.cwd();
12
- const cacheDir = path.join(homeDir, '.claude', 'cache');
13
- const cacheFile = path.join(cacheDir, 'declare-update-check.json');
14
-
15
- // VERSION file locations (check project first, then global)
16
- const projectVersionFile = path.join(cwd, '.claude', 'declare', 'VERSION');
17
- const globalVersionFile = path.join(homeDir, '.claude', 'declare', 'VERSION');
18
-
19
- // Ensure cache directory exists
20
- if (!fs.existsSync(cacheDir)) {
21
- fs.mkdirSync(cacheDir, { recursive: true });
22
- }
23
-
24
- // Run check in background (spawn background process, windowsHide prevents console flash)
25
- const child = spawn(process.execPath, ['-e', `
26
- const fs = require('fs');
27
- const { execSync } = require('child_process');
28
-
29
- const cacheFile = ${JSON.stringify(cacheFile)};
30
- const projectVersionFile = ${JSON.stringify(projectVersionFile)};
31
- const globalVersionFile = ${JSON.stringify(globalVersionFile)};
32
-
33
- // Check project directory first (local install), then global
34
- let installed = '0.0.0';
35
- try {
36
- if (fs.existsSync(projectVersionFile)) {
37
- installed = fs.readFileSync(projectVersionFile, 'utf8').trim();
38
- } else if (fs.existsSync(globalVersionFile)) {
39
- installed = fs.readFileSync(globalVersionFile, 'utf8').trim();
40
- }
41
- } catch (e) {}
42
-
43
- let latest = null;
44
- try {
45
- latest = execSync('npm view declare-cc version', { encoding: 'utf8', timeout: 10000, windowsHide: true }).trim();
46
- } catch (e) {}
47
-
48
- const result = {
49
- update_available: latest && installed !== latest,
50
- installed,
51
- latest: latest || 'unknown',
52
- checked: Math.floor(Date.now() / 1000)
53
- };
54
-
55
- fs.writeFileSync(cacheFile, JSON.stringify(result));
56
- `], {
57
- stdio: 'ignore',
58
- windowsHide: true,
59
- detached: true // Required on Windows for proper process detachment
60
- });
61
-
62
- child.unref();
@@ -1,116 +0,0 @@
1
- #!/usr/bin/env node
2
- // Declare dashboard server — SessionStart hook
3
- //
4
- // On every Claude Code session start (for a Declare project):
5
- // 1. Derive a stable port for this project (hash of cwd, range 3847-4846)
6
- // 2. If a server is already running on that port for THIS project, leave it
7
- // 3. If a server is running on that port for a DIFFERENT project, kill it
8
- // 4. Start a fresh server for the current project
9
- // 5. Write the port to .planning/server.port for /declare:dashboard to read
10
- //
11
- // This means each project gets its own port, servers survive between sessions,
12
- // and switching projects always gives you the right server.
13
-
14
- 'use strict';
15
-
16
- const fs = require('fs');
17
- const path = require('path');
18
- const http = require('http');
19
- const cp = require('child_process');
20
-
21
- const cwd = process.cwd();
22
- const planningDir = path.join(cwd, '.planning');
23
-
24
- // Only run for Declare projects
25
- if (!fs.existsSync(planningDir)) process.exit(0);
26
-
27
- const PORT_BASE = 3847;
28
- const PORT_RANGE = 1000; // ports 3847–4846
29
-
30
- /**
31
- * Simple djb2 hash to derive a stable port from the project path.
32
- * @param {string} str
33
- * @returns {number} port in [PORT_BASE, PORT_BASE + PORT_RANGE)
34
- */
35
- function projectPort(str) {
36
- let h = 5381;
37
- for (let i = 0; i < str.length; i++) {
38
- h = ((h << 5) + h) ^ str.charCodeAt(i);
39
- h = h >>> 0; // keep unsigned 32-bit
40
- }
41
- return PORT_BASE + (h % PORT_RANGE);
42
- }
43
-
44
- const port = projectPort(cwd);
45
- const portFile = path.join(planningDir, 'server.port');
46
- const bundle = path.join(cwd, '.claude', 'declare-tools.cjs');
47
-
48
- // If bundle doesn't exist, nothing to do
49
- if (!fs.existsSync(bundle)) process.exit(0);
50
-
51
- /**
52
- * Ask the running server on `port` which cwd it's serving, via /api/graph.
53
- * Returns the project name or null if nothing is running / not a Declare server.
54
- */
55
- function checkRunningServer(port, callback) {
56
- const req = http.get(`http://127.0.0.1:${port}/api/graph`, { timeout: 1500 }, res => {
57
- let body = '';
58
- res.on('data', c => body += c);
59
- res.on('end', () => {
60
- try {
61
- const data = JSON.parse(body);
62
- // If it has a valid graph response it's our server
63
- callback(data && !data.error ? 'declare' : null);
64
- } catch { callback(null); }
65
- });
66
- });
67
- req.on('error', () => callback(null));
68
- req.on('timeout', () => { req.destroy(); callback(null); });
69
- }
70
-
71
- /**
72
- * Kill any process currently listening on the given port.
73
- */
74
- function killPort(port) {
75
- try {
76
- const pid = cp.execSync(`lsof -ti :${port} 2>/dev/null`, { encoding: 'utf8' }).trim();
77
- if (pid) {
78
- pid.split('\n').forEach(p => {
79
- try { process.kill(parseInt(p), 'SIGTERM'); } catch {}
80
- });
81
- }
82
- } catch {}
83
- }
84
-
85
- /**
86
- * Start the dashboard server for this project in the background.
87
- */
88
- function startServer() {
89
- // Write port file before spawning so /declare:dashboard always finds it
90
- try { fs.writeFileSync(portFile, String(port)); } catch {}
91
-
92
- const child = cp.spawn(process.execPath, [bundle, 'serve', '--port', String(port)], {
93
- cwd,
94
- detached: true,
95
- stdio: 'ignore',
96
- });
97
- child.unref();
98
- }
99
-
100
- // Check if something is already running on this port
101
- checkRunningServer(port, status => {
102
- if (status === 'declare') {
103
- // A Declare server is already up on our port.
104
- // It might be from a previous session for this same project — reuse it.
105
- // Write port file to make sure /declare:dashboard finds it.
106
- try { fs.writeFileSync(portFile, String(port)); } catch {}
107
- process.exit(0);
108
- }
109
-
110
- // Nothing running (or non-Declare process) — kill whatever is there and start fresh
111
- killPort(port);
112
- setTimeout(() => {
113
- startServer();
114
- process.exit(0);
115
- }, 300);
116
- });
@@ -1,91 +0,0 @@
1
- #!/usr/bin/env node
2
- // Claude Code Statusline - Declare Edition
3
- // Shows: model | current task | directory | context usage
4
-
5
- const fs = require('fs');
6
- const path = require('path');
7
- const os = require('os');
8
-
9
- // Read JSON from stdin
10
- let input = '';
11
- process.stdin.setEncoding('utf8');
12
- process.stdin.on('data', chunk => input += chunk);
13
- process.stdin.on('end', () => {
14
- try {
15
- const data = JSON.parse(input);
16
- const model = data.model?.display_name || 'Claude';
17
- const dir = data.workspace?.current_dir || process.cwd();
18
- const session = data.session_id || '';
19
- const remaining = data.context_window?.remaining_percentage;
20
-
21
- // Context window display (shows USED percentage scaled to 80% limit)
22
- // Claude Code enforces an 80% context limit, so we scale to show 100% at that point
23
- let ctx = '';
24
- if (remaining != null) {
25
- const rem = Math.round(remaining);
26
- const rawUsed = Math.max(0, Math.min(100, 100 - rem));
27
- // Scale: 80% real usage = 100% displayed
28
- const used = Math.min(100, Math.round((rawUsed / 80) * 100));
29
-
30
- // Build progress bar (10 segments)
31
- const filled = Math.floor(used / 10);
32
- const bar = '█'.repeat(filled) + '░'.repeat(10 - filled);
33
-
34
- // Color based on scaled usage (thresholds adjusted for new scale)
35
- if (used < 63) { // ~50% real
36
- ctx = ` \x1b[32m${bar} ${used}%\x1b[0m`;
37
- } else if (used < 81) { // ~65% real
38
- ctx = ` \x1b[33m${bar} ${used}%\x1b[0m`;
39
- } else if (used < 95) { // ~76% real
40
- ctx = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
41
- } else {
42
- ctx = ` \x1b[5;31m💀 ${bar} ${used}%\x1b[0m`;
43
- }
44
- }
45
-
46
- // Current task from todos
47
- let task = '';
48
- const homeDir = os.homedir();
49
- const todosDir = path.join(homeDir, '.claude', 'todos');
50
- if (session && fs.existsSync(todosDir)) {
51
- try {
52
- const files = fs.readdirSync(todosDir)
53
- .filter(f => f.startsWith(session) && f.includes('-agent-') && f.endsWith('.json'))
54
- .map(f => ({ name: f, mtime: fs.statSync(path.join(todosDir, f)).mtime }))
55
- .sort((a, b) => b.mtime - a.mtime);
56
-
57
- if (files.length > 0) {
58
- try {
59
- const todos = JSON.parse(fs.readFileSync(path.join(todosDir, files[0].name), 'utf8'));
60
- const inProgress = todos.find(t => t.status === 'in_progress');
61
- if (inProgress) task = inProgress.activeForm || '';
62
- } catch (e) {}
63
- }
64
- } catch (e) {
65
- // Silently fail on file system errors - don't break statusline
66
- }
67
- }
68
-
69
- // Declare update available?
70
- let gsdUpdate = '';
71
- const cacheFile = path.join(homeDir, '.claude', 'cache', 'declare-update-check.json');
72
- if (fs.existsSync(cacheFile)) {
73
- try {
74
- const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
75
- if (cache.update_available) {
76
- gsdUpdate = '\x1b[33m⬆ /declare:update\x1b[0m │ ';
77
- }
78
- } catch (e) {}
79
- }
80
-
81
- // Output
82
- const dirname = path.basename(dir);
83
- if (task) {
84
- process.stdout.write(`${gsdUpdate}\x1b[2m${model}\x1b[0m │ \x1b[1m${task}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}`);
85
- } else {
86
- process.stdout.write(`${gsdUpdate}\x1b[2m${model}\x1b[0m │ \x1b[2m${dirname}\x1b[0m${ctx}`);
87
- }
88
- } catch (e) {
89
- // Silent fail - don't break statusline on parse errors
90
- }
91
- });
@@ -1,42 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Copy GSD hooks to dist for installation.
4
- */
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
-
9
- const HOOKS_DIR = path.join(__dirname, '..', 'hooks');
10
- const DIST_DIR = path.join(HOOKS_DIR, 'dist');
11
-
12
- // Hooks to copy (pure Node.js, no bundling needed)
13
- const HOOKS_TO_COPY = [
14
- 'gsd-check-update.js',
15
- 'gsd-statusline.js'
16
- ];
17
-
18
- function build() {
19
- // Ensure dist directory exists
20
- if (!fs.existsSync(DIST_DIR)) {
21
- fs.mkdirSync(DIST_DIR, { recursive: true });
22
- }
23
-
24
- // Copy hooks to dist
25
- for (const hook of HOOKS_TO_COPY) {
26
- const src = path.join(HOOKS_DIR, hook);
27
- const dest = path.join(DIST_DIR, hook);
28
-
29
- if (!fs.existsSync(src)) {
30
- console.warn(`Warning: ${hook} not found, skipping`);
31
- continue;
32
- }
33
-
34
- console.log(`Copying ${hook}...`);
35
- fs.copyFileSync(src, dest);
36
- console.log(` → ${dest}`);
37
- }
38
-
39
- console.log('\nBuild complete.');
40
- }
41
-
42
- build();
@@ -1,50 +0,0 @@
1
- #!/usr/bin/env node
2
- // Release script: bump version, build, commit, tag.
3
- // Usage: npm run release -- <version>
4
- // Example: npm run release -- 0.5.6
5
- //
6
- // After this runs, publish manually:
7
- // npm publish --otp=<your-2fa-code>
8
- // git push && git push --tags
9
-
10
- 'use strict';
11
-
12
- const { execSync } = require('child_process');
13
- const fs = require('fs');
14
- const path = require('path');
15
-
16
- const version = process.argv[2];
17
- if (!version || !/^\d+\.\d+\.\d+$/.test(version)) {
18
- console.error('Usage: npm run release -- <version> (e.g. 0.5.6)');
19
- process.exit(1);
20
- }
21
-
22
- const root = path.join(__dirname, '..');
23
- const pkgPath = path.join(root, 'package.json');
24
-
25
- function run(cmd) {
26
- console.log(`> ${cmd}`);
27
- execSync(cmd, { cwd: root, stdio: 'inherit' });
28
- }
29
-
30
- // 1. Bump version in package.json
31
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
32
- const prev = pkg.version;
33
- pkg.version = version;
34
- fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
35
- console.log(`Bumped ${prev} → ${version}`);
36
-
37
- // 2. Build
38
- run('npm run build');
39
-
40
- // 3. Commit + tag
41
- run(`git add package.json package-lock.json dist/`);
42
- run(`git commit -m "chore: bump version to ${version}"`);
43
- run(`git tag -f v${version}`);
44
-
45
- console.log(`
46
- Done. To publish:
47
-
48
- npm publish --otp=<your-2fa-code>
49
- git push && git push --tags
50
- `);
@@ -1,4 +0,0 @@
1
- # Future: [Project Name]
2
-
3
- <!-- Each declaration is a standalone truth statement about the future. -->
4
- <!-- Edit freely -- the system validates on load, not on save. -->
@@ -1,11 +0,0 @@
1
- # Milestones & Actions: [Project Name]
2
-
3
- ## Milestones
4
-
5
- | ID | Title | Status | Realizes | Caused By |
6
- |----|-------|--------|----------|-----------|
7
-
8
- ## Actions
9
-
10
- | ID | Title | Status | Causes |
11
- |----|-------|--------|--------|
@@ -1,89 +0,0 @@
1
- # Action Plan Derivation Workflow
2
-
3
- You are guiding a user through action plan derivation: for each milestone, working backward to determine the concrete actions that must be done to make the milestone true.
4
-
5
- ## Opening
6
-
7
- Show the milestones being processed:
8
-
9
- > Let's derive action plans for your milestones -- the concrete steps to make each one true.
10
- >
11
- > Milestones to plan:
12
- > - M-01: [title] (realizes D-XX)
13
- > - M-02: [title] (realizes D-XX)
14
- > ...
15
- >
16
- > For each milestone, I'll ask: "For this to be true, what must be done?" Each answer becomes an action with a clear artifact or state change it produces.
17
-
18
- If deriving for a specific milestone (argument provided), focus on just that one:
19
-
20
- > Let's derive an action plan for:
21
- > - [M-XX]: [title]
22
-
23
- ## Per-Milestone Derivation Loop
24
-
25
- For each milestone M that needs a plan:
26
-
27
- ### a. State the backward question
28
-
29
- > For "[M title]" to be true, what must be done?
30
-
31
- ### b. Derive actions (2-6 per milestone)
32
-
33
- For each proposed action:
34
-
35
- - **Title:** clear, action-oriented (e.g., "Build authentication middleware", "Write migration script")
36
- - **Produces:** what artifact or state change results (e.g., "auth middleware module", "migrated database schema")
37
- - **Atomicity check:** Can this be completed in one focused session? Does it produce a verifiable artifact? Is "done" clear?
38
- - If YES: include as an action.
39
- - If NO: it may need to be split or may actually be a sub-milestone.
40
-
41
- Err on the side of "atomic enough" -- over-decomposition creates bloat. If something is borderline, treat it as a single action.
42
-
43
- ### c. Present complete plan for approval
44
-
45
- Show all proposed actions together as a coherent plan:
46
-
47
- > Here's the proposed plan for M-XX "[milestone title]":
48
- >
49
- > 1. **[Action A]** -- produces [what]
50
- > 2. **[Action B]** -- produces [what]
51
- > 3. **[Action C]** -- produces [what]
52
- >
53
- > This plan will be presented for your approval.
54
-
55
- The command will present this for user approval via AskUserQuestion.
56
-
57
- ### d. Handle adjustments
58
-
59
- If the user wants changes:
60
- - Add, remove, rename, or reorder actions as requested
61
- - Re-present the adjusted plan for approval
62
-
63
- If the user approves: signal the command to persist via create-plan.
64
-
65
- ### e. Move to next milestone
66
-
67
- After a plan is approved and persisted, move to the next milestone.
68
-
69
- ## Closing
70
-
71
- After all milestones have plans:
72
-
73
- > Action derivation complete.
74
- >
75
- > Created plans for [X] milestones with [Y] total actions.
76
- >
77
- > Run `/declare:status` to see coverage and health.
78
-
79
- ## Design Principles
80
-
81
- Follow these throughout the conversation:
82
-
83
- - **Actions are derived and presented as a complete plan per milestone**, not individually. The user reviews the whole plan at once.
84
- - **"What must be done?" is the core question.** Keep the backward reasoning visible.
85
- - **Each action should be atomic** -- single focused session, verifiable artifact, clear "done" state.
86
- - **Err toward atomic enough.** Over-decomposition creates bloat. If something could be one action or two, lean toward one.
87
- - **Show your reasoning.** For each action, explain what it produces and why it's needed.
88
- - **Propose, don't dictate.** The user may have better ideas about how to decompose their work.
89
- - **Do not use emojis.** Keep the tone professional and grounded.