opencode-loops
v0.1.1
Published
Structured, repeatable workflow loops for OpenCode — Build, Feature, Refactor, Performance, Bug, and Security — driven to verified completion by an independent goal-verifier. Zero-config install: registers itself with OpenCode on install.
Readme
opencode-loops
Structured, repeatable workflow loops for OpenCode — Build, Feature, Refactor, Performance, Bug, and Security — each driven to verified completion by an independent goal-verifier.
What is opencode-loops
opencode-loops is an OpenCode plugin that turns fuzzy tasks ("add user auth", "fix the flaky test", "harden the login endpoint") into a fixed sequence of phases that an agent executes. The key idea is a strict separation of responsibilities:
- The framework provides structure and contracts. Each loop is a list of phases. Every phase declares an optional
agent(who runs it) and, for some phases, an I/O contract that its output must satisfy. - The model provides judgment. A
loop-orchestratoragent reads the loop definition and the current state, then decides how to achieve each phase — inline with its own tools, by dispatching a specialist subagent, or by spawning a nested/loop-*. - An independent
goal-verifierdecides when you are done. After every phase sequence, the orchestrator hands the original goal, all phase outputs, and the living doc to a separate, read-onlygoal-verifiersubagent. The verifier returns STOP (goal achieved) or CONTINUE (with the gaps it found). The orchestrator never gets to declare its own work finished — it loops until the verifier says STOP.
This prevents the classic failure mode where the model that did the work also decides the work is done. Completion is judged by a fresh, evidence-checking viewpoint.
Install
opencode-loops ships as a single npm package. Installing it auto-registers the plugin with OpenCode — you do not edit any config by hand.
Global install (recommended)
npm install -g opencode-loopsOn install, a postinstall step runs opencode-loops init --global, which adds the plugin to your global OpenCode config (~/.config/opencode/opencode.json, or %APPDATA%/opencode/opencode.json on Windows). Restart OpenCode and the /loop-* commands are available everywhere.
Project install
npm install opencode-loops
# or, in a pnpm project:
pnpm add opencode-loopsThe postinstall step runs opencode-loops init, registering the plugin in the project opencode.json (created next to your project if missing).
Manual / opt-out
If you disabled the auto-init (or set OPENCE_LOOPS_NO_AUTOINIT=1), register it yourself:
opencode-loops init # project config
opencode-loops init --global # global config
opencode-loops init --dry-run # preview what would be writtenThe entry added to your config is either the package name "opencode-loops" (project installs, resolved from local node_modules) or the absolute path to the bundled plugin (global installs, for reliable resolution).
Local development (from source)
Contributors clone the monorepo and register the plugin by path:
pnpm install{
"plugin": [
"./packages/plugin/src/index.ts"
]
}Quickstart
Invoke a loop from the OpenCode TUI or chat:
/loop-feature "add user auth"The loop-orchestrator takes over: it loads the Feature loop definition, initializes state at .opencode/loops/feature.state.json, and begins writing progress to the living doc at .opencode/loops/current.md. When the phase sequence completes, the goal-verifier checks whether "user auth" is actually done. If not, the loop continues.
Loop reference
All six loops end with a verify-goal phase run by the independent goal-verifier subagent.
| Loop | Command | Phases |
|------|---------|--------|
| Build | /loop-build | goal → inspect → implement → test → critic → fix → verify → verify-goal |
| Feature | /loop-feature | understand → spec → goal → inspect → implement → test → critic → fix → verify → verify-goal |
| Refactor | /loop-refactor | analyze → propose → validate → refactor → test → compare → verify-goal |
| Performance | /loop-performance | measure → profile → identify → optimize → benchmark → compare → verify-goal |
| Bug | /loop-bug | reproduce → isolate → hypothesize → patch → regression-test → verify → verify-goal |
| Security | /loop-security | scan → threat-model → exploitability → fix → retest → verify-goal |
Each phase's agent is either null (run inline by the orchestrator), explore / general (a specialist subagent), or goal-verifier (the independent read-only verifier). See docs/loops/ for a per-loop breakdown with example flows.
Architecture
User / OpenCode TUI
│ /loop-build · /loop-feature · /loop-bug · /loop-refactor · ...
▼
loop-orchestrator agent
│ reads def + state, executes phases, validates,
│ updates living doc, dispatches verifier, loops on CONTINUE
├── loop definitions (YAML) packages/loops/src/definitions
├── state store (.opencode/loops/<id>.state.json, atomic)
├── living doc (.opencode/loops/current.md)
└── goal-verifier subagent (read-only, returns STOP / CONTINUE)
▲
V2 plugin (packages/plugin) registers commands, agents, hookspackages/loops— shared, zero-runtime-dependency library: core types, phase I/O contracts, the validation engine, the YAML parser, the inheritance resolver, and the built-in loop definitions.packages/plugin— the OpenCode V2 plugin (Plugin.define). It registers theloop-orchestratorandgoal-verifieragents viactxtransforms, registers the/loop-*commands, and installs the defensive hooks (state init, auto-resume, compaction context).packages/cli— the developer CLI (opencode-loops list | status | reset | doc).
How it works
- You invoke
/loop-feature "add user auth". - The plugin hook creates/loads
LoopStateand initializes the living doc. - The
loop-orchestratorreceives the loop definition, the state, and your goal. - It executes phases sequentially:
- Inline phases (
agent: null) are performed by the orchestrator with its own tools. - Subagent phases are dispatched to a specialist (
explorefor investigation,generalfor generation/work). - Nested loops — a phase may invoke another
/loop-*programmatically (e.g. arefactorphase triggering/loop-bugto fix a regression).
- Inline phases (
- After each phase, the output is validated against the phase contract. Validation failures retry (where
retry: true) or route back into a fix cycle. - The orchestrator decides whether the work satisfies the contract, then updates state and the living doc (
.opencode/loops/current.md). - After the full sequence, the orchestrator dispatches the
goal-verifiersubagent with the goal statement, all phase outputs, and a living-doc summary. - The verifier returns STOP (loop ends, final report emitted) or CONTINUE (with gaps). On CONTINUE the orchestrator loops back to the phase that needs more work — the loop never stops until the verifier says STOP.
State survives compaction and restart: a session-created / restart hook offers to resume any incomplete loop, and compaction injects the loop-state summary so the orchestrator remembers where it was.
Customizing
- Edit an agent. Change the behavior, prompts, or constraints of the orchestrator or verifier by editing
.opencode/agents/loop-orchestrator.mdor.opencode/agents/goal-verifier.md. - Add a loop. Drop a new YAML file in
packages/loops/src/definitionsnamed<id>-loop.yamlcontainingid,name,description,phases(an ordered list, each withid,name, optionalagent, optionalcontract/validation), andextends(optional, to inherit another loop's phases). For example,qa-loop.yamlcouldextends: build. The<id>becomes the/loop-<id>command target once registered. - Force STOP. If the verifier is too strict, you can override to end a loop (calibrated via the example projects).
CLI
The developer CLI is available as opencode-loops (bin) and operates on the .opencode/loops/ state directory:
| Command | Description |
|---------|-------------|
| opencode-loops list | Show all loops (active and completed) from the state directory. |
| opencode-loops status <id> | Show the current phase and progress for a loop. |
| opencode-loops reset <id> | Reset a stuck loop — clears its state and living doc. |
| opencode-loops doc <id> | Regenerate the living doc for a loop. |
Contributing
This is a pnpm monorepo. To build, test, and lint locally:
pnpm install
pnpm build
pnpm test
pnpm lintpnpm dev— watch mode for all packages.pnpm changeset— add a changeset for your change (see.changeset/README.md).- Keep the separation of concerns:
packages/loopsstays framework-only (no OpenCode runtime deps),packages/pluginowns the V2 wiring, andpackages/clistays a thin developer tool.
License
MIT © Loops for OpenCode contributors.
