Unopinionated Ralph Loop runner. Runs an AI coding agent in a loop with fresh context per iteration.
A Ralph Loop runs an AI agent repeatedly, each iteration starting a new session with fresh context. The agent reads its own previous output from files and git history rather than relying on conversation memory. The pattern is named after Ralph Wiggum.
- Unopinionated. No conventions about what files your agent reads or writes, what task system you use, or how you track progress. Juggle runs the loop. You bring the workflow.
- Fresh context per iteration. Each loop starts a new agent session. State lives in git, not LLM memory.
- Cost-aware. Built for overnight runs with
--max-cost,--max-failures, and automatic quota backoff. - Composable. Shell hooks (
--cmd-after,--stop-when), phase agents (--agent-before,--agent-after), and environment variables let you wire in verification gates without juggle imposing a workflow.
# Run 3 iterations on a task
juggle "fix the failing tests" -n 3# @file reads a file's contents into the prompt
juggle @task.md -n 5# Mix and match -- all positional args join into one prompt
juggle @tdd @fix "the login form rejects valid emails" -n 5# Point JUGGLE_PROMPTS at a library of reusable prompts
export JUGGLE_PROMPTS=~/prompts
juggle @tdd @fix "broken email validation" -n 5prompt-lego is a starter kit of reusable prompt files that work out of the box.
# Add a test gate -- stop when tests pass
juggle @tdd @fix "broken email validation" --cmd-after "make test" --stop-when "make test" -n 10# Run a code review agent after each iteration
juggle @fix "broken email validation" --agent-after @code-review -n 5# Watch a directory -- agents pick up tasks as they appear
juggle --watch tasks/ready/ @tdd -n 0--watch runs a fresh agent session for each file in a directory, and waits for new files to appear. That pairs naturally with a task queue like frontloop, which stores tasks as markdown files in .frontloop/ready/ -- you plan tasks while a background juggle loop works through them. But juggle doesn't care where tasks come from -- a directory of markdown files, a script that dumps issues, or anything else that puts files in a folder.
All positional args are prompt content -- strings and @file references join into the final prompt. Point JUGGLE_PROMPTS at a directory of reusable prompts and compose them like lego pieces.
macOS (Homebrew):
brew tap ohare93/tap && brew install juggleWindows (Scoop):
scoop bucket add ohare93 https://github.com/ohare93/scoop && scoop install juggleLinux:
curl -sSL https://raw.githubusercontent.com/ohare93/juggle/main/install.sh | bashGo:
go install github.com/ohare93/juggle/cmd/juggle@latest- Loop control -- iterations, delay with jitter, per-iteration timeout, resume after crash
- Watch mode -- process task files from a directory or glob pattern, with parallel workers (
juggle --watch tasks/ready/ @worker-rules.md) - Lifecycle hooks -- run shell commands before/after each iteration, stop on a condition
- Phase agents -- run separate agent sessions before/after the main loop or each iteration
- Config file --
juggle.tomlfor project-level defaults - JSONL logging -- per-iteration token counts, cost estimates, and run summary
- Failure handling -- stop, continue, or retry with backoff on agent failures
Run juggle --help for the full flag reference.
Juggle wraps AI coding CLIs. Supported providers:
| Provider | Binary | Flag |
|---|---|---|
| Claude Code (default) | claude |
--provider claude |
| OpenCode | opencode |
--provider opencode |
| OpenAI Codex | codex |
--provider codex |
| Gemini CLI | gemini |
--provider gemini |
| Custom | any | --agent-cmd "your-cli" |
Juggle exposes loop state to every spawned agent process. Prompts, skills, and MCP servers can read these.
| Variable | Description |
|---|---|
JUGGLE_ITERATION |
Current iteration number (1-indexed) |
JUGGLE_MAX_ITERATIONS |
Total planned iterations (0 = unlimited) |
JUGGLE_RUN_ID |
Stable UUID for the entire run |
JUGGLE_MODEL |
Model name passed to the agent |
JUGGLE_PROVIDER |
Provider name (claude, opencode, ...) |
JUGGLE_LABEL |
Run label if --label was set (omitted otherwise) |
JUGGLE_TASK_FILE |
(watch mode) Absolute path to the current task file |
JUGGLE_WORKER_ID |
(glob watch) 0-indexed worker number |
One of the supported AI coding CLIs installed and authenticated:
Claude Code,
OpenCode,
Codex,
Gemini CLI,
or any CLI via --agent-cmd.
MIT