maxsimcli 4.15.3 → 4.16.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/dist/assets/CHANGELOG.md +14 -0
- package/dist/assets/hooks/maxsim-statusline.cjs +46 -7
- package/dist/assets/hooks/maxsim-statusline.cjs.map +1 -1
- package/dist/assets/templates/agents/AGENTS.md +1 -1
- package/dist/assets/templates/agents/executor.md +1 -1
- package/dist/assets/templates/agents/planner.md +4 -4
- package/dist/assets/templates/references/git-planning-commit.md +1 -1
- package/dist/assets/templates/references/questioning.md +1 -1
- package/dist/assets/templates/templates/codebase/structure.md +1 -1
- package/dist/assets/templates/templates/milestone-archive.md +3 -3
- package/dist/assets/templates/workflows/batch.md +2 -3
- package/dist/assets/templates/workflows/diagnose-issues.md +6 -6
- package/dist/assets/templates/workflows/discovery-phase.md +6 -7
- package/dist/assets/templates/workflows/discuss-phase.md +8 -11
- package/dist/assets/templates/workflows/execute-phase.md +11 -71
- package/dist/assets/templates/workflows/execute-plan.md +8 -37
- package/dist/assets/templates/workflows/execute.md +7 -9
- package/dist/assets/templates/workflows/go.md +4 -4
- package/dist/assets/templates/workflows/help.md +1 -1
- package/dist/assets/templates/workflows/init-existing.md +0 -5
- package/dist/assets/templates/workflows/new-milestone.md +2 -7
- package/dist/assets/templates/workflows/new-project.md +0 -5
- package/dist/assets/templates/workflows/progress.md +10 -11
- package/dist/assets/templates/workflows/quick.md +0 -1
- package/dist/assets/templates/workflows/sdd.md +29 -30
- package/dist/assets/templates/workflows/settings.md +2 -7
- package/dist/assets/templates/workflows/verify-work.md +2 -16
- package/dist/cli.cjs +6913 -6499
- package/dist/cli.cjs.map +1 -1
- package/dist/core-D5zUr9cb.cjs.map +1 -1
- package/dist/install.cjs +10 -26
- package/dist/install.cjs.map +1 -1
- package/dist/mcp-server.cjs +186 -91
- package/dist/mcp-server.cjs.map +1 -1
- package/dist/skills-CjFWZIGM.cjs.map +1 -1
- package/package.json +1 -1
- package/dist/assets/templates/references/dashboard-bridge.md +0 -59
- package/dist/assets/templates/workflows/plan-phase.md +0 -501
package/dist/assets/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [4.15.4](https://github.com/maystudios/maxsimcli/compare/v4.15.3...v4.15.4) (2026-03-12)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* remove stale references to dashboard, plan-phase, milestones shims and enhance statusline ([b895bf2](https://github.com/maystudios/maxsimcli/commit/b895bf22228117e93ad36cfb358777a4591109ed))
|
|
7
|
+
|
|
8
|
+
## [4.15.3](https://github.com/maystudios/maxsimcli/compare/v4.15.2...v4.15.3) (2026-03-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **workflows:** move init CLI call into router to prevent workflow freelancing ([242e943](https://github.com/maystudios/maxsimcli/commit/242e9438968e90012c7ccc5b3180380a628c7154))
|
|
14
|
+
|
|
1
15
|
## [4.15.2](https://github.com/maystudios/maxsimcli/compare/v4.15.1...v4.15.2) (2026-03-11)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -60,7 +60,7 @@ const CLAUDE_DIR = ".claude";
|
|
|
60
60
|
//#region src/hooks/maxsim-statusline.ts
|
|
61
61
|
/**
|
|
62
62
|
* Claude Code Statusline - MAXSIM Edition
|
|
63
|
-
* Shows: [update] model | P{N} |
|
|
63
|
+
* Shows: [update] model | P{N} {BoardColumn} | {milestone}: {pct}% | dirname
|
|
64
64
|
*/
|
|
65
65
|
const CACHE_TTL_SECONDS = 60;
|
|
66
66
|
/**
|
|
@@ -112,25 +112,49 @@ try {
|
|
|
112
112
|
// gh api failed for milestones, continue with defaults
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
// Get current phase from
|
|
115
|
+
// Get current phase from open issues with 'phase' label, parse number from title
|
|
116
116
|
let phaseNumber = null;
|
|
117
|
+
let issueNumber = null;
|
|
117
118
|
try {
|
|
118
119
|
const phaseRaw = execSync(
|
|
119
|
-
'gh api "repos/' + owner + '/' + repo + '/issues?state=open&labels=phase
|
|
120
|
+
'gh api "repos/' + owner + '/' + repo + '/issues?state=open&labels=phase&per_page=1&sort=updated&direction=desc" --jq ".[0] | {number: .number, title: .title}"',
|
|
120
121
|
{ encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }
|
|
121
122
|
).trim();
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
const phaseData = JSON.parse(phaseRaw || '{}');
|
|
124
|
+
const titleMatch = (phaseData.title || '').match(/^\\[Phase\\s+(\\S+)\\]/);
|
|
125
|
+
if (titleMatch) {
|
|
126
|
+
phaseNumber = titleMatch[1];
|
|
124
127
|
}
|
|
128
|
+
issueNumber = phaseData.number || null;
|
|
125
129
|
} catch (e) {
|
|
126
130
|
// gh api failed for phase, continue with null
|
|
127
131
|
}
|
|
128
132
|
|
|
133
|
+
// Get board column via GraphQL
|
|
134
|
+
let boardColumn = null;
|
|
135
|
+
if (issueNumber) {
|
|
136
|
+
try {
|
|
137
|
+
const gqlQuery = '{ repository(owner: "' + owner + '", name: "' + repo + '") { issue(number: ' + issueNumber + ') { projectItems(first: 5, includeArchived: false) { nodes { fieldValueByName(name: "Status") { ... on ProjectV2ItemFieldSingleSelectValue { name } } } } } } }';
|
|
138
|
+
const boardRaw = execSync(
|
|
139
|
+
'gh api graphql -f query=@-',
|
|
140
|
+
{ input: gqlQuery, encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }
|
|
141
|
+
).trim();
|
|
142
|
+
const boardData = JSON.parse(boardRaw);
|
|
143
|
+
const nodes = boardData?.data?.repository?.issue?.projectItems?.nodes || [];
|
|
144
|
+
if (nodes.length > 0 && nodes[0]?.fieldValueByName?.name) {
|
|
145
|
+
boardColumn = nodes[0].fieldValueByName.name;
|
|
146
|
+
}
|
|
147
|
+
} catch (e) {
|
|
148
|
+
boardColumn = null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
129
152
|
// Write cache
|
|
130
153
|
const cacheData = JSON.stringify({
|
|
131
154
|
phase_number: phaseNumber,
|
|
132
155
|
milestone_title: milestoneTitle,
|
|
133
156
|
milestone_pct: milestonePct,
|
|
157
|
+
board_column: boardColumn,
|
|
134
158
|
updated: Math.floor(Date.now() / 1000),
|
|
135
159
|
});
|
|
136
160
|
|
|
@@ -138,7 +162,18 @@ try {
|
|
|
138
162
|
fs.mkdirSync(dir, { recursive: true });
|
|
139
163
|
fs.writeFileSync(${JSON.stringify(cacheFile)}, cacheData);
|
|
140
164
|
} catch (e) {
|
|
141
|
-
|
|
165
|
+
try {
|
|
166
|
+
const dir = ${JSON.stringify(cacheDir)};
|
|
167
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
168
|
+
fs.writeFileSync(${JSON.stringify(cacheFile)}, JSON.stringify({
|
|
169
|
+
phase_number: null,
|
|
170
|
+
milestone_title: null,
|
|
171
|
+
milestone_pct: 0,
|
|
172
|
+
board_column: null,
|
|
173
|
+
offline: true,
|
|
174
|
+
updated: Math.floor(Date.now() / 1000),
|
|
175
|
+
}));
|
|
176
|
+
} catch (_) {}
|
|
142
177
|
process.exit(0);
|
|
143
178
|
}
|
|
144
179
|
`;
|
|
@@ -174,8 +209,12 @@ function formatStatusline(data) {
|
|
|
174
209
|
cache = null;
|
|
175
210
|
}
|
|
176
211
|
if (cacheAge > CACHE_TTL_SECONDS) spawnBackgroundRefresh(cacheDir, cacheFile);
|
|
212
|
+
if (cache?.offline) return `${updateIndicator}${DIM}${model}${RESET}${SEP}${DIM}P? offline${RESET}${SEP}${DIM}${dirname}${RESET}`;
|
|
177
213
|
let phaseSegment = "";
|
|
178
|
-
if (cache?.phase_number)
|
|
214
|
+
if (cache?.phase_number) {
|
|
215
|
+
const column = cache.board_column ? ` ${cache.board_column}` : "";
|
|
216
|
+
phaseSegment = `${SEP}${DIM}P${cache.phase_number}${column}${RESET}`;
|
|
217
|
+
}
|
|
179
218
|
let milestoneSegment = "";
|
|
180
219
|
if (cache?.milestone_title) milestoneSegment = `${SEP}${DIM}${cache.milestone_title}: ${cache.milestone_pct}%${RESET}`;
|
|
181
220
|
return `${updateIndicator}${DIM}${model}${RESET}${phaseSegment}${milestoneSegment}${SEP}${DIM}${dirname}${RESET}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maxsim-statusline.cjs","names":["path","fs"],"sources":["../../../src/hooks/shared.ts","../../../src/hooks/maxsim-statusline.ts"],"sourcesContent":["/**\n * Shared utilities for MAXSIM hooks.\n */\n\n/**\n * Read all stdin as a string, then invoke callback with parsed JSON.\n * Used by statusline and sync-reminder hooks.\n */\nexport function readStdinJson<T>(callback: (data: T) => void): void {\n let input = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk: string) => (input += chunk));\n process.stdin.on('end', () => {\n try {\n const data = JSON.parse(input) as T;\n callback(data);\n } catch {\n // Silent fail -- never block hook execution\n process.exit(0);\n }\n });\n}\n\n/** The '.claude' path segment -- template marker replaced during install. */\nexport const CLAUDE_DIR = '.claude';\n","#!/usr/bin/env node\n/**\n * Claude Code Statusline - MAXSIM Edition\n * Shows: [update] model | P{N} | v{M}: {pct}% | dirname\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { readStdinJson, CLAUDE_DIR } from './shared';\n\nexport interface StatuslineInput {\n model?: { display_name?: string };\n workspace?: { current_dir?: string; project_dir?: string };\n session_id?: string;\n}\n\nexport interface ProgressCache {\n phase_number: string | null;\n milestone_title: string | null;\n milestone_pct: number;\n updated: number;\n}\n\nconst CACHE_TTL_SECONDS = 60;\n\n/**\n * Spawn a detached Node child process to refresh the progress cache in the background.\n * The child runs gh CLI commands to detect owner/repo, find the first open milestone,\n * compute progress, and find the current phase label.\n */\nfunction spawnBackgroundRefresh(cacheDir: string, cacheFile: string): void {\n try {\n const script = `\nconst { execSync } = require('child_process');\nconst fs = require('fs');\nconst path = require('path');\n\ntry {\n // Detect owner/repo\n const nameWithOwner = execSync('gh repo view --json nameWithOwner -q .nameWithOwner', {\n encoding: 'utf8',\n timeout: 10000,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (!nameWithOwner || !nameWithOwner.includes('/')) {\n process.exit(0);\n }\n\n const [owner, repo] = nameWithOwner.split('/');\n\n // Get milestones\n let milestoneTitle = null;\n let milestonePct = 0;\n try {\n const milestonesRaw = execSync(\n 'gh api repos/' + owner + '/' + repo + '/milestones --jq \".\"',\n { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n if (milestonesRaw) {\n const milestones = JSON.parse(milestonesRaw);\n const openMilestone = milestones.find(function(m) { return m.state === 'open'; });\n if (openMilestone) {\n milestoneTitle = openMilestone.title || null;\n const total = (openMilestone.open_issues || 0) + (openMilestone.closed_issues || 0);\n if (total > 0) {\n milestonePct = Math.round(((openMilestone.closed_issues || 0) / total) * 100);\n }\n }\n }\n } catch (e) {\n // gh api failed for milestones, continue with defaults\n }\n\n // Get current phase from labels on open issues\n let phaseNumber = null;\n try {\n const phaseRaw = execSync(\n 'gh api \"repos/' + owner + '/' + repo + '/issues?state=open&labels=phase:&per_page=1&sort=created&direction=desc\" --jq \".[0].labels[] | select(.name | startswith(\\\\\"phase:\\\\\")) | .name\"',\n { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n if (phaseRaw && phaseRaw.startsWith('phase:')) {\n phaseNumber = phaseRaw.replace('phase:', '').trim();\n }\n } catch (e) {\n // gh api failed for phase, continue with null\n }\n\n // Write cache\n const cacheData = JSON.stringify({\n phase_number: phaseNumber,\n milestone_title: milestoneTitle,\n milestone_pct: milestonePct,\n updated: Math.floor(Date.now() / 1000),\n });\n\n const dir = ${JSON.stringify(cacheDir)};\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(${JSON.stringify(cacheFile)}, cacheData);\n} catch (e) {\n // Silently degrade if gh not available\n process.exit(0);\n}\n`;\n\n const child = spawn(process.execPath, ['-e', script], {\n stdio: 'ignore',\n windowsHide: true,\n detached: true,\n });\n child.unref();\n } catch {\n // Silent fail -- never break statusline\n }\n}\n\nexport function formatStatusline(data: StatuslineInput): string {\n const model = data.model?.display_name || 'Claude';\n const dir = data.workspace?.project_dir || data.workspace?.current_dir || process.cwd();\n const dirname = path.basename(dir);\n\n const SEP = ' \\u2502 ';\n const DIM = '\\x1b[2m';\n const RESET = '\\x1b[0m';\n\n // MAXSIM update available?\n let updateIndicator = '';\n const updateCacheFile = path.join(dir, CLAUDE_DIR, 'cache', 'maxsim-update-check.json');\n if (fs.existsSync(updateCacheFile)) {\n try {\n const cache = JSON.parse(fs.readFileSync(updateCacheFile, 'utf8'));\n if (cache.update_available) {\n updateIndicator = '\\x1b[33m\\u2B06\\x1b[0m ';\n }\n } catch {\n // ignore\n }\n }\n\n // Check if this is a MAXSIM project\n const planningDir = path.join(dir, '.planning');\n const isMaxsimProject = fs.existsSync(planningDir);\n\n if (!isMaxsimProject) {\n return `${updateIndicator}${DIM}${model}${RESET}${SEP}${DIM}${dirname}${RESET}`;\n }\n\n // Read progress cache\n const cacheDir = path.join(dir, CLAUDE_DIR, 'cache');\n const cacheFile = path.join(cacheDir, 'maxsim-progress.json');\n let cache: ProgressCache | null = null;\n let cacheAge = Infinity;\n\n if (fs.existsSync(cacheFile)) {\n try {\n cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8')) as ProgressCache;\n cacheAge = Math.floor(Date.now() / 1000) - (cache.updated || 0);\n } catch {\n cache = null;\n }\n }\n\n // Spawn background refresh if cache is stale or missing\n if (cacheAge > CACHE_TTL_SECONDS) {\n spawnBackgroundRefresh(cacheDir, cacheFile);\n }\n\n // Build phase segment\n let phaseSegment = '';\n if (cache?.phase_number) {\n phaseSegment = `${SEP}${DIM}P${cache.phase_number}${RESET}`;\n }\n\n // Build milestone segment\n let milestoneSegment = '';\n if (cache?.milestone_title) {\n milestoneSegment = `${SEP}${DIM}${cache.milestone_title}: ${cache.milestone_pct}%${RESET}`;\n }\n\n return `${updateIndicator}${DIM}${model}${RESET}${phaseSegment}${milestoneSegment}${SEP}${DIM}${dirname}${RESET}`;\n}\n\n// Standalone entry\nif (require.main === module) {\n readStdinJson<StatuslineInput>((data) => {\n process.stdout.write(formatStatusline(data));\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAAgB,cAAiB,UAAmC;CAClE,IAAI,QAAQ;AACZ,SAAQ,MAAM,YAAY,OAAO;AACjC,SAAQ,MAAM,GAAG,SAAS,UAAmB,SAAS,MAAO;AAC7D,SAAQ,MAAM,GAAG,aAAa;AAC5B,MAAI;AAEF,YADa,KAAK,MAAM,MAAM,CAChB;UACR;AAEN,WAAQ,KAAK,EAAE;;GAEjB;;;AAIJ,MAAa,aAAa;;;;;;;;ACA1B,MAAM,oBAAoB;;;;;;AAO1B,SAAS,uBAAuB,UAAkB,WAAyB;AACzE,KAAI;EACF,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAgEH,KAAK,UAAU,SAAS,CAAC;;qBAEpB,KAAK,UAAU,UAAU,CAAC;;;;;;AAY3C,gCALoB,QAAQ,UAAU,CAAC,MAAM,OAAO,EAAE;GACpD,OAAO;GACP,aAAa;GACb,UAAU;GACX,CAAC,CACI,OAAO;SACP;;AAKV,SAAgB,iBAAiB,MAA+B;CAC9D,MAAM,QAAQ,KAAK,OAAO,gBAAgB;CAC1C,MAAM,MAAM,KAAK,WAAW,eAAe,KAAK,WAAW,eAAe,QAAQ,KAAK;CACvF,MAAM,UAAUA,UAAK,SAAS,IAAI;CAElC,MAAM,MAAM;CACZ,MAAM,MAAM;CACZ,MAAM,QAAQ;CAGd,IAAI,kBAAkB;CACtB,MAAM,kBAAkBA,UAAK,KAAK,KAAK,YAAY,SAAS,2BAA2B;AACvF,KAAIC,QAAG,WAAW,gBAAgB,CAChC,KAAI;AAEF,MADc,KAAK,MAAMA,QAAG,aAAa,iBAAiB,OAAO,CAAC,CACxD,iBACR,mBAAkB;SAEd;CAMV,MAAM,cAAcD,UAAK,KAAK,KAAK,YAAY;AAG/C,KAAI,CAFoBC,QAAG,WAAW,YAAY,CAGhD,QAAO,GAAG,kBAAkB,MAAM,QAAQ,QAAQ,MAAM,MAAM,UAAU;CAI1E,MAAM,WAAWD,UAAK,KAAK,KAAK,YAAY,QAAQ;CACpD,MAAM,YAAYA,UAAK,KAAK,UAAU,uBAAuB;CAC7D,IAAI,QAA8B;CAClC,IAAI,WAAW;AAEf,KAAIC,QAAG,WAAW,UAAU,CAC1B,KAAI;AACF,UAAQ,KAAK,MAAMA,QAAG,aAAa,WAAW,OAAO,CAAC;AACtD,aAAW,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,IAAI,MAAM,WAAW;SACvD;AACN,UAAQ;;AAKZ,KAAI,WAAW,kBACb,wBAAuB,UAAU,UAAU;CAI7C,IAAI,eAAe;AACnB,KAAI,OAAO,aACT,gBAAe,GAAG,MAAM,IAAI,GAAG,MAAM,eAAe;CAItD,IAAI,mBAAmB;AACvB,KAAI,OAAO,gBACT,oBAAmB,GAAG,MAAM,MAAM,MAAM,gBAAgB,IAAI,MAAM,cAAc,GAAG;AAGrF,QAAO,GAAG,kBAAkB,MAAM,QAAQ,QAAQ,eAAe,mBAAmB,MAAM,MAAM,UAAU;;AAI5G,IAAI,QAAQ,SAAS,OACnB,gBAAgC,SAAS;AACvC,SAAQ,OAAO,MAAM,iBAAiB,KAAK,CAAC;EAC5C"}
|
|
1
|
+
{"version":3,"file":"maxsim-statusline.cjs","names":["path","fs"],"sources":["../../../src/hooks/shared.ts","../../../src/hooks/maxsim-statusline.ts"],"sourcesContent":["/**\n * Shared utilities for MAXSIM hooks.\n */\n\n/**\n * Read all stdin as a string, then invoke callback with parsed JSON.\n * Used by statusline and sync-reminder hooks.\n */\nexport function readStdinJson<T>(callback: (data: T) => void): void {\n let input = '';\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', (chunk: string) => (input += chunk));\n process.stdin.on('end', () => {\n try {\n const data = JSON.parse(input) as T;\n callback(data);\n } catch {\n // Silent fail -- never block hook execution\n process.exit(0);\n }\n });\n}\n\n/** The '.claude' path segment -- template marker replaced during install. */\nexport const CLAUDE_DIR = '.claude';\n","#!/usr/bin/env node\n/**\n * Claude Code Statusline - MAXSIM Edition\n * Shows: [update] model | P{N} {BoardColumn} | {milestone}: {pct}% | dirname\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { readStdinJson, CLAUDE_DIR } from './shared';\n\nexport interface StatuslineInput {\n model?: { display_name?: string };\n workspace?: { current_dir?: string; project_dir?: string };\n session_id?: string;\n}\n\nexport interface ProgressCache {\n phase_number: string | null;\n milestone_title: string | null;\n milestone_pct: number;\n board_column: string | null;\n offline?: boolean;\n updated: number;\n}\n\nconst CACHE_TTL_SECONDS = 60;\n\n/**\n * Spawn a detached Node child process to refresh the progress cache in the background.\n * The child runs gh CLI commands to detect owner/repo, find the first open milestone,\n * compute progress, and find the current phase label.\n */\nfunction spawnBackgroundRefresh(cacheDir: string, cacheFile: string): void {\n try {\n const script = `\nconst { execSync } = require('child_process');\nconst fs = require('fs');\nconst path = require('path');\n\ntry {\n // Detect owner/repo\n const nameWithOwner = execSync('gh repo view --json nameWithOwner -q .nameWithOwner', {\n encoding: 'utf8',\n timeout: 10000,\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (!nameWithOwner || !nameWithOwner.includes('/')) {\n process.exit(0);\n }\n\n const [owner, repo] = nameWithOwner.split('/');\n\n // Get milestones\n let milestoneTitle = null;\n let milestonePct = 0;\n try {\n const milestonesRaw = execSync(\n 'gh api repos/' + owner + '/' + repo + '/milestones --jq \".\"',\n { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n if (milestonesRaw) {\n const milestones = JSON.parse(milestonesRaw);\n const openMilestone = milestones.find(function(m) { return m.state === 'open'; });\n if (openMilestone) {\n milestoneTitle = openMilestone.title || null;\n const total = (openMilestone.open_issues || 0) + (openMilestone.closed_issues || 0);\n if (total > 0) {\n milestonePct = Math.round(((openMilestone.closed_issues || 0) / total) * 100);\n }\n }\n }\n } catch (e) {\n // gh api failed for milestones, continue with defaults\n }\n\n // Get current phase from open issues with 'phase' label, parse number from title\n let phaseNumber = null;\n let issueNumber = null;\n try {\n const phaseRaw = execSync(\n 'gh api \"repos/' + owner + '/' + repo + '/issues?state=open&labels=phase&per_page=1&sort=updated&direction=desc\" --jq \".[0] | {number: .number, title: .title}\"',\n { encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n const phaseData = JSON.parse(phaseRaw || '{}');\n const titleMatch = (phaseData.title || '').match(/^\\\\[Phase\\\\s+(\\\\S+)\\\\]/);\n if (titleMatch) {\n phaseNumber = titleMatch[1];\n }\n issueNumber = phaseData.number || null;\n } catch (e) {\n // gh api failed for phase, continue with null\n }\n\n // Get board column via GraphQL\n let boardColumn = null;\n if (issueNumber) {\n try {\n const gqlQuery = '{ repository(owner: \"' + owner + '\", name: \"' + repo + '\") { issue(number: ' + issueNumber + ') { projectItems(first: 5, includeArchived: false) { nodes { fieldValueByName(name: \"Status\") { ... on ProjectV2ItemFieldSingleSelectValue { name } } } } } } }';\n const boardRaw = execSync(\n 'gh api graphql -f query=@-',\n { input: gqlQuery, encoding: 'utf8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] }\n ).trim();\n const boardData = JSON.parse(boardRaw);\n const nodes = boardData?.data?.repository?.issue?.projectItems?.nodes || [];\n if (nodes.length > 0 && nodes[0]?.fieldValueByName?.name) {\n boardColumn = nodes[0].fieldValueByName.name;\n }\n } catch (e) {\n boardColumn = null;\n }\n }\n\n // Write cache\n const cacheData = JSON.stringify({\n phase_number: phaseNumber,\n milestone_title: milestoneTitle,\n milestone_pct: milestonePct,\n board_column: boardColumn,\n updated: Math.floor(Date.now() / 1000),\n });\n\n const dir = ${JSON.stringify(cacheDir)};\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(${JSON.stringify(cacheFile)}, cacheData);\n} catch (e) {\n try {\n const dir = ${JSON.stringify(cacheDir)};\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(${JSON.stringify(cacheFile)}, JSON.stringify({\n phase_number: null,\n milestone_title: null,\n milestone_pct: 0,\n board_column: null,\n offline: true,\n updated: Math.floor(Date.now() / 1000),\n }));\n } catch (_) {}\n process.exit(0);\n}\n`;\n\n const child = spawn(process.execPath, ['-e', script], {\n stdio: 'ignore',\n windowsHide: true,\n detached: true,\n });\n child.unref();\n } catch {\n // Silent fail -- never break statusline\n }\n}\n\nexport function formatStatusline(data: StatuslineInput): string {\n const model = data.model?.display_name || 'Claude';\n const dir = data.workspace?.project_dir || data.workspace?.current_dir || process.cwd();\n const dirname = path.basename(dir);\n\n const SEP = ' \\u2502 ';\n const DIM = '\\x1b[2m';\n const RESET = '\\x1b[0m';\n\n // MAXSIM update available?\n let updateIndicator = '';\n const updateCacheFile = path.join(dir, CLAUDE_DIR, 'cache', 'maxsim-update-check.json');\n if (fs.existsSync(updateCacheFile)) {\n try {\n const cache = JSON.parse(fs.readFileSync(updateCacheFile, 'utf8'));\n if (cache.update_available) {\n updateIndicator = '\\x1b[33m\\u2B06\\x1b[0m ';\n }\n } catch {\n // ignore\n }\n }\n\n // Check if this is a MAXSIM project\n const planningDir = path.join(dir, '.planning');\n const isMaxsimProject = fs.existsSync(planningDir);\n\n if (!isMaxsimProject) {\n return `${updateIndicator}${DIM}${model}${RESET}${SEP}${DIM}${dirname}${RESET}`;\n }\n\n // Read progress cache\n const cacheDir = path.join(dir, CLAUDE_DIR, 'cache');\n const cacheFile = path.join(cacheDir, 'maxsim-progress.json');\n let cache: ProgressCache | null = null;\n let cacheAge = Infinity;\n\n if (fs.existsSync(cacheFile)) {\n try {\n cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8')) as ProgressCache;\n cacheAge = Math.floor(Date.now() / 1000) - (cache.updated || 0);\n } catch {\n cache = null;\n }\n }\n\n // Spawn background refresh if cache is stale or missing\n if (cacheAge > CACHE_TTL_SECONDS) {\n spawnBackgroundRefresh(cacheDir, cacheFile);\n }\n\n // Offline fallback\n if (cache?.offline) {\n return `${updateIndicator}${DIM}${model}${RESET}${SEP}${DIM}P? offline${RESET}${SEP}${DIM}${dirname}${RESET}`;\n }\n\n // Build phase segment: P{N} {BoardColumn}\n let phaseSegment = '';\n if (cache?.phase_number) {\n const column = cache.board_column ? ` ${cache.board_column}` : '';\n phaseSegment = `${SEP}${DIM}P${cache.phase_number}${column}${RESET}`;\n }\n\n // Build milestone segment\n let milestoneSegment = '';\n if (cache?.milestone_title) {\n milestoneSegment = `${SEP}${DIM}${cache.milestone_title}: ${cache.milestone_pct}%${RESET}`;\n }\n\n return `${updateIndicator}${DIM}${model}${RESET}${phaseSegment}${milestoneSegment}${SEP}${DIM}${dirname}${RESET}`;\n}\n\n// Standalone entry\nif (require.main === module) {\n readStdinJson<StatuslineInput>((data) => {\n process.stdout.write(formatStatusline(data));\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,SAAgB,cAAiB,UAAmC;CAClE,IAAI,QAAQ;AACZ,SAAQ,MAAM,YAAY,OAAO;AACjC,SAAQ,MAAM,GAAG,SAAS,UAAmB,SAAS,MAAO;AAC7D,SAAQ,MAAM,GAAG,aAAa;AAC5B,MAAI;AAEF,YADa,KAAK,MAAM,MAAM,CAChB;UACR;AAEN,WAAQ,KAAK,EAAE;;GAEjB;;;AAIJ,MAAa,aAAa;;;;;;;;ACE1B,MAAM,oBAAoB;;;;;;AAO1B,SAAS,uBAAuB,UAAkB,WAAyB;AACzE,KAAI;EACF,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAwFH,KAAK,UAAU,SAAS,CAAC;;qBAEpB,KAAK,UAAU,UAAU,CAAC;;;kBAG7B,KAAK,UAAU,SAAS,CAAC;;uBAEpB,KAAK,UAAU,UAAU,CAAC;;;;;;;;;;;;AAkB7C,gCALoB,QAAQ,UAAU,CAAC,MAAM,OAAO,EAAE;GACpD,OAAO;GACP,aAAa;GACb,UAAU;GACX,CAAC,CACI,OAAO;SACP;;AAKV,SAAgB,iBAAiB,MAA+B;CAC9D,MAAM,QAAQ,KAAK,OAAO,gBAAgB;CAC1C,MAAM,MAAM,KAAK,WAAW,eAAe,KAAK,WAAW,eAAe,QAAQ,KAAK;CACvF,MAAM,UAAUA,UAAK,SAAS,IAAI;CAElC,MAAM,MAAM;CACZ,MAAM,MAAM;CACZ,MAAM,QAAQ;CAGd,IAAI,kBAAkB;CACtB,MAAM,kBAAkBA,UAAK,KAAK,KAAK,YAAY,SAAS,2BAA2B;AACvF,KAAIC,QAAG,WAAW,gBAAgB,CAChC,KAAI;AAEF,MADc,KAAK,MAAMA,QAAG,aAAa,iBAAiB,OAAO,CAAC,CACxD,iBACR,mBAAkB;SAEd;CAMV,MAAM,cAAcD,UAAK,KAAK,KAAK,YAAY;AAG/C,KAAI,CAFoBC,QAAG,WAAW,YAAY,CAGhD,QAAO,GAAG,kBAAkB,MAAM,QAAQ,QAAQ,MAAM,MAAM,UAAU;CAI1E,MAAM,WAAWD,UAAK,KAAK,KAAK,YAAY,QAAQ;CACpD,MAAM,YAAYA,UAAK,KAAK,UAAU,uBAAuB;CAC7D,IAAI,QAA8B;CAClC,IAAI,WAAW;AAEf,KAAIC,QAAG,WAAW,UAAU,CAC1B,KAAI;AACF,UAAQ,KAAK,MAAMA,QAAG,aAAa,WAAW,OAAO,CAAC;AACtD,aAAW,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,IAAI,MAAM,WAAW;SACvD;AACN,UAAQ;;AAKZ,KAAI,WAAW,kBACb,wBAAuB,UAAU,UAAU;AAI7C,KAAI,OAAO,QACT,QAAO,GAAG,kBAAkB,MAAM,QAAQ,QAAQ,MAAM,IAAI,YAAY,QAAQ,MAAM,MAAM,UAAU;CAIxG,IAAI,eAAe;AACnB,KAAI,OAAO,cAAc;EACvB,MAAM,SAAS,MAAM,eAAe,IAAI,MAAM,iBAAiB;AAC/D,iBAAe,GAAG,MAAM,IAAI,GAAG,MAAM,eAAe,SAAS;;CAI/D,IAAI,mBAAmB;AACvB,KAAI,OAAO,gBACT,oBAAmB,GAAG,MAAM,MAAM,MAAM,gBAAgB,IAAI,MAAM,cAAc,GAAG;AAGrF,QAAO,GAAG,kBAAkB,MAAM,QAAQ,QAAQ,eAAe,mBAAmB,MAAM,MAAM,UAAU;;AAI5G,IAAI,QAAQ,SAAS,OACnB,gBAAgC,SAAS;AACvC,SAAQ,OAAO,MAAM,iBAAiB,KAAK,CAAC;EAC5C"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
| Agent | Role | Tools | Preloaded Skills | On-Demand Skills |
|
|
8
8
|
|-------|------|-------|-----------------|-----------------|
|
|
9
9
|
| `executor` | Implements plans with atomic commits and deviation handling | Read, Write, Edit, Bash, Grep, Glob | handoff-contract, evidence-collection, commit-conventions | tool-priority-guide, agent-system-map |
|
|
10
|
-
| `planner` | Creates
|
|
10
|
+
| `planner` | Creates plans (posted as GitHub Issue comments) with task breakdown and goal-backward verification | Read, Write, Bash, Grep, Glob | handoff-contract, input-validation | research-methodology, agent-system-map |
|
|
11
11
|
| `researcher` | Investigates domains with source evaluation and confidence levels | Read, Bash, Grep, Glob, WebFetch | handoff-contract, evidence-collection | research-methodology, tool-priority-guide |
|
|
12
12
|
| `verifier` | Verifies work against specifications with fresh evidence and hard gates | Read, Bash, Grep, Glob | verification-gates, evidence-collection, handoff-contract | agent-system-map, tool-priority-guide |
|
|
13
13
|
|
|
@@ -19,7 +19,7 @@ You are a plan executor. You implement plans atomically -- one commit per task,
|
|
|
19
19
|
## Input Validation
|
|
20
20
|
|
|
21
21
|
Before any work, verify required inputs exist:
|
|
22
|
-
- Plan content (provided by the orchestrator from a GitHub Issue comment
|
|
22
|
+
- Plan content (provided by the orchestrator from a GitHub Issue comment)
|
|
23
23
|
- STATE.md readable -- `test -f .planning/STATE.md`
|
|
24
24
|
|
|
25
25
|
If missing, return immediately:
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: planner
|
|
3
3
|
description: >-
|
|
4
4
|
Creates executable phase plans with task breakdown, dependency analysis,
|
|
5
|
-
and goal-backward verification. Use when planning phases, creating
|
|
6
|
-
|
|
5
|
+
and goal-backward verification. Use when planning phases, creating plans
|
|
6
|
+
(posted as GitHub Issue comments), breaking work into tasks, or performing gap closure planning.
|
|
7
7
|
tools: Read, Write, Bash, Grep, Glob
|
|
8
8
|
model: inherit
|
|
9
9
|
skills:
|
|
@@ -24,13 +24,13 @@ Context and research input is provided from GitHub Issue comments (type: `contex
|
|
|
24
24
|
Before any work, verify required inputs exist:
|
|
25
25
|
- ROADMAP.md -- `test -f .planning/ROADMAP.md`
|
|
26
26
|
- REQUIREMENTS.md -- `test -f .planning/REQUIREMENTS.md`
|
|
27
|
-
- Phase
|
|
27
|
+
- Phase context provided in spawn prompt (GitHub Issues is the source of truth)
|
|
28
28
|
|
|
29
29
|
If missing, return immediately using the input-validation error format.
|
|
30
30
|
|
|
31
31
|
## Planning Protocol
|
|
32
32
|
|
|
33
|
-
1. **Load context** -- read ROADMAP.md, REQUIREMENTS.md, and context/research provided from GitHub Issue comments
|
|
33
|
+
1. **Load context** -- read ROADMAP.md, REQUIREMENTS.md, and context/research provided from GitHub Issue comments
|
|
34
34
|
2. **Identify scope** -- extract phase goal, requirements, and user decisions from context
|
|
35
35
|
3. **Break into tasks** -- each task is an atomic unit with clear action, done criteria, verify block, and file list
|
|
36
36
|
4. **Build dependency graph** -- identify which tasks depend on others
|
|
@@ -24,7 +24,7 @@ node ~/.claude/maxsim/bin/maxsim-tools.cjs commit "" --files .planning/codebase/
|
|
|
24
24
|
|
|
25
25
|
| Command | Scope | Example |
|
|
26
26
|
|---------|-------|---------|
|
|
27
|
-
| plan
|
|
27
|
+
| plan | phase | `docs(phase-03): create authentication plans` |
|
|
28
28
|
| execute-phase | phase | `docs(phase-03): complete authentication phase` |
|
|
29
29
|
| new-milestone | milestone | `docs: start milestone v1.1` |
|
|
30
30
|
| remove-phase | chore | `chore: remove phase 17 (dashboard)` |
|
|
@@ -19,7 +19,7 @@ By the end of questioning, you need enough clarity to write a PROJECT.md that do
|
|
|
19
19
|
- **Research** needs: what domain to research, what the user already knows, what unknowns exist
|
|
20
20
|
- **Requirements** needs: clear enough vision to scope v1 features
|
|
21
21
|
- **Roadmap** needs: clear enough vision to decompose into phases, what "done" looks like
|
|
22
|
-
- **plan
|
|
22
|
+
- **plan** needs: specific requirements to break into tasks, context for implementation choices
|
|
23
23
|
- **execute-phase** needs: success criteria to verify against, the "why" behind requirements
|
|
24
24
|
|
|
25
25
|
A vague PROJECT.md forces every downstream phase to guess. The cost compounds.
|
|
@@ -148,7 +148,7 @@ maxsim/
|
|
|
148
148
|
**commands/maxsim/**
|
|
149
149
|
- Purpose: Slash command definitions for Claude Code
|
|
150
150
|
- Contains: *.md files (one per command)
|
|
151
|
-
- Key files: new-project.md, plan
|
|
151
|
+
- Key files: new-project.md, plan.md, execute-plan.md
|
|
152
152
|
- Subdirectories: None (flat structure)
|
|
153
153
|
|
|
154
154
|
**maxsim/references/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Milestone Archive Template
|
|
2
2
|
|
|
3
|
-
This template is used by the complete-milestone workflow to create archive files in `.planning/
|
|
3
|
+
This template is used by the complete-milestone workflow to create archive files in `.planning/archive/`.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -112,8 +112,8 @@ _For current project status, see .planning/ROADMAP.md_
|
|
|
112
112
|
|
|
113
113
|
**Archive location:**
|
|
114
114
|
|
|
115
|
-
- Save to `.planning/
|
|
116
|
-
- Example: `.planning/
|
|
115
|
+
- Save to `.planning/archive/v{VERSION}-{NAME}.md`
|
|
116
|
+
- Example: `.planning/archive/v1.0-mvp.md`
|
|
117
117
|
|
|
118
118
|
**After archiving:**
|
|
119
119
|
|
|
@@ -13,7 +13,6 @@ Follows the batch-worktree skill process: Research (decompose) -> Plan (validate
|
|
|
13
13
|
|
|
14
14
|
<required_reading>
|
|
15
15
|
Read all files referenced by the invoking prompt's execution_context before starting.
|
|
16
|
-
@./references/dashboard-bridge.md
|
|
17
16
|
</required_reading>
|
|
18
17
|
|
|
19
18
|
<process>
|
|
@@ -225,7 +224,7 @@ For each unit (spawn all with `run_in_background: true` for parallel execution):
|
|
|
225
224
|
|
|
226
225
|
```
|
|
227
226
|
Task(
|
|
228
|
-
subagent_type="
|
|
227
|
+
subagent_type="executor",
|
|
229
228
|
model="{executor_model}",
|
|
230
229
|
isolation="worktree",
|
|
231
230
|
run_in_background=true,
|
|
@@ -299,7 +298,7 @@ For each failed unit:
|
|
|
299
298
|
**Attempt 1 — spawn fix agent:**
|
|
300
299
|
```
|
|
301
300
|
Task(
|
|
302
|
-
subagent_type="
|
|
301
|
+
subagent_type="executor",
|
|
303
302
|
model="{executor_model}",
|
|
304
303
|
isolation="worktree",
|
|
305
304
|
prompt="
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<purpose>
|
|
2
2
|
Orchestrate parallel debug agents to investigate UAT gaps and find root causes.
|
|
3
3
|
|
|
4
|
-
After UAT finds gaps, spawn one debug agent per gap. Each agent investigates autonomously with symptoms pre-filled from UAT. Collect root causes, update UAT.md gaps with diagnosis, then hand off to plan
|
|
4
|
+
After UAT finds gaps, spawn one debug agent per gap. Each agent investigates autonomously with symptoms pre-filled from UAT. Collect root causes, update UAT.md gaps with diagnosis, then hand off to plan --gaps with actual diagnoses.
|
|
5
5
|
|
|
6
6
|
Orchestrator stays lean: parse gaps, spawn agents, collect results, update UAT.
|
|
7
7
|
</purpose>
|
|
@@ -15,7 +15,7 @@ Debug files use the `.planning/debug/` path (hidden directory with leading dot).
|
|
|
15
15
|
<core_principle>
|
|
16
16
|
**Diagnose before planning fixes.**
|
|
17
17
|
|
|
18
|
-
UAT tells us WHAT is broken (symptoms). Debug agents find WHY (root cause). plan
|
|
18
|
+
UAT tells us WHAT is broken (symptoms). Debug agents find WHY (root cause). plan --gaps then creates targeted fixes based on actual causes, not guesses.
|
|
19
19
|
|
|
20
20
|
Without diagnosis: "Comment doesn't refresh" → guess at fix → maybe wrong
|
|
21
21
|
With diagnosis: "Comment doesn't refresh" → "useEffect missing dependency" → precise fix
|
|
@@ -94,7 +94,7 @@ Template placeholders:
|
|
|
94
94
|
- `{errors}`: Any error messages from UAT (or "None reported")
|
|
95
95
|
- `{reproduction}`: "Test {test_num} in UAT"
|
|
96
96
|
- `{timeline}`: "Discovered during UAT"
|
|
97
|
-
- `{goal}`: `find_root_cause_only` (UAT flow - plan
|
|
97
|
+
- `{goal}`: `find_root_cause_only` (UAT flow - plan --gaps handles fixes)
|
|
98
98
|
- `{slug}`: Generated from truth
|
|
99
99
|
</step>
|
|
100
100
|
|
|
@@ -118,7 +118,7 @@ Each agent returns with:
|
|
|
118
118
|
- {file1}: {what's wrong}
|
|
119
119
|
- {file2}: {related issue}
|
|
120
120
|
|
|
121
|
-
**Suggested Fix Direction:** {brief hint for plan
|
|
121
|
+
**Suggested Fix Direction:** {brief hint for plan --gaps}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
Parse each return to extract:
|
|
@@ -190,7 +190,7 @@ Do NOT offer manual next steps - verify-work handles the rest.
|
|
|
190
190
|
|
|
191
191
|
<context_efficiency>
|
|
192
192
|
Agents start with symptoms pre-filled from UAT (no symptom gathering).
|
|
193
|
-
Agents only diagnose—plan
|
|
193
|
+
Agents only diagnose—plan --gaps handles fixes (no fix application).
|
|
194
194
|
</context_efficiency>
|
|
195
195
|
|
|
196
196
|
<failure_handling>
|
|
@@ -206,7 +206,7 @@ Agents only diagnose—plan-phase --gaps handles fixes (no fix application).
|
|
|
206
206
|
**All agents fail:**
|
|
207
207
|
- Something systemic (permissions, git, etc.)
|
|
208
208
|
- Report for manual investigation
|
|
209
|
-
- Fall back to plan
|
|
209
|
+
- Fall back to plan --gaps without root causes (less precise)
|
|
210
210
|
</failure_handling>
|
|
211
211
|
|
|
212
212
|
<success_criteria>
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
Execute discovery at the appropriate depth level.
|
|
3
3
|
Produces DISCOVERY.md (for Level 2-3) that informs PLAN.md creation.
|
|
4
4
|
|
|
5
|
-
Called from plan-
|
|
5
|
+
Called from plan-create.md's mandatory_discovery step with a depth parameter.
|
|
6
6
|
|
|
7
7
|
NOTE: For comprehensive ecosystem research ("how do experts build this"), use /maxsim:plan --research instead, which produces RESEARCH.md.
|
|
8
8
|
</purpose>
|
|
9
9
|
|
|
10
10
|
<required_reading>
|
|
11
|
-
@./references/dashboard-bridge.md
|
|
12
11
|
</required_reading>
|
|
13
12
|
|
|
14
13
|
<depth_levels>
|
|
@@ -20,7 +19,7 @@ NOTE: For comprehensive ecosystem research ("how do experts build this"), use /m
|
|
|
20
19
|
| 2 | Standard | 15-30 min | DISCOVERY.md | Choosing between options, new integration |
|
|
21
20
|
| 3 | Deep Dive | 1+ hour | Detailed DISCOVERY.md with validation gates | Architectural decisions, novel problems |
|
|
22
21
|
|
|
23
|
-
**Depth is determined by plan-
|
|
22
|
+
**Depth is determined by plan-create.md before routing here.**
|
|
24
23
|
</depth_levels>
|
|
25
24
|
|
|
26
25
|
<source_hierarchy>
|
|
@@ -38,7 +37,7 @@ See ~/.claude/maxsim/templates/discovery.md `<discovery_protocol>` for full prot
|
|
|
38
37
|
<process>
|
|
39
38
|
|
|
40
39
|
<step name="determine_depth">
|
|
41
|
-
Check the depth parameter passed from plan-
|
|
40
|
+
Check the depth parameter passed from plan-create.md:
|
|
42
41
|
- `depth=verify` → Level 1 (Quick Verification)
|
|
43
42
|
- `depth=standard` → Level 2 (Standard Discovery)
|
|
44
43
|
- `depth=deep` → Level 3 (Deep Dive)
|
|
@@ -73,7 +72,7 @@ For: Single known library, confirming syntax/version still correct.
|
|
|
73
72
|
- API syntax unchanged
|
|
74
73
|
- No breaking changes in recent versions
|
|
75
74
|
|
|
76
|
-
4. **If verified:** Return to plan-
|
|
75
|
+
4. **If verified:** Return to plan-create.md with confirmation. No DISCOVERY.md needed.
|
|
77
76
|
|
|
78
77
|
5. **If concerns found:** Escalate to Level 2.
|
|
79
78
|
|
|
@@ -118,7 +117,7 @@ For: Choosing between options, new external integration.
|
|
|
118
117
|
- Code examples from Context7
|
|
119
118
|
- Confidence level (should be MEDIUM-HIGH for Level 2)
|
|
120
119
|
|
|
121
|
-
7. Return to plan-
|
|
120
|
+
7. Return to plan-create.md.
|
|
122
121
|
|
|
123
122
|
**Output:** `.planning/phases/XX-name/DISCOVERY.md`
|
|
124
123
|
</step>
|
|
@@ -171,7 +170,7 @@ For: Architectural decisions, novel problems, high-risk choices.
|
|
|
171
170
|
|
|
172
171
|
7. **Confidence gate:** If overall confidence is LOW, present options before proceeding.
|
|
173
172
|
|
|
174
|
-
8. Return to plan-
|
|
173
|
+
8. Return to plan-create.md.
|
|
175
174
|
|
|
176
175
|
**Output:** `.planning/phases/XX-name/DISCOVERY.md` (comprehensive)
|
|
177
176
|
</step>
|
|
@@ -11,7 +11,6 @@ You are a thinking partner, not an interviewer. The user is the visionary — yo
|
|
|
11
11
|
</purpose>
|
|
12
12
|
|
|
13
13
|
<required_reading>
|
|
14
|
-
@./references/dashboard-bridge.md
|
|
15
14
|
@./references/thinking-partner.md
|
|
16
15
|
</required_reading>
|
|
17
16
|
|
|
@@ -27,13 +26,11 @@ Every question directed at the user MUST use a structured tool. NEVER write a qu
|
|
|
27
26
|
- Any clarification or follow-up question
|
|
28
27
|
- Existing context handling (update/view/skip)
|
|
29
28
|
|
|
30
|
-
**Tool selection:**
|
|
31
|
-
- **DASHBOARD_ACTIVE = true** → use `mcp__maxsim-dashboard__ask_question` (questions appear in browser). Follow the schema translation rules from @dashboard-bridge.
|
|
32
|
-
- **DASHBOARD_ACTIVE = false** → use `AskUserQuestion` (questions appear in terminal).
|
|
29
|
+
**Tool selection:** Use `AskUserQuestion` (questions appear in terminal).
|
|
33
30
|
|
|
34
31
|
**Why:** Plain-text questions create a worse UX — the user has to type free-form answers instead of selecting from well-designed options. Structured choices are the entire point of the discuss workflow.
|
|
35
32
|
|
|
36
|
-
**The rule is simple:** If you need input from the user → use
|
|
33
|
+
**The rule is simple:** If you need input from the user → use `AskUserQuestion`. Zero exceptions.
|
|
37
34
|
</tool_mandate>
|
|
38
35
|
|
|
39
36
|
<downstream_awareness>
|
|
@@ -603,19 +600,19 @@ Display banner:
|
|
|
603
600
|
MAXSIM ► AUTO-ADVANCING TO PLAN
|
|
604
601
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
605
602
|
|
|
606
|
-
Context captured. Spawning plan
|
|
603
|
+
Context captured. Spawning plan...
|
|
607
604
|
```
|
|
608
605
|
|
|
609
|
-
Spawn plan
|
|
606
|
+
Spawn plan as Task with direct workflow file reference (do NOT use Skill tool — Skills don't resolve inside Task subagents):
|
|
610
607
|
```
|
|
611
608
|
Task(
|
|
612
609
|
prompt="
|
|
613
610
|
<objective>
|
|
614
|
-
You are the plan
|
|
611
|
+
You are the plan orchestrator. Create executable plans for Phase ${PHASE}: ${PHASE_NAME}, then auto-advance to execution.
|
|
615
612
|
</objective>
|
|
616
613
|
|
|
617
614
|
<execution_context>
|
|
618
|
-
@./workflows/plan
|
|
615
|
+
@./workflows/plan.md
|
|
619
616
|
@./references/ui-brand.md
|
|
620
617
|
@./references/model-profile-resolution.md
|
|
621
618
|
</execution_context>
|
|
@@ -626,7 +623,7 @@ Task(
|
|
|
626
623
|
</arguments>
|
|
627
624
|
|
|
628
625
|
<instructions>
|
|
629
|
-
1. Read plan
|
|
626
|
+
1. Read plan.md from execution_context for your complete workflow
|
|
630
627
|
2. Follow ALL steps: initialize, validate, load context, research, plan, verify, auto-advance
|
|
631
628
|
3. When spawning agents (researcher, planner), use Task with specified subagent_type and model
|
|
632
629
|
4. For step 14 (auto-advance to execute): spawn execute-phase as a Task with DIRECT file reference — tell it to read execute-phase.md. Include @file refs to execute-phase.md, checkpoints.md, tdd.md, model-profile-resolution.md. Pass --no-transition flag so execute-phase returns results instead of chaining further.
|
|
@@ -639,7 +636,7 @@ Task(
|
|
|
639
636
|
)
|
|
640
637
|
```
|
|
641
638
|
|
|
642
|
-
**Handle plan
|
|
639
|
+
**Handle plan return:**
|
|
643
640
|
- **PHASE COMPLETE** → Full chain succeeded. Display:
|
|
644
641
|
```
|
|
645
642
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
@@ -24,8 +24,6 @@ Orchestrator coordinates, not executes. Each subagent loads the full execute-pla
|
|
|
24
24
|
|
|
25
25
|
<required_reading>
|
|
26
26
|
Read STATE.md before any operation to load project context.
|
|
27
|
-
|
|
28
|
-
@./references/dashboard-bridge.md
|
|
29
27
|
</required_reading>
|
|
30
28
|
|
|
31
29
|
<process>
|
|
@@ -53,19 +51,6 @@ REVIEW_CONFIG (from init JSON review_config — spec_review, code_review, simpli
|
|
|
53
51
|
When `parallelization` is false, plans within a wave execute sequentially.
|
|
54
52
|
</step>
|
|
55
53
|
|
|
56
|
-
<step name="probe_dashboard">
|
|
57
|
-
Probe for MCP dashboard availability (see @dashboard-bridge). If `DASHBOARD_ACTIVE`, emit:
|
|
58
|
-
```
|
|
59
|
-
mcp__maxsim-dashboard__submit_lifecycle_event(
|
|
60
|
-
event_type: "phase-started",
|
|
61
|
-
phase_name: PHASE_NAME,
|
|
62
|
-
phase_number: PHASE_NUMBER
|
|
63
|
-
)
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Note:** The dashboard is NOT auto-launched. Users start it explicitly via `maxsim dashboard`. This step only checks if a running dashboard is reachable via MCP.
|
|
67
|
-
</step>
|
|
68
|
-
|
|
69
54
|
<step name="handle_branching">
|
|
70
55
|
Check `branching_strategy` from init:
|
|
71
56
|
|
|
@@ -124,17 +109,12 @@ When `phase_issue_number` is set (GitHub integration active):
|
|
|
124
109
|
|
|
125
110
|
**Filtering:** Skip plans where `has_summary: true`. If `--gaps-only`: also skip non-gap_closure plans. If all filtered: "No matching incomplete plans" → exit.
|
|
126
111
|
|
|
127
|
-
**
|
|
128
|
-
|
|
129
|
-
When `phase_issue_number` is not set, use local file scanning:
|
|
112
|
+
**If GitHub integration is NOT active** (`phase_issue_number` is not set):
|
|
130
113
|
|
|
131
|
-
|
|
132
|
-
|
|
114
|
+
GitHub Issues is the source of truth for plans. Report the error and exit:
|
|
115
|
+
```
|
|
116
|
+
GitHub integration required. Ensure GitHub Issues is configured: run /maxsim:init to set up.
|
|
133
117
|
```
|
|
134
|
-
|
|
135
|
-
Parse JSON for: `phase`, `plans[]` (each with `id`, `wave`, `autonomous`, `objective`, `files_modified`, `task_count`, `has_summary`), `waves` (map of wave number → plan IDs), `incomplete`, `has_checkpoints`.
|
|
136
|
-
|
|
137
|
-
**Skip plans where `has_summary: true`** (local SUMMARY.md file present). If `--gaps-only`: also skip non-gap_closure plans.
|
|
138
118
|
|
|
139
119
|
Report:
|
|
140
120
|
```
|
|
@@ -322,7 +302,7 @@ For each wave:
|
|
|
322
302
|
|
|
323
303
|
1. **Describe what's being built (BEFORE spawning):**
|
|
324
304
|
|
|
325
|
-
Read each plan's `<objective>` from the plan comment content
|
|
305
|
+
Read each plan's `<objective>` from the plan comment content. Extract what's being built and why.
|
|
326
306
|
|
|
327
307
|
```
|
|
328
308
|
---
|
|
@@ -338,16 +318,7 @@ For each wave:
|
|
|
338
318
|
- Bad: "Executing terrain generation plan"
|
|
339
319
|
- Good: "Procedural terrain generator using Perlin noise — creates height maps, biome zones, and collision meshes. Required before vehicle physics can interact with ground."
|
|
340
320
|
|
|
341
|
-
2. **
|
|
342
|
-
```
|
|
343
|
-
mcp__maxsim-dashboard__submit_lifecycle_event(
|
|
344
|
-
event_type: "plan-started",
|
|
345
|
-
phase_name: PHASE_NAME, phase_number: PHASE_NUMBER,
|
|
346
|
-
step: plan_index, total_steps: total_plans
|
|
347
|
-
)
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
3. **Spawn executor agents:**
|
|
321
|
+
2. **Spawn executor agents:**
|
|
351
322
|
|
|
352
323
|
Pass plan content from GitHub and GitHub context — executors do NOT need to read local PLAN.md files.
|
|
353
324
|
This keeps orchestrator context lean (~10-15%).
|
|
@@ -421,16 +392,7 @@ For each wave:
|
|
|
421
392
|
|
|
422
393
|
Review stages to check: `Spec:` and `Code:` lines in `## Review Cycle`. Both must be PASS or SKIPPED for the plan to be considered review-complete.
|
|
423
394
|
|
|
424
|
-
If pass —
|
|
425
|
-
```
|
|
426
|
-
mcp__maxsim-dashboard__submit_lifecycle_event(
|
|
427
|
-
event_type: "plan-complete",
|
|
428
|
-
phase_name: PHASE_NAME, phase_number: PHASE_NUMBER,
|
|
429
|
-
step: plan_index, total_steps: total_plans
|
|
430
|
-
)
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
Then report:
|
|
395
|
+
If pass — report:
|
|
434
396
|
```
|
|
435
397
|
---
|
|
436
398
|
## Wave {N} Complete
|
|
@@ -583,12 +545,6 @@ When GitHub integration is active, look for `<!-- maxsim:type=uat -->` comments
|
|
|
583
545
|
mcp_get_issue_detail(issue_number: parent_phase_issue_number)
|
|
584
546
|
```
|
|
585
547
|
|
|
586
|
-
As fallback, check local files:
|
|
587
|
-
```bash
|
|
588
|
-
PARENT_INFO=$(node ~/.claude/maxsim/bin/maxsim-tools.cjs find-phase "${PARENT_PHASE}" --raw)
|
|
589
|
-
# Extract directory from PARENT_INFO JSON, then find UAT file in that directory
|
|
590
|
-
```
|
|
591
|
-
|
|
592
548
|
**If no parent UAT found:** Skip this step (gap-closure may have been triggered by VERIFICATION.md instead).
|
|
593
549
|
|
|
594
550
|
**3. Update UAT gap statuses:**
|
|
@@ -645,11 +601,6 @@ mcp_get_issue_detail(issue_number: phase_issue_number)
|
|
|
645
601
|
|
|
646
602
|
Look for `<!-- maxsim:type=verification -->` comment and parse `status:` field.
|
|
647
603
|
|
|
648
|
-
Fallback:
|
|
649
|
-
```bash
|
|
650
|
-
grep "^status:" "$PHASE_DIR"/*-VERIFICATION.md | cut -d: -f2 | tr -d ' '
|
|
651
|
-
```
|
|
652
|
-
|
|
653
604
|
| Status | Action |
|
|
654
605
|
|--------|--------|
|
|
655
606
|
| `passed` | → update_roadmap |
|
|
@@ -725,14 +676,6 @@ mcp_post_comment(
|
|
|
725
676
|
)
|
|
726
677
|
```
|
|
727
678
|
|
|
728
|
-
**Emit phase-complete lifecycle event** (if `DASHBOARD_ACTIVE`):
|
|
729
|
-
```
|
|
730
|
-
mcp__maxsim-dashboard__submit_lifecycle_event(
|
|
731
|
-
event_type: "phase-complete",
|
|
732
|
-
phase_name: PHASE_NAME,
|
|
733
|
-
phase_number: PHASE_NUMBER
|
|
734
|
-
)
|
|
735
|
-
```
|
|
736
679
|
</step>
|
|
737
680
|
|
|
738
681
|
<step name="offer_next">
|
|
@@ -745,8 +688,7 @@ Parse `--no-transition` flag from $ARGUMENTS.
|
|
|
745
688
|
|
|
746
689
|
**If `--no-transition` flag present:**
|
|
747
690
|
|
|
748
|
-
Execute-phase was spawned by plan
|
|
749
|
-
After verification passes and roadmap is updated, return completion status to parent:
|
|
691
|
+
Execute-phase was spawned by plan's auto-advance. After verification passes and roadmap is updated, return completion status to parent:
|
|
750
692
|
|
|
751
693
|
```
|
|
752
694
|
## PHASE COMPLETE
|
|
@@ -780,13 +722,11 @@ STOP. Do not proceed to auto-advance or transition.
|
|
|
780
722
|
╚══════════════════════════════════════════╝
|
|
781
723
|
```
|
|
782
724
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
Read and follow `~/.claude/maxsim/workflows/transition.md`, passing through the `--auto` flag so it propagates to the next phase invocation.
|
|
725
|
+
Phase advancement is complete. The user may run `/maxsim:go` or `/maxsim:execute` to continue to the next phase.
|
|
786
726
|
|
|
787
727
|
**If neither `--auto` nor `AUTO_CFG` is true:**
|
|
788
728
|
|
|
789
|
-
The workflow ends. The user runs `/maxsim:
|
|
729
|
+
The workflow ends. The user runs `/maxsim:go` or `/maxsim:execute` to advance to the next phase.
|
|
790
730
|
</step>
|
|
791
731
|
|
|
792
732
|
</process>
|
|
@@ -802,7 +742,7 @@ Plan content passed directly from GitHub comments to subagents — no local PLAN
|
|
|
802
742
|
- **Dependency chain breaks:** Wave 1 fails → Wave 2 dependents likely fail → user chooses attempt or skip
|
|
803
743
|
- **All agents in wave fail:** Systemic issue → stop, report for investigation
|
|
804
744
|
- **Checkpoint unresolvable:** "Skip this plan?" or "Abort phase execution?" → record partial progress in STATE.md
|
|
805
|
-
- **GitHub integration unavailable:**
|
|
745
|
+
- **GitHub integration unavailable:** Report error — GitHub Issues is the source of truth for plans and summaries
|
|
806
746
|
</failure_handling>
|
|
807
747
|
|
|
808
748
|
<resumption>
|