diff --git a/gsd-orchestrator/SKILL.md b/gsd-orchestrator/SKILL.md index 48e044b8c..ad423afdf 100644 --- a/gsd-orchestrator/SKILL.md +++ b/gsd-orchestrator/SKILL.md @@ -1,13 +1,11 @@ --- name: gsd-orchestrator description: > - Orchestrate GSD (Get Shit Done) projects via subprocess execution. - Use when an agent needs to create milestones from specs, execute software - development workflows, monitor task progress, poll status, handle blockers, - or track costs. Triggers on requests to "run gsd", "create milestone", - "execute project", "check gsd status", "orchestrate development", - "run headless workflow", or any programmatic interaction with the GSD - project management system. + Build software products autonomously via GSD headless mode. Handles the full + lifecycle: write a spec, launch a build, poll for completion, handle blockers, + track costs, and verify the result. Use when asked to "build something", + "create a project", "run gsd", "check build status", or any task that + requires autonomous software development via subprocess. metadata: openclaw: requires: @@ -18,267 +16,166 @@ metadata: bins: [gsd] --- -# GSD Orchestrator + +You are an autonomous agent that builds software by orchestrating GSD as a subprocess. +GSD is a headless CLI that plans, codes, tests, and ships software from a spec. +You control it via shell commands, exit codes, and JSON output — no SDK, no RPC. + -Run GSD commands as subprocesses via `gsd headless`. No SDK, no RPC — just shell exec, exit codes, and JSON on stdout. + +GSD headless is a subprocess you launch and monitor. Think of it like a junior developer +you hand a spec to: -## Quick Start +1. You write the spec (what to build) +2. You launch the build (`gsd headless ... new-milestone --context spec.md --auto`) +3. You wait for it to finish (exit code tells you the outcome) +4. You check the result (query state, inspect files, verify deliverables) +5. If blocked, you intervene (steer, supply answers, or escalate) +The subprocess handles all planning, coding, testing, and git commits internally. +You never write application code yourself — GSD does that. + + + +- **Flags before command.** `gsd headless [--flags] [command] [args]`. Flags after the command are ignored. +- **Redirect stderr.** JSON output goes to stdout. Progress goes to stderr. Always `2>/dev/null` when parsing JSON. +- **Check exit codes.** 0=success, 1=error, 10=blocked (needs you), 11=cancelled. +- **Use `query` to poll.** Instant (~50ms), no LLM cost. Use it between steps, not `auto` for status. +- **Budget awareness.** Track `cost.total` from query results. Set limits before launching long runs. +- **One project directory per build.** Each GSD project needs its own directory with a `.gsd/` folder. + + + +Route based on what you need to do: + +**Build something from scratch:** +Read `workflows/build-from-spec.md` — write spec, init directory, launch, monitor, verify. + +**Check on a running or completed build:** +Read `workflows/monitor-and-poll.md` — query state, interpret phases, handle blockers. + +**Execute with fine-grained control:** +Read `workflows/step-by-step.md` — run one unit at a time with decision points. + +**Understand the JSON output:** +Read `references/json-result.md` — field reference for HeadlessJsonResult. + +**Pre-supply answers or secrets:** +Read `references/answer-injection.md` — answer file schema and injection mechanism. + +**Look up a specific command:** +Read `references/commands.md` — full command reference with flags and examples. + + + + +**Launch a full build (spec to working code):** ```bash -# Install GSD globally -npm install -g gsd-pi - -# Verify installation -gsd --version - -# Create a milestone from a spec and execute it -gsd headless --output-format json new-milestone --context spec.md --auto +mkdir -p /tmp/my-project && cd /tmp/my-project && git init +cat > spec.md << 'EOF' +# Your Product Spec Here +Build a ... +EOF +gsd headless --output-format json --context spec.md new-milestone --auto 2>/dev/null ``` -## Command Syntax - +**Check project state (instant, free):** ```bash -gsd headless [flags] [command] [args...] +cd /path/to/project +gsd headless query | jq '{phase: .state.phase, progress: .state.progress, cost: .cost.total}' ``` -Default command is `auto` (run all queued units). +**Resume work on an existing project:** +```bash +cd /path/to/project +gsd headless --output-format json auto 2>/dev/null +``` -### Flags +**Run one step at a time:** +```bash +RESULT=$(gsd headless --output-format json next 2>/dev/null) +echo "$RESULT" | jq '{status: .status, phase: .phase, cost: .cost.total}' +``` + + + +| Code | Meaning | Your action | +|------|---------|-------------| +| `0` | Success | Check deliverables, verify output, report completion | +| `1` | Error or timeout | Inspect stderr, check `.gsd/STATE.md`, retry or escalate | +| `10` | Blocked | Query state for blocker details, steer around it or escalate to human | +| `11` | Cancelled | Process was interrupted — resume with `--resume ` or restart | + + + +GSD creates and manages all state in `.gsd/`: +``` +.gsd/ + PROJECT.md # What this project is + REQUIREMENTS.md # Capability contract + DECISIONS.md # Architectural decisions (append-only) + KNOWLEDGE.md # Persistent project knowledge (patterns, rules, lessons) + STATE.md # Current phase and next action + milestones/ + M001-xxxxx/ + M001-xxxxx-CONTEXT.md # Scope, constraints, assumptions + M001-xxxxx-ROADMAP.md # Slices with checkboxes + M001-xxxxx-SUMMARY.md # Completion summary + slices/S01/ + S01-PLAN.md # Tasks + S01-SUMMARY.md # Slice summary + tasks/ + T01-PLAN.md # Individual task spec + T01-SUMMARY.md # Task completion summary +``` + +State is derived from files on disk — checkboxes in ROADMAP.md and PLAN.md are the source of truth for completion. You never need to edit these files. GSD manages them. But you can read them to understand progress. + + + | Flag | Description | |------|-------------| -| `--output-format ` | Output format: `text` (default), `json` (structured result at exit), `stream-json` (JSONL events) | +| `--output-format ` | `text` (default), `json` (structured result at exit), `stream-json` (JSONL events) | | `--json` | Alias for `--output-format stream-json` — JSONL event stream to stdout | -| `--bare` | Minimal context: skip CLAUDE.md, AGENTS.md, user settings, user skills. Use for CI/ecosystem runs. | +| `--bare` | Skip CLAUDE.md, AGENTS.md, user settings, user skills. Use for CI/ecosystem runs. | | `--resume ` | Resume a prior headless session by its session ID | -| `--timeout N` | Overall timeout in ms (default: 300000) | +| `--timeout N` | Overall timeout in ms (default: 300000, use 0 to disable) | | `--model ID` | Override LLM model | | `--supervised` | Forward interactive UI requests to orchestrator via stdout/stdin | | `--response-timeout N` | Timeout (ms) for orchestrator response in supervised mode (default: 30000) | | `--answers ` | Pre-supply answers and secrets from JSON file | -| `--events ` | Filter JSONL output to specific event types (comma-separated, implies `--json`) | +| `--events ` | Filter JSONL to specific event types (comma-separated, implies `--json`) | | `--verbose` | Show tool calls in progress output | +| `--context ` | Spec file path for `new-milestone` (use `-` for stdin) | +| `--context-text ` | Inline spec text for `new-milestone` | +| `--auto` | Chain into auto-mode after `new-milestone` | + -### Exit Codes - -| Code | Meaning | Constant | -|------|---------|----------| -| `0` | Success — unit/milestone completed | `EXIT_SUCCESS` | -| `1` | Error or timeout | `EXIT_ERROR` | -| `10` | Blocked — needs human intervention | `EXIT_BLOCKED` | -| `11` | Cancelled by user or orchestrator | `EXIT_CANCELLED` | - -These codes are stable and suitable for CI pipelines and orchestrator logic. - -### Output Formats - -| Format | Behavior | -|--------|----------| -| `text` | Human-readable progress on stderr. Default. | -| `json` | Collect events silently. Emit a single `HeadlessJsonResult` JSON object to stdout at exit. | -| `stream-json` | Stream JSONL events to stdout in real time (same as `--json`). | - -Use `--output-format json` when you need a structured result for decision-making. See [references/json-result.md](references/json-result.md) for the full field reference. - -## Core Workflows - -### 1. Create + Execute a Milestone (end-to-end) + +Pre-supply answers and secrets for fully autonomous runs: ```bash -gsd headless --output-format json new-milestone --context spec.md --auto +gsd headless --answers answers.json --output-format json auto 2>/dev/null ``` -Reads a spec file, bootstraps `.gsd/`, creates the milestone, then chains into auto-mode executing all phases (discuss → research → plan → execute → summarize → complete). The JSON result is emitted on stdout at exit. - -Extra flags for `new-milestone`: -- `--context ` — path to spec/PRD file (use `-` for stdin) -- `--context-text ` — inline specification text -- `--auto` — start auto-mode after milestone creation -- `--verbose` — show tool calls in progress output - -```bash -# From stdin -cat spec.md | gsd headless --output-format json new-milestone --context - --auto - -# Inline text -gsd headless new-milestone --context-text "Build a REST API for user management" --auto -``` - -### 2. Run All Queued Work - -```bash -gsd headless --output-format json auto -``` - -Loop through all pending units until milestone complete or blocked. - -### 3. Run One Unit (step-by-step) - -```bash -gsd headless --output-format json next -``` - -Execute exactly one unit (task/slice/milestone step), then exit. This is the recommended pattern for orchestrators that need control between steps. - -### 4. Instant State Snapshot (no LLM) - -```bash -gsd headless query -``` - -Returns a single JSON object with the full project snapshot — no LLM session, instant (~50ms). **This is the recommended way for orchestrators to inspect state.** - ```json { - "state": { - "phase": "executing", - "activeMilestone": { "id": "M001", "title": "..." }, - "activeSlice": { "id": "S01", "title": "..." }, - "progress": { "completed": 3, "total": 7 }, - "registry": [...] - }, - "next": { "action": "dispatch", "unitType": "execute-task", "unitId": "M001/S01/T01" }, - "cost": { "workers": [{ "milestoneId": "M001", "cost": 1.50 }], "total": 1.50 } + "questions": { "question_id": "selected_option" }, + "secrets": { "API_KEY": "sk-..." }, + "defaults": { "strategy": "first_option" } } ``` -### 5. Dispatch Specific Phase +- **questions** — question ID to answer (string for single-select, string[] for multi-select) +- **secrets** — env var to value, injected into child process environment +- **defaults.strategy** — `"first_option"` (default) or `"cancel"` for unmatched questions -```bash -gsd headless dispatch research|plan|execute|complete|reassess|uat|replan -``` +See `references/answer-injection.md` for the full mechanism. + -Force-route to a specific phase, bypassing normal state-machine routing. - -### 6. Resume a Session - -```bash -gsd headless --resume auto -``` - -Resume a prior headless session. The session ID is available in the `HeadlessJsonResult.sessionId` field from a previous `--output-format json` run. - -## Orchestrator Patterns - -### Parse the Structured JSON Result - -When using `--output-format json`, the process emits a single `HeadlessJsonResult` on stdout at exit. Parse it for decision-making: - -```bash -RESULT=$(gsd headless --output-format json next 2>/dev/null) -EXIT=$? - -STATUS=$(echo "$RESULT" | jq -r '.status') -COST=$(echo "$RESULT" | jq -r '.cost.total') -PHASE=$(echo "$RESULT" | jq -r '.phase') -NEXT=$(echo "$RESULT" | jq -r '.nextAction') -SESSION_ID=$(echo "$RESULT" | jq -r '.sessionId') - -echo "Status: $STATUS, Cost: \$${COST}, Phase: $PHASE, Next: $NEXT" -``` - -See [references/json-result.md](references/json-result.md) for the full field reference. - -### Blocker Detection and Handling - -Exit code `10` means the execution hit a blocker requiring human intervention: - -```bash -gsd headless --output-format json next 2>/dev/null -EXIT=$? - -if [ $EXIT -eq 10 ]; then - # Inspect the blocker - BLOCKER=$(gsd headless query | jq '.state.phase') - echo "Blocked: $BLOCKER" - - # Option 1: Use --supervised mode to handle interactively - gsd headless --supervised auto - - # Option 2: Pre-supply answers to resolve the blocker - gsd headless --answers blocker-answers.json auto - - # Option 3: Steer the plan to work around it - gsd headless steer "Skip the blocked dependency, use mock instead" -fi -``` - -### Cost Tracking and Budget Enforcement - -```bash -MAX_BUDGET=10.00 - -RESULT=$(gsd headless --output-format json next 2>/dev/null) -COST=$(echo "$RESULT" | jq -r '.cost.total') - -# Check cumulative cost via query (includes all workers) -TOTAL_COST=$(gsd headless query | jq -r '.cost.total') - -if (( $(echo "$TOTAL_COST > $MAX_BUDGET" | bc -l) )); then - echo "Budget exceeded: \$$TOTAL_COST > \$$MAX_BUDGET" - gsd headless stop - exit 1 -fi -``` - -### Step-by-Step with Monitoring - -The recommended pattern for full control. Run one unit at a time, inspect state between steps: - -```bash -while true; do - RESULT=$(gsd headless --output-format json next 2>/dev/null) - EXIT=$? - - STATUS=$(echo "$RESULT" | jq -r '.status') - COST=$(echo "$RESULT" | jq -r '.cost.total') - - echo "Exit: $EXIT, Status: $STATUS, Cost: \$$COST" - - # Handle terminal states - [ $EXIT -eq 0 ] || break - - # Check if milestone is complete - PHASE=$(gsd headless query | jq -r '.state.phase') - [ "$PHASE" = "complete" ] && echo "Milestone complete" && break - - # Budget check - TOTAL=$(gsd headless query | jq -r '.cost.total') - if (( $(echo "$TOTAL > 20.00" | bc -l) )); then - echo "Budget limit reached" - break - fi -done -``` - -### Poll-and-React Loop - -Lightweight pattern using only the instant `query` command: - -```bash -PHASE=$(gsd headless query | jq -r '.state.phase') -NEXT_ACTION=$(gsd headless query | jq -r '.next.action') - -case "$PHASE" in - complete) echo "Done" ;; - blocked) echo "Needs intervention — exit code 10" ;; - *) [ "$NEXT_ACTION" = "dispatch" ] && gsd headless next ;; -esac -``` - -### CI/Ecosystem Mode - -Use `--bare` to skip user-specific configuration for deterministic CI runs: - -```bash -gsd headless --bare --output-format json auto 2>/dev/null -``` - -This skips CLAUDE.md, AGENTS.md, user settings, and user skills. Bundled GSD extensions and `.gsd/` state are still loaded (they're required for GSD to function). - -### JSONL Event Stream - -Use `--json` (or `--output-format stream-json`) for real-time events: + +For real-time monitoring, use JSONL event streaming: ```bash gsd headless --json auto 2>/dev/null | while read -r line; do @@ -291,84 +188,28 @@ gsd headless --json auto 2>/dev/null | while read -r line; do done ``` -### Filtered Event Stream +Filter to specific events: `--events agent_end,execution_complete,extension_ui_request` -Use `--events` to receive only specific event types: - -```bash -# Only phase-relevant events -gsd headless --events agent_end,extension_ui_request auto 2>/dev/null - -# Only tool execution events -gsd headless --events tool_execution_start,tool_execution_end auto -``` - -Available event types: `agent_start`, `agent_end`, `tool_execution_start`, `tool_execution_end`, `tool_execution_update`, `extension_ui_request`, `message_start`, `message_end`, `message_update`, `turn_start`, `turn_end`. - -## Answer Injection - -Pre-supply answers and secrets for fully autonomous headless runs: - -```bash -gsd headless --answers answers.json auto -``` - -Answer file schema: -```json -{ - "questions": { "question_id": "selected_option" }, - "secrets": { "API_KEY": "sk-..." }, - "defaults": { "strategy": "first_option" } -} -``` - -- **questions** — question ID → answer (string for single-select, string[] for multi-select) -- **secrets** — env var → value, injected into child process environment -- **defaults.strategy** — `"first_option"` (default) or `"cancel"` for unmatched questions - -See [references/answer-injection.md](references/answer-injection.md) for the full mechanism. - -## GSD Project Structure - -All state lives in `.gsd/` as markdown files (version-controllable): - -``` -.gsd/ - PROJECT.md - REQUIREMENTS.md - DECISIONS.md - KNOWLEDGE.md - STATE.md - milestones/ - M001/ - M001-CONTEXT.md # Requirements, scope, decisions - M001-ROADMAP.md # Slices with tasks, dependencies, checkboxes - M001-SUMMARY.md # Completion summary - slices/ - S01/ - S01-PLAN.md # Task list - S01-SUMMARY.md # Slice summary - tasks/ - T01-PLAN.md # Individual task spec - T01-SUMMARY.md # Task completion summary -``` - -State is derived from files on disk — checkboxes in ROADMAP.md and PLAN.md are the source of truth for completion. - -## All Commands - -See [references/commands.md](references/commands.md) for the complete reference. +Available types: `agent_start`, `agent_end`, `tool_execution_start`, `tool_execution_end`, +`tool_execution_update`, `extension_ui_request`, `message_start`, `message_end`, +`message_update`, `turn_start`, `turn_end`, `cost_update`, `execution_complete`. + + | Command | Purpose | |---------|---------| -| `auto` | Run all queued units (default) | -| `next` | Run one unit | -| `query` | Instant JSON snapshot — state, next dispatch, costs (no LLM) | -| `new-milestone` | Create milestone from spec | -| `dispatch ` | Force specific phase | +| `auto` | Run all queued units until milestone complete or blocked (default) | +| `next` | Run exactly one unit, then exit | +| `query` | Instant JSON snapshot — state, next dispatch, costs (no LLM, ~50ms) | +| `new-milestone` | Create milestone from spec file | +| `dispatch ` | Force specific phase (research, plan, execute, complete, reassess, uat, replan) | | `stop` / `pause` | Control auto-mode | | `steer ` | Hard-steer plan mid-execution | | `skip` / `undo` | Unit control | | `queue` | Queue/reorder milestones | | `history` | View execution history | | `doctor` | Health check + auto-fix | +| `knowledge ` | Add persistent project knowledge | + +See `references/commands.md` for the complete reference. +