From 1246202b0e5edd62fb402cdd1fd757dc27bed824 Mon Sep 17 00:00:00 2001 From: Roman Kiprin Date: Tue, 7 Apr 2026 20:07:04 -0500 Subject: [PATCH 1/2] Add M-TRANSLATE workflow and update agent call syntax in workflows --- CHANGELOG.md | 16 + assets/antipatterns.toml | 1 + assets/configs/config.json | 6 +- assets/prompts/M-TRANSLATE.md | 329 ++++++++++++++++++ gsd-opencode/commands/gsd/gsd-set-profile.md | 1 - .../workflows/discovery-phase.md | 2 +- .../workflows/discuss-phase-assumptions.md | 4 +- .../get-shit-done/workflows/discuss-phase.md | 13 +- 8 files changed, 358 insertions(+), 14 deletions(-) create mode 100644 assets/prompts/M-TRANSLATE.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ef077849..ca320790 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.33.1] - 2026-04-07 + +Overview: Added M-TRANSLATE.md workflow for sync from upstream GSD, updated gsd-set-profile to remove model constraint, converted task() calls to @subagent syntax, and enhanced discovery and discuss-phase workflows. + +### Added + +- `M-TRANSLATE.md` workflow for copying and translating changes from upstream GSD repository to OpenCode equivalents in `assets/prompts/M-TRANSLATE.md` +- `model: haiku` to forbidden strings list in `assets/antipatterns.toml` to prevent incorrect model assignments + +### Changed + +- Removed `model: haiku` constraint from `gsd-set-profile.md` command in `gsd-opencode/commands/gsd/gsd-set-profile.md` to allow dynamic model assignment +- Converted `task()` function calls to `@subagent_type` shorthand syntax in `gsd-opencode/get-shit-done/workflows/discuss-phase-assumptions.md` and `gsd-opencode/get-shit-done/workflows/discuss-phase.md` +- Updated agent call syntax from `task()` to `@subagent_type prompt` format in discuss-phase workflow in `gsd-opencode/get-shit-done/workflows/discuss-phase.md` +- Enhanced discovery-phase workflow with improved formatting for library resolution in `gsd-opencode/get-shit-done/workflows/discovery-phase.md` + ## [1.33.0] - 2026-04-06 Overview: Major upstream sync from GSD v1.33.0 introducing security auditing pipeline, automated documentation generation with codebase verification, dependency analysis, and discuss-phase power mode. Enhanced planner with scope reduction prohibition and decision coverage matrices. Added response language support, worktree isolation control, Kilo runtime support, and schema drift detection across 150 files. diff --git a/assets/antipatterns.toml b/assets/antipatterns.toml index 32b83b8d..177dd692 100644 --- a/assets/antipatterns.toml +++ b/assets/antipatterns.toml @@ -34,4 +34,5 @@ forbidden_strings = [ "workflows/set-profile.md", "quality/balanced/budget", 'gsd:update\\|GSD update\\|gsd-install', + 'model: haiku' ] diff --git a/assets/configs/config.json b/assets/configs/config.json index 177c4f3b..19e7c7d5 100644 --- a/assets/configs/config.json +++ b/assets/configs/config.json @@ -504,7 +504,11 @@ "replacement": "ALWAYS use `@gsd-{agent}` call (e.g., `@gsd-phase-researcher`, `@gsd-executor`, `@gsd-planner`)", "description": "gsd-opencode/get-shit-done/references/universal-anti-patterns.md" }, - + { + "pattern": "model: haiku\n", + "replacement": "", + "description": "gsd-set-profile.md" + }, { "pattern": "label: \"Budget\"", "replacement": "label: \"Genius (most flexible)\"", diff --git a/assets/prompts/M-TRANSLATE.md b/assets/prompts/M-TRANSLATE.md new file mode 100644 index 00000000..821a53b0 --- /dev/null +++ b/assets/prompts/M-TRANSLATE.md @@ -0,0 +1,329 @@ +# Copy and Translate: Sync from Original GSD to OpenCode + +> **Purpose**: Copy files from the upstream GSD submodule (`original/get-shit-done/`) into the working folder (`gsd-opencode/`), then translate all Claude Code artifacts to OpenCode equivalents, and validate that no forbidden patterns remain. + +--- + +## Context + +This project maintains `gsd-opencode/` as an adapted fork of the upstream `original/get-shit-done/` submodule. The sync workflow has four phases: + +2. **Translate** -- replace Claude Code naming, paths, tools, and commands with OpenCode equivalents +3. **Add Agents Mode** -- inject `mode: subagent` into all agent definition files +4. **Modify Agent Calls** -- replace `task()` calls with `@subagent_type` shorthand syntax +5. **Validate** -- ensure zero forbidden strings remain in the translated files + +### Tools + +| Tool | Script | Documentation | +|------|--------|---------------| +| copy-service | `assets/bin/gsd-copy-from-original.js` | `assets/bin/GSD-COPY-FROM-ORIGINAL.md` | +| translate-service | `assets/bin/gsd-translate-in-place.js` | `assets/bin/GSD-TRANSLATE-IN-PLACE.md` | +| forbidden-strings-checker | `assets/bin/check-forbidden-strings.js` | `assets/bin/CHECK-FORBIDDEN-STRINGS.md` | + +### Critical Rule: Protect OpenCode-Specific Files + +**Never overwrite, modify, or delete any file or folder whose name contains `oc-` or `-oc-`.** These are OpenCode-native additions that do not exist in the upstream. The exclude rules in `assets/configs/config.json` (`**/oc-*`, `**/*-oc-*`) enforce this, but you must also verify it manually. + + +--- + +## Step 2: Translate Claude Code Artifacts to OpenCode + +The primary config is `assets/configs/config.json`. It contains all translation rules (URLs, paths, commands, tool names, profile names, colors, HTML tags, etc.). + +--- +## Step 2A: Modify Agent Calls + +Replace `task()` function calls with the OpenCode `@subagent_type` shorthand syntax. The config `assets/configs/remove-task.json` contains regex rules that match the most common `task()` call patterns found in commands, workflows, references, and templates. + +**Scope**: Only files in `gsd-opencode/commands/gsd/`, `gsd-opencode/get-shit-done/references/`, `gsd-opencode/get-shit-done/templates/`, and `gsd-opencode/get-shit-done/workflows/`. + +**What gets replaced** (examples): + +``` +# Before (multiline variable prompt) +task( + prompt=filled_prompt, + subagent_type="gsd-phase-researcher", + model="{researcher_model}", + description="Research Phase {phase}" +) + +# After +@gsd-phase-researcher filled_prompt +``` + +``` +# Before (single-line quoted prompt) +task(prompt="Stack research", subagent_type="gsd-project-researcher", model="{researcher_model}", description="Stack research") + +# After +@gsd-project-researcher "Stack research" +``` + +``` +# Before (triple-quoted prompt) +task( + prompt="""...""", + subagent_type="gsd-planner", + model="{planner_model}", + description="Plan Phase {phase}" +) + +# After +@gsd-planner """...""" +``` + +**What does NOT get replaced**: Prose references to `subagent_type=` inside inline code spans (e.g., `` `subagent_type="gsd-executor"` ``) are left untouched -- they are documentation, not function calls. + +### 2Aa. Preview + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/remove-task.json --show-diff +``` + +**What to check:** +- Files affected are only within the scoped directories (commands, references, templates, workflows) +- Each diff shows a `task(...)` call replaced with an `@subagent_type ...` shorthand +- No `oc-` or `-oc-` files appear in the output +- Prose references (inside backticks) are NOT modified +- Verify the extracted prompt value is correct for each replacement (no truncated prompts) + +**Common issues to watch for:** +- **Truncated multiline prompts**: Some `task()` calls have massive multi-line prompts (50+ lines). If a replacement looks like it captured only part of the prompt, note it for manual review. +- **Expression prompts**: Prompts using string concatenation (`+`) may only capture the first segment -- verify these replacements look correct. +- **Unmatched calls**: Not every `task()` variant is covered by regex. Complex patterns (deeply indented, extra args in unusual positions) may need manual conversion. + +### 2Ab. Apply + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/remove-task.json --apply +``` + +### 2Ac. Verify + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/remove-task.json +``` + +**Expected output**: 0 changes remaining (all matching `task()` calls already replaced). + +### 2Ad. Manual review of unmatched calls + +After apply, search for any remaining `task(` calls with `gsd-` subagent types that were not auto-replaced: + +```bash +grep -rn 'subagent_type="gsd-' gsd-opencode/commands/gsd/ gsd-opencode/get-shit-done/references/ gsd-opencode/get-shit-done/templates/ gsd-opencode/get-shit-done/workflows/ || echo "No remaining task() calls" +``` + +If results are found: +- Check if each is a prose reference (inside backticks or plain text) -- these are correct to leave as-is +- If any are actual `task()` calls that the regex missed, convert them manually following the pattern: `@subagent_type prompt_value` + + +--- + +## Step 2B: Add Agents Mode + +Add `mode: subagent` declaration to all agent definition files. See [M-ADD-AGENTS-MODE.md](./M-ADD-AGENTS-MODE.md) for details. + +### 2Ba. Preview + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/add-agent-mode.json --show-diff +``` + +**What to check:** +- All agent files in `gsd-opencode/agents/` are listed +- Each file shows exactly one replacement: `mode: subagent` added after `description:` +- No duplicate `mode:` lines are created (files with existing `mode:` are skipped) + +### 2Bb. Apply + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/add-agent-mode.json --apply +``` + +### 2Bc. Verify + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/add-agent-mode.json +``` + +**Expected output**: 0 changes remaining (all agent files have `mode: subagent`). + +--- + +## Step 3: Translate -- Supplemental Rules (If Needed) + +### 3a. Preview translations + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/config.json --show-diff +``` + +**What to check:** +- Number of files affected and total replacements +- Scan the diffs for any unexpected changes (false positives) +- Verify no `oc-` or `-oc-` files appear in the output + +### 3b. Apply translations + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/config.json --apply +``` + +### 3c. Verify translations applied + +```bash +node assets/bin/gsd-translate-in-place.js assets/configs/config.json +``` + +**Expected output**: 0 changes remaining (all patterns already translated). + +--- + +## Step 4: Validate -- Check for Forbidden Strings + +```bash +node assets/bin/check-forbidden-strings.js +``` + +This reads `assets/antipatterns.toml` and scans `gsd-opencode/*.md` for forbidden strings like `Claude`, `~/.claude`, `/gsd:`, ``, etc. + +### If NO violations found + +The workflow is complete. Produce a final summary report: + +- Files copied in Step 1 (count) +- Files translated in Step 2 (count, total replacements) +- Forbidden strings check: PASSED +- Confirm no `oc-` / `-oc-` files were modified + +**Stop here.** + +### If violations ARE found + +Forbidden strings remain that the base config did not cover. You must create a supplemental config and re-translate: + +#### 4a. Create a version-specific config file + +File path: `assets/configs/$VERSION.json` (e.g., `assets/configs/v1.22.4.json`) + +Structure the config to target only the remaining violations from Step 4: + +```json +{ + "_description": "Supplemental translation rules for $VERSION -- fixes remaining forbidden strings", + "include": ["gsd-opencode/**"], + "exclude": [ + "node_modules/**", + ".git/**", + ".translate-backups/**", + "**/oc-*", + "**/*-oc-*" + ], + "rules": [ + { + "pattern": "", + "replacement": "", + "description": "Fix: " + } + ] +} +``` + +**Guidelines for writing rules:** +- Examine each violation line in context to determine the correct replacement +- Use `caseSensitive: true` when the pattern is case-specific +- Order rules from most-specific to least-specific (longer patterns first) +- Do not duplicate rules already in `assets/configs/config.json` + +#### 4b. Re-run translation with both configs + +```bash +# Preview +node assets/bin/gsd-translate-in-place.js assets/configs/config.json assets/configs/$VERSION.json --show-diff + +# Apply +node assets/bin/gsd-translate-in-place.js assets/configs/config.json assets/configs/$VERSION.json --apply +``` + +#### 4c. Re-run forbidden strings check + +```bash +node assets/bin/check-forbidden-strings.js +``` + +#### 4d. Iterate if needed + +Repeat steps 4a-4c. **Maximum 3 iterations.** If violations persist after 3 attempts: +- List remaining violations with file paths and line numbers +- Explain why each could not be auto-fixed (may require manual context-aware edits) +- Stop and report to the user for manual resolution + +--- + +## Final Report Template + +When the workflow completes (forbidden strings check passes), produce this report: + +``` +## Sync Report + +**Submodule version**: $VERSION +**Date**: YYYY-MM-DD + +### Step 1: Copy +- Files copied: N +- Diverged files: N (overwritten / skipped) +- Orphaned files: N (preserved) + +### Step 2: Translate +- Config(s) used: assets/configs/config.json [, assets/configs/$VERSION.json] +- Files modified: N +- Total replacements: N + +### Step 2B: Add Agents Mode +- Config used: assets/configs/add-agent-mode.json +- Agent files processed: N +- Files with mode added: N +- Files skipped (already had mode): N + +### Step 2C: Modify Agent Calls +- Config used: assets/configs/remove-task.json +- Files modified: N +- Total task() calls replaced: N +- Manual conversions needed: N (list files if any) + +### Step 4: Validate +- Forbidden strings check: PASSED +- Iterations required: N + +### Protected Files +- oc-/\-oc- files verified untouched: YES +``` + +--- + +## Error Recovery + +If anything goes wrong at any step: + +| Problem | Recovery | +|---------|----------| +| Copy corrupted files | Restore from `.planning/backups/` (auto-created by copy-service) | +| Translation produced wrong output | Restore from `.translate-backups/` (auto-created by translate-service) | +| Need to start over completely | `git checkout -- gsd-opencode/` to reset all changes | + +--- + +## Constraints + +- **Never modify** files/folders with `oc-` or `-oc-` in the name +- **Always preview** before applying (both copy and translate) +- **Always verify** after applying (re-run in dry-run mode) +- **Always validate** with the forbidden strings checker before declaring success +- **Config files go in** `assets/configs/` (not `assets/config/`) +- **Translation scope is** `gsd-opencode/**` only -- never translate files in `assets/`, `original/`, or project root diff --git a/gsd-opencode/commands/gsd/gsd-set-profile.md b/gsd-opencode/commands/gsd/gsd-set-profile.md index a6075e54..9816cada 100644 --- a/gsd-opencode/commands/gsd/gsd-set-profile.md +++ b/gsd-opencode/commands/gsd/gsd-set-profile.md @@ -2,7 +2,6 @@ name: gsd-set-profile description: Switch model profile for GSD agents (simple/smart/genius/inherit) argument-hint: -model: haiku permissions: bash: true --- diff --git a/gsd-opencode/get-shit-done/workflows/discovery-phase.md b/gsd-opencode/get-shit-done/workflows/discovery-phase.md index 4f6a8179..1b4388a3 100644 --- a/gsd-opencode/get-shit-done/workflows/discovery-phase.md +++ b/gsd-opencode/get-shit-done/workflows/discovery-phase.md @@ -93,7 +93,7 @@ For: Choosing between options, new external integration. ``` For each library/framework: - - mcp__context7__resolve-library-id + - mcp__context7__resolve-library-id - mcp__context7__get-library-docs (mode: "code" for API, "info" for concepts) ``` diff --git a/gsd-opencode/get-shit-done/workflows/discuss-phase-assumptions.md b/gsd-opencode/get-shit-done/workflows/discuss-phase-assumptions.md index 49185fb6..5cabd3fd 100644 --- a/gsd-opencode/get-shit-done/workflows/discuss-phase-assumptions.md +++ b/gsd-opencode/get-shit-done/workflows/discuss-phase-assumptions.md @@ -310,7 +310,7 @@ Parse the subagent's response. Extract: If research topics were flagged, spawn a general research agent: ``` -task(subagent_type="general", prompt=""" +@general """ Research the following topics for Phase {PHASE}: {phase_name}. Topics needing research: @@ -323,7 +323,7 @@ For each topic, return: Use Context7 (resolve-library-id then query-docs) for library-specific questions. Use websearch for ecosystem/best-practice questions. -""") +""" ``` Merge findings back into assumptions: diff --git a/gsd-opencode/get-shit-done/workflows/discuss-phase.md b/gsd-opencode/get-shit-done/workflows/discuss-phase.md index 63100b8e..04f3b7ab 100644 --- a/gsd-opencode/get-shit-done/workflows/discuss-phase.md +++ b/gsd-opencode/get-shit-done/workflows/discuss-phase.md @@ -551,10 +551,9 @@ After user selects gray areas in present_gray_areas, spawn parallel research age 1. Display brief status: "Researching {N} areas..." -2. For EACH user-selected gray area, spawn a task() in parallel: +2. For EACH user-selected gray area, spawn a relevant subagent using `@subagent prompt` syntax in parallel: - task( - prompt="First, read @$HOME/.config/opencode/agents/gsd-advisor-researcher.md for your role and instructions. + @gsd-advisor-researcher "First, read @$HOME/.config/opencode/agents/gsd-advisor-researcher.md for your role and instructions. {area_name}: {area_description from gray area identification} {phase_goal and description from ROADMAP.md} @@ -562,13 +561,9 @@ After user selects gray areas in present_gray_areas, spawn parallel research age {resolved calibration tier: full_maturity | standard | minimal_decisive} Research this gray area and return a structured comparison table with rationale. - ${AGENT_SKILLS_ADVISOR}", - subagent_type="general", - model="{ADVISOR_MODEL}", - description="Research: {area_name}" - ) + ${AGENT_SKILLS_ADVISOR}" - All task() calls spawn simultaneously — do NOT wait for one before starting the next. + All subagents spawn simultaneously — do NOT wait for one before starting the next. 3. After ALL agents return, SYNTHESIZE results before presenting: For each agent's return: From 8298b01ceb44d1f602bd5cbeaa4f3f1352ceb796 Mon Sep 17 00:00:00 2001 From: Roman Kiprin Date: Sun, 12 Apr 2026 19:57:39 -0500 Subject: [PATCH 2/2] Add Agent() translation rule for OpenCode compatibility - Add rule 21 in remove-task.json to convert Agent(description=..., run_in_background=true, prompt=...) calls to @gsd- shorthand - Extract agent name dynamically from skill="gsd:" patterns - Convert Agent() calls in autonomous.md to @gsd-plan-phase and @gsd-execute-phase - Update CHANGELOG.md with v1.33.2 release notes - Update README.md with v1.33.2 overview --- CHANGELOG.md | 13 +++++++++++++ README.md | 4 ++++ assets/configs/remove-task.json | 8 ++++++++ gsd-opencode/get-shit-done/workflows/autonomous.md | 12 ++---------- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca320790..84fe5775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,19 @@ Overview: Added M-TRANSLATE.md workflow for sync from upstream GSD, updated gsd- - Updated agent call syntax from `task()` to `@subagent_type prompt` format in discuss-phase workflow in `gsd-opencode/get-shit-done/workflows/discuss-phase.md` - Enhanced discovery-phase workflow with improved formatting for library resolution in `gsd-opencode/get-shit-done/workflows/discovery-phase.md` +## [1.33.2] - 2026-04-12 + +Overview: Added regex translation rule for Agent() background task calls in autonomous workflows, converting OpenCode-incompatible Agent() syntax to @gsd-xxx shorthand with dynamic agent name extraction. + +### Added + +- Translation rule 21 in `assets/configs/remove-task.json` for converting `Agent(description=..., run_in_background=true, prompt=...)` calls to `@gsd-` shorthand syntax, extracting agent name from `skill="gsd:"` patterns + +### Changed + +- Converted `Agent()` background task dispatch calls to `@gsd-plan-phase` and `@gsd-execute-phase` shorthand in `gsd-opencode/get-shit-done/workflows/autonomous.md` for OpenCode compatibility +- Updated skill invocation syntax from `skill="gsd:plan-phase"` to `skill="gsd-plan-phase"` (colon to dash) in autonomous workflow agent prompts + ## [1.33.0] - 2026-04-06 Overview: Major upstream sync from GSD v1.33.0 introducing security auditing pipeline, automated documentation generation with codebase verification, dependency analysis, and discuss-phase power mode. Enhanced planner with scope reduction prohibition and decision coverage matrices. Added response language support, worktree isolation control, Kilo runtime support, and schema drift detection across 150 files. diff --git a/README.md b/README.md index 4e999f86..2c4bcad6 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,10 @@ I just love both GSD and OpenCode. I felt like having GSD available only for Cla — **Roman** +## Version 1.33.2 + +Added support for translating `Agent()` background task calls to OpenCode-compatible `@gsd-` shorthand syntax. The new translation rule 21 in `assets/configs/remove-task.json` dynamically extracts agent names from `skill="gsd-"` patterns and converts them to the OpenCode format. This update fixes two `Agent()` calls in `autonomous.md` workflow for plan and execute phase dispatch, ensuring full OpenCode compatibility. + ## Version 1.33.0 Again we keep up with the original GSDv1 [v1.33.0](https://github.com/gsd-build/get-shit-done/releases/tag/v1.33.0) (2026-04-04). diff --git a/assets/configs/remove-task.json b/assets/configs/remove-task.json index 6c568af7..1ea347d3 100644 --- a/assets/configs/remove-task.json +++ b/assets/configs/remove-task.json @@ -208,6 +208,14 @@ "isRegex": true, "caseSensitive": true, "description": "Replace task(subagent_type=general, prompt=triple-quoted) with @general shorthand" + }, + { + "_comment": "21. Agent() with skill(skill=\"gsd:xxx\", ...) in prompt → @gsd-xxx shorthand", + "pattern": "Agent\\(\\s*\\r?\\n\\s*description=\"[^\"]*\",\\s*\\r?\\n\\s*run_in_background=true,\\s*\\r?\\n\\s*prompt=\"Run ([^\"]+) for phase \\$\\{PHASE_NUM\\}: skill\\(skill=\\\\\"gsd:([^\\\\\"]+)\\\\\", args=\\\\\"([^\\\\\"]+)\\\\\"\\)\"\\s*\\r?\\n\\s*\\)", + "replacement": "@gsd-$2 \"Run $1 for phase ${PHASE_NUM}: skill(skill=\\\"gsd-$2\\\", args=\\\"$3\\\")\"", + "isRegex": true, + "caseSensitive": true, + "description": "Replace Agent() with gsd skill reference to @gsd-xxx shorthand, extracting agent name from skill=\"gsd:xxx\" and converting to gsd-xxx" } ] } diff --git a/gsd-opencode/get-shit-done/workflows/autonomous.md b/gsd-opencode/get-shit-done/workflows/autonomous.md index e60e10de..1a26f41d 100644 --- a/gsd-opencode/get-shit-done/workflows/autonomous.md +++ b/gsd-opencode/get-shit-done/workflows/autonomous.md @@ -319,11 +319,7 @@ UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1) **If `INTERACTIVE` is set:** Dispatch plan as a background agent to keep the main context lean. While plan runs, the workflow can immediately start discussing the next phase (see step 4). ``` -Agent( - description="Plan phase ${PHASE_NUM}: ${PHASE_NAME}", - run_in_background=true, - prompt="Run plan-phase for phase ${PHASE_NUM}: skill(skill=\"gsd:plan-phase\", args=\"${PHASE_NUM}\")" -) +@gsd-plan-phase "Run plan-phase for phase ${PHASE_NUM}: skill(skill=\"gsd-plan-phase\", args=\"${PHASE_NUM}\")" ``` Store the agent task_id. After discuss for the next phase completes (or if no next phase), wait for the plan agent to finish before proceeding to execute. @@ -341,11 +337,7 @@ Verify plan produced output — re-run `init phase-op` and check `has_plans`. If **If `INTERACTIVE` is set:** Wait for the plan agent to complete (if not already), verify plans exist, then dispatch execute as a background agent: ``` -Agent( - description="Execute phase ${PHASE_NUM}: ${PHASE_NAME}", - run_in_background=true, - prompt="Run execute-phase for phase ${PHASE_NUM}: skill(skill=\"gsd:execute-phase\", args=\"${PHASE_NUM} --no-transition\")" -) +@gsd-execute-phase "Run execute-phase for phase ${PHASE_NUM}: skill(skill=\"gsd-execute-phase\", args=\"${PHASE_NUM} --no-transition\")" ``` Store the agent task_id. The workflow can now start discussing the next phase while this phase executes in the background. Before starting post-execution routing for this phase, wait for the execute agent to complete.