Agent Loop
License
This project is source-available under the PolyForm Perimeter 1.0.1.
You may use, study, modify, and contribute to the software subject to the license terms. Use of this software to create or provide a competing product is not permitted.
Commercial licensing and other licensing arrangements are available from the copyright holder.
One button that runs a self-routing AI development loop against a ClickUp board.
Claude, Codex and Grok take turns coding and reviewing each other's work. A ClickUp list is the task
queue, the state machine and the audit trail. You press one button; work moves from ready to
committed on its own, and stops there — deploy is always yours.
What it actually does
Every pass, the dispatcher senses which agent CLIs are up and not rate-limited, then routes itself.
There are no modes and no reviewer to pick.
| Claude |
Codex |
Grok |
What happens |
| ✓ |
✓ |
✓ |
Grok codes → Codex reviews → commit + push |
| ✓ |
✓ |
✗ |
Claude codes → Codex reviews → commit + push |
| ✓ |
✗ |
✓ |
Grok codes → Claude reviews → approved, lands next pass |
| ✓ |
✗ |
✗ |
Claude codes and self-reviews → parks on in review |
| ✗ |
✓ |
✓ |
Grok codes → Codex reviews → parks on approved |
| ✗ |
✗ |
✓ |
Grok codes and self-reviews → parks on in review |
| ✗ |
✓ |
✗ |
Stops — a reviewer is up but nothing can code |
The invariant that never bends: nothing is ever committed that was reviewed by the agent that
wrote it. When the second opinion isn't available, work parks instead of landing. That is the
whole design — an agent grading its own homework is not review.
Beyond the routing, the parts that matter in practice:
- A verification gate. Before reviewed work lands, your test command runs against the reviewed
commit in an isolated checkout with credentials stripped. "The reviewer approved it" and "the
suite is green" are different claims, and this one requires both. Nothing here pins a database or
a service: whatever the verify process exports would override the non-forced env declarations in
your test config, so a hardcoded engine would silently test a stack production does not run. Point
AGENT_LOOP_VERIFY_ENV_FILE at the same environment file CI uses instead. Keep
AGENT_LOOP_VERIFY repo-relative (for example, node tools/verify.mjs) so the sandbox runs the
reviewed copy; an absolute path back into the primary repo is refused at startup.
- Isolation. Every agent call runs in a throwaway
git clone under the temp directory, with no
remotes and no credential helper. The dispatcher is the only thing that touches your real repo.
It snapshots git status before and after every call and stops hard if anything moved.
- Churn escalation. A task that fails review five rounds running is not retried blindly. It gets
one diagnosis pass: a fixable contradiction in its acceptance criteria is repaired automatically
and the task returns to
ready; a genuine multi-concern task is parked for a human to split.
- Safe Stop. Click the button while it runs and it finishes the round it is in, never
interrupting an agent mid-task, writes a handover report, and exits with the tree and board
consistent.
- Watcher. While the loop runs, the extension watches a heartbeat file and the new log
lines. A known failure gets a fixed response (repair, wait, report, or Safe Stop). An unknown
frozen loop or a repeated unknown error is sent to headless Claude with no tools, and only an
allowlisted action can run. Before the first call it checks that the command
replies
OK; if not, the playbook runs and the watcher log says why. That
bundle includes the churn tally in ~/.agent-loop-rounds.json. While the
loop runs, a zero-commit stub counted beyond its chain base makes the watcher
stop the loop, wait until it exits, run --reset-stub, and start it again.
A refusal stays a report with the two manual steps. A coder that is out of
credit can be benched only through a dispatcher command that re-checks the
preconditions. Your own Safe Stop is never restarted. A process that keeps
spinning after that stop is killed, and the loop stays stopped. A coder killed
by the implementation ceiling twice on the same task is reported: those kills
do not count toward the round limit, so the churn guard cannot see them.
While the loop runs, the Output channel Agent Loop Watcher logs stage
changes, status lines, verdicts, kills and playbook decisions. It does not
log a line on every poll. Set AGENT_LOOP_WATCHER_VERBOSE=off to keep it
quiet. A NOTIFY row is written once. It is written again only when its
signature changes, and a ceiling repeat's signature includes the count.
Only one window on the machine runs the watcher. Another window says so
once in the Output channel and does not act or narrate.
AGENT_LOOP_WATCHER_NARRATE can also explain those events in that same
Output channel (off by default). Experimental. It uses the claude CLI,
not a Claude chat. problems sends a playbook match at once and shows the
channel without taking focus. events also sends stage, status, verdict
and kill changes, batched at AGENT_LOOP_WATCHER_NARRATE_MIN_S (default
300), and does not show the channel on its own. Calls share the hourly
Claude cap. Each call is stateless. The command is the default headless
command, including --no-session-persistence, with tools disabled,
permission prompts off, and --safe-mode. --bare is not used. The
working directory is an empty temp directory, so the workspace's
instructions and hooks stay out. The reply is redacted and written as one
block. A failure is logged and the tick continues. One measured call in
that temp directory, with --output-format json (narration does not pass
that flag), used 2 input tokens, 10,422 cache-creation tokens and 73,283
cache-read tokens. The same call with --safe-mode used 2, 392 and 1,647,
and a subscription login still worked, so narration passes --safe-mode.
The report is ~/.agent-loop-watcher-report.md.
- Reviewers only ever see the task's own work. The review diff is taken from the merge base
with the base branch, never from its moving tip. A hotfix landing on
main while a task is open
is not part of that task's diff, so no reviewer can fail a task for "reverting" work it never
touched — and no round is burned on an implementer refusing to fix a change it never made.
- Dependency chaining. A task whose completed blockers left exactly one unmerged branch forks
from that branch, so sequential work accumulates and reviewers still see only each task's own
increment. Landing pushes each task branch and never merges to
main, so when two finished
predecessors still sit on separate branches no single fork base holds both — the task is parked on
blocked naming them, instead of quietly forking from main with neither prerequisite present.
Requirements
- Node.js 18+, Git, VS Code 1.85+ (or Cursor)
- A ClickUp account and a personal API token
- At least one of the
claude, codex, grok CLIs on PATH — two to land code unattended
The extension ships the dispatcher inside itself. Your repository needs nothing added to it.
Install
Search Agent Loop in your editor's Extensions panel, or install from the command line.
Either way the editor keeps it up to date for you.
VS Code — Marketplace listing
code --install-extension SergeyOhanyan.agent-loop
Cursor, VSCodium, Windsurf — these do not use the Microsoft Marketplace, so they pull the same
extension from Open VSX
cursor --install-extension SergeyOhanyan.agent-loop
Installing the .vsix by hand — for an air-gapped machine, or to pin a version
Download it from the
latest release and
verify it against SHA256SUMS.txt, then:
code --install-extension agent-loop-<version>.vsix
Or in VS Code: Extensions → … menu → Install from VSIX…
A hand-installed .vsix does not auto-update — that is the one thing you give up by taking
this path. To move to a new version, download and install it again.
Building it yourself instead — no dependencies, Node 18+ is all you need:
npm test && npx @vscode/vsce package
Setup
Then click Agent Loop: set up in the status bar and follow the wizard. It validates your token,
creates the ClickUp list, and tells you exactly which statuses and custom fields to add by hand —
ClickUp's API cannot create those, so the wizard checks rather than pretends.
SETUP.md is the full walkthrough, including the one setting people get wrong
(committed must be created in ClickUp's Done category, or every chained task waits forever).
AI_Setup.md is the same procedure written as a prompt — paste it into Claude
Code, Copilot or Cursor and have your editor's agent configure it interactively.
Configuration
Everything lives in one env file, ~/.agent-loop.env, deliberately outside every repository:
the dispatcher resets working trees as it moves between task branches, so a token file inside a repo
can get swept into a commit.
agent-loop.env.example documents every setting. Copy it and delete
what you don't need — two keys are required, everything else has a working default. Run
Agent Loop: Open the config file to open it, seeded from the example on first use.
|
|
| Required |
CLICKUP_TOKEN, AGENT_LOOP_LIST_ID |
| Your project |
base branch, repo path, project prompt contract |
| Verification |
repo-relative test command, sandbox location, dependency dirs to seed (coder/reviewer/verify), test env file, deliberate primary-path opt-out, parseable verify-scope line |
| Board vocabulary |
all 8 status names, both custom field names, the never-pick-up column |
| Agent commands |
the full CLI invocation for each agent — change model, flags, or binary; the Codex availability check (default codex login status, no tokens); Codex reviews default to medium reasoning; the one-time Codex self-update when the CLI is too old for its configured model (default codex update, empty = off) |
| Timing |
poll interval, churn cap, per-stage timeouts, implement idle-progress cap, CLI turn budget, opt-in forge check wait, retry policy |
| State files |
lock, stop flag, log, handover report, heartbeat, churn tally, rescue manifest |
| Watcher |
on/auto/off, poll, Claude command, fix cap, hourly Claude cap, report, log, offset file, coder log paths, verbose Output channel, optional experimental Claude narration |
Nothing about your board's vocabulary is hardcoded. If your workflow spells things differently,
override the names; no code change is needed. npm test enforces this — a setting the dispatcher
reads but the example never documents fails the build.
Commands
| Command |
|
| Agent Loop: Start / Safe Stop |
The status-bar button. Start, or stop cleanly. |
| Agent Loop: Set up / reconfigure ClickUp |
The first-run wizard. |
| Agent Loop: Check the ClickUp board |
Validate token, statuses and fields. Writes nothing. |
| Agent Loop: Open the config file |
Open ~/.agent-loop.env. |
| Agent Loop: Force Stop |
Kill now. May leave a task mid-implement; the next start recovers it. |
| Agent Loop: Open last handover report |
What the last Safe Stop left behind. |
| Agent Loop: Recover unsafe stop |
Commit preserved sandbox work after an unsafe-child stop, if no descendant is still alive. |
| Agent Loop: Open the watcher report |
What the watcher last decided, and what to do next. |
| Agent Loop: Show watcher activity |
Open the Agent Loop Watcher output channel. |
Writing tasks
This is the part that determines whether the loop converges or churns, and it is worth ten minutes
before you write twenty tasks. examples/TASK_AUTHORING.md covers
it in full. The short version:
- The Acceptance Criteria field is the spec. The task name is just a label the branch name is
derived from.
- One concern, one layer, per task. Not a line-count rule — a large cohesive change is safer
than a small one secretly bundling two independent issues.
- Add an explicit SCOPE GUARD line naming what the task must not touch. Single biggest
churn-preventer there is.
- Bake required tests and known edge cases into the criteria. A reviewer will block on an untested
edge case whether or not you mentioned it — better to state it than to lose a round discovering it.
Other examples in this repository:
agent-loop.contract.example.md — a per-project rules
file appended to every implement and review prompt.
agent-loop-verify.example.mjs — a selective
verification harness, for when running the whole suite is too slow. Also the worked example of
loading test environment from a file rather than hardcoding an engine, and of the one rule that
makes a narrowed run trustworthy: a diff is run against only its own changed tests when it
contains nothing but test files. One production file and the whole suite runs.
Safety and scope
Be clear-eyed about what this is: you are letting AI agents write, review and push code to your
repository unattended. The guard rails are real but they are not a sandbox.
- Agent calls run in throwaway clones with no remotes and no credentials, and the dispatcher detects
any agent that reaches back into your primary repo — detects, not prevents. Nothing stops an
agent that invents an absolute path. Real containment needs an OS-level sandbox and is out of
scope here.
- Only reviewed, verified commits are pushed, and only to task branches merged into your base branch.
- Deploy is never automated. The loop stops at
committed.
- Your ClickUp token is a personal token with your full permissions. It lives in one file outside
your repos, at
0600, and the VS Code extension never loads it into memory.
Run it on a repository you can recover, with a base branch you can revert, and read the review
comments for the first few tasks.
Contributing
Contributions are welcome, subject to CONTRIBUTING.md and the Contributor
License Agreement in CLA.md. npm test needs no network, no token and no VS Code.
Its --selftest keeps the log and the other state files in a temp directory.
License details
Agent Loop is source-available, not OSI open-source software.
See LICENSE.md for the full PolyForm Perimeter License 1.0.1 text and the required
notices. The PolyForm license itself is the controlling legal text; the summary at the top of this
file does not replace or modify it.
Commercial licensing
If you want to use Agent Loop in a way the public license does not permit — including any use that
would provide a competing product — contact sergey.ohanyan@gmail.com to discuss a separate
commercial license. See COMMERCIAL-LICENSING.md.
The Contributor License Agreement allows the Project Owner to incorporate community contributions
while retaining the ability to offer the Project under separate commercial or future licensing terms.
Copyright © 2026 Sergey Ohanyan. All rights reserved.