Idle-safe auto-continue, scheduled OpenCode work, and background loops.
OpenCode Loop adds /loop, scheduled prompt/command/shell jobs, compact scheduling, verification/checkpoints, and the opencode-loopd background daemon.
Current stable release:
0.5.35.
Recommended:
npx -y @bybrawe/opencode-loop@latestRun the same command again to update. Then fully restart OpenCode and verify:
/loop-help
/loop-doctor
Install/update Loop and the dedicated Goals companion together:
npx -y @bybrawe/opencode-loop@latest --with-goals --without-loop-goals--without-loop-goals removes only Loop's older experimental /loop-goal* command files. It keeps normal /loop, command/shell scheduling, daemon support, and the separate /goal plugin.
Install only Loop and skip companion network work:
npx -y @bybrawe/opencode-loop@latest --loop-onlyGlobal npm alternative:
npm install -g @bybrawe/opencode-loop@latest
opencode-loopTo uninstall:
npx -y @bybrawe/opencode-loop@latest --uninstallor, for a global install:
opencode-loop --uninstall
npm uninstall -g @bybrawe/opencode-loopProject Loop state under .opencode/opencode-loop/ is intentionally preserved by uninstall.
Loop separates two ideas:
- When does work become due? Idle, a timer, a watch trigger, or
/loop-now. - When is it safe to dispatch? Only when the session is actually idle and no active tool/child work would overlap it.
A timer expiring does not intentionally inject a second model turn on top of an active one. Due work waits for idle.
/loop continue
Turkish shorthand works naturally too:
/loop devam et
Explicit equivalent:
/loop idle continue
This is an unlimited idle loop by default. When the assistant finishes and the session becomes safely idle, Loop sends the prompt again. When that turn finishes, it does the same again, until you pause/stop it or a configured limit is reached.
For very short continuation prompts such as continue, keep going, or devam et, Loop adds project-continuation guidance: treat the turn as continuation of the current repository/conversation, inspect relevant files/TODO/progress/git state as needed, find the next unfinished step, avoid redoing completed work, and verify meaningful changes when practical.
For project work, a strong default is:
/loop --safe --ask-never --progress-file progress.md devam et
Create a starter progress file first if needed:
/loop-init
/loop every 5m continue the project
This waits five minutes before the first run, then becomes due every five minutes. If the timer expires while OpenCode is busy, it waits for the next safe idle boundary rather than stacking prompts.
/loop after 5m continue once
Alias:
/loop in 5m continue once
This is a one-shot delayed job. Five minutes passing makes it due; it still waits for idle before dispatching.
/loop 5m continue the project
For backward compatibility, this form starts on the next safe idle boundary and then follows a five-minute interval.
Delay its first run explicitly:
/loop 5m --no-now continue the project
Legacy idle form is still valid:
/loop 0s continue
For the exact schedule truth table and edge cases, see docs/SCHEDULING.md.
| Command | Meaning | First dispatch | Repeats |
|---|---|---|---|
/loop continue |
auto-continue on idle | next safe idle | every idle |
/loop idle continue |
explicit idle loop | next safe idle | every idle |
/loop every 5m continue |
recurring timer | after 5m, then idle | yes |
/loop after 5m continue |
delayed one-shot | after 5m, then idle | no |
/loop in 5m continue |
delayed one-shot alias | after 5m, then idle | no |
/loop 5m continue |
legacy recurring form | next safe idle | yes |
/loop 5m --no-now continue |
legacy delayed-first recurring | after 5m, then idle | yes |
/loop 0s continue |
legacy idle form | next safe idle | every idle |
A useful first loop for an unfamiliar repository is:
/loop-init
/loop --safe --ask-never --progress-file progress.md Understand the existing project architecture and current state first. Inspect relevant source, tests, docs, TODOs, git status, and recent work. Record useful state in progress.md, choose the next unfinished safe improvement, implement it, verify it, update progress.md, and continue from there on later idle turns.
Once the project state is established, this is enough:
/loop --safe --ask-never --progress-file progress.md devam et
The short continuation form is deliberately interpreted as “resume this project”, not “invent a new task from scratch”.
Schedule an OpenCode slash command:
/loop-command 200m /compact
Run a real shell command:
/loop-shell 10m npm test
Ask a recurring quality-control prompt:
/loop-ask 1h did you run tests, typecheck, and build? If not, run them and fix errors.
Watch a path:
/loop --watch progress.md inspect the updated progress and continue
Prompt, command, shell, compact, and watch jobs use the same idle-safe scheduling path but different execution transports.
| Command | Purpose |
|---|---|
/loop <prompt> |
Add/update an unlimited idle prompt loop |
/loop idle <prompt> |
Explicit idle-loop form |
/loop every <duration> <prompt> |
Recurring timer, first run delayed |
/loop after <duration> <prompt> |
One-shot delayed prompt |
/loop in <duration> <prompt> |
Alias for after |
/loop <duration> <prompt> |
Backward-compatible compact interval form |
/loop-command <interval> <slash-command> |
Schedule an OpenCode command |
/loop-cmd <interval> <slash-command> |
Alias for /loop-command |
/loop-ask <interval> <question> |
Schedule a recurring check/question |
/loop-shell <interval> <command> |
Schedule a shell command |
/loop-status |
Show jobs plus schedule/state |
/loop-now [id/name/all] |
Mark selected jobs due now; still waits for idle |
/loop-pause [id/name/all] |
Pause jobs |
/loop-resume [id/name/all] |
Resume jobs |
/loop-remove [id/name/all] |
Remove jobs |
/loop-clear |
Remove all jobs for the current session |
/loop-logs |
Show recent scheduler/runtime events |
/loop-doctor |
Diagnose session/state/scheduling problems |
/loop-init |
Create a starter progress.md |
/loop-export |
Export current-session Loop state |
Lifecycle and limits:
--name <name>
--max-runs <n>
--max-runtime <duration>
--max-failures <n>
--timeout <duration>
--no-now
--now
Safety and verification:
--safe
--ask-never
--no-overlap
--verify "npm test"
--preflight "npm install"
--postrun "git status --short"
--pause-on-verify-fail
Project context:
--progress-file progress.md
--prompt-file loop-prompt.md
--include-file ARCHITECTURE.md
--batch 5
--compact-every 20
--watch progress.md
Checkpoints:
--checkpoint-only
--git-checkpoint
--git-checkpoint may stage/commit work; use it only when intentional.
/loop-status reports both the schedule definition and the current scheduler state. Examples:
schedule=every idle | state=waiting for idle
schedule=every 5m, first after 5m | state=due in 3m
schedule=once after 5m | state=due; waiting for idle
This is intentional: “due” is a clock fact, while “waiting for idle” is an admission/safety fact.
The problematic shape is typically:
enabled=true
paused=false
runCount=0
lastRunAt=0
Some OpenCode TUI versions can leave session.status at busy/retry after a plugin command acknowledgement. Loop cross-checks that stale state against the chronological message tail before the first Loop run too. It recovers only when the latest assistant message is actually completed and no active tool/child work is known. A genuinely unfinished assistant turn, latest user turn, active tool, busy child, or unknown completion remains busy.
Recovery is logged as:
status-message-idle-recovery
Busy retries are also written as throttled deferred events so loop.log does not misleadingly contain only the original add line.
Use:
/loop-status
/loop-logs
/loop-doctor
Normal plugin Loop jobs are session-bound and stored under:
.opencode/opencode-loop/<session-id>.json
A new OpenCode session does not silently inherit another session's jobs. /loop-doctor reports other persisted session files that still contain enabled jobs, including jobs that have never run, so an old loop is visible instead of appearing lost.
For work that must continue after the TUI/session closes, use opencode-loopd.
They can be installed together. Recommended split:
- use
/goalfor durable outcome-driven work, evidence, verification, restart recovery, and semantic completion; - use
/loop,/loop-command,/loop-shell, andopencode-loopdfor scheduling/repetition/background infrastructure.
A prompt-producing Loop and an active dedicated /goal should not both own autonomous continuation of the same session. The runtime therefore blocks a new prompt Loop when it detects an active dedicated Goal for that session.
Recommended choices are to finish/pause the Goal or use a separate session. Advanced users can deliberately override the guard with:
/loop --allow-goal-overlap continue
That escape hatch can create competing autonomous turns; use it only when that is intentional.
Loop's older experimental /loop-goal* commands remain available for compatibility unless installed with --without-loop-goals. For new strongly verified Goal work, prefer:
npx -y @bybrawe/opencode-goal@latest/loop --name dev --ask-never --safe --no-overlap --batch 5 --compact-every 200m --checkpoint-only --progress-file progress.md Treat progress.md as the project state. Continue with the next unfinished TODO, implement it, mark completed items, add useful follow-up TODOs, run tests/lint/build when available, and keep going while work remains.
Test/fix loop:
/loop --name testfix --ask-never --safe --verify "npm test" --max-failures 3 Continue from progress.md. If tests fail, analyze the failure, fix it, and run the tests again.
The normal /loop plugin is session-bound. opencode-loopd pins one exact OpenCode session for daemon iterations and can keep scheduling outside the normal interactive Loop timer lifecycle.
opencode-loopd --project . --every 5m --prompt-file loop-prompt.mdImmediate daemon cadence:
opencode-loopd --project . --every 0s --prompt "continue from progress.md and implement the next unfinished TODO"Pin a session and limit runs:
opencode-loopd --project . --session ses_xxx --every 5m --max-runs 20 --timeout 30m --prompt-file loop-prompt.mdWindows Task Scheduler:
opencode-loopd install-task --project "C:\path\to\project" --every 10m --prompt-file loop-prompt.md --name OpenCodeLoop
opencode-loopd uninstall-task --name OpenCodeLoopRuntime state and logs:
.opencode/opencode-loop/
.opencode/opencode-loop/loop.log
Patch checkpoints:
.opencode/opencode-loop/checkpoints/
Add .opencode/opencode-loop/ to .gitignore if runtime state should not be committed.
For unattended work, avoid permanently allowing every shell command. Grant routine read/edit/test operations while keeping destructive commands on ask/deny. --safe reduces risk but does not replace OpenCode permission configuration.
@bybrawe/opencode-loop
Stable package peer range:
@opencode-ai/plugin >=1.4.0 <2
The repository contains experimental OpenCode 2 work, but the stable package does not claim full OpenCode 2 parity.
See docs/SCHEDULING.md for the scheduling contract and CHANGELOG.md for release history.
MIT