Skip to content
AI & Agents
Skill

/gsd-headless

Orchestrate GSD (Git Ship Done) projects programmatically via headless CLI. Use when an agent needs to create milestones from specs, execute dev workflows, monitor progress, check status, or control execution (pause/stop/skip/steer). Triggers on "run gsd", "create milestone",

BOOST
From plugin
gsd-pi
1.3k37 skills13 agents
Install
$ npx -y skills add open-gsd/gsd-pi --skill gsd-headless --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/gsd-headless

Context preview

The summary Claude sees to decide when to auto-load this skill.

Orchestrate GSD (Git Ship Done) projects programmatically via headless CLI. Use when an agent needs to create milestones from specs, execute dev workflows, monitor progress, check status, or control execution (pause/stop/skip/steer). Triggers on "run gsd", "create milestone",

SKILL.md

gsd-headless.SKILL.md
name: gsd-headless
description: Orchestrate GSD (Git Ship Done) projects programmatically via headless CLI. Use when an agent needs to create milestones from specs, execute dev workflows, monitor progress, check status, or control execution (pause/stop/skip/steer). Triggers on "run gsd", "create milestone", "execute project", "check gsd status", "orchestrate development", "run headless workflow", or building orchestrators that coordinate multiple GSD workers.

GSD Headless Orchestration

Run GSD commands without TUI via `gsd headless`. Spawns an RPC child process, auto-responds to UI prompts, streams progress.

Command Syntax

gsd headless [flags] [command] [args...]

**Flags:**

  • `--timeout N` — overall timeout in ms; `auto` has no overall timeout unless this flag is set
  • `--json` — JSONL event stream ending with the authoritative `headless_result`
  • `--model ID` — override LLM model
  • `--thinking LEVEL` — override thinking level (`off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`)
  • `--resume <id>` — resume a prior headless session by ID
  • `--bare` — start with minimal context for CI/ecosystem use
  • `--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, 10=blocked, 11=cancelled

Core Workflows

1. Create + Execute a Milestone (end-to-end)

gsd headless new-milestone --context spec.md --auto

Reads 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`.

2. Run All Queued Work

gsd headless auto

Default command. Loops through all pending units until milestone complete or blocked.

3. Run One Unit

gsd headless next

Execute exactly one unit (task/slice/milestone step), then exit. Ideal for step-by-step orchestration with external decision logic between steps.

4. Instant State Snapshot (no LLM)

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.**

{
  "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'

5. Dispatch Specific Phase

gsd headless dispatch research|plan|execute|complete|reassess|uat|replan

Force-route to a specific phase, bypassing normal state-machine routing.

Orchestrator Patterns

Poll-and-React Loop

# 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 ;;
esac

Step-by-Step with Monitoring

while 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}'
done

Multi-Session Orchestration

GSD tracks concurrent workers via status files in `.gsd/parallel/`. See [references/multi-session.md](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.

# 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 &
M001_PID=$!

# 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

# Stop the M001 worker
kill -TERM "$M001_PID"

**Status file fields:** `milestoneId`, `pid`, `state` (running/paused/stopped/error), `currentUnit`, `completedUnits`, `cost`, `lastHeartbeat`, `startedAt`, `worktreePath`.

**Worker commands:** `pause`, `resume` and `stop` are `command_queue` rows in the project database. The coordinator writes them (`/gsd parallel pause|resume|stop`). An external orchestrator stops a worker with `SIGTERM`. A signal file `.gsd/parallel/<milestoneId>.signal.json` is still accepted for compatibility and is deprecated: the worker turns it into a `command_queue` row and removes the file.

**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.

JSONL Event Stream

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
    to
Read more
Ships withgsd-pi

GSD Pi is a local-first coding agent for planning, implementing, verifying, and tracking project work from the command line.

Get the whole plugin

Other skills on gsd-pi.