Skip to main content
Run SoulForge without the TUI —pipe in a prompt, get back results.

Quick start

# Inline prompt
soulforge --headless "explain the auth middleware"

# Pipe from stdin
echo "find all unused exports" | soulforge --headless

# JSON output for scripting
soulforge --headless --json "list all TODO comments"

# JSONL event stream (real-time)
soulforge --headless --events "refactor the store"

# Override model and mode
soulforge --headless --model anthropic/claude-sonnet-4-20250514 --mode architect "review auth"

# Inject system prompt + include files
soulforge --headless --system "you are a security auditor" --include src/auth.ts "find vulnerabilities"

# CI/CD with safety limits
soulforge --headless --max-steps 20 --timeout 120000 --save-session "fix lint errors"

# Interactive multi-turn chat
soulforge --headless --chat

CLI flags

Headless execution

FlagDescription
--headless <prompt>Run without TUI. Prompt is all non-flag arguments joined.
--model <provider/model>Override the configured default model.
--mode <mode>Set forge mode: default, architect, socratic, challenge, plan, auto.
--jsonOutput structured JSON after completion.
--eventsJSONL event stream —one JSON object per line, real-time.
--quiet / -qSuppress header/footer on stderr.
--max-steps <n>Limit agent to N steps, then abort.
--timeout <ms>Abort after N milliseconds.
--cwd <dir>Set working directory.
--system "..."Inject custom system prompt instructions.
--include <file>Pre-load a file into context (repeatable).
--no-repomapSkip repo map scan.
--diffShow list of files changed after the run.
--no-renderOutput raw text without ANSI styling.
--session <id>Resume a previous session (prefix match supported).
--save-sessionSave the conversation for later resume.
--chatInteractive multi-turn chat with auto-save.
Exit codes: 0 success, 1 error, 2 timeout, 130 abort (Ctrl+C).

Provider management

These work standalone —no --headless needed:
soulforge --list-providers                   # Show providers + key status
soulforge --list-models                      # Show models for all providers
soulforge --list-models anthropic            # Show models for one provider
soulforge --set-key anthropic sk-ant-...     # Save API key to OS keychain

Output modes

Agent text streams to stdout in real time. Status messages go to stderr.
# Only agent output goes to the file
soulforge --headless "summarize the architecture" > summary.txt

# stderr shows progress:
# Model: anthropic/claude-sonnet-4-20250514
# Repo:  847 files, 12340 symbols
# 3 steps -- 12.1k in, 2.1k out, 89% cached -- 8.4s

Chat mode events

In --chat --events mode, additional events are emitted:
  • ready —agent is ready for the next prompt
  • turn-done —a turn completed (per-turn stats)
  • chat-done —chat session ended (total stats, sessionId if saved)

What’s available

Headless runs the full Forge agent with all tools:
  • All 31 tools
  • Multi-agent dispatch with shared cache
  • Repo map (tree-sitter analysis, PageRank, cochange, blast radius)
  • Intelligence layer (LSP, ts-morph, tree-sitter fallback)
  • Context management (compaction, tool result pruning)
  • Provider options (prompt caching, thinking modes)

What’s skipped

  • Splash animation and TUI renderer
  • Neovim editor embedding
  • Interactive approval prompts (destructive actions auto-allowed)
  • Keyboard shortcuts and modal UI
  • Plan review flow
  • User steering (no stdin during execution)

Examples

CI/CD: lint and fix

soulforge --headless --max-steps 20 --timeout 120000 --diff \
  "run the linter, fix all issues, then verify typecheck passes"

Security review

soulforge --headless --mode architect \
  --system "you are a security auditor. focus on OWASP top 10." \
  --include src/auth/middleware.ts \
  "review this authentication code for vulnerabilities"

Batch analysis

for dir in packages/*/; do
  echo "analyze $dir for unused exports" | soulforge --headless --json >> report.jsonl
done

Multi-step workflow with sessions

# Step 1: analyze and save
soulforge --headless --save-session "analyze the auth module, find all issues"
# Step 2: resume and fix
soulforge --headless --session <id> --save-session "now fix the issues you found"
# Step 3: resume and test
soulforge --headless --session <id> "write tests for the fixes"

Real-time monitoring

soulforge --headless --events "refactor the store module" | while read -r line; do
  type=$(echo "$line" | jq -r '.type')
  case "$type" in
    tool-call) echo "Tool: $(echo "$line" | jq -r '.tool')" ;;
    done) echo "Done in $(echo "$line" | jq -r '.duration')ms" ;;
  esac
done

Custom providers

Add any OpenAI-compatible API as a provider via config:
{
  "providers": [
    {
      "id": "deepseek",
      "name": "DeepSeek",
      "baseURL": "https://api.deepseek.com/v1",
      "envVar": "DEEPSEEK_API_KEY",
      "models": ["deepseek-chat", "deepseek-coder"]
    }
  ]
}
FieldRequiredDescription
idYesProvider ID, used in model strings like deepseek/deepseek-chat.
nameNoDisplay name. Defaults to id.
baseURLYesOpenAI-compatible API endpoint.
envVarNoEnv var name for the API key.
modelsNoFallback model list.
modelsAPINoURL to fetch models dynamically (OpenAI /v1/models format).
Custom providers can be scoped globally (~/.soulforge/config.json) or per-project (.soulforge/config.json). Project providers override global entries with the same id.

Architecture

Headless bypasses the entire TUI stack:
boot.tsx (CLI flag detected)
  -> headless/index.ts
    -> parse.ts (parseHeadlessArgs)
    -> initConfig() + registerCustomProviders()
    -> run.ts (runPrompt)
      -> ContextManager.createAsync()   (repo map, memory)
      -> loadInstructions()             (SOULFORGE.md + --system)
      -> SessionManager.loadSession()   (if --session)
      -> createForgeAgent()             (same agent as TUI)
      -> agent.stream()                 (async iterator)
      -> SessionManager.saveSession()   (if --save-session)
      -> stdout                         (text, JSON, or JSONL events)
The createForgeAgent() factory is shared with the TUI —same tools, same prompts, same agent loop. The only difference is no interactive callbacks and no renderer.