whiletrue
The loop around your coding agents.
Run pipelines of agentic and deterministic steps around Claude Code, opencode and Codex, locally, with gates, humans in the loop, and crash-safe resume.
LangGraph builds the agent; whiletrue runs the loop around agents you already have.
A real run, not a mock-up: two Claude Code agents in parallel, a pytest gate, a human approval and a resume, about $0.23 in total. Captured from the live tmux panes; the two tmux windows are drawn side by side.
uvx whiletrue init # scaffold a Ralph loop
uvx whiletrue run # agent -> pytest gate -> repeat until green
Overview
Coding agents are good at one task and bad at finishing a backlog unattended. whiletrue is the orchestrator you put around them. You describe the loop in a single whiletrue.yaml: which agent does the work, which deterministic gate checks it, when to retry, when to ask a person. whiletrue validates the config before spending a token, runs it, and records every step so you can inspect, replay or resume it.
- Pipelines, not prompts. Agent steps, shell and git steps, and gates compose with
sequence,loop,map,parallel,switch,retry,tryandhuman.approve. Every loop is bounded. - Any backend.
claude-code-headless,claude-code(the real interactive CLI in a tmux pane you can type into),opencodeandcodex. Mix them in one pipeline. - Many items at once. One item per task or GitHub issue, each in its own git worktree, with
parallel: Nand a cap on live agent sessions. - Humans in the loop. A gate parks an item until a person approves, rejects or comments; other items keep running. Every review comment gets an answer.
- Durable. State lives in SQLite. Kill the process at any point and
whiletrue resumereplays finished steps instead of redoing them; side effects (PRs, merges, replies) happen exactly once. - Local. One machine, no server, no account. Everything is a file in your repo plus
.whiletrue/.
Contents
Install
Requires Python 3.12+ and at least one agent CLI on your PATH (Claude Code, opencode or Codex). git is needed for worktrees, tmux for interactive agents, and gh for the GitHub integration.
uv tool install whiletrue # or: pip install whiletrue
whiletrue --help
uvx whiletrue --help # or run it without installing
If an agent CLI is not on PATH, set WHILETRUE_CLAUDE_BIN, WHILETRUE_OPENCODE_BIN or WHILETRUE_CODEX_BIN.
Quickstart
cd my-project
whiletrue init # writes whiletrue.yaml and agents/ralph.md
whiletrue validate # config, wiring, limits and safety rules; spends nothing
whiletrue plan # prints the expanded step tree; spends nothing
whiletrue run # runs it
whiletrue status # steps, outcomes and cost of the latest run
The scaffold is a Ralph loop. The agent runs in a fresh context, a deterministic pytest gate checks the result, and the loop repeats (at most 5 times) until the gate is green:
# whiletrue.yaml
name: ralph
pipeline:
loop:
max: 5 # every loop is bounded; `max: unbounded` is an explicit opt-out
do:
- agent: { uses: ./agents/ralph.md }
- gate.shell: { run: "pytest" }
---
# agents/ralph.md
agent: ralph
runner: claude-code-headless
permission_mode: acceptEdits
tools: [Read, Edit, Write, "Bash(pytest*)", "Bash(git *)"]
limits: { budget_usd: 2, turns: 40, wall: 20m }
---
Work through the next unfinished item in TODO.md. Make the tests pass.
Failure output from the previous attempt (empty on the first try):
{{iter.previous}}
Every agent must declare limits; validate refuses the config otherwise.
Architecture
The core knows nothing about git, GitHub, tmux or any agent. Every integration is a plugin built on the public plugin API, so you can add your own (plugins, architecture).
Concepts
| Concept | What it is |
|---|---|
| Pipeline | A list of steps, or one strategy, in whiletrue.yaml. |
| Step | An action: agent, a shell command, a git or GitHub operation, a gate. Pure, deterministic, agentic or side-effecting. |
| Strategy | Control flow over steps: sequence, tap, loop, map, parallel, switch, retry, try, human.approve. |
| Outcome ports | Every step ends on ok, fail, needs_human, skip or rejected. wires: routes a port to another step; back-wires make loops. |
| Item | One unit of work from a source: (json, markdown_tasks, github_issues). Items run in parallel, in dependency order. |
| Workspace | Per-item checkout: git-worktree, dir-copy or none. |
| Gate | A deterministic check, or a human decision, that an item must pass. |
| Recipe | A ready-made composite: ralph, review-pass, review-respond, issue-loop. |
| Run record | The SQLite log of steps, parks, effects, comments and cost that makes replay and resume possible. |
Details: reference, authoring guide, architecture.
Examples
A Ralph loop
This is what whiletrue init scaffolds. See the YAML under Quickstart.
Review loop with a read-only reviewer
pipeline:
composite:
uses: "recipe:review-pass"
params: { reviewer: ./agents/review.md, fixer: ./agents/fix.md, max_rounds: 3 }
A backlog in parallel worktrees
parallel: 4
max_agents: 4
source: { markdown_tasks: { path: TASKS.md } } # - [ ] Title {#id after=other}
workspace: { git-worktree: { branch: "wt/{{item.id}}" } }
pipeline:
loop:
max: 5
do:
- agent: { uses: ./agents/implement.md }
- gate.shell: { run: "pytest" }
A human gate on a pull request
- id: review
human.approve:
what: pr
wake: { any: [cli, { github.pr_review: any }] }
do:
- composite: { uses: "recipe:review-respond", params: { responder: ./agents/respond.md } }
wires: { rejected: fix }
whiletrue run # parks at the gate and exits with code 2
whiletrue status # lists what is waiting
whiletrue approve 12 # or: reject 12 --note "what to change"
whiletrue resume # finished steps are replayed, never redone
The reference pipeline: issues with a human in the loop
examples/issue-loop takes every issue in a GitHub milestone from open to merged: implement in a worktree, run the gate, open a PR, answer review comments, merge, close. You review every PR, and every comment you leave gets an answer.
Backends
Choose per agent with runner:.
| Runner | Runs | Notes |
|---|---|---|
claude-code-headless |
claude -p |
Default. Budget, turns and wall limits enforced. |
claude-code |
Interactive Claude Code in a tmux pane | Watch it, type into it (recorded as a steer). Submits through a bundled MCP tool and hooks. |
opencode |
opencode run |
Structured output checked against the step's cap. |
codex |
codex exec |
Sandbox derived from permission_mode. No budget enforcement. |
Structured outputs: work on all of them. See choosing a backend.
CLI
| Command | Purpose |
|---|---|
init, validate, plan |
Scaffold, check and preview a pipeline without spending tokens. |
run, resume, rerun, cancel |
Start, continue after a park or crash, redo, or stop items. |
status, logs, cost, replay |
Inspect runs, steps and spend; replay a recorded run. |
approve, reject, comment |
Decide human gates and talk to waiting items. |
attach, panel |
Open the tmux session and the live control panel. |
history, learnings |
Audit trail and approved lessons for future agents. |
lock |
Show or clear the run lock. |
Full reference: docs/cli.md. New here? Follow the tutorial.
Documentation
Start at docs/README.md.
- Tutorial: from an empty folder to your own loop with gates, a reviewer, parallel tasks and a human approval.
- Getting started: a longer walkthrough, including interactive agents, gates and parallel items.
- Authoring guide: writing pipelines and agents.
- Reference: every module, strategy, provider and config key.
- CLI and plugins: the command line and extending whiletrue.
- Architecture, plan, todo and changelog.
Development
Requires devenv (or Python 3.12 + uv). See developing.md.
git clone https://github.com/dariussingh/whiletrue && cd whiletrue
direnv allow # or: devenv shell
poe check # format check, lint, pyright, tests + coverage, docs check
whiletrue --help # installed editable into .devenv/state/venv
Live tests against real agent CLIs are opt-in: WHILETRUE_LIVE=1 uv run pytest tests/live -v.
License
MIT. See LICENSE.
Metadata
Release files for whiletrue 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| whiletrue-0.1.1.tar.gz | 306.7 kB | With provenance | Details for whiletrue-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| whiletrue-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for whiletrue-0.1.1-py3-none-any.whl |
Total release size: 460.0 kB
Release files / whiletrue-0.1.1.tar.gz
| Download URL | whiletrue-0.1.1.tar.gz |
|---|---|
| Size | 306.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1ec6a4064ec3deae8d02d48f705fc844c372ce89fc0eda11469942f66448e864
|
|
BLAKE2b-256 checksum How to use checksums |
c63df5fa17e9c8dfbfcc9ba632145fb3608d426eeaaf57d94d07acc627b0e0c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logRelease files / whiletrue-0.1.1-py3-none-any.whl
| Download URL | whiletrue-0.1.1-py3-none-any.whl |
|---|---|
| Size | 153.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
43912197906d94eec048390f44c15324341ea1983caf6dc2b70b49e533ef8b7e
|
|
BLAKE2b-256 checksum How to use checksums |
1db34ba083fa31263ae02445e3f0ca003587afa5ea09ef022bab6c3730b9ebba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logSecurity for whiletrue 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for whiletrue-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.