| description | Headless dispatch patterns for parallel AI agent execution via OpenCode | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| mode | subagent | ||||||||||||||||
| tools |
|
- One-shot:
opencode run "prompt"| Warm server:opencode run --attach http://localhost:4096 "prompt" - Server:
opencode serve [--port 4096]| SDK:npm install @opencode-ai/sdk - Runners:
runner-helper.sh [create|run|status|list|stop|destroy]→~/.aidevops/.agent-workspace/runners/ - Model override:
opencode run -m openrouter/anthropic/claude-sonnet-4-6 "Task"| Auth:opencode auth login
Use for: parallel tasks, scheduled/cron AI work, CI/CD, chat-triggered dispatch (Matrix/Discord/Slack via OpenClaw), background tasks.
Don't use for: interactive dev (use TUI), frequent human-in-the-loop, single quick questions.
Diagnostics: When workers fail, stall, or loop: reference/worker-diagnostics.md.
Draft agents: Share domain instructions across workers via ~/.aidevops/agents/draft/. See tools/build-agent/build-agent.md.
Remote dispatch: tools/containers/remote-dispatch.md (SSH/Tailscale with credential forwarding).
Never use bare
opencode runfor dispatch — skips lifecycle reinforcement, workers stop after PR creation (GH#5096). Always useheadless-runtime-helper.sh run.
- Network:
--hostname 127.0.0.1(default) | SetOPENCODE_SERVER_PASSWORDfor network exposure - Permissions:
OPENCODE_PERMISSIONenv var for headless autonomy ('{"*":"allow"}'for CI/CD) - Credentials: Never pass secrets in prompts — use environment variables. Delete sessions after use.
- Scoped tokens (t1412.2): Workers get minimal-permission GitHub tokens (
contents:write,pull_requests:write,issues:write) scoped to target repo. Flow:worker-token-helper.sh create --repo owner/repo --ttl 3600→GH_TOKENenv → worker executes →worker-token-helper.sh revoke. GitHub App installation tokens (repo-scoped, 1h TTL) or delegated tokens (configurable TTL). Disable:WORKER_SCOPED_TOKENS=false. Setup:https://github.com/settings/apps/new→ Contents/PRs/Issues R&W → configure~/.config/aidevops/github-app.json(600 perms). - Worker sandbox (t1412.1): Fake HOME — only
.gitconfig,GH_TOKEN,.aidevops/symlink (read-only), MCP config, writable XDG dirs. No~/.ssh/, gopass,credentials.sh, cloud/publish tokens, browser profiles.WORKER_SANDBOX_ENABLED=true(default). CLI:worker-sandbox-helper.sh create <task_id>→ auto-clean on exit. - Network tiering (t1412.3): 5-tier domain classification. Tier 5 (exfiltration) denied, Tier 4 (unknown) flagged. Config:
configs/network-tiers.conf. Seenetwork-tier-helper.sh.
opencode run "Review src/auth.ts for security issues" # one-shot
opencode run -m anthropic/claude-sonnet-4-6 "Task" # model override
opencode run --agent plan "Analyze the database schema" # agent override
opencode run -f ./schema.sql "Generate types" # file context
opencode run -c "Continue" | -s ses_abc123 "Add handling" # resume sessionWarm server: opencode serve --port 4096 once, then opencode run --attach http://localhost:4096 "Task" (avoids MCP cold boot).
SDK: import { createOpencode } from "@opencode-ai/sdk" → createOpencode({ port: 4096 }). Connect: createOpencodeClient({ baseUrl: "http://localhost:4096" }).
HTTP API: tools/ai-assistants/opencode-server.md. Key: POST /session → POST /session/$ID/message. Async: POST .../prompt_async (204). SSE: GET /event. Fork: POST /session/$ID/fork. No-reply: noReply:true.
Stagger manual launches by 30-60s to avoid thundering herd (RAM exhaustion, API rate limiting, MCP cold boot storms). Pulse supervisor handles staggering automatically (RAM_PER_WORKER_MB, RAM_RESERVE_MB, MAX_WORKERS_CAP).
HELPER="$(aidevops config get paths.agents_dir | sed "s|^~|$HOME|")/scripts/headless-runtime-helper.sh"
for issue in 42 43 44; do
$HELPER run --role worker --session-key "issue-${issue}" --dir ~/Git/myproject \
--title "Issue #${issue}" --prompt "/full-loop Implement issue #${issue}" &
sleep 30
doneMonitoring: worker-watchdog.sh --status (active) | --install (launchd hung/idle detection with transcript-tail inspection). SDK: Promise.all for concurrent sessions, SSE via client.event.subscribe().
Runners: Named, persistent agent instances at ~/.aidevops/.agent-workspace/runners/<name>/ with AGENTS.md, config.json, optional memory.db. CLI: runner-helper.sh create|run|status|list|destroy. Memory: memory-helper.sh store/recall --namespace "runner-name". Inter-runner: mail-helper.sh send --to/--from. Templates: tools/ai-assistants/runners/ (README).
Custom agents: Define via .opencode/agents/<name>.md or opencode.json with frontmatter controlling tools, permission, model, temperature. Example: restrict to read-only git commands with permission: { bash: { "git diff*": allow, "*": deny } }. Usage: opencode run --agent <name> "prompt".
opencode auth login for setup. Override: opencode run -m openrouter/anthropic/claude-sonnet-4-6 "Task".
OAuth-aware routing (t1163): SUPERVISOR_PREFER_OAUTH=true (default) routes Anthropic requests through Claude CLI if OAuth available (zero marginal cost). Non-Anthropic → opencode. Override: SUPERVISOR_CLI=opencode. Detection: ~/.claude/ credentials, cached 5 min. Budget: budget-tracker-helper.sh configure claude-oauth --billing-type subscription.
Proceed autonomously (document in commit): inferable from context/conventions, only affects own task scope, multiple valid approaches (pick simplest), style ambiguity (follow conventions), equivalent patterns (match precedent), minor adjacent issues (note in PR body).
Exit BLOCKED: contradicts codebase, breaks public API, task done/obsolete, missing deps/credentials, architectural decisions affecting other tasks, create-vs-modify with data loss risk, multiple interpretations with very different outcomes. Example: BLOCKED: 'update the auth endpoint' but 3 exist (JWT, OAuth, API key). Need clarification.
Supervisor: Proceed → normal PR review. BLOCKED → clarifies/retries or creates prerequisite. Unclear error → diagnostic worker (-diag-N).
Lineage context (t1408): When dispatching subtasks (dot-notation IDs like t1408.3), include a lineage block to prevent scope drift. Include when task ID has a dot AND siblings may run in parallel. Workers: focus only on <-- THIS TASK, stub sibling deps, exit BLOCKED on hard dependencies.
TASK LINEAGE:
0. [parent] Build a CRM (t1408)
1. Contact management (t1408.1)
2. Deal pipeline (t1408.2) <-- THIS TASK
3. Email integration (t1408.3)
LINEAGE RULES: Focus ONLY on "<-- THIS TASK". Stub sibling deps. Exit BLOCKED if hard dependency.
Assembly: PARENT_ID="${TASK_ID%.*}", grep TODO.md for siblings. task-decompose-helper.sh format-lineage does not yet support task-id lookup (t1408.1). Dispatch: append ${LINEAGE_BLOCK} to --prompt via headless-runtime-helper.sh run.
Decomposition (t1408.2): Tasks classified as atomic (dispatch directly) or composite (split into 2-5 subtasks with dependency edges). Interactive: show tree, ask Y/n/edit. Pulse: auto-proceed (depth limit: 3). Integration: /full-loop (Step 0.45), /pulse (Step 3), /new-task (Step 5.5), /mission. CLI: task-decompose-helper.sh classify|decompose|format-lineage|has-subtasks. Config: DECOMPOSE_MAX_DEPTH=3, DECOMPOSE_MODEL=haiku, DECOMPOSE_ENABLED=true. Principle: "When in doubt, atomic."
Batch strategies (t1408.4): batch-strategy-helper.sh next-batch --strategy depth-first|breadth-first --tasks "$JSON" --concurrency "$SLOTS". Depth-first (default): finish one branch before next. Breadth-first: one subtask per branch per batch. Hybrid: parallel analysis → sequential implementation.
Injected via supervisor dispatch (~300-500 token overhead, 20-100x ROI):
- TodoWrite — 3-7 subtasks at start. Last: "Push and create PR". Survives compaction.
- Commit early — per subtask. After first:
git push -u origin HEAD && gh pr create --draft. - ShellCheck gate (t234) — Before push, if
.shchanged:shellcheck -x -S warning. - Parallel sub-work (MANDATORY) — Task tool for independent ops. Sequential for: same-file writes, dependent steps, git ops.
- Research offloading — Task sub-agents for 500+ line files. Checkpoint:
session-checkpoint-helper.sh saveper subtask. - Fail fast — Verify assumptions before coding. Exit BLOCKED after one retry. Token min: read ranges, concise commits.
Parallel vs sequential: Independent read-only ops (reviews, audits, multi-module tests) → parallel. Dependent chains (fix→test, refactor→docs, plan→implement→verify) → sequential.
- run: opencode run --format json "Review PR changes for security and quality" > review.md
env: { ANTHROPIC_API_KEY: "${{ secrets.ANTHROPIC_API_KEY }}", OPENCODE_PERMISSION: '{"*":"allow"}' }tools/ai-assistants/opencode-server.md (server API) | tools/ai-assistants/overview.md (assistant comparison) | tools/ai-assistants/runners-README.md (templates) | scripts/runner-helper.sh | scripts/cron-dispatch.sh, scripts/cron-helper.sh (cron) | scripts/matrix-dispatch-helper.sh, services/communications/matrix-bot.md (Matrix) | scripts/commands/pulse.md (supervisor) | scripts/mail-helper.sh (mailbox) | scripts/worker-token-helper.sh (t1412.2) | scripts/network-tier-helper.sh, scripts/sandbox-exec-helper.sh (network+sandbox) | configs/network-tiers.conf | tools/security/prompt-injection-defender.md | reference/memory.md (memory system)