Orchestrate GSD (Get Shit Done) projects programmatically via headless CLI. Use when an agent needs to create milestones from specs, execute software development workflows, monitor task progress, check project status, or control GSD execution (pause/stop/skip/steer). 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. Essential for building orchestrators that coordinate multiple GSD workers.
75
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Run GSD commands without TUI via gsd headless. Spawns an RPC child process, auto-responds to UI prompts, streams progress.
gsd headless [flags] [command] [args...]Flags:
--timeout N — overall timeout in ms (default 300000)--json — JSONL event stream to stdout--model ID — override LLM model--verbose — show tool calls in progress output--supervised — forward interactive UI requests to orchestrator via stdout/stdin--response-timeout N — timeout for orchestrator response in supervised mode (default 30000)--max-restarts N — auto-restart on crash with backoff (default 3, 0 to disable)--answers <path> — pre-supply answers and secrets from JSON file--events <types> — filter JSONL output to specific event types (comma-separated, implies --json)Exit codes: 0=complete, 1=error/timeout, 2=blocked
gsd headless new-milestone --context spec.md --autoReads spec, bootstraps .gsd/, creates milestone, then chains into auto-mode executing all phases (discuss → research → plan → execute → summarize → complete).
Extra flags for new-milestone: --context <path> (use - for stdin), --context-text <text>, --auto.
gsd headless autoDefault command. Loops through all pending units until milestone complete or blocked.
gsd headless nextExecute exactly one unit (task/slice/milestone step), then exit. Ideal for step-by-step orchestration with external decision logic between steps.
gsd headless queryReturns a single JSON object with the full project snapshot — no LLM session, instant (~50ms). This is the recommended way for orchestrators to inspect state.
{
"state": { "phase": "executing", "activeMilestone": {...}, "activeSlice": {...}, "progress": {...}, "registry": [...] },
"next": { "action": "dispatch", "unitType": "execute-task", "unitId": "M001/S01/T01" },
"cost": { "workers": [{ "milestoneId": "M001", "cost": 1.50, ... }], "total": 1.50 }
}# What phase is the project in?
gsd headless query | jq '.state.phase'
# What would auto-mode do next?
gsd headless query | jq '.next'
# Total spend across parallel workers
gsd headless query | jq '.cost.total'gsd headless dispatch research|plan|execute|complete|reassess|uat|replanForce-route to a specific phase, bypassing normal state-machine routing.
# Instant state check — no LLM cost
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" ;;
*) [ "$NEXT_ACTION" = "dispatch" ] && gsd headless next ;;
esacwhile true; do
gsd headless next
EXIT=$?
[ $EXIT -ne 0 ] && break
# Instant progress check between steps
gsd headless query | jq '{phase: .state.phase, progress: .state.progress}'
doneGSD tracks concurrent workers via file-based IPC in .gsd/parallel/. See references/multi-session.md for the full architecture.
Quick overview:
Each worker spawns with GSD_MILESTONE_LOCK=M00X + its own git worktree. Workers write heartbeats to .gsd/parallel/<milestoneId>.status.json. The orchestrator enumerates all status files to get a dashboard of all workers, and sends commands via signal files.
# Spawn a worker for milestone M001 in its worktree
GSD_MILESTONE_LOCK=M001 GSD_PARALLEL_WORKER=1 \
gsd headless --json auto \
--cwd .gsd/worktrees/M001 2>worker-M001.log &
# Monitor all workers: read .gsd/parallel/*.status.json
for f in .gsd/parallel/*.status.json; do
jq '{mid: .milestoneId, state: .state, unit: .currentUnit.id, cost: .cost}' "$f"
done
# Send pause signal to M001
echo '{"signal":"pause","sentAt":'$(date +%s000)',"from":"coordinator"}' \
> .gsd/parallel/M001.signal.jsonStatus file fields: milestoneId, pid, state (running/paused/stopped/error), currentUnit, completedUnits, cost, lastHeartbeat, startedAt, worktreePath.
Signal commands: pause, resume, stop, rebase.
Liveness detection: PID alive check (kill -0 $pid) + heartbeat freshness (30s timeout). Stale sessions are auto-cleaned.
For multiple projects: each project has its own .gsd/ directory. The orchestrator must track (projectPath, milestoneId) tuples externally.
Use --json to get real-time events on stdout for downstream processing:
gsd headless --json auto 2>/dev/null | while read -r line; do
TYPE=$(echo "$line" | jq -r '.type')
case "$TYPE" in
tool_execution_start) echo "Tool: $(echo "$line" | jq -r '.toolName')" ;;
extension_ui_request) echo "GSD: $(echo "$line" | jq -r '.message // .title // empty')" ;;
agent_end) echo "Session ended" ;;
esac
doneEvent types: agent_start, agent_end, tool_execution_start, tool_execution_end, extension_ui_request, message_update, error.
Use --events to receive only specific event types — reduces noise for orchestrators:
# 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 autoThe filter applies only to stdout output. Internal processing (completion detection, supervised mode, answer injection) is unaffected — all events are still processed internally.
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.
Pre-supply answers and secrets for headless runs via --answers:
gsd headless --answers answers.json autoAnswer file schema:
{
"questions": { "question_id": "selected_option" },
"secrets": { "API_KEY": "sk-..." },
"defaults": { "strategy": "first_option" }
}"first_option" (default) or "cancel" for unmatchedSee references/answer-injection.md for full details.
All state lives in .gsd/ as markdown files (version-controllable):
.gsd/
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 with frontmatter
tasks/T01-PLAN.md # Individual task specState is derived from files on disk — checkboxes in ROADMAP.md are the source of truth for completion.
Quick reference — see references/commands.md for the complete list.
| 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 |
queue | Queue/reorder milestones |
history | View execution history |
stop / pause | Control auto-mode |
dispatch <phase> | Force specific phase |
skip / undo | Unit control |
doctor | Health check + auto-fix |
steer <desc> | Hard-steer plan mid-execution |
33c00aa
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.