Spaces:
Runtime error
Runtime error
File size: 25,972 Bytes
a6b96c2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | <purpose>
Interactive command center for managing a milestone from a single terminal. Shows a dashboard of all phases with visual status, dispatches discuss inline and plan/execute as background agents, and loops back to the dashboard after each action. Enables parallel phase work from one terminal.
</purpose>
<required_reading>
Read all files referenced by the invoking prompt's execution_context before starting.
</required_reading>
<process>
<step name="initialize" priority="first">
## 1. Initialize
Bootstrap via manager init:
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "/Users/theogengineer/Projects/Multilingual-Absa/.opencode/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="/Users/theogengineer/Projects/Multilingual-Absa/.opencode/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
INIT=$(gsd_run query init.manager)
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
```
Parse JSON for: `milestone_version`, `milestone_name`, `phase_count`, `completed_count`, `in_progress_count`, `phases`, `recommended_actions`, `all_complete`, `waiting_signal`, `manager_flags`, and the optional trio `queued_milestone_version`, `queued_milestone_name`, `queued_phases` (added in SDK fix `2495-2496-2497` β may be absent on older SDK versions, treat missing as empty).
`manager_flags` contains per-step passthrough flags from config:
- `manager_flags.discuss` β appended to `/gsd-discuss-phase` args (e.g. `"--auto --analyze"`)
- `manager_flags.plan` β appended to plan agent init command
- `manager_flags.execute` β appended to execute agent init command
These are empty strings by default. Set via: `gsd-tools.cjs query config-set manager.flags.discuss "--auto --analyze"`
**If error:** Display the error message and exit.
Display startup banner:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
GSD βΊ MANAGER
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
{milestone_version} β {milestone_name}
{phase_count} phases Β· {completed_count} complete
β Discuss β inline β Plan/Execute β background
Dashboard auto-refreshes when background work is active.
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
Proceed to dashboard step.
</step>
<step name="dashboard">
## 2. Dashboard (Refresh Point)
**Every time this step is reached**, re-read state from disk to pick up changes from background agents:
```bash
INIT=$(gsd_run query init.manager)
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
```
Parse the full JSON. Build the dashboard display.
Build dashboard from JSON. Symbols: `β` done, `β` active, `β` pending, `Β·` queued. Progress bar: 20-char `ββ`.
**Status mapping** (disk_status β D P E Status):
- `complete` β `β β β` `β Complete`
- `partial` β `β β β` `β Executing...`
- `planned` β `β β β` `β Ready to execute`
- `discussed` β `β β Β·` `β Ready to plan`
- `researched` β `β Β· Β·` `β Ready to plan`
- `empty`/`no_directory` + `is_next_to_discuss` β `β Β· Β·` `β Ready to discuss`
- `empty`/`no_directory` otherwise β `Β· Β· Β·` `Β· Up next`
- If `is_active`, replace status icon with `β` and append `(active)`
If any `is_active` phases, show: `β Background: {action} Phase {N}, ...` above grid.
Use `display_name` (not `name`) for the Phase column β it's pre-truncated to 20 chars with `β¦` if clipped. Pad all phase names to the same width for alignment.
Use `deps_display` from init JSON for the Deps column β shows which phases this phase depends on (e.g. `1,3`) or `β` for none.
Example output:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
GSD βΊ DASHBOARD
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββ 60% (3/5 phases)
β Background: Planning Phase 4
| # | Phase | Deps | D | P | E | Status |
|---|----------------------|------|---|---|---|---------------------|
| 1 | Foundation | β | β | β | β | β Complete |
| 2 | API Layer | 1 | β | β | β | β Executing (active)|
| 3 | Auth System | 1 | β | β | β | β Ready to execute |
| 4 | Dashboard UI & Setβ¦ | 1,2 | β | β | Β· | β Planning (active) |
| 5 | Notifications | β | β | Β· | Β· | β Ready to discuss |
| 6 | Polish & Final Mail⦠| 1-5 | · | · | · | · Up next |
```
**Queued section (next milestone preview):**
If `queued_phases` is present and non-empty, render a compact preview of the next milestone's phases directly below the main table. This surfaces upcoming work without cluttering the active-milestone grid. Skip this section entirely when `queued_phases` is empty or missing (e.g. the active milestone is the last one in the roadmap).
Use `queued_milestone_version` and `queued_milestone_name` for the header. Phases render without D/P/E columns since they aren't discussed yet β just number, name (pre-truncated `display_name`), dependencies (`deps_display`), and a fixed `Β· Queued` status. Phase-name padding should match the active-table column width for visual alignment.
Example:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Queued β {queued_milestone_version} {queued_milestone_name} ({queued_phases.length} phases)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| # | Phase | Deps | Status |
|---|----------------------|------|--------------|
| 31| Email Logs | β | Β· Queued |
| 32| Today's Sheets | 31 | Β· Queued |
| 33| Resend Backfill | 31 | Β· Queued |
| 34| Business Day Audit | 31 | Β· Queued |
```
Queued phases are NOT eligible for the Continue action menu β they live in a future milestone and must wait for the current milestone to ship. The preview exists purely for situational awareness.
**Recommendations section:**
If `all_complete` is true:
```
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MILESTONE COMPLETE β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
All {phase_count} phases done. Ready for final steps:
β /gsd-verify-work β run acceptance testing
β /gsd-complete-milestone β archive and wrap up
```
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `question` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-the agent runtimes (OpenAI Codex, Gemini CLI, etc.) where `question` is not available.
Ask user via question:
- **question:** "All phases complete. What next?"
- **options:** "Verify work" / "Complete milestone" / "Exit manager"
Handle responses:
- "Verify work": `Skill(skill="gsd-verify-work")` then loop to dashboard.
- "Complete milestone": `Skill(skill="gsd-complete-milestone")` then exit.
- "Exit manager": Go to exit step.
**If NOT all_complete**, build compound options from `recommended_actions`:
**Compound option logic:** Group background actions (plan/execute) together, and pair them with the single inline action (discuss) when one exists. The goal is to present the fewest options possible β one option can dispatch multiple background agents plus one inline action.
**Building options:**
1. Collect all background actions (execute and plan recommendations) β there can be multiple of each.
2. Collect the inline action (discuss recommendation, if any β there will be at most one since discuss is sequential).
3. Build compound options:
**If there are ANY recommended actions (background, inline, or both):**
Create ONE primary "Continue" option that dispatches ALL of them together:
- Label: `"Continue"` β always this exact word
- Below the label, list every action that will happen. Enumerate ALL recommended actions β do not cap or truncate:
```
Continue:
β Execute Phase 32 (background)
β Plan Phase 34 (background)
β Discuss Phase 35 (inline)
```
- This dispatches all background agents first, then runs the inline discuss (if any).
- If there is no inline discuss, the dashboard refreshes after spawning background agents.
**Important:** The Continue option must include EVERY action from `recommended_actions` β not just 2. If there are 3 actions, list 3. If there are 5, list 5.
4. Always add:
- `"Refresh dashboard"`
- `"Exit manager"`
Display recommendations compactly:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΆ Next Steps
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Continue:
β Execute Phase 32 (background)
β Plan Phase 34 (background)
β Discuss Phase 35 (inline)
```
**Auto-refresh:** If background agents are running (`is_active` is true for any phase), set a 60-second auto-refresh cycle. After presenting the action menu, if no user input is received within 60 seconds, automatically refresh the dashboard. This interval is configurable via `manager_refresh_interval` in GSD config (default: 60 seconds, set to 0 to disable).
Present via question:
- **question:** "What would you like to do?"
- **options:** (compound options as built above + refresh + exit, question auto-adds "Other")
**On "Other" (free text):** Parse intent β if it mentions a phase number and action, dispatch accordingly. If unclear, display available actions and loop to action_menu.
Proceed to handle_action step with the selected action.
</step>
<step name="handle_action">
## 4. Handle Action
### Refresh Dashboard
Loop back to dashboard step.
### Exit Manager
Go to exit step.
### Compound Action (background + inline)
When the user selects a compound option, behavior depends on the runtime β the Plan Phase N / Execute Phase N handlers below resolve it via `gsd_run query config-get runtime`:
- **On Claude Code:** a backgrounded agent cannot nest the pipeline's subagents, so run the chosen plan/execute step(s) **inline** via their handlers below (in order), then run the inline discuss. There is no overlap.
- **On other runtimes:** **Spawn all background agents first** (plan/execute) β dispatch them in parallel using the Plan Phase N / Execute Phase N handlers below β then run the inline discuss; the background agents continue while you discuss.
Inline discuss:
```
Skill(skill="gsd-discuss-phase", args="{PHASE_NUM} {manager_flags.discuss}")
```
After discuss completes, loop back to dashboard step.
### Discuss Phase N
Discussion is interactive β needs user input. Run inline with any configured flags:
```
Skill(skill="gsd-discuss-phase", args="{PHASE_NUM} {manager_flags.discuss}")
```
After discuss completes, loop back to dashboard step.
### Plan Phase N
Planning runs autonomously. **First resolve the runtime.** On Claude Code a backgrounded agent has no `Agent`/`Task` tool, so it cannot spawn the plan-checker the pipeline relies on β backgrounding it there silently turns `workflow.plan_check` into a self-check. So run plan **inline** on Claude Code, and **background** it only on runtimes where a backgrounded agent can still nest subagents.
```bash
RUNTIME=$(gsd_run query config-get runtime --default claude 2>/dev/null || echo "claude")
```
**If `RUNTIME` is `claude` (Claude Code):** Run plan inline so the plan-checker and quality gates actually run β do NOT wrap it in `Agent(run_in_background=true, β¦)`:
```
Skill(skill="gsd-plan-phase", args="{N} --auto {manager_flags.plan}")
```
Display while it runs:
```
β Planning Phase {N}: {phase_name}... (runs inline so the plan-checker runs β the dashboard resumes when it returns, ~1β5 min; expected, not a freeze)
```
Then loop back to dashboard step.
**If `RUNTIME` is not `claude` (e.g. Codex):** Spawn a background agent that delegates to the Skill pipeline with any configured flags:
```
Agent(
description="Plan phase {N}: {phase_name}",
run_in_background=true,
prompt="You are running the GSD plan-phase workflow for phase {N} of the project.
Working directory: {cwd}
Phase: {N} β {phase_name}
Goal: {goal}
Manager flags: {manager_flags.plan}
Run the plan-phase Skill with any configured manager flags:
Skill(skill=\"gsd-plan-phase\", args=\"{N} --auto {manager_flags.plan}\")
This delegates to the full plan-phase pipeline including local patches, research, plan-checker, and all quality gates.
Important: You are running in the background. Do NOT use question β make autonomous decisions based on project context. If you hit a blocker, write it to STATE.md as a blocker and stop. Do NOT silently work around permission or file access errors β let them fail so the manager can surface them with resolution hints. Do NOT use --no-verify on git commits."
)
```
> **ORCHESTRATOR RULE β NON-CLAUDE RUNTIME**: After calling Agent() above with `run_in_background=true`, do NOT do any planning work for this phase independently. Return to the dashboard immediately and wait for the background agent to report back. Only resume planning-related work when the subagent result is available.
Display:
```
β Spawning planner for Phase {N}: {phase_name}... (runs in a subagent β no output until it returns, ~1β5 min; expected, not a freeze)
```
Loop back to dashboard step.
### Execute Phase N
Execution runs autonomously. **First resolve the runtime.** On Claude Code a backgrounded agent has no `Agent`/`Task` tool, so it cannot spawn the per-plan worktree-isolated executors or the verifier β backgrounding it there silently disables `workflow.use_worktrees` isolation and `workflow.verifier`. So run execute **inline** on Claude Code, and **background** it only on runtimes where a backgrounded agent can still nest subagents.
```bash
RUNTIME=$(gsd_run query config-get runtime --default claude 2>/dev/null || echo "claude")
```
**If `RUNTIME` is `claude` (Claude Code):** Run execute inline so worktree isolation and the verifier actually run β do NOT wrap it in `Agent(run_in_background=true, β¦)`:
```
Skill(skill="gsd-execute-phase", args="{N} {manager_flags.execute}")
```
Display while it runs:
```
β Executing Phase {N}: {phase_name}... (runs inline so worktree isolation and verification run β the dashboard resumes when it returns; expected, not a freeze)
```
Then loop back to dashboard step.
**If `RUNTIME` is not `claude` (e.g. Codex):** Spawn a background agent that delegates to the Skill pipeline with any configured flags:
```
Agent(
description="Execute phase {N}: {phase_name}",
run_in_background=true,
prompt="You are running the GSD execute-phase workflow for phase {N} of the project.
Working directory: {cwd}
Phase: {N} β {phase_name}
Goal: {goal}
Manager flags: {manager_flags.execute}
Run the execute-phase Skill with any configured manager flags:
Skill(skill=\"gsd-execute-phase\", args=\"{N} {manager_flags.execute}\")
This delegates to the full execute-phase pipeline including local patches, branching, wave-based execution, verification, and all quality gates.
Important: You are running in the background. Do NOT use question β make autonomous decisions. Do NOT use --no-verify on git commits β let pre-commit hooks run normally. If you hit a permission error, file lock, or any access issue, do NOT work around it β let it fail and write the error to STATE.md as a blocker so the manager can surface it with resolution guidance."
)
```
> **ORCHESTRATOR RULE β NON-CLAUDE RUNTIME**: After calling Agent() above with `run_in_background=true`, do NOT do any execution work for this phase independently. Return to the dashboard immediately and wait for the background agent to report back. Only resume execution-related work when the subagent result is available.
Display:
```
β Spawning executor for Phase {N}: {phase_name}... (runs in a subagent β no output until it returns, ~1β5 min; expected, not a freeze)
```
Loop back to dashboard step.
</step>
<step name="background_completion">
## 5. Background Agent Completion
When notified that a background agent completed:
1. Read the result message from the agent.
2. Display a brief notification:
```
β {description}
{brief summary from agent result}
```
3. Loop back to dashboard step.
**If the agent reported an error or blocker:**
Classify the error:
**Permission / tool access error** (e.g. tool not allowed, permission denied, sandbox restriction):
- Parse the error to identify which tool or command was blocked.
- Display the error clearly, then offer to fix it:
- **question:** "Phase {N} failed β permission denied for `{tool_or_command}`. Want me to add it to settings.local.json so it's allowed?"
- **options:** "Add permission and retry" / "Run this phase inline instead" / "Skip and continue"
- "Add permission and retry": Use `Skill(skill="update-config")` to add the permission to `settings.local.json`, then re-spawn the background agent. Loop to dashboard.
- "Run this phase inline instead": Dispatch the same action inline via the appropriate Skill β use `Skill(skill="gsd-plan-phase", args="{N}")` if the failed action was planning, or `Skill(skill="gsd-execute-phase", args="{N}")` if the failed action was execution. Loop to dashboard after.
- "Skip and continue": Loop to dashboard (phase stays in current state).
**Other errors** (git lock, file conflict, logic error, etc.):
- Display the error, then offer options via question:
- **question:** "Background agent for Phase {N} encountered an issue: {error}. What next?"
- **options:** "Retry" / "Run inline instead" / "Skip and continue" / "View details"
- "Retry": Re-spawn the same background agent. Loop to dashboard.
- "Run inline instead": Dispatch the action inline via the appropriate Skill β use `Skill(skill="gsd-plan-phase", args="{N}")` if the failed action was planning, or `Skill(skill="gsd-execute-phase", args="{N}")` if the failed action was execution. Loop to dashboard after.
- "Skip and continue": Loop to dashboard (phase stays in current state).
- "View details": Read STATE.md blockers section, display, then re-present options.
</step>
<step name="exit">
## 6. Exit
Display final status with progress bar:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
GSD βΊ SESSION END
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
{milestone_version} β {milestone_name}
{PROGRESS_BAR} {progress_pct}% ({completed_count}/{phase_count} phases)
Resume anytime: /gsd-manager
βββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
**Note:** Any background agents still running will continue to completion. Their results will be visible on next `/gsd-manager` or `/gsd-progress` invocation.
</step>
</process>
<success_criteria>
- [ ] Dashboard displays all phases with correct status indicators (D/P/E/V columns)
- [ ] Progress bar shows accurate completion percentage
- [ ] Dependency resolution: blocked phases show which deps are missing
- [ ] Recommendations prioritize: execute > plan > discuss
- [ ] Discuss phases run inline via Skill() β interactive questions work
- [ ] Plan phases spawn background Task agents β return to dashboard immediately
- [ ] Execute phases spawn background Task agents β return to dashboard immediately
- [ ] Dashboard refreshes pick up changes from background agents via disk state
- [ ] Background agent completion triggers notification and dashboard refresh
- [ ] Background agent errors present retry/skip options
- [ ] All-complete state offers verify-work and complete-milestone
- [ ] Exit shows final status with resume instructions
- [ ] "Other" free-text input parsed for phase number and action
- [ ] Manager loop continues until user exits or milestone completes
- [ ] Queued section renders when `queued_phases` is non-empty; skipped when absent or empty
</success_criteria>
|