Claude Code style auto-continue for OpenCode.
OpenCode Loop adds a practical /loop command and opencode-loopd daemon to OpenCode so an agent can keep working after each idle turn instead of waiting for you to type “continue” again.
It is useful for long coding sessions, progress.md workflows, TODO automation, test-fix loops, periodic /compact, checkpoints, safe autonomous development, and background OpenCode continuation jobs.
Repository: ByBrawe/opencode-loop
NPM package name: @bybrawe/opencode-loop
v0.5.11 includes a referenced heartbeat scheduler. This is important in OpenCode TUI because local command hooks are event-driven: a normal /loop-status command can wake the plugin, but a timer-only loop should not depend on a user typing another command. The heartbeat periodically checks active loop jobs, clears stale completed runs, and starts due work only when the session appears idle.
v0.5.11 is a reliability hotfix for recurring timers that only continued after manual activity. It keeps the real due timer from v0.5.8 and the stale-busy recovery from v0.5.9, then adds a watchdog checker and stronger stale-active-run recovery. This targets the case where /loop 1m ... reaches its due time but does not fire until you run /loop-status or type another command. Scheduled /compact still routes through OpenCode's current TUI alias first, with fallback paths for older builds.
The known update-related symptoms from older builds are fixed:
/loop looks queued but the job stays at runs=0/loop commands create confusing queued turns/compact accidentally being treated as a normal agent promptTool execution aborted behavior caused by triggering a new turn too early/loop-goal support for goal-driven work that continues until complete, blocked, paused, or cleared--no-now interval jobs not waking until another OpenCode event happens/loop-ask, /loop-command, and /loop-shell being configured but not reliably firing on their ownThe TUI loop is still intentionally session-bound: it runs while OpenCode is open and the current session emits status/idle events. For long-running background work after closing the terminal or OpenCode, use opencode-loopd.
OpenCode Loop has two triggers now:
All TUI jobs are still idle-safe. If the timer expires while OpenCode is busy, the job does not interrupt the active turn. It waits and retries until the session becomes idle.
Simple examples:
/loop 0s continue the project
Run every time OpenCode becomes idle.
/loop 1m --no-now continue the project
Wait 1 minute first, then run when OpenCode is idle.
/loop-command 200m /compact
Run OpenCode compact about every 200 minutes, but only when OpenCode is idle.
/loop-ask 1h did you run tests, tsc --noEmit, and build? If not, run them and fix errors.
Ask a recurring quality-control question every hour.
/loop-shell 10m npm test
Run a shell command every 10 minutes when idle.
/loop-goal --max-turns 5 --check "npm run build" --complete-when-checks-pass make the project build cleanly
Experimental persistent goal mode: keep working until the goal is complete, blocked, paused, cleared, or a safety limit is reached.
Note: OpenCode custom command markdown still creates a tiny assistant turn for slash commands. v0.5.11 keeps these command templates short and asks the model to reply
OK. The actual loop scheduling is handled locally by the plugin. If that short turn briefly makes OpenCode look busy, the loop now recovers with fresh status checks, stale-active-run recovery, and a watchdog that does not require another manual command.
Claude Code users often rely on a loop-like workflow where the agent finishes one step, then immediately continues with the next step.
OpenCode is powerful, but long-running autonomous workflows usually need extra control around:
progress.md and TODO-driven developmentOpenCode Loop is designed for developers searching for:
/loop commandThe TUI
/loopcommand is session-bound. It runs while OpenCode is open and the session receives idle/status events. If the terminal closes, the machine sleeps, the process is killed, or the provider connection is lost for a long time, the TUI loop cannot continue in the background. For long-running loops, useopencode-loopddaemon mode.
/loop 0s ..../loop, active while OpenCode is open.opencode-loopd for long-running loops outside the OpenCode TUI.opencode-loopd install-task.--prompt-file loop-prompt.md for long reusable instructions.opencode-loopd --prompt-file loop-prompt.md.--include-file.--progress-file progress.md.--batch./loop 200m /compact or --compact-every.--verify "npm test".--preflight "npm install".--postrun.--max-failures and --pause-on-verify-fail.--max-runtime 6h.--max-runs.--no-now for TUI loops and --sleep-first for daemon mode.--checkpoint-only or --git-checkpoint.--safe and prompt-level destructive command warnings.--branch ai-loop.--stop-file STOP_LOOP, --until, /loop-stop, /loop-pause, /loop-resume, and /loop-remove.--watch progress.md./loop-goal, goal status, goal tools, acceptance criteria, and verification checks./loop-doctor./loop-init./loop-export.Use the npm installer from any shell: Windows PowerShell, Windows CMD, macOS, or Linux.
npx -y @bybrawe/opencode-loop@latest
The installer copies the plugin and slash command files into your OpenCode config directory.
It also removes the old local opencode-loop.js copy from earlier releases so only the current local opencode-loop.ts plugin remains.
Windows target paths:
%USERPROFILE%\.config\opencode\plugins\opencode-loop.ts
%USERPROFILE%\.config\opencode\commands\loop*.md
macOS / Linux target paths:
~/.config/opencode/plugins/opencode-loop.ts
~/.config/opencode/commands/loop*.md
Then fully restart OpenCode and run:
/loop-help
/loop-doctor
The npm package also installs the opencode-loopd CLI for background loops:
opencode-loopd --help
npx is the recommended npm installOpenCode can load npm plugins from the plugin array in opencode.json, but OpenCode slash commands are discovered from command definitions such as markdown files in a commands/ directory or command entries in config.
The npx installer installs both parts:
/loop-* command markdown filesUse the OpenCode config-only method only if you already installed the command files separately or you are only testing plugin loading.
Do not use the config package entry and the local npx-installed plugin at the same time unless you intentionally want to test duplicate plugin loading.
If you want OpenCode to load the npm plugin package directly, add the scoped package name to your OpenCode config:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@bybrawe/opencode-loop"]
}
Use the scoped package name exactly as shown.
opencode-loop without @bybrawe/ is a different npm package name.
If /loop does not appear after using only the config method, run the installer once:
npx -y @bybrawe/opencode-loop
If you later switch back to the recommended npx local install, remove @bybrawe/opencode-loop from the plugin array to avoid loading the package plugin and local plugin together.
Use this if you want to install from source instead of npm.
Windows PowerShell:
git clone https://github.com/ByBrawe/opencode-loop.git
cd opencode-loop
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1
macOS / Linux / Git Bash:
git clone https://github.com/ByBrawe/opencode-loop.git
cd opencode-loop
chmod +x ./scripts/install.sh
./scripts/install.sh
Then restart OpenCode and run:
/loop-help
/loop-doctor
Windows PowerShell:
mkdir "$env:USERPROFILE\.config\opencode\plugins" -Force
mkdir "$env:USERPROFILE\.config\opencode\commands" -Force
copy .\src\index.js "$env:USERPROFILE\.config\opencode\plugins\opencode-loop.ts"
copy .\commands\*.md "$env:USERPROFILE\.config\opencode\commands\"
macOS / Linux:
mkdir -p ~/.config/opencode/plugins ~/.config/opencode/commands
cp ./src/index.js ~/.config/opencode/plugins/opencode-loop.ts
cp ./commands/*.md ~/.config/opencode/commands/
Use this when you want the plugin to be available only inside one repository.
mkdir -p .opencode/plugins .opencode/commands
cp ./src/index.js .opencode/plugins/opencode-loop.ts
cp ./commands/*.md .opencode/commands/
On Windows PowerShell:
mkdir .opencode\plugins -Force
mkdir .opencode\commands -Force
copy .\src\index.js .opencode\plugins\opencode-loop.ts
copy .\commands\*.md .opencode\commands\
After restarting OpenCode, run:
/loop-help
/loop-doctor
If the commands do not appear:
opencode-loop.ts exists in the OpenCode plugin directory.loop.md, loop-help.md, and the other command files exist in the OpenCode commands directory.npx -y @bybrawe/opencode-loop again to reinstall the command files.Auto-continue every time OpenCode finishes a turn:
/loop 0s continue from progress.md and implement the next unfinished TODO
Run now, then continue every 1 minute when OpenCode is idle:
/loop 1m continue the project
Wait 1 minute before the first run, then continue every 1 minute when idle:
/loop 1m --no-now continue the project
Run OpenCode compact every 200 minutes, but only when OpenCode is idle:
/loop-command 200m /compact
Ask a recurring check question every hour:
/loop-ask 1h did you run tests, tsc --noEmit, and build? If not, run them and fix any error.
Run a real shell command every 10 minutes when idle:
/loop-shell 10m npm test
Experimental goal mode: keep working until the objective is actually done, blocked, paused, or cleared:
/loop-goal finish the feature, run tsc --noEmit and build, fix every error, and stop only when everything passes
OpenCode Loop is idle-safe. It does not intentionally start a new agent turn while OpenCode is already busy.
Example:
/loop 5m continue the project
If 5 minutes pass while OpenCode is still working, the job becomes due but waits. As soon as OpenCode becomes idle, the loop sends the prompt. This avoids queued turns, aborted tools, and overlapping responses.
Use a prompt loop when you want to ask or instruct the agent:
/loop 1h check if tests, tsc --noEmit, and build pass. If not, fix them.
Use a command loop when the action starts with / and should be executed as an OpenCode command:
/loop-command 200m /compact
Do not use this for compacting:
/loop 200m /compact
That can look like a chat prompt in older versions or unclear setups. Prefer /loop-command 200m /compact or the shortcut below:
/loop-compact 200m
Goal Mode is experimental. Use it when you do not want a timer such as “every 5 minutes”. Use it when you want OpenCode to keep pursuing a result until it is complete or blocked.
Basic goal:
/loop-goal fix the TypeScript build errors. Run tsc --noEmit and npm run build. Stop only when both pass.
What happens:
$ claude mcp add opencode-loop \
-- python -m otcore.mcp_server <graph>