maestro-flow 0.3.8 → 0.3.9
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/learn-decompose.md +3 -3
- package/.claude/commands/learn-follow.md +5 -5
- package/.claude/commands/learn-investigate.md +3 -3
- package/.claude/commands/learn-retro.md +6 -6
- package/.claude/commands/learn-second-opinion.md +3 -3
- package/.claude/commands/maestro-analyze.md +123 -99
- package/.claude/commands/maestro-brainstorm.md +2 -2
- package/.claude/commands/maestro-execute.md +137 -97
- package/.claude/commands/maestro-fork.md +111 -0
- package/.claude/commands/maestro-init.md +6 -6
- package/.claude/commands/maestro-merge.md +77 -0
- package/.claude/commands/maestro-milestone-audit.md +72 -60
- package/.claude/commands/maestro-milestone-complete.md +67 -59
- package/.claude/commands/maestro-milestone-release.md +6 -6
- package/.claude/commands/maestro-plan.md +151 -130
- package/.claude/commands/maestro-quick.md +4 -4
- package/.claude/commands/maestro-roadmap.md +5 -5
- package/.claude/commands/maestro-spec-generate.md +5 -5
- package/.claude/commands/maestro-ui-design.md +3 -3
- package/.claude/commands/maestro-verify.md +106 -87
- package/.claude/commands/maestro.md +10 -4
- package/.claude/commands/manage-codebase-rebuild.md +4 -4
- package/.claude/commands/manage-codebase-refresh.md +1 -1
- package/.claude/commands/manage-harvest.md +5 -5
- package/.claude/commands/manage-issue-discover.md +1 -1
- package/.claude/commands/manage-issue-execute.md +6 -6
- package/.claude/commands/manage-issue.md +6 -6
- package/.claude/commands/manage-learn.md +2 -2
- package/.claude/commands/manage-memory-capture.md +4 -4
- package/.claude/commands/manage-memory.md +2 -2
- package/.claude/commands/manage-status.md +24 -24
- package/.claude/commands/quality-business-test.md +5 -5
- package/.claude/commands/quality-debug.md +4 -4
- package/.claude/commands/quality-integration-test.md +4 -4
- package/.claude/commands/quality-refactor.md +3 -3
- package/.claude/commands/quality-retrospective.md +2 -2
- package/.claude/commands/quality-review.md +4 -4
- package/.claude/commands/quality-sync.md +3 -3
- package/.claude/commands/quality-test-gen.md +4 -4
- package/.claude/commands/quality-test.md +9 -9
- package/.claude/commands/spec-add.md +2 -2
- package/.claude/commands/spec-load.md +1 -1
- package/.claude/commands/spec-setup.md +5 -5
- package/.claude/commands/wiki-connect.md +3 -3
- package/.claude/commands/wiki-digest.md +4 -4
- package/.codex/skills/maestro-analyze/SKILL.md +52 -14
- package/.codex/skills/maestro-execute/SKILL.md +27 -26
- package/.codex/skills/maestro-milestone-audit/SKILL.md +103 -209
- package/.codex/skills/maestro-milestone-complete/SKILL.md +149 -158
- package/.codex/skills/maestro-plan/SKILL.md +47 -17
- package/.codex/skills/maestro-roadmap/SKILL.md +3 -2
- package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +2 -2
- package/.codex/skills/team-executor/roles/executor/commands/monitor.md +1 -1
- package/.codex/skills/team-lifecycle-v4/roles/coordinator/commands/monitor.md +2 -2
- package/.codex/skills/team-lifecycle-v4/specs/knowledge-transfer.md +2 -2
- package/.codex/skills/team-quality-assurance/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-review/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +1 -1
- package/.codex/skills/team-testing/roles/coordinator/commands/monitor.md +1 -1
- package/README.md +19 -14
- package/README.zh-CN.md +16 -12
- package/bin/maestro-mcp.js +1 -1
- package/chains/_intent-map.json +21 -9
- package/chains/_router.json +30 -77
- package/chains/brainstorm-driven.json +17 -6
- package/chains/full-lifecycle.json +22 -23
- package/chains/milestone-close.json +20 -7
- package/chains/milestone-fork-merge.json +50 -0
- package/chains/roadmap-driven.json +17 -6
- package/chains/spec-driven.json +17 -6
- package/dashboard/dist/assets/{ArtifactsPage-BmPOu8sO.js → ArtifactsPage-DZNCi6tn.js} +12 -7
- package/dashboard/dist/assets/ChatInput-Bvr-FeEq.js +49 -0
- package/dashboard/dist/assets/ChatPage-D9zTkJZo.js +22 -0
- package/dashboard/dist/assets/CollabPage-B4NAHXS2.js +1 -0
- package/dashboard/dist/assets/ExecutionPanel-CFt4LJyq.js +1 -0
- package/dashboard/dist/assets/KanbanPage-C8USth6H.js +21 -0
- package/dashboard/dist/assets/{MarkdownRenderer-BjZ43aSa.js → MarkdownRenderer-X4af_WNb.js} +1 -1
- package/dashboard/dist/assets/McpPage-BKfCVIyU.js +21 -0
- package/dashboard/dist/assets/OutputPanel-BlBQFJSW.js +1 -0
- package/dashboard/dist/assets/ProblemsPanel-De3DLvoI.js +1 -0
- package/dashboard/dist/assets/{RequirementBoardPage-B7yRL0s_.js → RequirementBoardPage-Bf1trzqs.js} +2 -2
- package/dashboard/dist/assets/{RequirementPage-D8J_-b6O.js → RequirementPage-Bllxe2XI.js} +10 -5
- package/dashboard/dist/assets/{SpecsPage-6lO8v8_C.js → SpecsPage-9lwxKT27.js} +2 -2
- package/dashboard/dist/assets/{SupervisorPage-Ds5N378a.js → SupervisorPage-SusdfHFq.js} +1 -1
- package/dashboard/dist/assets/{TeamsPage-DrkKr17T.js → TeamsPage-DsuM6OwC.js} +2 -2
- package/dashboard/dist/assets/TreeBrowser-Q12qobZs.js +6 -0
- package/dashboard/dist/assets/WorkflowPage-D_Fzdy3_.js +6 -0
- package/dashboard/dist/assets/{arrow-left-CadP5YgU.js → arrow-left-Bqtb2hle.js} +1 -1
- package/dashboard/dist/assets/{check-5xufDzS8.js → check-u6fGOwQO.js} +1 -1
- package/dashboard/dist/assets/{chevron-right-CYbpR4ev.js → chevron-right-Csu22t58.js} +1 -1
- package/dashboard/dist/assets/{circle-Bm-5Q-Yh.js → circle-CMrkbRNg.js} +1 -1
- package/dashboard/dist/assets/{circle-alert-BqcYuT7x.js → circle-alert-c3tH1P4z.js} +1 -1
- package/dashboard/dist/assets/{circle-check-big-yyzAFysU.js → circle-check-big-TDSeWstm.js} +1 -1
- package/dashboard/dist/assets/{circle-check-DEVzW_lm.js → circle-check-gYxxSYuH.js} +1 -1
- package/dashboard/dist/assets/{code-BBdC8Wmw.js → code-CFN2uX9V.js} +1 -1
- package/dashboard/dist/assets/{columns-3-CQ9Trztr.js → columns-3-38xIDlzy.js} +1 -1
- package/dashboard/dist/assets/{download-DayuF-sn.js → download-DC7KkKyP.js} +1 -1
- package/dashboard/dist/assets/{folder-CqXeSKeC.js → folder-CWq_lAnf.js} +1 -1
- package/dashboard/dist/assets/index-DWG-WrzT.js +231 -0
- package/dashboard/dist/assets/{index-Dru5HYy0.js → index-Do71weNR.js} +1 -1
- package/dashboard/dist/assets/index-GUNJodSR.css +1 -0
- package/dashboard/dist/assets/{list-DBOD6IUt.js → list-CgIP_2A-.js} +1 -1
- package/dashboard/dist/assets/{minus-fQI1Syn2.js → minus-DYoN5UGk.js} +1 -1
- package/dashboard/dist/assets/{pen-line-Bkbbngl5.js → pen-line-Bh_WKYHm.js} +1 -1
- package/dashboard/dist/assets/{proxy-teW12DdZ.js → proxy-BKxDAKTj.js} +1 -1
- package/dashboard/dist/assets/{search-Bq3ygFUW.js → search-SieXnOgr.js} +1 -1
- package/dashboard/dist/assets/{shallow-22ZN8sFt.js → shallow-Bme1JY57.js} +1 -1
- package/dashboard/dist/assets/{table-BEYtdWc4.js → table-llyEtj-7.js} +1 -1
- package/dashboard/dist/assets/terminal-BB3Xfuv5.js +6 -0
- package/dashboard/dist/assets/{trash-2-DMqGBgcF.js → trash-2-C8f4vFFM.js} +1 -1
- package/dashboard/dist/assets/{zap-9DVkGVtt.js → zap-4uwlzVm0.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js +8 -4
- package/dashboard/dist-server/dashboard/src/server/agents/claude-code-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.d.ts +1 -0
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js +2 -1
- package/dashboard/dist-server/dashboard/src/server/agents/entry-normalizer.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js +20 -10
- package/dashboard/dist-server/dashboard/src/server/agents/stream-json-adapter.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/git.d.ts +2 -0
- package/dashboard/dist-server/dashboard/src/server/routes/git.js +79 -0
- package/dashboard/dist-server/dashboard/src/server/routes/git.js.map +1 -0
- package/dashboard/dist-server/dashboard/src/server/routes/index.js +3 -0
- package/dashboard/dist-server/dashboard/src/server/routes/index.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/routes/workspace.js +43 -0
- package/dashboard/dist-server/dashboard/src/server/routes/workspace.js.map +1 -1
- package/dashboard/dist-server/dashboard/src/server/state/state-manager.js +43 -3
- package/dashboard/dist-server/dashboard/src/server/state/state-manager.js.map +1 -1
- package/dashboard/package.json +59 -59
- package/dist/src/cli.js +3 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/{team.d.ts → collab.d.ts} +2 -2
- package/dist/src/commands/collab.d.ts.map +1 -0
- package/dist/src/commands/{team.js → collab.js} +391 -24
- package/dist/src/commands/collab.js.map +1 -0
- package/dist/src/commands/msg.d.ts.map +1 -1
- package/dist/src/commands/msg.js +4 -3
- package/dist/src/commands/msg.js.map +1 -1
- package/dist/src/hooks/team-monitor.d.ts.map +1 -1
- package/dist/src/hooks/team-monitor.js +16 -0
- package/dist/src/hooks/team-monitor.js.map +1 -1
- package/dist/src/tools/collab-adapter.d.ts +85 -0
- package/dist/src/tools/collab-adapter.d.ts.map +1 -0
- package/dist/src/tools/collab-adapter.js +320 -0
- package/dist/src/tools/collab-adapter.js.map +1 -0
- package/dist/src/tools/namespace-guard.d.ts +2 -0
- package/dist/src/tools/namespace-guard.d.ts.map +1 -1
- package/dist/src/tools/namespace-guard.js +12 -0
- package/dist/src/tools/namespace-guard.js.map +1 -1
- package/dist/src/tools/phase-gate-evaluator.d.ts +45 -0
- package/dist/src/tools/phase-gate-evaluator.d.ts.map +1 -0
- package/dist/src/tools/phase-gate-evaluator.js +42 -0
- package/dist/src/tools/phase-gate-evaluator.js.map +1 -0
- package/dist/src/tools/team-members.d.ts +18 -0
- package/dist/src/tools/team-members.d.ts.map +1 -1
- package/dist/src/tools/team-members.js +50 -0
- package/dist/src/tools/team-members.js.map +1 -1
- package/dist/src/tools/team-tasks.d.ts +120 -0
- package/dist/src/tools/team-tasks.d.ts.map +1 -0
- package/dist/src/tools/team-tasks.js +365 -0
- package/dist/src/tools/team-tasks.js.map +1 -0
- package/dist/src/tools/transition-recorder.d.ts +3 -0
- package/dist/src/tools/transition-recorder.d.ts.map +1 -1
- package/dist/src/tools/transition-recorder.js +52 -1
- package/dist/src/tools/transition-recorder.js.map +1 -1
- package/dist/src/utils/get-version.d.ts.map +1 -1
- package/dist/src/utils/get-version.js +15 -4
- package/dist/src/utils/get-version.js.map +1 -1
- package/package.json +1 -1
- package/templates/config.json +7 -0
- package/templates/worktree-scope.json +10 -0
- package/templates/worktrees.json +27 -0
- package/workflows/analyze.md +86 -36
- package/workflows/brainstorm.md +17 -37
- package/workflows/execute.md +94 -28
- package/workflows/fork.md +309 -0
- package/workflows/init.md +10 -1
- package/workflows/issue.md +66 -7
- package/workflows/maestro-coordinate.md +23 -16
- package/workflows/maestro.md +52 -35
- package/workflows/merge.md +285 -0
- package/workflows/milestone-audit.md +89 -70
- package/workflows/milestone-complete.md +89 -156
- package/workflows/plan.md +122 -17
- package/workflows/retrospective.md +3 -3
- package/workflows/roadmap.md +11 -3
- package/workflows/spec-generate.md +9 -0
- package/workflows/status.md +76 -27
- package/workflows/ui-design.md +14 -12
- package/workflows/verify.md +44 -8
- package/.claude/commands/maestro-phase-add.md +0 -63
- package/.claude/commands/maestro-phase-transition.md +0 -75
- package/.codex/skills/maestro-phase-add/SKILL.md +0 -154
- package/.codex/skills/maestro-phase-transition/SKILL.md +0 -173
- package/chains/singles/phase-add.json +0 -31
- package/chains/singles/phase-transition.json +0 -23
- package/dashboard/dist/assets/ChatInput-CL8YDfOU.js +0 -67
- package/dashboard/dist/assets/ChatPage-CT-ozBK2.js +0 -8
- package/dashboard/dist/assets/CollabPage-C0rWMden.js +0 -1
- package/dashboard/dist/assets/KanbanPage-C6WbAlwI.js +0 -16
- package/dashboard/dist/assets/McpPage-BPIXADQi.js +0 -16
- package/dashboard/dist/assets/TreeBrowser-g_QUKemL.js +0 -11
- package/dashboard/dist/assets/WorkflowPage-X8aNkDEr.js +0 -6
- package/dashboard/dist/assets/git-branch-SqFf4Ru5.js +0 -6
- package/dashboard/dist/assets/index-D2Mtyw7I.css +0 -1
- package/dashboard/dist/assets/index-nufWop4p.js +0 -231
- package/dashboard/dist/assets/wrench-B84-zdLI.js +0 -11
- package/dist/src/commands/team.d.ts.map +0 -1
- package/dist/src/commands/team.js.map +0 -1
- package/workflows/phase-add.md +0 -252
- package/workflows/phase-transition.md +0 -399
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Workflow: fork
|
|
2
|
+
|
|
3
|
+
Create a git worktree for an entire milestone, enabling inter-milestone parallel development. Copies `.workflow/` context into the worktree since `.workflow/` is gitignored.
|
|
4
|
+
|
|
5
|
+
Worktrees operate at the **milestone level** — all phases within a milestone are owned by one worktree and executed sequentially inside it. Per-phase parallelism within a milestone is not supported.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Step 1: Parse Arguments and Flags
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const getUtc8ISOString = () => new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString()
|
|
13
|
+
|
|
14
|
+
// Parse flags
|
|
15
|
+
const syncMode = $ARGUMENTS.includes('--sync')
|
|
16
|
+
const baseMatch = $ARGUMENTS.match(/--base\s+(\S+)/)
|
|
17
|
+
const baseBranch = baseMatch ? baseMatch[1] : 'HEAD'
|
|
18
|
+
|
|
19
|
+
// Parse milestone number: -m <N> or bare <N>
|
|
20
|
+
const mFlagMatch = $ARGUMENTS.match(/-m\s+(\d+)/)
|
|
21
|
+
const cleaned = $ARGUMENTS
|
|
22
|
+
.replace(/--sync|--base\s+\S+|-m\s+\d+/g, '')
|
|
23
|
+
.trim()
|
|
24
|
+
const bareNumMatch = cleaned.match(/^(\d+)$/)
|
|
25
|
+
const milestoneNum = mFlagMatch
|
|
26
|
+
? parseInt(mFlagMatch[1])
|
|
27
|
+
: bareNumMatch
|
|
28
|
+
? parseInt(bareNumMatch[1])
|
|
29
|
+
: null
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 2: Validate Prerequisites
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
IF NOT file_exists(".workflow/state.json"):
|
|
38
|
+
ERROR E001: "Project not initialized. Run maestro-init first."
|
|
39
|
+
EXIT
|
|
40
|
+
|
|
41
|
+
IF NOT file_exists(".workflow/roadmap.md"):
|
|
42
|
+
ERROR E002: "No roadmap found. Run maestro-roadmap first."
|
|
43
|
+
EXIT
|
|
44
|
+
|
|
45
|
+
IF file_exists(".workflow/worktree-scope.json"):
|
|
46
|
+
ERROR E003: "Cannot fork from inside a worktree. Run from the main worktree."
|
|
47
|
+
EXIT
|
|
48
|
+
|
|
49
|
+
IF milestoneNum === null:
|
|
50
|
+
ERROR E004: "Milestone number required. Usage: maestro-fork -m <number>"
|
|
51
|
+
EXIT
|
|
52
|
+
|
|
53
|
+
Read .workflow/state.json → projectState
|
|
54
|
+
Read .workflow/config.json → config (if exists, else use defaults)
|
|
55
|
+
|
|
56
|
+
worktreeRoot = config.worktree?.root ?? ".worktrees"
|
|
57
|
+
branchPrefix = config.worktree?.branch_prefix ?? "milestone/"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Step 3: Resolve Milestone
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
// Lookup milestone by number from state.json.milestones[]
|
|
66
|
+
IF NOT projectState.milestones || NOT Array.isArray(projectState.milestones):
|
|
67
|
+
ERROR E005: "No milestones defined in state.json."
|
|
68
|
+
EXIT
|
|
69
|
+
|
|
70
|
+
// milestones[] is 0-indexed, milestoneNum is 1-based
|
|
71
|
+
milestoneEntry = projectState.milestones[milestoneNum - 1]
|
|
72
|
+
|
|
73
|
+
IF NOT milestoneEntry:
|
|
74
|
+
availableList = projectState.milestones
|
|
75
|
+
.map((m, i) => " M" + (i + 1) + ": " + m.name + " (" + m.title + ")")
|
|
76
|
+
.join("\n")
|
|
77
|
+
ERROR E006: "Milestone {milestoneNum} not found.\nAvailable:\n{availableList}"
|
|
78
|
+
EXIT
|
|
79
|
+
|
|
80
|
+
milestoneName = milestoneEntry.name // e.g. "Production"
|
|
81
|
+
milestoneTitle = milestoneEntry.title // e.g. "生产就绪"
|
|
82
|
+
milestonePhases = milestoneEntry.phases // e.g. [3, 4]
|
|
83
|
+
milestoneSlug = milestoneName.toLowerCase().replace(/[^a-z0-9]+/g, '-').substring(0, 40)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Step 4: Sync Mode (--sync)
|
|
89
|
+
|
|
90
|
+
If `syncMode` is true, this is a sync operation on an existing worktree, not a fork.
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
IF syncMode:
|
|
94
|
+
Read .workflow/worktrees.json → registry
|
|
95
|
+
entry = registry.worktrees.find(w =>
|
|
96
|
+
w.milestone_num === milestoneNum && w.status === "active"
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
IF NOT entry:
|
|
100
|
+
ERROR E007: "No active worktree for milestone {milestoneNum} ({milestoneName})"
|
|
101
|
+
EXIT
|
|
102
|
+
|
|
103
|
+
// Step 4a: Pull source code
|
|
104
|
+
Bash("cd {entry.path} && git merge main")
|
|
105
|
+
IF conflict:
|
|
106
|
+
WARN "Merge conflict in worktree. Resolve in {entry.path} before continuing."
|
|
107
|
+
EXIT
|
|
108
|
+
|
|
109
|
+
// Step 4b: Re-copy shared context
|
|
110
|
+
Copy .workflow/project.md → {entry.path}/.workflow/project.md
|
|
111
|
+
Copy .workflow/roadmap.md → {entry.path}/.workflow/roadmap.md
|
|
112
|
+
Copy .workflow/config.json → {entry.path}/.workflow/config.json (if exists)
|
|
113
|
+
Copy .workflow/specs/ → {entry.path}/.workflow/specs/ (if exists)
|
|
114
|
+
|
|
115
|
+
Display "Worktree for M{milestoneNum} ({milestoneName}) synced with main."
|
|
116
|
+
EXIT (sync complete)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Step 5: Validate & Confirm
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
// Load phase index files for all milestone phases
|
|
125
|
+
phaseList = []
|
|
126
|
+
for (phaseNum of milestonePhases):
|
|
127
|
+
Glob: .workflow/phases/{NN}-*/index.json where NN matches phaseNum
|
|
128
|
+
Read index.json → phaseIndex
|
|
129
|
+
phaseList.push(phaseIndex)
|
|
130
|
+
|
|
131
|
+
// Validate: milestone should have at least one non-completed phase
|
|
132
|
+
nonCompleted = phaseList.filter(p => p.status !== "completed")
|
|
133
|
+
IF nonCompleted.length === 0:
|
|
134
|
+
Display "All phases in M{milestoneNum} ({milestoneName}) are already completed. Nothing to fork."
|
|
135
|
+
EXIT
|
|
136
|
+
|
|
137
|
+
// Check for already-forked milestone
|
|
138
|
+
IF file_exists(".workflow/worktrees.json"):
|
|
139
|
+
Read .workflow/worktrees.json → existingRegistry
|
|
140
|
+
alreadyForked = existingRegistry.worktrees.find(w =>
|
|
141
|
+
w.milestone_num === milestoneNum && w.status === "active"
|
|
142
|
+
)
|
|
143
|
+
IF alreadyForked:
|
|
144
|
+
ERROR E008: "M{milestoneNum} already has an active worktree at {alreadyForked.path}. Merge or cleanup first."
|
|
145
|
+
EXIT
|
|
146
|
+
|
|
147
|
+
Display "Fork Milestone {milestoneNum}: {milestoneName} ({milestoneTitle})"
|
|
148
|
+
Display "Phases ({phaseList.length}):"
|
|
149
|
+
for (p of phaseList):
|
|
150
|
+
Display " Phase {p.phase}: {p.title} [{p.status}]"
|
|
151
|
+
|
|
152
|
+
AskUserQuestion: "Create worktree for this milestone? (y/n)"
|
|
153
|
+
IF response !== 'y': EXIT
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Step 6: Create Worktree
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
const forkSessionId = "fork-" + getUtc8ISOString().substring(0, 19).replace(/[-:T]/g, '')
|
|
162
|
+
const baseCommit = Bash("git rev-parse HEAD").trim()
|
|
163
|
+
const branch = branchPrefix + milestoneSlug
|
|
164
|
+
const wtPath = worktreeRoot + "/m" + milestoneNum + "-" + milestoneSlug
|
|
165
|
+
|
|
166
|
+
// 6a: Clean up stale worktree/branch if exists
|
|
167
|
+
IF directory_exists(wtPath):
|
|
168
|
+
Bash("git worktree remove --force {wtPath}") // ignore errors
|
|
169
|
+
Bash("git branch -D {branch}") // ignore errors (may not exist)
|
|
170
|
+
|
|
171
|
+
// 6b: Create worktree
|
|
172
|
+
Bash("git worktree add -b {branch} {wtPath} {baseBranch}")
|
|
173
|
+
|
|
174
|
+
// 6c: Create .workflow/ structure in worktree
|
|
175
|
+
Bash("mkdir -p {wtPath}/.workflow/phases")
|
|
176
|
+
|
|
177
|
+
// 6d: Copy shared context (read-only)
|
|
178
|
+
Copy .workflow/project.md → {wtPath}/.workflow/project.md
|
|
179
|
+
Copy .workflow/roadmap.md → {wtPath}/.workflow/roadmap.md
|
|
180
|
+
IF file_exists(".workflow/config.json"):
|
|
181
|
+
Copy .workflow/config.json → {wtPath}/.workflow/config.json
|
|
182
|
+
IF directory_exists(".workflow/specs"):
|
|
183
|
+
Copy .workflow/specs/ → {wtPath}/.workflow/specs/
|
|
184
|
+
|
|
185
|
+
// 6e: Copy ALL phase directories for this milestone
|
|
186
|
+
ownedPhaseNumbers = []
|
|
187
|
+
for (p of phaseList):
|
|
188
|
+
NN = String(p.phase).padStart(2, '0')
|
|
189
|
+
Copy .workflow/phases/{NN}-{p.slug}/ → {wtPath}/.workflow/phases/{NN}-{p.slug}/
|
|
190
|
+
ownedPhaseNumbers.push(p.phase)
|
|
191
|
+
|
|
192
|
+
// 6f: Copy completed dependency phase dirs outside this milestone (read-only reference)
|
|
193
|
+
allDeps = new Set()
|
|
194
|
+
for (p of phaseList):
|
|
195
|
+
for (dep of p.depends_on):
|
|
196
|
+
IF NOT ownedPhaseNumbers.includes(dep):
|
|
197
|
+
allDeps.add(dep)
|
|
198
|
+
|
|
199
|
+
for (dep of allDeps):
|
|
200
|
+
depNN = String(dep).padStart(2, '0')
|
|
201
|
+
Glob: .workflow/phases/{depNN}-*/index.json
|
|
202
|
+
Read → depIndex
|
|
203
|
+
Copy .workflow/phases/{depNN}-{depIndex.slug}/ → {wtPath}/.workflow/phases/{depNN}-{depIndex.slug}/
|
|
204
|
+
|
|
205
|
+
// 6g: Write worktree-scope.json
|
|
206
|
+
Write {wtPath}/.workflow/worktree-scope.json:
|
|
207
|
+
{
|
|
208
|
+
"worktree": true,
|
|
209
|
+
"milestone_num": milestoneNum,
|
|
210
|
+
"milestone": milestoneName,
|
|
211
|
+
"owned_phases": ownedPhaseNumbers,
|
|
212
|
+
"main_worktree": resolve(cwd),
|
|
213
|
+
"branch": branch,
|
|
214
|
+
"base_commit": baseCommit,
|
|
215
|
+
"created_at": getUtc8ISOString()
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 6h: Write scoped state.json
|
|
219
|
+
Read .workflow/state.json → mainState
|
|
220
|
+
firstPending = phaseList.find(p => p.status !== "completed")
|
|
221
|
+
scopedState = {
|
|
222
|
+
...mainState,
|
|
223
|
+
current_phase: firstPending?.phase ?? phaseList[0].phase,
|
|
224
|
+
current_milestone: milestoneName
|
|
225
|
+
}
|
|
226
|
+
Write {wtPath}/.workflow/state.json: scopedState
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Step 7: Update Main Registry
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
IF file_exists(".workflow/worktrees.json"):
|
|
235
|
+
Read .workflow/worktrees.json → registry
|
|
236
|
+
ELSE:
|
|
237
|
+
registry = { version: "1.0", worktrees: [], fork_sessions: [] }
|
|
238
|
+
|
|
239
|
+
registry.worktrees.push({
|
|
240
|
+
milestone_num: milestoneNum,
|
|
241
|
+
milestone: milestoneName,
|
|
242
|
+
slug: milestoneSlug,
|
|
243
|
+
branch: branch,
|
|
244
|
+
path: wtPath,
|
|
245
|
+
base_commit: baseCommit,
|
|
246
|
+
status: "active",
|
|
247
|
+
created_at: getUtc8ISOString(),
|
|
248
|
+
owned_phases: ownedPhaseNumbers,
|
|
249
|
+
fork_session: forkSessionId
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
registry.fork_sessions.push({
|
|
253
|
+
session_id: forkSessionId,
|
|
254
|
+
created_at: getUtc8ISOString(),
|
|
255
|
+
milestone_num: milestoneNum,
|
|
256
|
+
milestone: milestoneName,
|
|
257
|
+
base_branch: baseBranch,
|
|
258
|
+
base_commit: baseCommit
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
Write .workflow/worktrees.json: registry
|
|
262
|
+
|
|
263
|
+
// Mark milestone phases as "forked" in main
|
|
264
|
+
for (p of phaseList):
|
|
265
|
+
IF p.status !== "completed":
|
|
266
|
+
NN = String(p.phase).padStart(2, '0')
|
|
267
|
+
Read .workflow/phases/{NN}-{p.slug}/index.json → idx
|
|
268
|
+
idx.status = "forked"
|
|
269
|
+
idx.updated_at = getUtc8ISOString()
|
|
270
|
+
Write .workflow/phases/{NN}-{p.slug}/index.json: idx
|
|
271
|
+
|
|
272
|
+
mainState.last_updated = getUtc8ISOString()
|
|
273
|
+
Write .workflow/state.json: mainState
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Step 8: Display Summary
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
Display:
|
|
282
|
+
=== FORK COMPLETE ===
|
|
283
|
+
Session: {forkSessionId}
|
|
284
|
+
Base: {baseBranch} ({baseCommit.substring(0, 7)})
|
|
285
|
+
Milestone: M{milestoneNum} — {milestoneName} ({milestoneTitle})
|
|
286
|
+
Branch: {branch}
|
|
287
|
+
Path: {wtPath}
|
|
288
|
+
Phases: {ownedPhaseNumbers.join(', ')}
|
|
289
|
+
|
|
290
|
+
Next steps (run in the worktree):
|
|
291
|
+
cd {wtPath}
|
|
292
|
+
|
|
293
|
+
# Sequential lifecycle for each phase:
|
|
294
|
+
/maestro-analyze {firstPending.phase}
|
|
295
|
+
/maestro-plan {firstPending.phase}
|
|
296
|
+
/maestro-execute {firstPending.phase}
|
|
297
|
+
/maestro-verify {firstPending.phase}
|
|
298
|
+
/maestro-phase-transition {firstPending.phase}
|
|
299
|
+
# ... repeat for next phases in milestone
|
|
300
|
+
|
|
301
|
+
Or delegate (automated):
|
|
302
|
+
maestro delegate "run full lifecycle for milestone" --cd {wtPath} --mode write
|
|
303
|
+
|
|
304
|
+
Sync worktree with main (if needed later):
|
|
305
|
+
/maestro-fork -m {milestoneNum} --sync
|
|
306
|
+
|
|
307
|
+
When all phases in milestone complete:
|
|
308
|
+
/maestro-merge -m {milestoneNum}
|
|
309
|
+
```
|
package/workflows/init.md
CHANGED
|
@@ -4,6 +4,15 @@ Project initialization with automatic state detection. Creates project infrastru
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## Worktree Guard
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
# Block in worktree
|
|
11
|
+
IF file_exists(".workflow/worktree-scope.json"):
|
|
12
|
+
ERROR "Cannot run maestro-init inside a worktree. Run from the main worktree."
|
|
13
|
+
EXIT
|
|
14
|
+
```
|
|
15
|
+
|
|
7
16
|
## Step 1: State Detection
|
|
8
17
|
|
|
9
18
|
Detect current project state to determine initialization path.
|
|
@@ -41,7 +50,7 @@ CHECK .workflow/state.json exists?
|
|
|
41
50
|
|
|
42
51
|
If `--auto` flag: skip interactive questioning, extract from @ referenced document.
|
|
43
52
|
If `--from-brainstorm SESSION-ID`:
|
|
44
|
-
- Locate brainstorm session directory (`.workflow/scratch/brainstorm-*/`
|
|
53
|
+
- Locate brainstorm session directory (`.workflow/scratch/brainstorm-*/`)
|
|
45
54
|
- Read `guidance-specification.md`:
|
|
46
55
|
- Problem statement → project vision + core value
|
|
47
56
|
- Features → project goals (Active requirements)
|
package/workflows/issue.md
CHANGED
|
@@ -65,14 +65,21 @@ Parse options from ARGS:
|
|
|
65
65
|
Options:
|
|
66
66
|
--title TEXT Issue title (required)
|
|
67
67
|
--severity VALUE critical|high|medium|low (default: medium)
|
|
68
|
-
--source VALUE
|
|
68
|
+
--source VALUE planned|supplement|bug|review|verification|discovery|manual (default: manual)
|
|
69
69
|
--phase VALUE Phase reference, e.g. "01-auth" (optional)
|
|
70
|
+
--milestone VALUE Milestone reference, e.g. "MVP" (optional, auto-derived from state.json if omitted)
|
|
70
71
|
--description TEXT Detailed description (optional, prompted if missing)
|
|
71
72
|
--priority NUMBER 1-5, lower is higher priority (default: 3)
|
|
72
73
|
--tags TAG1,TAG2 Comma-separated tags (optional)
|
|
73
74
|
|
|
74
75
|
If --title is missing:
|
|
75
76
|
AskUserQuestion({ question: "What is the issue title?" })
|
|
77
|
+
|
|
78
|
+
Derive milestone_ref if not provided:
|
|
79
|
+
IF --milestone not provided AND file_exists(".workflow/state.json"):
|
|
80
|
+
milestone_ref = state.json.current_milestone
|
|
81
|
+
ELSE:
|
|
82
|
+
milestone_ref = --milestone value or null
|
|
76
83
|
```
|
|
77
84
|
|
|
78
85
|
Generate issue ID:
|
|
@@ -96,6 +103,7 @@ Build issue record from template:
|
|
|
96
103
|
"priority": {PRIORITY},
|
|
97
104
|
"severity": "{SEVERITY}",
|
|
98
105
|
"source": "{SOURCE}",
|
|
106
|
+
"milestone_ref": "{MILESTONE_REF or null}",
|
|
99
107
|
"phase_ref": "{PHASE_REF or null}",
|
|
100
108
|
"gap_ref": null,
|
|
101
109
|
"description": "{DESCRIPTION}",
|
|
@@ -135,8 +143,56 @@ Write to storage:
|
|
|
135
143
|
Title: {TITLE}
|
|
136
144
|
Status: open
|
|
137
145
|
Severity: {SEVERITY}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Ask for supplementary information:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
4. Ask user for supplementary context:
|
|
152
|
+
AskUserQuestion({
|
|
153
|
+
question: "Do you have any supplementary information for this issue?\n1. Additional context or background?\n2. Reproduction steps or affected files?\n3. Related issues or tasks?\n4. Other notes?\n\n(Press Enter to skip)"
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
5. Process user response:
|
|
157
|
+
- If response is non-empty:
|
|
158
|
+
a. Build supplement entry:
|
|
159
|
+
{
|
|
160
|
+
"content": "{RESPONSE_TEXT}",
|
|
161
|
+
"stage": "post_creation",
|
|
162
|
+
"author": "user",
|
|
163
|
+
"created_at": "{NOW_ISO}"
|
|
164
|
+
}
|
|
165
|
+
b. Read issues.jsonl
|
|
166
|
+
c. Find the just-created issue by {ID}
|
|
167
|
+
d. Initialize supplements as [] if not present
|
|
168
|
+
e. Append the supplement entry
|
|
169
|
+
f. Set updated_at = NOW_ISO
|
|
170
|
+
g. Rewrite issues.jsonl with updated record
|
|
171
|
+
h. Display: "Added supplement to {ID}"
|
|
172
|
+
- If response is empty: skip supplement step
|
|
173
|
+
```
|
|
138
174
|
|
|
139
|
-
|
|
175
|
+
Cross-milestone conflict check (for supplement issues):
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
6. IF source == "supplement" AND milestone_ref is not null:
|
|
179
|
+
a. Read .workflow/roadmap.md
|
|
180
|
+
b. Identify phases belonging to OTHER milestones (not milestone_ref)
|
|
181
|
+
c. For each other-milestone phase, check if plan.json exists:
|
|
182
|
+
Read .workflow/phases/{NN}-{slug}/plan.json (if exists)
|
|
183
|
+
Collect files_to_create[] as planned_files
|
|
184
|
+
d. IF affected_components in the new issue overlap with planned_files:
|
|
185
|
+
WARNING: "Conflict detected: this supplement issue affects components planned in milestone {other_milestone}"
|
|
186
|
+
Display:
|
|
187
|
+
" Issue affects: {overlapping_components}"
|
|
188
|
+
" Planned in: Phase {NN} ({milestone})"
|
|
189
|
+
Display: "Consider: minimal fix now (supplement), or defer to {other_milestone} for full rework"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Suggest next steps:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
7. Suggest next steps:
|
|
140
196
|
- Skill({ skill: "manage-issue", args: "status {ID}" }) -- View full details
|
|
141
197
|
- Skill({ skill: "manage-issue", args: "link {ID} --task TASK-NNN" }) -- Link to a task
|
|
142
198
|
- Skill({ skill: "manage-issue", args: "list" }) -- List all issues
|
|
@@ -150,11 +206,12 @@ Parse filter options from ARGS:
|
|
|
150
206
|
|
|
151
207
|
```
|
|
152
208
|
Options:
|
|
153
|
-
--status VALUE
|
|
154
|
-
--phase VALUE
|
|
155
|
-
--
|
|
156
|
-
--
|
|
157
|
-
--
|
|
209
|
+
--status VALUE Filter by status (open|in_progress|completed|failed|deferred)
|
|
210
|
+
--phase VALUE Filter by phase_ref
|
|
211
|
+
--milestone VALUE Filter by milestone_ref
|
|
212
|
+
--severity VALUE Filter by severity (critical|high|medium|low)
|
|
213
|
+
--source VALUE Filter by source
|
|
214
|
+
--all Include closed issues from issue-history.jsonl
|
|
158
215
|
```
|
|
159
216
|
|
|
160
217
|
Read and filter:
|
|
@@ -167,6 +224,7 @@ Read and filter:
|
|
|
167
224
|
- If --status: match record.status == VALUE
|
|
168
225
|
- If --phase: match record.phase_ref contains VALUE
|
|
169
226
|
- If --severity: match record.severity == VALUE
|
|
227
|
+
- If --milestone: match record.milestone_ref == VALUE
|
|
170
228
|
- If --source: match record.source == VALUE
|
|
171
229
|
5. Sort by priority (ascending), then severity order (critical > high > medium > low)
|
|
172
230
|
```
|
|
@@ -284,6 +342,7 @@ Options:
|
|
|
284
342
|
--tags TAG1,TAG2 Replace tags
|
|
285
343
|
--add-tag TAG Add a tag
|
|
286
344
|
--phase VALUE Set phase_ref
|
|
345
|
+
--milestone VALUE Set milestone_ref
|
|
287
346
|
--fix-direction TEXT Set fix_direction
|
|
288
347
|
--description TEXT Update description
|
|
289
348
|
--note TEXT Add feedback entry (type=clarification)
|
|
@@ -37,9 +37,9 @@ test -f .workflow/state.json && echo "exists" || echo "missing"
|
|
|
37
37
|
```javascript
|
|
38
38
|
const projectState = {
|
|
39
39
|
initialized: true,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
current_milestone: /* from state.json */,
|
|
41
|
+
latest_artifact: /* last artifact in artifacts[] */,
|
|
42
|
+
milestone_progress: '...', // derived from artifact registry
|
|
43
43
|
phase_artifacts: { brainstorm: false, analysis: false, context: false, plan: false, verification: false, uat: false },
|
|
44
44
|
execution: { tasks_completed: 0, tasks_total: 0 },
|
|
45
45
|
verification_status: 'pending',
|
|
@@ -75,6 +75,10 @@ if (exactMatch[normalized]) {
|
|
|
75
75
|
|
|
76
76
|
#### 3a-2: Structured intent extraction (LLM-native)
|
|
77
77
|
|
|
78
|
+
> **Implementation note**: The runtime (`src/coordinator/intent-router.ts`) currently
|
|
79
|
+
> uses pattern-based regex matching via `chains/_intent-map.json`. The structured
|
|
80
|
+
> extraction below is a design target, not the current implementation.
|
|
81
|
+
|
|
78
82
|
Instead of regex, extract a structured intent tuple using LLM semantic understanding:
|
|
79
83
|
|
|
80
84
|
```json
|
|
@@ -105,7 +109,7 @@ function routeIntent(intent, projectState) {
|
|
|
105
109
|
// Action × Object matrix
|
|
106
110
|
const matrix = {
|
|
107
111
|
'fix': { 'bug': 'debug', 'issue': 'issue', 'code': 'debug', 'performance': 'debug', 'security': 'debug', '_default': 'debug' },
|
|
108
|
-
'create': { 'feature': 'quick', 'issue': 'issue', 'test': 'test_gen', 'spec': 'spec_generate', 'ui': 'ui_design', 'config': 'init', 'phase': '
|
|
112
|
+
'create': { 'feature': 'quick', 'issue': 'issue', 'test': 'test_gen', 'spec': 'spec_generate', 'ui': 'ui_design', 'config': 'init', 'phase': 'roadmap', '_default': 'quick' },
|
|
109
113
|
'analyze': { 'bug': 'analyze', 'issue': 'issue_analyze', 'code': 'analyze', 'codebase': 'spec_map', '_default': 'analyze' },
|
|
110
114
|
'explore': { 'issue': 'issue_discover', 'feature': 'brainstorm', 'ui': 'ui_design', '_default': 'brainstorm' },
|
|
111
115
|
'plan': { 'issue': 'issue_plan', 'spec': 'spec_generate', '_default': 'plan' },
|
|
@@ -115,8 +119,8 @@ function routeIntent(intent, projectState) {
|
|
|
115
119
|
'test': { '_default': 'test' },
|
|
116
120
|
'debug': { '_default': 'debug' },
|
|
117
121
|
'refactor': { '_default': 'refactor' },
|
|
118
|
-
'manage': { 'issue': 'issue', 'milestone': 'milestone_audit', 'phase': '
|
|
119
|
-
'transition':{ 'phase': '
|
|
122
|
+
'manage': { 'issue': 'issue', 'milestone': 'milestone_audit', 'phase': 'milestone_close', 'memory': 'memory', 'doc': 'sync', 'codebase': 'codebase_refresh', 'team': 'team_coordinate', '_default': 'status' },
|
|
123
|
+
'transition':{ 'phase': 'milestone_close', 'milestone': 'milestone_complete', '_default': 'milestone_close' },
|
|
120
124
|
'continue': { '_default': 'state_continue' },
|
|
121
125
|
'sync': { '_default': 'sync' },
|
|
122
126
|
'learn': { '_default': 'learn' },
|
|
@@ -166,18 +170,18 @@ function detectNextAction(s) {
|
|
|
166
170
|
if (s.verification_status === 'passed') {
|
|
167
171
|
if (!s.review_verdict) return { chain: 'review', steps: [{ cmd: 'quality-review', args: '{phase}' }] };
|
|
168
172
|
if (s.uat_status === 'pending') return { chain: 'test', steps: [{ cmd: 'quality-test', args: '{phase}' }] };
|
|
169
|
-
if (s.uat_status === 'passed') return { chain: '
|
|
173
|
+
if (s.uat_status === 'passed') return { chain: 'milestone-close', steps: [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }] };
|
|
170
174
|
return { chain: 'debug', steps: [{ cmd: 'quality-debug', args: '--from-uat {phase}' }] };
|
|
171
175
|
}
|
|
172
176
|
return { chain: 'quality-loop-partial', steps: [{ cmd: 'maestro-plan', args: '{phase} --gaps' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }] };
|
|
173
177
|
}
|
|
174
178
|
if (ps === 'testing') {
|
|
175
|
-
if (s.uat_status === 'passed') return { chain: '
|
|
179
|
+
if (s.uat_status === 'passed') return { chain: 'milestone-close', steps: [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }] };
|
|
176
180
|
return { chain: 'debug', steps: [{ cmd: 'quality-debug', args: '--from-uat {phase}' }] };
|
|
177
181
|
}
|
|
178
182
|
if (ps === 'completed') {
|
|
179
183
|
if (s.phases_completed >= s.phases_total) return { chain: 'milestone-close', steps: [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }] };
|
|
180
|
-
return { chain: '
|
|
184
|
+
return { chain: 'milestone-close', steps: [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }] };
|
|
181
185
|
}
|
|
182
186
|
if (ps === 'blocked') return { chain: 'debug', steps: [{ cmd: 'quality-debug' }] };
|
|
183
187
|
return { chain: 'status', steps: [{ cmd: 'manage-status' }] };
|
|
@@ -205,8 +209,8 @@ const chainMap = {
|
|
|
205
209
|
'retrospective': [{ cmd: 'quality-retrospective', args: '{phase}' }],
|
|
206
210
|
'learn': [{ cmd: 'manage-learn', args: '"{description}"' }],
|
|
207
211
|
'sync': [{ cmd: 'quality-sync', args: '{phase}' }],
|
|
208
|
-
'
|
|
209
|
-
'
|
|
212
|
+
'milestone_close': [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }],
|
|
213
|
+
'roadmap': [{ cmd: 'maestro-roadmap', args: '"{description}"' }],
|
|
210
214
|
'milestone_audit': [{ cmd: 'maestro-milestone-audit' }],
|
|
211
215
|
'milestone_complete': [{ cmd: 'maestro-milestone-complete' }],
|
|
212
216
|
'codebase_rebuild': [{ cmd: 'manage-codebase-rebuild' }],
|
|
@@ -223,6 +227,8 @@ const chainMap = {
|
|
|
223
227
|
'issue_plan': [{ cmd: 'manage-issue-plan', args: '"{description}"' }],
|
|
224
228
|
'issue_execute': [{ cmd: 'manage-issue-execute', args: '"{description}"' }],
|
|
225
229
|
'quick': [{ cmd: 'maestro-quick', args: '"{description}"' }],
|
|
230
|
+
'fork': [{ cmd: 'maestro-fork', args: '-m {milestone_num}' }],
|
|
231
|
+
'merge': [{ cmd: 'maestro-merge', args: '-m {milestone_num}' }],
|
|
226
232
|
'team_lifecycle': [{ cmd: 'team-lifecycle-v4', args: '"{description}"' }],
|
|
227
233
|
'team_coordinate': [{ cmd: 'team-coordinate', args: '"{description}"' }],
|
|
228
234
|
'team_qa': [{ cmd: 'team-quality-assurance', args: '"{description}"' }],
|
|
@@ -234,7 +240,7 @@ const chainMap = {
|
|
|
234
240
|
'spec-driven': [{ cmd: 'maestro-init' }, { cmd: 'maestro-spec-generate', args: '"{description}"' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
|
|
235
241
|
'brainstorm-driven': [{ cmd: 'maestro-brainstorm', args: '"{description}"' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
|
|
236
242
|
'ui-design-driven': [{ cmd: 'maestro-ui-design', args: '{phase}' }, { cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
|
|
237
|
-
'full-lifecycle': [{ cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }, { cmd: 'quality-review', args: '{phase}' }, { cmd: 'quality-test', args: '{phase}' }, { cmd: 'maestro-
|
|
243
|
+
'full-lifecycle': [{ cmd: 'maestro-plan', args: '{phase}' }, { cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }, { cmd: 'quality-review', args: '{phase}' }, { cmd: 'quality-test', args: '{phase}' }, { cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }],
|
|
238
244
|
'execute-verify': [{ cmd: 'maestro-execute', args: '{phase}' }, { cmd: 'maestro-verify', args: '{phase}' }],
|
|
239
245
|
'quality-loop': [{ cmd: 'maestro-verify', args: '{phase}' }, { cmd: 'quality-review', args: '{phase}' }, { cmd: 'quality-test', args: '{phase}' }, { cmd: 'quality-debug', args: '--from-uat {phase}' }, { cmd: 'maestro-plan', args: '{phase} --gaps' }, { cmd: 'maestro-execute', args: '{phase}' }],
|
|
240
246
|
'milestone-close': [{ cmd: 'maestro-milestone-audit' }, { cmd: 'maestro-milestone-complete' }],
|
|
@@ -269,7 +275,8 @@ function resolvePhase() {
|
|
|
269
275
|
// Fallback regex
|
|
270
276
|
const m = intent.match(/phase\s*(\d+)|^(\d+)$/);
|
|
271
277
|
if (m) return m[1] || m[2];
|
|
272
|
-
|
|
278
|
+
// With scratch-based architecture, commands default to milestone-wide when no phase specified
|
|
279
|
+
// Return null to let commands use their default scope routing
|
|
273
280
|
return null;
|
|
274
281
|
}
|
|
275
282
|
|
|
@@ -320,7 +327,7 @@ const state = {
|
|
|
320
327
|
};
|
|
321
328
|
Write(`${sessionDir}/state.json`, JSON.stringify(state, null, 2));
|
|
322
329
|
|
|
323
|
-
const context = {
|
|
330
|
+
const context = { resolved_phase: resolvedPhase, user_intent: intent, issue_id: resolvedIssueId, spec_session_id: null };
|
|
324
331
|
```
|
|
325
332
|
|
|
326
333
|
---
|
|
@@ -338,7 +345,7 @@ const AUTO_FLAG_MAP = {
|
|
|
338
345
|
|
|
339
346
|
function assembleArgs(step) {
|
|
340
347
|
let a = (step.args || '')
|
|
341
|
-
.replace(/\{phase\}/g, context.
|
|
348
|
+
.replace(/\{phase\}/g, context.resolved_phase || '') // empty = milestone-wide default
|
|
342
349
|
.replace(/\{description\}/g, context.user_intent || '')
|
|
343
350
|
.replace(/\{issue_id\}/g, context.issue_id || '')
|
|
344
351
|
.replace(/\{spec_session_id\}/g, context.spec_session_id || '')
|
|
@@ -418,7 +425,7 @@ step.completed_at = new Date().toISOString();
|
|
|
418
425
|
|
|
419
426
|
// Context propagation
|
|
420
427
|
const phaseMatch = output.match(/PHASE:\s*(\d+)/m);
|
|
421
|
-
if (phaseMatch) context.
|
|
428
|
+
if (phaseMatch) context.resolved_phase = phaseMatch[1];
|
|
422
429
|
const specMatch = output.match(/SPEC-[\w-]+/);
|
|
423
430
|
if (specMatch) context.spec_session_id = specMatch[0];
|
|
424
431
|
const scratchMatch = output.match(/scratch_dir:\s*(.+)/m);
|