A persistent, agent-aware task execution engine with stop-condition convergence.
npm install -g .New to CLI agents or automation? Read the Beginner's Guide first.
If you have ever wanted an agent to "keep trying until it works" and then walked away — yes.
You don't need to understand the architecture to use it. The quick start is two commands. The daemon starts itself. The hard parts (lease enforcement, crash recovery, event sourcing) are invisible until something goes wrong, at which point they're exactly what you want.
If a shell script with sleep 300 would have solved your problem, Converge will solve it better with one command and an audit log. If you need multiple agents coordinating work across sessions, it scales to that too.
I work almost exclusively through CLI agents — Claude, Gemini, Codex, and others. When I discovered the /loop command in Claude Code, my immediate reaction was: this should exist for every agent, not just one. At the same time, I kept running into the limits of what a session-bound loop can actually do. It dies when the session ends. It can't be triggered by another agent. There's no history, no stop conditions, no way to pause or recover.
Converge is the answer to both questions at once: a universal recurring task primitive that any CLI agent can use, built to be more capable than a simple loop from the ground up.
/loop (Claude Code) |
Converge | |
|---|---|---|
| Survives session end | No | Yes |
| Survives Claude restart | No | Yes |
| Works with Gemini, Codex, etc. | No | Yes |
External trigger (run-now) |
No | Yes |
| Another agent can enqueue it | No | Yes |
| Job state (pause / resume / cancel) | No | Yes |
| Run history and logs | No | Yes |
| Stop conditions | No | Yes |
| Multiple concurrent jobs | No | Yes |
| Actor attribution | No | Yes |
Cron schedules commands. Converge schedules tasks that converge toward outcomes.
| Cron | Converge | |
|---|---|---|
| Runs arbitrary commands | Yes | Yes |
| Agent-aware execution | No | Yes |
| Structured stop conditions | No | Yes |
| Persistent run history | No | Yes |
| Job lifecycle (pause / resume / cancel) | No | Yes |
| Cross-agent triggering | No | Yes |
| Stateful evaluation between runs | No | Yes |
| Crash recovery | No | Yes |
Cron fires and forgets. Converge fires, evaluates, and decides whether to fire again.
Converge is a deterministic job execution engine built around four contracts:
- Job Definition — A task, interval, agent adapter, and optional stop condition. Immutable after creation.
- Execution — One run per tick, enforced by a single-writer lease. No overlapping executions.
- Evaluation — After each run, stop conditions are evaluated deterministically against the output.
- State — All transitions are event-sourced. Every run produces a persisted result.
The daemon runs independently of any agent session. Jobs are defined over a Unix domain socket, executed on schedule via subprocess, and evaluated against stop conditions after each run. All state is written to ~/.converge/. If the daemon restarts, all jobs and run history are recovered from SQLite.
Cross-agent triggering — one agent can enqueue a job that runs a different agent entirely:
- At-most-one active execution per job — lease enforcement prevents concurrent runs of the same job
- No silent failures — every run produces a persisted result:
success,failed, orerror - Deterministic stop evaluation — conditions are evaluated against the full run output after each tick, not approximated
- Ordered event log — all state transitions are recorded with actor identity and timestamp
- Crash-safe scheduling — if the daemon dies mid-run, the lease expires and the job is rescheduled cleanly on restart
- Agent crash → run marked
failed, exit code recorded, next scheduled tick proceeds normally - Daemon crash → all job state recovered from SQLite on restart; stale leases are reclaimed automatically
- Adapter not found → run marked
errorimmediately, logged, schedule continues - Stop condition parse error → job creation rejected at definition time, never silently ignored
- Socket unavailable → CLI auto-relaunches the daemon and retries before surfacing an error
# Install globally from the repo root
npm install -g .
# Run any command — the daemon starts automatically on first use
converge ls
# Create a job: ask claude to run tests every 5 minutes until they pass
converge add --task "run the integration test suite and fix any failures" \
--every 5m \
--cli claude \
--stop '{"type":"exitCode","code":0}'
# Inspect
converge ls
converge logs <job-id>The daemon launches automatically in the background on first use. You do not need to start it manually.
Create a new recurring job.
converge add --task "<prompt or command>" --every <interval> [options]| Flag | Description |
|---|---|
--task <text> |
The task or prompt to pass to the agent on each run |
--every <interval> |
How often to run — duration (5m, 1h, 30s) or cron expression |
--cli <name> |
Agent adapter to use. Default: claude |
--stop <json> |
Stop condition as JSON (see Stop Conditions) |
Examples:
# Run every 10 minutes until tests pass
converge add --task "run npm test and fix any failures" \
--every 10m --cli claude \
--stop '{"type":"exitCode","code":0}'
# Run on a cron schedule indefinitely
converge add --task "summarize open PRs" --every "0 9 * * 1-5" --cli geminiList all jobs with current state, schedule, and next run time.
Get full job details as JSON.
View the run history for a job. Each entry includes status, start/end times, and exit code.
converge logs <job-id>
converge logs <job-id> --json # raw JSONPause a job. The scheduler skips it until resumed. Any run already in progress finishes.
Resume a paused job and return it to the active schedule.
Permanently remove a job from the schedule. Run history is preserved.
Trigger an immediate out-of-schedule execution. The regular schedule continues afterwards.
Human-readable explanation of a job's current state, configuration, and recent run history.
Active environment probe. Checks adapter availability, database connectivity, and filesystem access.
Start the daemon in the foreground. Under normal use this is unnecessary — the daemon launches automatically. Use this for debugging or to run it under a process supervisor.
converge daemonThe socket is created at ~/.converge/converge.sock. Override with CONVERGE_SOCKET_PATH.
Stop conditions tell Converge when a job is done. Pass them as JSON to --stop.
Stop when the agent process exits with a specific code.
{"type": "exitCode", "code": 0}Stop when the agent's stdout matches a regex pattern.
{"type": "stdoutMatches", "pattern": "all tests passed"}Combine conditions with any (OR) or all (AND).
{
"type": "compound",
"operator": "any",
"conditions": [
{"type": "exitCode", "code": 0},
{"type": "stdoutMatches", "pattern": "all tests passed"}
]
}With "operator": "any", the job stops as soon as one condition is met.
With "operator": "all", every condition must be met on the same run.
If no stop condition is provided, the job runs on its schedule until manually cancelled.
| Adapter | CLI invoked | Notes |
|---|---|---|
claude |
claude |
Supports session continuation via --resume |
gemini |
gemini |
New subprocess per run |
codex |
codex |
New subprocess per run |
kimi |
kimi |
New subprocess per run |
opencode |
opencode |
New subprocess per run |
test |
echo |
For local testing and development |
The claude adapter supports session continuation — subsequent runs resume the previous conversation context rather than starting fresh.
All data is stored locally in ~/.converge/. Nothing leaves your machine.
The daemon launches automatically on first use. For production or always-on setups, run it under a process supervisor.
[Unit]
Description=Converge Daemon
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/converge daemon
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.targetsystemctl --user enable converge
systemctl --user start converge<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.converge.daemon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/converge</string>
<string>daemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>launchctl load ~/Library/LaunchAgents/com.converge.daemon.plistConverge ships a native Claude Code plugin that lets Claude create and manage recurring jobs directly from a conversation — no manual CLI invocation required.
claude plugin install /path/to/converge- Skill (
skills/converge/SKILL.md) — Teaches Claude when to reach for Converge. Activates automatically when the user asks to monitor, retry, poll, or schedule work. - Commands (
commands/converge-*.md) — Slash commands that invoke theconvergeCLI. Available in any Claude Code session once installed.
| Command | Description |
|---|---|
/converge-add |
Create a new recurring task |
/converge-ls |
List all jobs |
/converge-status <job-id> |
Get full job details |
/converge-pause <job-id> |
Pause a job |
/converge-resume <job-id> |
Resume a paused job |
/converge-cancel <job-id> |
Delete a job permanently |
/converge-run-now <job-id> |
Trigger immediate execution |
/converge-logs <job-id> |
View run history |
/converge-doctor |
Check system health |
- Confirm the plugin is installed:
claude plugin listshould showconverge-loop - Run
/reload-pluginsin Claude Code - If that fails, restart Claude Code — plugins load at session start
- Verify
commands/exists at the plugin root and contains.mdfiles
# View daemon logs
tail -f ~/.converge/daemon.log
# Start manually to see errors directly
converge daemon
# Check if a socket already exists (daemon may already be running)
ls -la ~/.converge/converge.sockconverge doctor # verify all systems healthy
converge ls # confirm job state is active (not paused or cancelled)
converge logs <job-id> # inspect last run output and exit codeconverge doctor # lists available adapters
which claude # verify the CLI binary is on your PATHPull requests are welcome. There is no rigid process — open an issue to discuss what you want to change, or just send the PR.
A few things that would genuinely be useful:
- New adapters — if you use a CLI agent that isn't listed, adding an adapter is straightforward (see
src/adapters/) - Stop condition types —
convergenceis partially stubbed and would benefit from a real implementation - Windows support — the daemon uses Unix sockets; named pipes would get it working on Windows
- Bug reports — if something breaks, open an issue with the output of
converge doctorandconverge logs <job-id>
The test suite is strict but the bar for contribution isn't. If you are not sure whether something is worth a PR, open an issue first and ask. The worst answer is "not right now."
| Version | 2.0.0 |
| Tests | 785 / 787 passing |
| Storage | SQLite, local only |
| Platforms | Linux, macOS |
| Node.js | 20+ |
| License | MIT |





