maestro-flow 0.3.9 → 0.3.10
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/.claude/commands/maestro-analyze.md +46 -3
- package/.claude/commands/maestro-execute.md +14 -0
- package/.claude/commands/maestro-plan.md +16 -0
- package/.claude/commands/manage-harvest.md +1 -1
- package/.claude/commands/manage-issue-discover.md +2 -2
- package/.claude/commands/manage-issue.md +3 -3
- package/.codex/skills/maestro/SKILL.md +463 -0
- package/.codex/skills/maestro-analyze/SKILL.md +28 -7
- package/.codex/skills/maestro-chain/SKILL.md +248 -0
- package/.codex/skills/maestro-coordinate/SKILL.md +279 -224
- package/.codex/skills/maestro-execute/SKILL.md +8 -0
- package/.codex/skills/maestro-plan/SKILL.md +9 -1
- package/README.md +7 -7
- package/README.zh-CN.md +7 -7
- package/chains/issue-lifecycle.json +13 -13
- package/chains/singles/issue-analyze.json +3 -3
- package/chains/singles/issue-execute.json +3 -3
- package/chains/singles/issue-plan.json +3 -3
- package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js +2 -2
- package/dashboard/dist-server/dashboard/src/server/commander/commander-agent.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js +3 -3
- package/dashboard/dist-server/dashboard/src/server/coordinator/chain-map.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/issues.js +34 -0
- package/dashboard/dist-server/dashboard/src/server/routes/issues.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js +2 -3
- package/dashboard/dist-server/dashboard/src/server/ws/handlers/execution-handler.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/shared/issue-types.d.ts +5 -0
- package/dashboard/dist-server/dashboard/src/shared/issue-types.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/shared/normalize-task.d.ts +2 -0
- package/dashboard/dist-server/dashboard/src/shared/normalize-task.js +75 -0
- package/dashboard/dist-server/dashboard/src/shared/normalize-task.js.map +1 -0
- package/dashboard/dist-server/src/hooks/constants.d.ts +90 -12
- package/dashboard/dist-server/src/hooks/constants.js +149 -16
- package/dashboard/dist-server/src/hooks/constants.js.map +1 -1
- package/dashboard/dist-server/src/types/index.d.ts +5 -0
- package/dist/src/commands/collab.d.ts +1 -34
- package/dist/src/commands/collab.d.ts.map +1 -1
- package/dist/src/commands/collab.js +4 -72
- package/dist/src/commands/collab.js.map +1 -1
- package/dist/src/commands/hooks.d.ts +5 -1
- package/dist/src/commands/hooks.d.ts.map +1 -1
- package/dist/src/commands/hooks.js +50 -10
- package/dist/src/commands/hooks.js.map +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.d.ts +3 -1
- package/dist/src/commands/install-ui/InstallConfirm.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallConfirm.js +3 -1
- package/dist/src/commands/install-ui/InstallConfirm.js.map +1 -1
- package/dist/src/commands/install-ui/InstallExecution.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallExecution.js +5 -1
- package/dist/src/commands/install-ui/InstallExecution.js.map +1 -1
- package/dist/src/commands/install-ui/InstallFlow.d.ts.map +1 -1
- package/dist/src/commands/install-ui/InstallFlow.js +7 -3
- package/dist/src/commands/install-ui/InstallFlow.js.map +1 -1
- package/dist/src/commands/install-ui/StatuslineConfig.d.ts +6 -1
- package/dist/src/commands/install-ui/StatuslineConfig.d.ts.map +1 -1
- package/dist/src/commands/install-ui/StatuslineConfig.js +27 -5
- package/dist/src/commands/install-ui/StatuslineConfig.js.map +1 -1
- package/dist/src/hooks/__tests__/statusline-visual-test.d.ts +7 -0
- package/dist/src/hooks/__tests__/statusline-visual-test.d.ts.map +1 -0
- package/dist/src/hooks/__tests__/statusline-visual-test.js +236 -0
- package/dist/src/hooks/__tests__/statusline-visual-test.js.map +1 -0
- package/dist/src/hooks/constants.d.ts +90 -12
- package/dist/src/hooks/constants.d.ts.map +1 -1
- package/dist/src/hooks/constants.js +149 -16
- package/dist/src/hooks/constants.js.map +1 -1
- package/dist/src/hooks/guards/index.d.ts +1 -0
- package/dist/src/hooks/guards/index.d.ts.map +1 -1
- package/dist/src/hooks/guards/index.js +1 -0
- package/dist/src/hooks/guards/index.js.map +1 -1
- package/dist/src/hooks/guards/preflight-guard.d.ts +29 -0
- package/dist/src/hooks/guards/preflight-guard.d.ts.map +1 -0
- package/dist/src/hooks/guards/preflight-guard.js +95 -0
- package/dist/src/hooks/guards/preflight-guard.js.map +1 -0
- package/dist/src/hooks/index.d.ts +1 -0
- package/dist/src/hooks/index.d.ts.map +1 -1
- package/dist/src/hooks/index.js +1 -0
- package/dist/src/hooks/index.js.map +1 -1
- package/dist/src/hooks/preflight-core.d.ts +37 -0
- package/dist/src/hooks/preflight-core.d.ts.map +1 -0
- package/dist/src/hooks/preflight-core.js +86 -0
- package/dist/src/hooks/preflight-core.js.map +1 -0
- package/dist/src/hooks/statusline.d.ts +8 -17
- package/dist/src/hooks/statusline.d.ts.map +1 -1
- package/dist/src/hooks/statusline.js +269 -112
- package/dist/src/hooks/statusline.js.map +1 -1
- package/dist/src/i18n/locales/en.d.ts.map +1 -1
- package/dist/src/i18n/locales/en.js +5 -0
- package/dist/src/i18n/locales/en.js.map +1 -1
- package/dist/src/i18n/locales/zh.d.ts.map +1 -1
- package/dist/src/i18n/locales/zh.js +5 -0
- package/dist/src/i18n/locales/zh.js.map +1 -1
- package/dist/src/i18n/types.d.ts +5 -0
- package/dist/src/i18n/types.d.ts.map +1 -1
- package/dist/src/tools/collab-adapter.d.ts +17 -0
- package/dist/src/tools/collab-adapter.d.ts.map +1 -1
- package/dist/src/tools/collab-adapter.js +138 -0
- package/dist/src/tools/collab-adapter.js.map +1 -1
- package/dist/src/tools/merge-validator.d.ts +24 -0
- package/dist/src/tools/merge-validator.d.ts.map +1 -0
- package/dist/src/tools/merge-validator.js +220 -0
- package/dist/src/tools/merge-validator.js.map +1 -0
- package/dist/src/types/index.d.ts +5 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/cli/prompts/workflow-skill-conflict-patterns.txt +3 -3
- package/templates/cli/prompts/workflow-skill-lessons-learned.txt +3 -3
- package/templates/search-tools.md +1 -1
- package/workflows/cli-tools-usage.md +44 -27
- package/workflows/delegate-usage.md +3 -3
- package/workflows/issue-analyze.md +6 -2
- package/workflows/issue-discover.md +4 -4
- package/workflows/issue-execute.md +6 -3
- package/workflows/issue-plan.md +5 -2
- package/workflows/maestro-coordinate.codex.md +281 -470
- package/workflows/maestro-coordinate.md +14 -14
- package/workflows/maestro-link-coordinate.md +2 -2
- package/workflows/maestro.codex.md +710 -0
- package/workflows/maestro.md +10 -11
- package/workflows/retrospective.md +1 -1
- package/.claude/commands/manage-issue-analyze.md +0 -62
- package/.claude/commands/manage-issue-execute.md +0 -73
- package/.claude/commands/manage-issue-plan.md +0 -62
- package/.codex/skills/manage-issue-analyze/SKILL.md +0 -207
- package/.codex/skills/manage-issue-execute/SKILL.md +0 -200
- package/.codex/skills/manage-issue-plan/SKILL.md +0 -186
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
# Workflow: Maestro (Codex Edition)
|
|
2
|
+
|
|
3
|
+
CSV wave coordinator version of the intelligent coordinator. Replaces `spawn_agent / wait / close_agent` loop with `spawn_agents_on_csv` (max_workers=1) for sequential pipeline execution. Each chain step is a CSV row with `skill_call` column; agents read prior results from session directory for context propagation.
|
|
4
|
+
|
|
5
|
+
> Referenced by: `~/.codex/skills/maestro/SKILL.md`
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Step 1: Parse Arguments
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const args = $ARGUMENTS.trim();
|
|
13
|
+
const AUTO_YES = new RegExp('\\b(-y|--yes)\\b').test(args);
|
|
14
|
+
const RESUME = new RegExp('\\b(-c|--continue)\\b').test(args);
|
|
15
|
+
const DRY_RUN = new RegExp('\\b--dry-run\\b').test(args);
|
|
16
|
+
const forceChain = args.match(new RegExp('--chain\\s+(\\S+)'))?.[1] ?? null;
|
|
17
|
+
const intent = args
|
|
18
|
+
.replace(new RegExp('\\b(-y|--yes|-c|--continue|--dry-run)\\b', 'g'), '')
|
|
19
|
+
.replace(new RegExp('--(chain)\\s+\\S+', 'g'), '')
|
|
20
|
+
.trim();
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**Resume mode**: If `RESUME`:
|
|
24
|
+
1. Glob `.workflow/.maestro-coordinate/coord-*/state.json`, sort desc by name, load latest
|
|
25
|
+
2. Set `current_step` to index of first step where `status === "pending"`
|
|
26
|
+
3. Jump to **Step 6**
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Step 2: Read Project State
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
const stateFile = '.workflow/state.json';
|
|
34
|
+
let projectState = { initialized: false };
|
|
35
|
+
|
|
36
|
+
if (fileExists(stateFile)) {
|
|
37
|
+
const raw = JSON.parse(Read(stateFile));
|
|
38
|
+
projectState = {
|
|
39
|
+
initialized: true,
|
|
40
|
+
current_phase: raw.current_phase,
|
|
41
|
+
phase_slug: raw.phase_slug,
|
|
42
|
+
phase_status: raw.phase_status, // pending|exploring|planning|executing|verifying|testing|completed|blocked
|
|
43
|
+
phase_artifacts: raw.phase_artifacts ?? {},
|
|
44
|
+
execution: raw.execution ?? { tasks_completed: 0, tasks_total: 0 },
|
|
45
|
+
verification_status: raw.verification_status ?? 'pending',
|
|
46
|
+
review_verdict: raw.review_verdict ?? null,
|
|
47
|
+
uat_status: raw.uat_status ?? 'pending',
|
|
48
|
+
phases_total: raw.phases_total ?? 0,
|
|
49
|
+
phases_completed: raw.phases_completed ?? 0,
|
|
50
|
+
has_blockers: raw.has_blockers ?? false,
|
|
51
|
+
accumulated_context: raw.accumulated_context ?? null
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!projectState.initialized && !intent) throw new Error('E001: No project state and no intent. Run $maestro-init first.');
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Step 3: Classify Intent & Select Chain
|
|
61
|
+
|
|
62
|
+
### 3a: Exact-match keywords (fast path)
|
|
63
|
+
|
|
64
|
+
If `forceChain` is set → validate against chainMap and jump to **3c**.
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const exactMatch = {
|
|
68
|
+
'continue': 'state_continue', 'next': 'state_continue', 'go': 'state_continue',
|
|
69
|
+
'继续': 'state_continue', '下一步': 'state_continue',
|
|
70
|
+
'status': 'status', '状态': 'status', 'dashboard': 'status',
|
|
71
|
+
};
|
|
72
|
+
const normalized = intent.toLowerCase().trim();
|
|
73
|
+
if (exactMatch[normalized]) {
|
|
74
|
+
taskType = exactMatch[normalized];
|
|
75
|
+
// → skip to 3c
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 3a-2: Structured intent extraction (LLM-native)
|
|
80
|
+
|
|
81
|
+
Instead of regex, extract a structured intent tuple using LLM semantic understanding:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"action": "<create|fix|analyze|plan|execute|verify|review|test|debug|refactor|explore|manage|transition|continue|sync|learn|retrospect>",
|
|
86
|
+
"object": "<feature|bug|issue|code|test|spec|phase|milestone|doc|performance|security|ui|memory|codebase|config>",
|
|
87
|
+
"scope": "<module/file/area or null>",
|
|
88
|
+
"issue_id": "<ISS-XXXXXXXX-NNN if mentioned, else null>",
|
|
89
|
+
"phase_ref": "<integer if mentioned, else null>",
|
|
90
|
+
"urgency": "<low|normal|high>"
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Key disambiguation**: "问题"/"issue"/"problem" as something broken → `object: "bug"` (routes to debug). As a tracked item (with ISS-ID or management context) → `object: "issue"` (routes to issue management). When ambiguous, prefer `"bug"`.
|
|
95
|
+
|
|
96
|
+
### 3a-3: Route via action × object matrix
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
function routeIntent(intent, projectState) {
|
|
100
|
+
const { action, object, issue_id } = intent;
|
|
101
|
+
|
|
102
|
+
// Hard signal: explicit issue ID → issue pipeline
|
|
103
|
+
if (issue_id) {
|
|
104
|
+
const issueRoutes = { 'analyze': 'issue_analyze', 'plan': 'issue_plan', 'fix': 'issue_execute', 'execute': 'issue_execute', 'debug': 'issue_analyze', 'manage': 'issue' };
|
|
105
|
+
return issueRoutes[action] || 'issue';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Action × Object matrix
|
|
109
|
+
const matrix = {
|
|
110
|
+
'fix': { 'bug': 'debug', 'issue': 'issue', 'code': 'debug', 'performance': 'debug', 'security': 'debug', '_default': 'debug' },
|
|
111
|
+
'create': { 'feature': 'quick', 'issue': 'issue', 'test': 'test_gen', 'spec': 'spec_generate', 'ui': 'ui_design', 'config': 'init', 'phase': 'phase_add', '_default': 'quick' },
|
|
112
|
+
'analyze': { 'bug': 'analyze', 'issue': 'issue_analyze', 'code': 'analyze', 'codebase': 'spec_map', '_default': 'analyze' },
|
|
113
|
+
'explore': { 'issue': 'issue_discover', 'feature': 'brainstorm', 'ui': 'ui_design', '_default': 'brainstorm' },
|
|
114
|
+
'plan': { 'issue': 'issue_plan', 'spec': 'spec_generate', '_default': 'plan' },
|
|
115
|
+
'execute': { 'issue': 'issue_execute', '_default': 'execute' },
|
|
116
|
+
'verify': { '_default': 'verify' },
|
|
117
|
+
'review': { '_default': 'review' },
|
|
118
|
+
'test': { '_default': 'test' },
|
|
119
|
+
'debug': { '_default': 'debug' },
|
|
120
|
+
'refactor': { '_default': 'refactor' },
|
|
121
|
+
'manage': { 'issue': 'issue', 'milestone': 'milestone_audit', 'phase': 'phase_transition', 'memory': 'memory', 'doc': 'sync', 'codebase': 'codebase_refresh', '_default': 'status' },
|
|
122
|
+
'transition':{ 'phase': 'phase_transition', 'milestone': 'milestone_complete', '_default': 'phase_transition' },
|
|
123
|
+
'continue': { '_default': 'state_continue' },
|
|
124
|
+
'sync': { '_default': 'sync' },
|
|
125
|
+
'learn': { '_default': 'learn' },
|
|
126
|
+
'retrospect':{ '_default': 'retrospective' },
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const actionMap = matrix[action] || matrix['fix'];
|
|
130
|
+
return actionMap[object] || actionMap['_default'] || 'quick';
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Clarity scoring**: 3 = action+object+scope, 2 = action+object, 1 = action only, 0 = empty.
|
|
135
|
+
If `clarity < 2` and not `AUTO_YES`: call `functions.request_user_input` with one focused question (max 2 rounds).
|
|
136
|
+
|
|
137
|
+
### 3b: State-based routing (when `taskType === 'state_continue'`)
|
|
138
|
+
|
|
139
|
+
```javascript
|
|
140
|
+
function detectNextAction(s) {
|
|
141
|
+
if (!s.initialized) return { chain: 'init', steps: [{ cmd: 'maestro-init' }] };
|
|
142
|
+
const ps = s.phase_status, art = s.phase_artifacts, exec = s.execution;
|
|
143
|
+
|
|
144
|
+
if (s.phases_total === 0 && !fileExists('.workflow/roadmap.md') && s.accumulated_context)
|
|
145
|
+
return { chain: 'next-milestone', steps: [{ cmd: 'maestro-roadmap', args: '"{description}"' }] };
|
|
146
|
+
if (s.phases_total === 0)
|
|
147
|
+
return { chain: 'brainstorm-driven', steps: [
|
|
148
|
+
{ cmd: 'maestro-brainstorm', args: '"{description}"' },
|
|
149
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
150
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
151
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
152
|
+
]};
|
|
153
|
+
|
|
154
|
+
if (ps === 'pending') {
|
|
155
|
+
if (art.context) return { chain: 'plan', steps: [{ cmd: 'maestro-plan', args: '{phase}' }] };
|
|
156
|
+
return { chain: 'analyze', steps: [{ cmd: 'maestro-analyze', args: '{phase}' }] };
|
|
157
|
+
}
|
|
158
|
+
if (ps === 'exploring' || ps === 'planning') {
|
|
159
|
+
if (art.plan) return { chain: 'execute-verify', steps: [
|
|
160
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
161
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
162
|
+
]};
|
|
163
|
+
return { chain: 'plan', steps: [{ cmd: 'maestro-plan', args: '{phase}' }] };
|
|
164
|
+
}
|
|
165
|
+
if (ps === 'executing') {
|
|
166
|
+
if (exec.tasks_completed >= exec.tasks_total && exec.tasks_total > 0)
|
|
167
|
+
return { chain: 'verify', steps: [{ cmd: 'maestro-verify', args: '{phase}' }] };
|
|
168
|
+
return { chain: 'execute', steps: [{ cmd: 'maestro-execute', args: '{phase}' }] };
|
|
169
|
+
}
|
|
170
|
+
if (ps === 'verifying') {
|
|
171
|
+
if (s.verification_status === 'passed') {
|
|
172
|
+
if (!s.review_verdict) return { chain: 'review', steps: [{ cmd: 'quality-review', args: '{phase}' }] };
|
|
173
|
+
if (s.uat_status === 'pending') return { chain: 'test', steps: [{ cmd: 'quality-test', args: '{phase}' }] };
|
|
174
|
+
if (s.uat_status === 'passed') return { chain: 'phase-transition', steps: [{ cmd: 'maestro-phase-transition' }] };
|
|
175
|
+
return { chain: 'debug', steps: [{ cmd: 'quality-debug', args: '--from-uat {phase}' }] };
|
|
176
|
+
}
|
|
177
|
+
return { chain: 'quality-loop-partial', steps: [
|
|
178
|
+
{ cmd: 'maestro-plan', args: '{phase} --gaps' },
|
|
179
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
180
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
181
|
+
]};
|
|
182
|
+
}
|
|
183
|
+
if (ps === 'testing') {
|
|
184
|
+
if (s.uat_status === 'passed') return { chain: 'phase-transition', steps: [{ cmd: 'maestro-phase-transition' }] };
|
|
185
|
+
return { chain: 'debug', steps: [{ cmd: 'quality-debug', args: '--from-uat {phase}' }] };
|
|
186
|
+
}
|
|
187
|
+
if (ps === 'completed') {
|
|
188
|
+
if (s.phases_completed >= s.phases_total)
|
|
189
|
+
return { chain: 'milestone-close', steps: [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }] };
|
|
190
|
+
return { chain: 'phase-transition', steps: [{ cmd: 'maestro-phase-transition' }] };
|
|
191
|
+
}
|
|
192
|
+
if (ps === 'blocked') return { chain: 'debug', steps: [{ cmd: 'quality-debug' }] };
|
|
193
|
+
return { chain: 'status', steps: [{ cmd: 'manage-status' }] };
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 3c: Intent-based chain map
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
const chainMap = {
|
|
201
|
+
// ── Single-step ──────────────────────────────────────────────────────────
|
|
202
|
+
'status': [{ cmd: 'manage-status' }],
|
|
203
|
+
'init': [{ cmd: 'maestro-init' }],
|
|
204
|
+
'analyze': [{ cmd: 'maestro-analyze', args: '{phase}' }],
|
|
205
|
+
'ui_design': [{ cmd: 'maestro-ui-design', args: '{phase}' }],
|
|
206
|
+
'plan': [{ cmd: 'maestro-plan', args: '{phase}' }],
|
|
207
|
+
'execute': [{ cmd: 'maestro-execute', args: '{phase}' }],
|
|
208
|
+
'verify': [{ cmd: 'maestro-verify', args: '{phase}' }],
|
|
209
|
+
'test_gen': [{ cmd: 'quality-test-gen', args: '{phase}' }],
|
|
210
|
+
'test': [{ cmd: 'quality-test', args: '{phase}' }],
|
|
211
|
+
'debug': [{ cmd: 'quality-debug', args: '"{description}"' }],
|
|
212
|
+
'integration_test': [{ cmd: 'quality-integration-test',args: '{phase}' }],
|
|
213
|
+
'refactor': [{ cmd: 'quality-refactor', args: '"{description}"' }],
|
|
214
|
+
'review': [{ cmd: 'quality-review', args: '{phase}' }],
|
|
215
|
+
'retrospective': [{ cmd: 'quality-retrospective', args: '{phase}' }],
|
|
216
|
+
'learn': [{ cmd: 'manage-learn', args: '"{description}"' }],
|
|
217
|
+
'sync': [{ cmd: 'quality-sync', args: '{phase}' }],
|
|
218
|
+
'phase_transition': [{ cmd: 'maestro-phase-transition' }],
|
|
219
|
+
'phase_add': [{ cmd: 'maestro-phase-add', args: '"{description}"' }],
|
|
220
|
+
'milestone_audit': [{ cmd: 'maestro-milestone-audit' }],
|
|
221
|
+
'milestone_complete': [{ cmd: 'maestro-milestone-complete' }],
|
|
222
|
+
'codebase_rebuild': [{ cmd: 'manage-codebase-rebuild' }],
|
|
223
|
+
'codebase_refresh': [{ cmd: 'manage-codebase-refresh' }],
|
|
224
|
+
'spec_setup': [{ cmd: 'spec-setup' }],
|
|
225
|
+
'spec_add': [{ cmd: 'spec-add', args: '"{description}"' }],
|
|
226
|
+
'spec_load': [{ cmd: 'spec-load', args: '"{description}"' }],
|
|
227
|
+
'spec_map': [{ cmd: 'manage-codebase-rebuild' }],
|
|
228
|
+
'memory_capture': [{ cmd: 'manage-memory-capture', args: '"{description}"' }],
|
|
229
|
+
'memory': [{ cmd: 'manage-memory', args: '"{description}"' }],
|
|
230
|
+
'issue': [{ cmd: 'manage-issue', args: '"{description}"' }],
|
|
231
|
+
'issue_discover': [{ cmd: 'manage-issue-discover', args: '"{description}"' }],
|
|
232
|
+
'issue_analyze': [{ cmd: 'maestro-analyze', args: '--gaps "{description}"' }],
|
|
233
|
+
'issue_plan': [{ cmd: 'maestro-plan', args: '--gaps' }],
|
|
234
|
+
'issue_execute': [{ cmd: 'maestro-execute', args: '' }],
|
|
235
|
+
'quick': [{ cmd: 'maestro-quick', args: '"{description}"' }],
|
|
236
|
+
// ── Multi-step chains ────────────────────────────────────────────────────
|
|
237
|
+
'spec-driven': [
|
|
238
|
+
{ cmd: 'maestro-init' },
|
|
239
|
+
{ cmd: 'maestro-spec-generate', args: '"{description}"' },
|
|
240
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
241
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
242
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
243
|
+
],
|
|
244
|
+
'brainstorm-driven': [
|
|
245
|
+
{ cmd: 'maestro-brainstorm', args: '"{description}"' },
|
|
246
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
247
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
248
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
249
|
+
],
|
|
250
|
+
'ui-design-driven': [
|
|
251
|
+
{ cmd: 'maestro-ui-design', args: '{phase}' },
|
|
252
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
253
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
254
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
255
|
+
],
|
|
256
|
+
'full-lifecycle': [
|
|
257
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
258
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
259
|
+
{ cmd: 'maestro-verify', args: '{phase}' },
|
|
260
|
+
{ cmd: 'quality-review', args: '{phase}' },
|
|
261
|
+
{ cmd: 'quality-test', args: '{phase}' },
|
|
262
|
+
{ cmd: 'maestro-phase-transition' }
|
|
263
|
+
],
|
|
264
|
+
'execute-verify': [
|
|
265
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
266
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
267
|
+
],
|
|
268
|
+
'quality-loop': [
|
|
269
|
+
{ cmd: 'maestro-verify', args: '{phase}' },
|
|
270
|
+
{ cmd: 'quality-review', args: '{phase}' },
|
|
271
|
+
{ cmd: 'quality-test', args: '{phase}' },
|
|
272
|
+
{ cmd: 'quality-debug', args: '--from-uat {phase}' },
|
|
273
|
+
{ cmd: 'maestro-plan', args: '{phase} --gaps' },
|
|
274
|
+
{ cmd: 'maestro-execute', args: '{phase}' }
|
|
275
|
+
],
|
|
276
|
+
'milestone-close': [
|
|
277
|
+
{ cmd: 'maestro-milestone-audit' },
|
|
278
|
+
{ cmd: 'maestro-milestone-complete' }
|
|
279
|
+
],
|
|
280
|
+
'roadmap-driven': [
|
|
281
|
+
{ cmd: 'maestro-init' },
|
|
282
|
+
{ cmd: 'maestro-roadmap', args: '"{description}"' },
|
|
283
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
284
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
285
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
286
|
+
],
|
|
287
|
+
'next-milestone': [
|
|
288
|
+
{ cmd: 'maestro-roadmap', args: '"{description}"' },
|
|
289
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
290
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
291
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
292
|
+
],
|
|
293
|
+
'analyze-plan-execute': [
|
|
294
|
+
{ cmd: 'maestro-analyze', args: '"{description}" -q' },
|
|
295
|
+
{ cmd: 'maestro-plan', args: '--dir {scratch_dir}' },
|
|
296
|
+
{ cmd: 'maestro-execute', args: '--dir {scratch_dir}' }
|
|
297
|
+
],
|
|
298
|
+
|
|
299
|
+
// ── SKILL.md simplified aliases (--chain <name> shortcuts) ───────────────
|
|
300
|
+
'feature': [
|
|
301
|
+
{ cmd: 'maestro-plan', args: '{phase}' },
|
|
302
|
+
{ cmd: 'maestro-execute', args: '{phase}' },
|
|
303
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
304
|
+
],
|
|
305
|
+
'quality-fix': [
|
|
306
|
+
{ cmd: 'maestro-analyze', args: '--gaps "{description}"' },
|
|
307
|
+
{ cmd: 'maestro-execute', args: '' },
|
|
308
|
+
{ cmd: 'maestro-verify', args: '{phase}' }
|
|
309
|
+
],
|
|
310
|
+
'deploy': [
|
|
311
|
+
{ cmd: 'maestro-verify', args: '{phase}' },
|
|
312
|
+
{ cmd: 'maestro-execute', args: '{phase}' }
|
|
313
|
+
],
|
|
314
|
+
|
|
315
|
+
// ── Issue lifecycle chains (with quality gates) ────────────────────────────
|
|
316
|
+
'issue-full': [
|
|
317
|
+
{ cmd: 'maestro-analyze', args: '--gaps {issue_id}' },
|
|
318
|
+
{ cmd: 'maestro-plan', args: '--gaps' },
|
|
319
|
+
{ cmd: 'maestro-execute', args: '' },
|
|
320
|
+
{ cmd: 'quality-review', args: '--scope {affected_files}' },
|
|
321
|
+
{ cmd: 'manage-issue', args: 'close {issue_id} --resolution fixed' }
|
|
322
|
+
],
|
|
323
|
+
'issue-quick': [
|
|
324
|
+
{ cmd: 'maestro-plan', args: '--gaps' },
|
|
325
|
+
{ cmd: 'maestro-execute', args: '' },
|
|
326
|
+
{ cmd: 'manage-issue', args: 'close {issue_id} --resolution fixed' }
|
|
327
|
+
],
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// Aliases: task type → named chain
|
|
331
|
+
const taskToChain = {
|
|
332
|
+
'spec_generate': 'spec-driven',
|
|
333
|
+
'brainstorm': 'brainstorm-driven',
|
|
334
|
+
'issue_execute': 'issue-full', // issue execute always gets review gate
|
|
335
|
+
};
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
**Resolution order:**
|
|
339
|
+
1. `forceChain` → `chainMap[forceChain]` (E002 if not found)
|
|
340
|
+
2. `state_continue` → `detectNextAction(projectState)`
|
|
341
|
+
3. `taskToChain[taskType]` → named chain
|
|
342
|
+
4. `chainMap[taskType]` → direct lookup
|
|
343
|
+
|
|
344
|
+
### 3d: Resolve phase, description, and issue ID
|
|
345
|
+
|
|
346
|
+
```javascript
|
|
347
|
+
function resolvePhase() {
|
|
348
|
+
// From structured extraction
|
|
349
|
+
if (intentAnalysis.phase_ref) return intentAnalysis.phase_ref;
|
|
350
|
+
// Fallback regex
|
|
351
|
+
const m = intent.match(new RegExp('^(\\d+)$')) ?? intent.match(new RegExp('phase\\s*(\\d+)', 'i'));
|
|
352
|
+
if (m) return m[1] ?? m[2];
|
|
353
|
+
if (projectState.initialized) return projectState.current_phase;
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function resolveIssueId() {
|
|
358
|
+
if (intentAnalysis.issue_id) return intentAnalysis.issue_id;
|
|
359
|
+
const m = intent.match(new RegExp('ISS-[\\w]+-\\d+', 'i'));
|
|
360
|
+
return m ? m[0] : null;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const resolvedPhase = resolvePhase();
|
|
364
|
+
const resolvedIssueId = resolveIssueId();
|
|
365
|
+
const context = {
|
|
366
|
+
current_phase: resolvedPhase,
|
|
367
|
+
user_intent: intent,
|
|
368
|
+
issue_id: resolvedIssueId,
|
|
369
|
+
spec_session_id: null,
|
|
370
|
+
scratch_dir: null
|
|
371
|
+
};
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Step 4: Confirm
|
|
377
|
+
|
|
378
|
+
**If `DRY_RUN`**: Display chain and exit.
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
MAESTRO-COORDINATE: {chain_name} (dry run)
|
|
382
|
+
1. ${step.cmd} {step.args}
|
|
383
|
+
2. ${step.cmd} {step.args}
|
|
384
|
+
…
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
**If not `AUTO_YES`**: Ask user via `functions.request_user_input`:
|
|
388
|
+
- Execute all steps
|
|
389
|
+
- Execute from step N
|
|
390
|
+
- Cancel
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Step 5: Setup Session
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
const ts = new Date().toISOString().replaceAll('-', '').replaceAll(':', '').replaceAll('T', '').slice(0, 15);
|
|
398
|
+
const sessionId = `coord-${ts}`;
|
|
399
|
+
const sessionDir = `.workflow/.maestro-coordinate/${sessionId}`;
|
|
400
|
+
Bash(`mkdir -p "${sessionDir}"`);
|
|
401
|
+
|
|
402
|
+
const BARRIER_SKILLS = new Set([
|
|
403
|
+
'maestro-analyze', 'maestro-plan', 'maestro-brainstorm',
|
|
404
|
+
'maestro-spec-generate', 'maestro-execute'
|
|
405
|
+
]);
|
|
406
|
+
|
|
407
|
+
const AUTO_FLAG_MAP = {
|
|
408
|
+
'maestro-analyze': '-y',
|
|
409
|
+
'maestro-brainstorm': '-y',
|
|
410
|
+
'maestro-ui-design': '-y',
|
|
411
|
+
'maestro-plan': '--auto',
|
|
412
|
+
'maestro-spec-generate': '-y',
|
|
413
|
+
'quality-test': '--auto-fix',
|
|
414
|
+
'quality-retrospective': '--auto-yes',
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
const context = {
|
|
418
|
+
phase: resolvedPhase,
|
|
419
|
+
plan_dir: null,
|
|
420
|
+
analysis_dir: null,
|
|
421
|
+
brainstorm_dir: null,
|
|
422
|
+
spec_session_id: null,
|
|
423
|
+
issue_id: resolvedIssueId,
|
|
424
|
+
gaps: null
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
const state = {
|
|
428
|
+
session_id: sessionId,
|
|
429
|
+
status: 'running',
|
|
430
|
+
created_at: new Date().toISOString(),
|
|
431
|
+
intent,
|
|
432
|
+
task_type: taskType,
|
|
433
|
+
chain_name: chainName,
|
|
434
|
+
auto_yes: AUTO_YES,
|
|
435
|
+
context,
|
|
436
|
+
waves: [],
|
|
437
|
+
steps: chain.map((s, i) => ({
|
|
438
|
+
index: i,
|
|
439
|
+
cmd: s.cmd,
|
|
440
|
+
args: s.args ?? '',
|
|
441
|
+
status: 'pending',
|
|
442
|
+
wave_n: null,
|
|
443
|
+
findings: null,
|
|
444
|
+
artifacts: null
|
|
445
|
+
}))
|
|
446
|
+
};
|
|
447
|
+
Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Step 6: Wave Execution Loop
|
|
453
|
+
|
|
454
|
+
### 6a: Helper functions
|
|
455
|
+
|
|
456
|
+
```javascript
|
|
457
|
+
function buildSkillCall(step, ctx) {
|
|
458
|
+
let a = (step.args ?? '')
|
|
459
|
+
.replaceAll('{phase}', ctx.phase ?? '')
|
|
460
|
+
.replaceAll('{description}', state.intent ?? '')
|
|
461
|
+
.replaceAll('{issue_id}', ctx.issue_id ?? '')
|
|
462
|
+
.replaceAll('{plan_dir}', ctx.plan_dir ?? '')
|
|
463
|
+
.replaceAll('{analysis_dir}', ctx.analysis_dir ?? '')
|
|
464
|
+
.replaceAll('{brainstorm_dir}', ctx.brainstorm_dir ?? '')
|
|
465
|
+
.replaceAll('{spec_session_id}', ctx.spec_session_id ?? '')
|
|
466
|
+
.replaceAll('{scratch_dir}', ctx.scratch_dir ?? '');
|
|
467
|
+
|
|
468
|
+
if (state.auto_yes) {
|
|
469
|
+
const flag = AUTO_FLAG_MAP[step.cmd];
|
|
470
|
+
if (flag && !a.includes(flag)) a = a ? `${a} ${flag}` : flag;
|
|
471
|
+
}
|
|
472
|
+
return `$${step.cmd} ${a}`.trim();
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function buildNextWave(steps) {
|
|
476
|
+
const pending = steps.filter(s => s.status === 'pending');
|
|
477
|
+
if (!pending.length) return [];
|
|
478
|
+
const first = pending[0];
|
|
479
|
+
// Barrier skill → solo wave
|
|
480
|
+
if (BARRIER_SKILLS.has(first.cmd)) return [first];
|
|
481
|
+
// Group consecutive non-barriers
|
|
482
|
+
const wave = [first];
|
|
483
|
+
for (let i = 1; i < pending.length; i++) {
|
|
484
|
+
if (BARRIER_SKILLS.has(pending[i].cmd)) break;
|
|
485
|
+
wave.push(pending[i]);
|
|
486
|
+
}
|
|
487
|
+
return wave;
|
|
488
|
+
}
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### 6b: Wave instruction template (simple)
|
|
492
|
+
|
|
493
|
+
```javascript
|
|
494
|
+
const WAVE_INSTRUCTION = `你是 CSV job 子 agent。
|
|
495
|
+
|
|
496
|
+
先原样执行这一段技能调用:
|
|
497
|
+
{skill_call}
|
|
498
|
+
|
|
499
|
+
然后基于结果完成这一行任务说明:
|
|
500
|
+
{topic}
|
|
501
|
+
|
|
502
|
+
限制:
|
|
503
|
+
- 不要修改 .workflow/.maestro-coordinate/ 下的 state 文件
|
|
504
|
+
- skill 内部有自己的 session 管理,按 skill SKILL.md 执行即可
|
|
505
|
+
|
|
506
|
+
最后必须调用 report_agent_job_result,返回 JSON:
|
|
507
|
+
{"status":"completed|failed","skill_call":"{skill_call}","summary":"一句话结果","artifacts":"产物路径或空字符串","error":"失败原因或空字符串"}`;
|
|
508
|
+
|
|
509
|
+
const RESULT_SCHEMA = {
|
|
510
|
+
type: "object",
|
|
511
|
+
properties: {
|
|
512
|
+
status: { type: "string", enum: ["completed", "failed"] },
|
|
513
|
+
skill_call: { type: "string" },
|
|
514
|
+
summary: { type: "string" },
|
|
515
|
+
artifacts: { type: "string" },
|
|
516
|
+
error: { type: "string" }
|
|
517
|
+
},
|
|
518
|
+
required: ["status", "skill_call", "summary", "artifacts", "error"]
|
|
519
|
+
};
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### 6c: Main loop
|
|
523
|
+
|
|
524
|
+
```javascript
|
|
525
|
+
let waveNum = 0;
|
|
526
|
+
|
|
527
|
+
while (state.steps.some(s => s.status === 'pending')) {
|
|
528
|
+
waveNum++;
|
|
529
|
+
const waveSteps = buildNextWave(state.steps);
|
|
530
|
+
if (!waveSteps.length) break;
|
|
531
|
+
|
|
532
|
+
// Build wave CSV — skill_call assembled with latest context
|
|
533
|
+
const csvRows = waveSteps.map(step => {
|
|
534
|
+
const skillCall = buildSkillCall(step, context);
|
|
535
|
+
const topic = `Chain "${state.chain_name}" step ${step.index + 1}/${state.steps.length}`;
|
|
536
|
+
return `"${step.index + 1}","${skillCall.replace(/"/g, '""')}","${topic.replace(/"/g, '""')}"`;
|
|
537
|
+
});
|
|
538
|
+
Write(`${sessionDir}/wave-${waveNum}.csv`, 'id,skill_call,topic\n' + csvRows.join('\n'));
|
|
539
|
+
|
|
540
|
+
// Execute wave
|
|
541
|
+
spawn_agents_on_csv({
|
|
542
|
+
csv_path: `${sessionDir}/wave-${waveNum}.csv`,
|
|
543
|
+
id_column: "id",
|
|
544
|
+
instruction: WAVE_INSTRUCTION,
|
|
545
|
+
max_workers: waveSteps.length, // parallel for non-barriers, 1 for barriers
|
|
546
|
+
max_runtime_seconds: 1800,
|
|
547
|
+
output_csv_path: `${sessionDir}/wave-${waveNum}-results.csv`,
|
|
548
|
+
output_schema: RESULT_SCHEMA
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// Read results
|
|
552
|
+
const results = parseCSV(Read(`${sessionDir}/wave-${waveNum}-results.csv`));
|
|
553
|
+
|
|
554
|
+
// Update step status
|
|
555
|
+
for (const row of results) {
|
|
556
|
+
const step = state.steps[parseInt(row.id) - 1];
|
|
557
|
+
step.status = row.status;
|
|
558
|
+
step.findings = row.summary;
|
|
559
|
+
step.artifacts = row.artifacts;
|
|
560
|
+
step.wave_n = waveNum;
|
|
561
|
+
step.completed_at = new Date().toISOString();
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Barrier analysis — coordinator reads artifacts, updates context
|
|
565
|
+
if (waveSteps.length === 1 && BARRIER_SKILLS.has(waveSteps[0].cmd)) {
|
|
566
|
+
analyzeBarrierArtifacts(waveSteps[0], results[0], context);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Record wave
|
|
570
|
+
state.waves.push({ wave_n: waveNum, step_ids: waveSteps.map(s => s.index + 1) });
|
|
571
|
+
Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
|
|
572
|
+
|
|
573
|
+
// Abort on failure
|
|
574
|
+
if (results.some(r => r.status === 'failed')) {
|
|
575
|
+
state.status = 'aborted';
|
|
576
|
+
state.steps.filter(s => s.status === 'pending').forEach(s => { s.status = 'skipped'; });
|
|
577
|
+
Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## Step 7: Barrier Artifact Analysis
|
|
586
|
+
|
|
587
|
+
After a barrier skill completes, the coordinator reads its artifacts and updates `context` for subsequent waves:
|
|
588
|
+
|
|
589
|
+
```javascript
|
|
590
|
+
function analyzeBarrierArtifacts(step, result, ctx) {
|
|
591
|
+
const artifactPath = result.artifacts;
|
|
592
|
+
if (!artifactPath) return;
|
|
593
|
+
|
|
594
|
+
switch (step.cmd) {
|
|
595
|
+
case 'maestro-analyze': {
|
|
596
|
+
// Read analysis conclusions → extract gaps, phase
|
|
597
|
+
ctx.analysis_dir = artifactPath;
|
|
598
|
+
const contextMd = Read(`${artifactPath}/context.md`);
|
|
599
|
+
// Extract gap markers
|
|
600
|
+
const gapLines = contextMd.match(/^[-*]\s.*gap|issue|problem.*/gmi);
|
|
601
|
+
if (gapLines) ctx.gaps = gapLines.join('; ').slice(0, 500);
|
|
602
|
+
// Extract phase if detected
|
|
603
|
+
const phaseMatch = contextMd.match(/phase\s*[:=]\s*(\d+)/i);
|
|
604
|
+
if (phaseMatch && !ctx.phase) ctx.phase = phaseMatch[1];
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
case 'maestro-plan': {
|
|
608
|
+
// Read plan.json → know task count and structure
|
|
609
|
+
ctx.plan_dir = artifactPath;
|
|
610
|
+
if (fileExists(`${artifactPath}/plan.json`)) {
|
|
611
|
+
const plan = JSON.parse(Read(`${artifactPath}/plan.json`));
|
|
612
|
+
ctx.task_count = plan.tasks?.length ?? 0;
|
|
613
|
+
ctx.wave_count = plan.waves?.length ?? 0;
|
|
614
|
+
}
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
case 'maestro-brainstorm': {
|
|
618
|
+
ctx.brainstorm_dir = artifactPath;
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
case 'maestro-spec-generate': {
|
|
622
|
+
ctx.spec_session_id = artifactPath.match(/SPEC-[\w-]+/)?.[0] ?? artifactPath;
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
case 'maestro-execute': {
|
|
626
|
+
// Read execution results for verify context
|
|
627
|
+
if (fileExists(`${artifactPath}/results.csv`)) {
|
|
628
|
+
const execResults = parseCSV(Read(`${artifactPath}/results.csv`));
|
|
629
|
+
ctx.exec_completed = execResults.filter(r => r.status === 'completed').length;
|
|
630
|
+
ctx.exec_failed = execResults.filter(r => r.status === 'failed').length;
|
|
631
|
+
}
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
**Key principle**: The coordinator owns all context assembly. Sub-agents receive a fully-resolved `skill_call` — they don't need to discover or resolve anything themselves.
|
|
639
|
+
|
|
640
|
+
---
|
|
641
|
+
|
|
642
|
+
## Step 8: Completion Report
|
|
643
|
+
|
|
644
|
+
```javascript
|
|
645
|
+
const done = state.steps.filter(s => s.status === 'completed').length;
|
|
646
|
+
const failed = state.steps.filter(s => s.status === 'failed').length;
|
|
647
|
+
const total = state.steps.length;
|
|
648
|
+
|
|
649
|
+
state.status = state.steps.every(s => s.status === 'completed') ? 'completed' : state.status;
|
|
650
|
+
state.completed_at = new Date().toISOString();
|
|
651
|
+
Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
Generate `context.md`:
|
|
655
|
+
|
|
656
|
+
```markdown
|
|
657
|
+
# Coordinate Report — {chainName}
|
|
658
|
+
|
|
659
|
+
## Summary
|
|
660
|
+
- Session: {sessionId}
|
|
661
|
+
- Chain: {chainName}
|
|
662
|
+
- Waves: {waveNum} executed
|
|
663
|
+
- Steps: {done}/{total} completed, {failed} failed
|
|
664
|
+
|
|
665
|
+
## Wave Results
|
|
666
|
+
### Wave {N}
|
|
667
|
+
| Step | Skill Call | Status | Summary |
|
|
668
|
+
|------|-----------|--------|---------|
|
|
669
|
+
| {index+1} | {skill_call} | {status} | {summary} |
|
|
670
|
+
|
|
671
|
+
Context update: {what changed in ctx}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
Display:
|
|
675
|
+
|
|
676
|
+
```
|
|
677
|
+
============================================================
|
|
678
|
+
MAESTRO-COORDINATE COMPLETE
|
|
679
|
+
============================================================
|
|
680
|
+
Session: {session_id}
|
|
681
|
+
Chain: {chain_name}
|
|
682
|
+
Waves: {waveNum} executed
|
|
683
|
+
Steps: {done}/{total}
|
|
684
|
+
|
|
685
|
+
WAVE RESULTS:
|
|
686
|
+
[W1] $maestro-analyze --gaps → ✓ found 3 gaps
|
|
687
|
+
[W2] $maestro-plan --gaps → ✓ 12 tasks in 3 waves
|
|
688
|
+
[W3] $maestro-execute → ✓ 12/12 tasks done
|
|
689
|
+
[W4] $maestro-verify → ✓ all criteria met
|
|
690
|
+
|
|
691
|
+
Artifacts: .workflow/.maestro-coordinate/{session_id}/
|
|
692
|
+
Resume: $maestro --continue
|
|
693
|
+
============================================================
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
## Core Rules
|
|
699
|
+
|
|
700
|
+
1. **Semantic routing**: LLM-native structured extraction (`action × object`) replaces regex; disambiguates "问题" by context
|
|
701
|
+
2. **Wave-by-wave**: Never start wave N+1 before wave N results are read and barrier artifacts analyzed
|
|
702
|
+
3. **Barrier = solo wave**: A barrier skill always executes alone; coordinator analyzes its artifacts before proceeding
|
|
703
|
+
4. **Non-barriers can parallel**: Consecutive non-barrier skills share a wave with `max_workers = N`
|
|
704
|
+
5. **Coordinator owns context**: Sub-agents receive fully-resolved `skill_call` — no context discovery needed
|
|
705
|
+
6. **Simple instruction**: Sub-agent instruction is minimal — "execute {skill_call}, report result"
|
|
706
|
+
7. **Quality gates**: Issue chains auto-include review; `issue-full` is default for issue execution
|
|
707
|
+
8. **report_agent_job_result**: Every agent MUST call this with the output schema
|
|
708
|
+
9. **State.json tracks waves**: Each wave recorded with step IDs and results; `--continue` resumes from next pending
|
|
709
|
+
10. **Dry-run is read-only**: Display chain with [BARRIER] markers, no execution
|
|
710
|
+
11. **Abort on failure**: Failed step → skip remaining → report
|