docs: rewrite gsd-orchestrator skill as agent-oriented playbook (#2889)
Restructure from flat documentation reference into proper agent-oriented skill with XML structure, mental model, routing to workflows, and restored reference content (KNOWLEDGE.md, flags, event streaming, answer injection, command table). Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
da7f5793be
commit
3e0b2b7c6b
1 changed files with 148 additions and 307 deletions
|
|
@ -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
|
||||
<objective>
|
||||
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.
|
||||
</objective>
|
||||
|
||||
Run GSD commands as subprocesses via `gsd headless`. No SDK, no RPC — just shell exec, exit codes, and JSON on stdout.
|
||||
<mental_model>
|
||||
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.
|
||||
</mental_model>
|
||||
|
||||
<critical_rules>
|
||||
- **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.
|
||||
</critical_rules>
|
||||
|
||||
<routing>
|
||||
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.
|
||||
</routing>
|
||||
|
||||
<quick_reference>
|
||||
|
||||
**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}'
|
||||
```
|
||||
|
||||
</quick_reference>
|
||||
|
||||
<exit_codes>
|
||||
| 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 <sessionId>` or restart |
|
||||
</exit_codes>
|
||||
|
||||
<project_structure>
|
||||
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.
|
||||
</project_structure>
|
||||
|
||||
<flags>
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--output-format <fmt>` | Output format: `text` (default), `json` (structured result at exit), `stream-json` (JSONL events) |
|
||||
| `--output-format <fmt>` | `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 <id>` | 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 <path>` | Pre-supply answers and secrets from JSON file |
|
||||
| `--events <types>` | Filter JSONL output to specific event types (comma-separated, implies `--json`) |
|
||||
| `--events <types>` | Filter JSONL to specific event types (comma-separated, implies `--json`) |
|
||||
| `--verbose` | Show tool calls in progress output |
|
||||
| `--context <path>` | Spec file path for `new-milestone` (use `-` for stdin) |
|
||||
| `--context-text <text>` | Inline spec text for `new-milestone` |
|
||||
| `--auto` | Chain into auto-mode after `new-milestone` |
|
||||
</flags>
|
||||
|
||||
### 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)
|
||||
<answer_injection>
|
||||
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>` — path to spec/PRD file (use `-` for stdin)
|
||||
- `--context-text <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.
|
||||
</answer_injection>
|
||||
|
||||
Force-route to a specific phase, bypassing normal state-machine routing.
|
||||
|
||||
### 6. Resume a Session
|
||||
|
||||
```bash
|
||||
gsd headless --resume <session-id> 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:
|
||||
<event_streaming>
|
||||
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`.
|
||||
</event_streaming>
|
||||
|
||||
<all_commands>
|
||||
| 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 <phase>` | 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 <phase>` | Force specific phase (research, plan, execute, complete, reassess, uat, replan) |
|
||||
| `stop` / `pause` | Control auto-mode |
|
||||
| `steer <desc>` | Hard-steer plan mid-execution |
|
||||
| `skip` / `undo` | Unit control |
|
||||
| `queue` | Queue/reorder milestones |
|
||||
| `history` | View execution history |
|
||||
| `doctor` | Health check + auto-fix |
|
||||
| `knowledge <rule>` | Add persistent project knowledge |
|
||||
|
||||
See `references/commands.md` for the complete reference.
|
||||
</all_commands>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue