openloop
v0.7.0
Published
Global CLI and service for unattended Pi-driven development across linked repositories.
Downloads
683
Maintainers
Readme
OpenLoop
Ship while you sleep. OpenLoop turns your AI coding agent into a tireless developer that works across all your repositories — planning tasks, writing code, running validations, and promoting changes — on a loop, without manual intervention.
One CLI. One daemon. Every linked repo gets its own control plane, task ledger, and safety policy. You define the work; OpenLoop handles the rest.
Quick Start
1. Install
npm install -g openloopRequires Node.js 22+ (Bun also works). To run from source instead:
git clone https://github.com/jaltez/openloop.git && cd openloop
npm install
npm run build
npm link # makes `openloop` available globally2. Link a project
openloop project add myapp ~/projects/my-app --initThis registers the project and materializes its control-plane files into ~/projects/my-app/.openloop/.
You can also split the two steps (project add then project init) if you want to review config before initialization.
3. Configure validation (recommended)
OpenLoop auto-detects lint, test, and typecheck commands from package.json during init. Verify they look right:
openloop config project-show myappTo override, edit ~/projects/my-app/.openloop/project.json:
{
"validation": {
"lintCommand": "npm run lint",
"testCommand": "npm test",
"typecheckCommand": "npm run check"
}
}4. Add a task
openloop task add --project myapp --title "Add input validation to the signup form"Or enqueue from an issue reference:
openloop enqueue --project myapp --ref "https://github.com/org/repo/issues/42"5. Run
Run a single scheduler iteration to try things out:
openloop run-once --project myappOr start the daemon for continuous, unattended operation:
openloop service start
openloop service status # check progress
openloop service stop # shut down6. Review and promote
Check what was done and land the results:
openloop task list --project myapp
openloop task show --project myapp --task <task-id>
openloop promotion list --project myapp
openloop promotion apply --project myapp --task <task-id>Low-risk tasks with passing validations can auto-merge. Everything else waits for your review.
Requirements
- Node.js 22+ (Bun also works). The interactive TUI additionally requires Bun; without it,
openloop watchprovides a no-Bun live dashboard. - An AI coding agent on
PATH— Pi (default), Claude Code, Aider, Codex, OpenCode, ka, Oh My Pi (omp), or a custom command gitavailable onPATHgit worktreesupport whenruntime.useWorktreeis enabled (opt-in isolation);runtime.worktreeSetupCommandcan provision worktree-local build state (e.g.npm install)
Development
npm run check # type-check
npm test # run tests
npm run build # build CLIHow It Works
OpenLoop cycles through three modes automatically:
- Active development — picks the next eligible task, runs your configured agent with a role-specific prompt, validates the output, and decides whether to auto-merge or create a review branch.
- Self-healing — detects and fixes lint errors, type errors, and localized test failures without being asked.
- Continuous improvement — when idle, discovers gaps like missing validations or loose scope policies and proposes tasks to address them.
Each run is labeled with a worker role that shapes the agent's behavior:
Runtime Model
- The configured agent runs as a subprocess. Supports Pi, Claude Code, Aider, Codex, OpenCode, ka, Oh My Pi (omp), or a custom command via the provider abstraction.
- Model resolution is deterministic: CLI flag > project config > global config.
- A single resident daemon manages scheduling across all linked projects.
- One active worker per project at a time; the daemon sleeps between iterations.
- Daemon state persists under
~/.openloop/run/.
Worker Roles
| Role | When |
| --------------- | --------------------------------------------------------- |
| sdd-planner | A task needs planning before code changes |
| implementer | A task is ready for implementation |
| repo-improver | The scheduler is doing discovery or idle improvement work |
| ci-healer | The scheduler is handling ledger-driven self-healing |
Self-Healing
V1 supports automatic fixes for:
lint-fix— linter violationstype-fix— type-checker errorslocalized-test-fix— isolated test failures
Anything outside these categories is blocked rather than attempted unattended.
Risk and Promotion
| Risk | Auto-merge | Human review |
| ------------- | ------------------------------------------------ | ------------ |
| low-risk | Allowed when policy permits and validations pass | Optional |
| medium-risk | Not allowed | Required |
| high-risk | Never | Required |
Tasks can declare scope.paths, and the runtime enforces project policy:
- allow —
allowGlobswhitelist - block —
denyGlobsblacklist - escalate —
highRiskAreasrequire human review - default — unknown scope is classified conservatively
Safety Guardrails
| Guard | Default | Details |
| --------------------- | ------------- | --------------------------------------------------------------------- |
| Budget ceiling | $25/day | Daemon pauses when exhausted |
| Max attempts | 3 per task | Task is blocked after repeated failures |
| Run timeout | 30 min | Hard cap per agent invocation |
| No-progress detection | On | Blocks tasks with ineffective diffs or repeated errors |
| Scope policy | Per-project | allowGlobs, denyGlobs, highRiskAreas in .openloop/policy.yaml |
| Auto-merge | Low-risk only | All validations must pass; medium/high-risk always requires review |
| Post-implementation review | Optional | Scope-drift and secret detection on diffs; blocking findings downgrade auto-merge to manual review |
CLI Reference
Project Management
| Command | Description |
| ------------------------------------- | ----------------------------------- |
| project add <alias> <path> [--init] | Register a repository |
| project init <alias> | Materialize control-plane templates |
| project list | List linked projects |
| project show <alias> | Show project details |
Tasks
| Command | Description |
| ------------------------------------------- | -------------------------------------------------- |
| task add --project <alias> --title <text> | Add a task (accepts --kind, --risk, --scope) |
| task list --project <alias> | List tasks (accepts --status, --risk filters) |
| task show --project <alias> --task <id> | Show task detail with promotion history |
| enqueue --project <alias> --ref <ref> | Create a task from an issue or external reference |
Execution
| Command | Description |
| --------------------------------------- | -------------------------------- |
| run --project <alias> --prompt <text> | Run Pi directly with a prompt |
| run-once --project <alias> | Execute one scheduler iteration |
| service start\|stop\|status\|restart | Manage the resident daemon |
| pause / resume | Pause/resume the daemon globally |
Promotion
| Command | Description |
| ------------------------------------------------- | --------------------------------------------- |
| promotion list --project <alias> | List promotion artifacts |
| promotion show --project <alias> --task <id> | Show promotion detail |
| promotion history --project <alias> --task <id> | Chronological promotion log |
| promotion apply --project <alias> --task <id> | Apply a pending promotion (merge or checkout) |
| promotion reject --project <alias> --task <id> | Reject a pending promotion |
Configuration
| Command | Description |
| -------------------------------------------- | ------------------------------------ |
| config show | Show global configuration |
| config set-model <model> | Set default Pi model |
| config add-hook / config list-hooks | Manage global lifecycle hooks |
| config project-add-hook <project> | Manage project-local lifecycle hooks |
| config project-show <project> | Show project-local config |
| config project-set-model <project> <model> | Set project Pi model |
Lifecycle Hooks
OpenLoop can fire command and webhook hooks for lifecycle events including task-complete, task-failed, validation-failed, task-awaiting-approval, promotion-auto-merge-queued, promotion-review-queued, promotion-blocked, all-tasks-done, and budget-blocked.
Global hook example:
openloop config add-hook \
--type command \
--events promotion-auto-merge-queued \
--command 'node scripts/review-gate.mjs'Project-local hook example:
openloop config project-add-hook myapp \
--type webhook \
--events task-awaiting-approval,validation-failed \
--url https://example.com/openloop/hooksCommand hooks receive the JSON payload on stdin. Command and webhook hooks may return JSON like {"note":"Needs security review","requireManualReview":true} to attach a note to the run summary and downgrade a queued auto-merge to manual review.
Project Structure
~/.openloop/ # global state
config.json # model, budgets, runtime limits
projects.json # linked project registry
run/ # daemon pid, state, logs
<project>/.openloop/ # per-project control plane
project.json # project runtime config
policy.yaml # scope and risk policy
tasks.json # task ledger
specs/ # planning artifacts
runs/ # run summaries
promotions/ # promotion decision artifacts
promotion-results/ # promotion outcome records
<project>/.agents/skills/openloop/
SKILL.md # agent instructions inside linked repositories
<project>/.pi/
SYSTEM.md # base Pi system prompt
APPEND_SYSTEM.md # runtime-specific Pi rulesRelease
Before publishing:
npm run release:verify # validates tarball contents
npm run release:pack # verify + packThe npm tarball includes README.md, dist/, and templates/project/ only. Internal docs and source maps are excluded.
Roadmap
- Approval packets — structured review artifacts for
awaiting-approvaltasks with spec, scope, and validation plan - Confidence digest — per-run trust signal summarizing validation, review findings, and risk assessment
- Context packs — persistent repo maps for faster agent context loading
- Scheduled execution — cron-like triggers and event-driven runs from webhooks
- Inline task capture —
OPENLOOP:markers in source code as lightweight task intake
