The gsd headless Command
gsd headless [subcommand] is the main entry point for non-interactive use. It spawns a child GSD process in RPC mode, auto-responds to interactive prompts, and exits with a meaningful code when done.
Subcommands
Key Flags
Exit Codes
Instant State Snapshot with query
gsd headless query returns a single JSON object describing the full project state without starting an LLM session. It’s the recommended way for orchestrators and external scripts to inspect GSD state between runs.
state (current phase, active milestone, progress, blockers), next (the next dispatch action), and cost (per-worker and aggregate spend).
Streaming JSON Events
Add--json to stream all session events as JSONL to stdout. This is useful for log aggregation, monitoring dashboards, and build pipelines that need structured output.
Auto-Mode Without the TUI
Usegsd auto as a shorthand for non-interactive auto mode with pipeable output:
gsd headless auto for most purposes and respects all the same flags.
GitHub Actions Example
Here’s a complete example workflow that runs GSD Pi in CI to continue work on a project, failing gracefully when blocked:Remote Questions for Unattended Runs
When GSD needs to ask a question during headless auto mode, it can route that question to Slack, Discord, or Telegram instead of blocking the process. Configureremote_questions in your project’s PREFERENCES.md:
timeout_minutes, GSD exits with code 10.
When
notifications.enabled: true is set alongside a remote channel, informational notifications — milestone completions, budget alerts, blockers — are also sent to that channel, not just to the desktop.Crash Recovery and Auto-Restart
Headless auto mode restarts automatically on crash with exponential backoff (5s → 10s → 30s cap, default 3 attempts). Combined with GSD’s database-backed state persistence, this enables true overnight “run until done” execution.--max-restarts 0 to disable auto-restart. SIGINT and SIGTERM always bypass the restart logic and exit immediately.
After a crash, run gsd headless recover to reset the DB hierarchy and rebuild state from rendered markdown before retrying:
