A coordinated sub-agent swarm for OpenCode. Give it a spec, it builds, tests, and reviews your code autonomously — using local models.
Local LLMs (Qwen, Gemma, Llama, etc.) stop generating after 1-3 tool calls. Every agentic coding tool fights this. They all lose. Your agent reads a file, writes some code, maybe runs a test — then stops. You hit enter. It does one more thing. Stops again. That's not autonomous. That's a fancy autocomplete.
Stop fighting the model. Work with it.
Salvo splits work across focused sub-agents. Each one does exactly one job and returns — by design. An orchestrator coordinates the pipeline. The model's tendency to stop becomes the architecture, not a bug.
Orchestrator (primary)
├── @code-writer — implements features
├── @test-writer — writes and runs tests
├── @code-reviewer — PASS/FAIL code review
├── @task-tracker — tracks progress in tasks.json
└── @bug-reporter — documents unfixable issues
spec → implement → test → review → ship. Each step is one focused agent call. No token-burning retry loops. No hoping the model keeps going.
- OpenCode installed and configured with at least one model provider
- A model that supports tool calling (Qwen 3.5, Gemma 4, Llama 3.3, etc.)
git clone https://github.com/nicdavidson/salvo.git
cd salvo
./setup.sh installThat puts oc-salvo on your PATH. Then in any project:
cd my-project
oc-salvo initDone. Agents are copied into .opencode/agent/ and ready to go.
cd your-project
opencodeThe orchestrator is your default agent. Give it work:
Build a REST API for managing todo items with SQLite storage.
Or point it at a spec file:
Read spec.md and build everything in it.
Or use sub-agents directly:
@code-writer Add a /api/users endpoint with pagination.
| Agent | Purpose | Mode | Can edit files? |
|---|---|---|---|
orchestrator |
Drives the full build pipeline | primary (default) | yes |
@code-writer |
Implements features | subagent | yes |
@test-writer |
Writes and runs tests | subagent | yes |
@code-reviewer |
Reviews code quality | subagent | no (read-only) |
@task-tracker |
Manages tasks.json + progress.md |
subagent | yes (state files only) |
@bug-reporter |
Documents bugs when fixes fail | subagent | no (read-only) |
┌─────────────────────────────────────────────────┐
│ Orchestrator │
│ │
│ 1. Parse spec → break into features │
│ 2. @task-tracker init │
│ │
│ For each feature: │
│ ├── @code-writer → implement │
│ ├── @test-writer → write + run tests │
│ │ └── FAIL? → @code-writer fix (2x max) │
│ │ └── Still failing? → @bug-reporter │
│ ├── @code-reviewer → review │
│ │ └── FAIL? → @code-writer fix (2x max) │
│ └── @task-tracker → mark complete │
│ │
│ 3. @task-tracker summary │
└─────────────────────────────────────────────────┘
- Max 2 fix attempts per issue — prevents infinite token-burning loops
- Unresolvable issues get documented as bug reports, not retried forever
- Progress tracking via
tasks.jsonsurvives session restarts
Agents ship without a hardcoded model — they use whatever OpenCode defaults to. To pin a specific model, add model: to any agent's frontmatter:
---
description: Implements features from specs or task descriptions.
model: ollama/qwen3.5:27b
---Each agent is a single markdown file in .opencode/agent/. The frontmatter controls behavior:
---
description: What this agent does (shown in @ menu)
prompt: System prompt for the agent
mode: primary | subagent
model: provider/model-name # optional
temperature: 0.2 # optional
tools:
read: true
write: true
edit: true
bash: true
glob: true
grep: true
---The body of the file is the agent's detailed instructions. Edit freely — these are yours.
If you ran ./setup.sh install, oc-salvo is already on your PATH. Just oc-salvo init in any project.
Salvo works best with clear specs. A good spec has:
# Project: My App
## Feature 1: User Authentication
- POST /api/register — email + password, returns JWT
- POST /api/login — email + password, returns JWT
- Passwords hashed with bcrypt
- JWT expires in 24h
## Feature 2: Todo CRUD
- GET /api/todos — list all for authenticated user
- POST /api/todos — create, requires title
- DELETE /api/todos/:id — delete, only owner can deleteConcrete endpoints. Clear acceptance criteria. No ambiguity. The more specific your spec, the better Salvo builds it.
Create a new .md file in your project's .opencode/agent/ directory:
---
description: What it does
prompt: You are a... [system prompt]
mode: subagent
tools:
read: true
bash: true
---
## Purpose
What this agent is for.
## Rules
- What it should and shouldn't do.The orchestrator can call any agent with @agent-name. Add new specialists as needed — a @db-migrator, @api-designer, @security-auditor, whatever your workflow needs.
PRs welcome. Some areas that could use work:
- New agents — security auditor, API designer, documentation writer, performance profiler
- Orchestrator improvements — better error recovery, parallel feature building, smarter retry logic
- Model-specific tuning — temperature, prompt tweaks for different model families
- Pipeline variants — not everything needs the full test+review cycle
- Examples — real specs and the code Salvo built from them
If you've got a local model setup and opinions about how agents should coordinate, this is your repo.
- Fork the repo
- Create a branch (
git checkout -b my-agent) - Add or modify agents in
agents/ - Test with OpenCode locally
- Open a PR with what you changed and why
Keep agent files focused. One job per agent. If an agent needs 200 lines of instructions, it's doing too much.
A salvo is a coordinated volley — multiple shots fired in sequence, each aimed at a specific target. That's what this does. Each agent fires one focused burst, hits its target, and the next one goes. No spray and pray. No single-agent-does-everything chaos.
MIT