agent-control-plane
v0.9.0
Published
Help a repo keep GitHub-driven coding agents running reliably without constant human babysitting
Maintainers
Readme
agent-control-plane (ACP) v0.7.1
agent-control-plane (ACP) keeps your coding agents running reliably without you having to stare at them all day.
✅ ROADMAP UPDATE (v0.7.1) - Package Fixes & Hardening!
v0.7.1 Fixes
- Package Contents: All adapter files now included (codex, claude, openclaw, ollama, pi, opencode, kilo)
- Ollama Adapter: Fixed context window detection to parse
model_infocorrectly - Package Cleanup: Removed
__pycache__directories from published package
v0.7.0 Features
- Real-time Dashboard: WebSocket updates (no more 5s polling!)
- Hardened Adapters: All 6 backends now production-ready
- Native Windows Support: Run as Windows Service (NSSM/sc.exe/PowerShell)
- Standardized Capabilities: Worker capability detection across all backends
- Provider Failover: Auto-switch when backend is rate-limited/degraded
✅ ROADMAP COMPLETE (v0.6.0) - All 5 Sections Delivered!
✅ ROADMAP COMPLETE (v0.6.0) - All planned features delivered!
It is the operator layer for coding agents that need to keep running after the novelty wears off — and the responsible adult in the room that stops them from going completely off the rails.
- License:
MIT - Changelog: CHANGELOG.md
- Roadmap: ROADMAP.md
- Architecture: references/architecture.md
- Commands: references/commands.md
- Examples: docs/examples.md
The Big Idea
Here is the dirty secret nobody in the AI hype cycle wants to admit: the free models are not that dumb. They are just chaotic. Left alone to manage their own execution loop, retry logic, GitHub labels, and publish pipeline, they will reliably discover creative new ways to do absolutely nothing useful at 3am while you sleep. Give them a tight operating harness and a clear job description, however, and suddenly that "not smart enough" free model is grinding through your issue backlog like a junior developer who is weirdly enthusiastic about reading CI logs.
That is what ACP does. It turns a forge-backed repo into a managed runtime: a
repeatable setup, a stable home for state, a heartbeat that keeps agents
scheduled and supervised, and a dashboard you can actually glance at without
spelunking through temp folders, worktrees, or half-remembered tmux sessions.
ACP does not try to be the coding agent. It makes the surrounding system less
fragile: profile setup, runtime start and stop, heartbeat scheduling,
reconcile-owned outcomes, background execution, and operator visibility under
~/.agent-runtime. The agent writes the code. ACP writes the boring
infrastructure that keeps the agent from losing its own work.
Free models: surprisingly economical
If you are using ACP for research, the economics are almost embarrassing.
Running a free-tier model like openrouter/qwen3.6-plus:free continuously
across multiple repos costs roughly what a large latte costs — per month, not
per hour. ACP handles quota cooldowns, stall detection, provider failover, and
retry backoff, so free-tier models become genuinely useful in a production-shaped
loop instead of a toy demo. For researchers studying agent behavior, measuring
output quality, or iterating on prompting strategies at scale: you can run
hundreds of sessions for what you would otherwise spend on a single GPT-4
afternoon.
The free model is not brilliant. ACP makes it relentless.
Smarter models: powerful, and worth supervising
ACP works equally well with Claude Sonnet, OpenAI Codex, and other high-capability backends. They produce better code, handle harder tasks, and generally understand the first time what the free model needed three attempts and a blocker comment to figure out.
But here is the thing about powerful AI agents running autonomously against your GitHub repo: they are, in a very real sense, a slow-burning fuse. An agent with broad permissions, no supervision, and no circuit breakers will eventually push something broken, auto-merge a PR it should not have touched, burn through a monthly API budget in a long weekend, or enter a retry loop that only stops when the credit card does.
ACP is the person standing next to the fuse. It enforces launch limits, reconciles outcomes before touching your forge, validates before it publishes, and respects cooldowns instead of hammering a provider at full throttle. The agent gets to be smart and fast. ACP makes sure "smart and fast" does not also mean "unattended and irreversible."
You would not hand a brilliant but impulsive junior developer the repository admin key and leave for a two-week vacation. ACP is the on-call rotation for your AI workforce — quiet when things go well, essential when they do not.
Why people use it
ACP is a good fit when your pain is not "the agent cannot code" but "the setup around the agent is too easy to break" — or "I would trust this agent more if it had a supervisor."
| Need | What ACP provides |
| --- | --- |
| Keep agent workflows running without babysitting | Supervisor, heartbeat loop, and reconcile scripts that manage the lifecycle automatically |
| Get real value out of free-tier models | Quota cooldowns, stall detection, provider failover, and retry backoff that free-tier models need to be actually useful |
| Manage multiple repos cleanly | One profile per repo with isolated runtime state, each with its own identity and status |
| Observe what is happening without digging through files | Dashboard and runtime status that show the real state without spelunking through tmux or temp folders |
| Compare worker backends on real workloads | Swap between codex, claude, openclaw, ollama, pi, opencode, and kilo without rebuilding your runtime habits |
| Run reproducible agent research cheaply | Cost-controlled execution harness for studying agent behavior, output quality, or prompting strategies |
| Enforce safety by architecture, not by hope | Launch limits, reconcile gates, and cooldowns that are built into the runtime, not left to chance |
Why Gitea Local-First
ACP started GitHub-first, but a local-first Gitea loop is often a better daily working setup:
- It reduces dependence on GitHub API rate limits for routine issue and PR work.
- It lets agents collaborate against a local forge while you keep GitHub as the public mirror or release boundary.
- It gives you a safer place to let ACP iterate quickly, because local Gitea is cheaper to reset, inspect, and isolate than a live hosted repo.
- It matches how ACP now works best operationally: local runtime state, local worktrees, local dashboard, and a forge that can live on the same machine.
The intended model is:
Gitea mainis the working mainline ACP automates day to day.- Your local source checkout auto-syncs from that forge mainline.
- GitHub becomes the publish/release mirror once the codebase is stable enough to push outward.
Use Cases
Teams and solo builders usually reach for ACP when one of these starts to feel familiar:
- Issue-driven or PR-driven agent work should keep running in the background, but still be inspectable and recoverable when something goes wrong.
- The project has more than one repo, and each one deserves a clean, separate runtime identity instead of sharing state.
- You want to swap or compare worker backends without rebuilding your runtime setup from scratch every time.
- You want one command to tell you whether automation is healthy, instead of
inferring it from stale branches, dangling sessions, or mystery files under
/tmp. - You are doing research on agent behavior, output quality, or prompt strategy and need a reproducible, cost-controlled execution harness.
- Your local machine should behave like a reliable operator box, not a pile of shell history that breaks after a reboot.
Screenshots
Light Mode

Dark Mode

Roadmap
ACP is moving toward a true multi-backend control plane. The goal is one runtime and one dashboard for many coding-agent backends, across macOS, Linux, Windows (WSL2), and native Windows (service model).
Windows Support
ACP now supports running as a native Windows Service!
- Docs: See Windows Setup Guide
- Service managers: NSSM (recommended), sc.exe, or PowerShell cmdlets
- Quick start:
# Using NSSM (download from https://nssm.cc/download) nssm install "ACP_Dashboard" "C:\Path\To\python.exe" "C:\Path\To\agent-control-plane\tools\dashboard\server.py" nssm start "ACP_Dashboard" - PowerShell installer:
tools/bin/install-windows-service.ps1
Windows
Backend Status
| Backend | Status | Notes |
| --- | --- | --- |
| codex | Production-ready | Full ACP workflow support today. |
| claude | Production-ready | Full ACP workflow support today. |
| openclaw | Production-ready | Full ACP workflow, including resident-style runs. |
| ollama | Hardening | Working adapter with Node.js agentic loop. v0.4.9+: Added health-check + context detection. Moved toward production-ready. |
| pi | Experimental | Working adapter using the pi CLI. Health-check + API key validation. |
| opencode | Experimental | Working adapter for Crush. Health-check (verify crush binary). |
| kilo | Experimental | Working adapter for Kilo Code. Health-check + JSON stream validation. |
| gemini-cli | Integrated | Google's official terminal agent (v0.39.1+). Full ACP adapter with health-check, API key validation, and streaming JSON output. |
| nanoclaw | Not integrable | Standalone agent system (like ACP), not a CLI backend. Reference for container patterns. |
| picoclaw | Not integrable | Standalone agent system (Go-based). Runs on $10 hardware. Not a CLI backend. |
Adapter Pattern
ACP uses a standardized adapter interface to support multiple backends. Every adapter implements these functions:
| Function | Purpose |
| --- | --- |
| adapter_info() | Print adapter metadata (id, name, type, version, model) |
| adapter_health_check() | Verify backend is available (exit 0 = healthy) |
| adapter_run() | Execute a task (params: MODE SESSION WORKTREE PROMPT_FILE) |
| adapter_status() | Get run status for a session |
Available adapters:
tools/bin/ollama-adapter.sh- Ollama local models (implements health-check)- All existing backends (
codex,claude,pi,opencode,kilo) use the same interface viarun-codex-task.sh,run-claude-task.sh, etc.
Using adapters:
# Print adapter info
bash tools/bin/ollama-adapter.sh
# Run a task with generic runner
bash tools/bin/run-with-adapter.sh tools/bin/ollama-adapter.sh safe my-session /path/to/worktree /path/to/prompt.txtSee tools/bin/adapter-interface.sh for the full interface specification.
If you are trying ACP on a real repo right now, start with codex, claude,
or openclaw. Use ollama to run local models — useful for research, offline
workflows, or comparing local model output against cloud backends without
incurring API costs. Use pi to experiment with OpenRouter-hosted free-tier
models via the pi CLI. The remaining entries show the direction of travel, not
finished support.
See ROADMAP.md for the fuller public roadmap.
Using Ollama (local models)
To run ACP with a local model via Ollama:
# 1. Install Ollama and pull a model
ollama pull qwen3.5:9b
# 2. Init a profile with ollama backend
npx agent-control-plane@latest init \
--profile-id my-repo \
--repo-slug owner/my-repo \
--repo-root ~/src/my-repo \
--agent-root ~/.agent-runtime/projects/my-repo \
--worktree-root ~/src/my-repo-worktrees \
--coding-worker ollama
# 3. Configure the model in your profile YAML
# ~/.agent-runtime/control-plane/profiles/my-repo/control-plane.yaml
#
# execution:
# coding_worker: "ollama"
# ollama:
# model: "qwen3.5:9b"
# base_url: "http://localhost:11434"
# timeout_seconds: 900The Ollama adapter runs a Node.js agentic loop that calls the Ollama API with tool-use support. It handles both native tool-call responses and models that return tool calls as JSON text in the content field.
Model guidance: Models in the 7–14B range can explore codebases and run
commands, but may struggle with complex multi-step repair tasks. Larger models
(27B+) produce significantly better results if your hardware supports them.
Thinking mode is disabled by default (think: false) and context is set to
32K tokens to balance speed and capability.
See It Running
The dashboard gives you a single view across all active profiles — running sessions, recent history, provider cooldowns, scheduled issues, and queue state.

Architecture
ACP is easiest to trust once you can see the moving pieces. The npm package stages a shared runtime, installed profiles live outside the package, a shared heartbeat loop decides what to launch, worker adapters do the coding work, and reconcile scripts own the GitHub-facing outcome.
flowchart LR
User[Operator] --> CLI["agent-control-plane.js"]
CLI --> Profiles["installed profiles"]
CLI --> RuntimeHome["runtime-home"]
CLI --> RuntimeCtl["project-runtimectl.sh"]
RuntimeCtl --> Supervisor["project-runtime-supervisor.sh"]
Supervisor --> Heartbeat["heartbeat-safe-auto.sh"]
Heartbeat --> Scheduler["agent-project-heartbeat-loop"]
Scheduler --> Workers["issue / PR worker launchers"]
Workers --> Backends["codex / claude / openclaw / ollama / pi / opencode / kilo"]
Backends --> Reconcile["reconcile issue / PR session"]
Reconcile --> Forge["issues / PRs / labels / comments"]
Scheduler --> State["runs + state + history"]
State --> Dashboard["dashboard snapshot + UI"]Runtime Loop At A Glance
sequenceDiagram
participant Operator
participant RuntimeCtl as project-runtimectl
participant Supervisor
participant Bootstrap
participant Heartbeat
participant Worker
participant Reconcile
participant Forge
Operator->>RuntimeCtl: runtime start --profile-id <id>
RuntimeCtl->>Supervisor: keep runtime alive
loop each pass
Supervisor->>Bootstrap: run profile bootstrap
Bootstrap->>Heartbeat: invoke published heartbeat
Heartbeat->>Worker: launch eligible issue/PR flow
Worker->>Reconcile: emit result artifacts
Reconcile->>Forge: labels, comments, PR actions
endArchitecture shortcuts:
- System overview
- Install and publication flow
- Runtime scheduler loop
- Worker session lifecycle
- Dashboard snapshot pipeline
- Control plane ownership map
Visual assets:
- Architecture deck PDF
- Overview infographic
- Runtime loop infographic
- Worker lifecycle infographic
- State and dashboard infographic
Prerequisites
ACP is a shell-first operator tool. Most install problems become easier to debug once it is clear which dependency is responsible for which part of the system.
Cross-Platform Installation
macOS:
# Install Node.js (if needed)
brew install node
# Install required tools
brew install bash git jq python3 tmux
brew install gh # for GitHub-first setupsLinux (Ubuntu/Debian):
# Install Node.js (if needed)
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt-get install -y nodejs
# Install required tools
sudo apt-get install -y bash git jq python3 tmux
sudo apt-get install -y gh # for GitHub-first setupsLinux (RHEL/CentOS/Fedora):
# Install Node.js (if needed)
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo yum install -y nodejs
# Install required tools
sudo yum install -y bash git jq python3 tmux
sudo yum install -y gh # for GitHub-first setupsWindows: See Windows Setup Guide for native Windows Service setup.
Dependency Table
| Tool | Required | Purpose | Notes |
| --- | --- | --- | --- |
| Node.js >= 18 | yes | Runs the npm package entrypoint and npx wrapper. | CI runs on Node 22. Node 20 or 22 both work fine. |
| bash | yes | All runtime, profile, and worker orchestration scripts are Bash. | Your login shell can be zsh or fish; bash just needs to be on PATH. |
| git | yes | Manages worktrees, checks branch state, and coordinates repo automation. | Required even if you interact only through forge issues and PRs. |
| gh | for GitHub-first setups | GitHub CLI auth and API access for issues, PRs, labels, and metadata. | Run gh auth login before first use when --forge-provider github. |
| jq | yes | Parses JSON from gh output and worker metadata throughout. | Missing jq will break GitHub-heavy and Gitea-heavy runtime flows. |
| python3 | yes | Powers the dashboard server, snapshot renderer, and config helpers. | Required for both dashboard use and several internal scripts. |
| tmux | yes | Runs long-lived worker sessions and captures their status. | Missing tmux means background worker workflows will not launch. |
| Worker CLI (backend-specific) | depends on backend | The coding agent for a profile. Supported: codex, claude, openclaw (production); ollama, pi, opencode, kilo (experimental). | Install and authenticate your chosen backend before starting background runs. |
| ollama | for ollama backend | Serves local models via OpenAI-compatible API at http://localhost:11434. | Install from ollama.com and pull a model (e.g. ollama pull qwen3.5:9b) before use. |
| pi CLI | for pi backend | Lightweight coding agent using OpenRouter-compatible APIs. | Install via npm i -g @mariozechner/pi-coding-agent. Set OPENROUTER_API_KEY before use. |
| crush (opencode) | for opencode backend | Go-based coding agent by Charm (charmbracelet/crush). | macOS: brew install charmbracelet/tap/crush. Linux: download from releases page. |
| kilo CLI | for kilo backend | TypeScript coding agent (kilocode/cli). | Install via npm i -g @kilocode/cli. |
| Bundled codex-quota + ACP quota manager | automatic for Codex | Quota-aware failover and health signals for Codex profiles. | Bundled by default. Override with ACP_CODEX_QUOTA_BIN only if you have a custom setup. |
Make sure your chosen worker backend is authenticated for the same OS user
before starting any background runtime. For GitHub-first setups, authenticate
gh. For Gitea local-first setups, provide --gitea-base-url plus a token or
username/password during setup so ACP can write issues, PR comments, and labels.
Install
The easiest way to try ACP is with npx:
npx agent-control-plane@latest helpIf you use it often, a global install gives you a shorter command:
npm install -g agent-control-plane
agent-control-plane helpThe examples below use npx agent-control-plane@latest ..., but every command
works the same way after a global install.
First Run
Option A — Guided setup (recommended)
The fastest path is the interactive wizard:
npx agent-control-plane@latest setupThe wizard walks you through the full setup in one pass:
- Detects the current repo and suggests sane defaults
- Captures forge mode (
githuborgitea) and the auth/settings that mode needs - Checks backend readiness (API keys for openclaw/pi, local server for ollama)
- Scaffolds the profile, runs health checks, starts the runtime
- Launches the monitoring dashboard in the background
- Offers to create recurring starter issues so ACP starts working immediately
After the wizard finishes, your repo has a running agent, a live dashboard,
and a set of agent-keep-open issues that ACP will continuously work through.
To preview exactly what it would do before touching anything:
npx agent-control-plane@latest setup --dry-runFor non-interactive use (CI, scripted installs, GUI frontends):
npx agent-control-plane@latest setup \
--non-interactive \
--install-missing-deps \
--start-runtime \
--start-dashboard \
--create-starter-issues \
--jsonWith --json, ACP emits a single structured object on stdout and sends
progress logs to stderr, which keeps parsing stable.
Example: local-first Gitea setup
npx agent-control-plane@latest setup \
--forge-provider gitea \
--repo-slug acp-admin/my-repo \
--gitea-base-url http://127.0.0.1:3000 \
--gitea-token <token> \
--start-runtime \
--start-dashboardThis writes the forge settings into the profile runtime.env, so later
heartbeat, reconcile, and publish steps keep talking to the same Gitea
instance without extra shell exports.
Option B — Manual setup
If you prefer explicit control over each step:
1. Authenticate the working forge
gh auth loginFor Gitea local-first, skip gh auth login and pass Gitea settings directly to
setup or init:
--forge-provider gitea \
--gitea-base-url http://127.0.0.1:3000 \
--gitea-token <token>2. Install the packaged runtime
npx agent-control-plane@latest syncThis stages the ACP runtime into ~/.agent-runtime/runtime-home. Safe to
re-run after upgrades.
3. Create a profile for your repo
npx agent-control-plane@latest init \
--profile-id my-repo \
--repo-slug owner/my-repo \
--forge-provider github \
--repo-root ~/src/my-repo \
--agent-root ~/.agent-runtime/projects/my-repo \
--worktree-root ~/src/my-repo-worktrees \
--coding-worker openclaw| Flag | Purpose |
| --- | --- |
| --profile-id | Short name used in all ACP commands |
| --repo-slug | Forge repo ACP should track |
| --forge-provider | Which forge ACP should automate (github or gitea) |
| --gitea-base-url | Base URL when --forge-provider gitea |
| --repo-root | Path to your local checkout |
| --agent-root | Where ACP keeps per-project runtime state |
| --worktree-root | Where ACP places repo worktrees |
| --coding-worker | Backend to orchestrate (codex, claude, openclaw, ollama, pi, opencode, or kilo) |
4. Validate before trusting it
npx agent-control-plane@latest doctor
npx agent-control-plane@latest profile-smoke --profile-id my-repodoctor checks installation health. profile-smoke gives the profile a fast
confidence pass before you turn on background loops.
5. Start the runtime
npx agent-control-plane@latest runtime start --profile-id my-repo
npx agent-control-plane@latest runtime status --profile-id my-repoOnce runtime status returns clean output, ACP is actively managing the
runtime for that profile. Per-profile state lives under ~/.agent-runtime,
grouped and inspectable without digging through scattered temp files.
Starter Issues
The setup wizard can create a set of recurring agent-keep-open issues on your
repo so ACP starts working immediately after installation. ACP picks them up on
its next heartbeat cycle without requiring a separate readiness label.
Built-in templates:
| Issue | What ACP does | | --- | --- | | Code quality sweep | Fix lint warnings, type errors, and dead code | | Test coverage improvement | Add tests for critical untested modules | | Documentation refresh | Keep README and inline docs accurate | | Dependency audit | Fix vulnerabilities and update safe patches | | Refactoring sweep | Reduce complexity and duplication |
You can also create your own recurring issues by adding the
agent-keep-open label to any GitHub issue. ACP will keep revisiting that
issue continuously unless it is blocked or already claimed by an open agent PR.
To skip this step during setup, pass --no-create-starter-issues.
Everyday Usage
# Check runtime state
npx agent-control-plane@latest runtime status --profile-id my-repo
# Restart the runtime
npx agent-control-plane@latest runtime restart --profile-id my-repo
# Stop the runtime
npx agent-control-plane@latest runtime stop --profile-id my-repo
# Run smoke checks
npx agent-control-plane@latest profile-smoke --profile-id my-repo
npx agent-control-plane@latest smokeDashboard
npx agent-control-plane@latest dashboard --host 127.0.0.1 --port 8765Then open http://127.0.0.1:8765.
The dashboard shows all active profiles in one place: running sessions, recent
run history, provider cooldowns, scheduled issues, and queue state — without
having to dig through tmux panes or temp folders.
macOS Autostart
Install a per-profile LaunchAgent so the runtime survives reboots:
npx agent-control-plane@latest launchd-install --profile-id my-repoRemove it:
npx agent-control-plane@latest launchd-uninstall --profile-id my-repoThese commands are macOS-only and manage per-user launchd agents.
Windows (WSL2) Autostart
ACP runs inside WSL2 (Windows Subsystem for Linux) where it uses systemd for service management. This requires WSL2 with systemd enabled (Windows 11 22H2+).
Prerequisites:
- Install WSL2 with Ubuntu:
wsl --install -d Ubuntu(in PowerShell Admin) - Enable systemd in WSL2 (create
/etc/wsl.confwith[boot] systemd=true) - Run
wsl --shutdownfrom PowerShell, then restart WSL2
Install project service in WSL2:
# Inside WSL2 Ubuntu terminal
cd /mnt/c/Users/You/Projects/your-repo
# Bootstrap systemd service (same as Linux)
agent-control-plane project systemd-bootstrap \
--project-dir . \
--repo-url https://github.com/your-org/your-repo.git \
--worker-type claude \
--schedule "*/30 * * * *" \
--issues "1,2,3"Manage the service:
systemctl --user daemon-reload
systemctl --user enable --now agent-control-plane@$(basename $(pwd)).timer
systemctl --user status agent-control-plane@$(basename $(pwd)).timerSee WSL2_SETUP.md for full setup guide, Docker in WSL2, and troubleshooting.
Update
After upgrading the package, refresh the runtime and verify health:
npx agent-control-plane@latest sync
npx agent-control-plane@latest doctor
npx agent-control-plane@latest smoke # optional confidence checkRemove a Profile
Remove one profile and its ACP-managed runtime state:
npx agent-control-plane@latest remove --profile-id my-repoAlso remove ACP-managed repo and worktree directories:
npx agent-control-plane@latest remove --profile-id my-repo --purge-pathsUse --purge-paths only when you want ACP-managed direcories deleted too.
Cross-Platform Notes
Timeout Command Requirement
The scheduler wrapper (kick-scheduler-wrapper.sh) requires a timeout command for process timeout enforcement:
- Linux:
timeoutis usually pre-installed (part ofcoreutils) - macOS: Install via Homebrew:
brew install coreutils(providesgtimeout) - Windows/WSL2: Available in WSL2 Ubuntu by default
If timeout is not available, the scheduler will run without timeout protection. The flow-runtime-doctor.sh script now checks for this and reports it in the TIMEOUT_CMD output.
Doctor Output
Run flow-runtime-doctor.sh to check your environment:
bash tools/bin/flow-runtime-doctor.shLook for TIMEOUT_CMD= in the output to verify timeout command availability.
Troubleshooting
| Symptom | Fix |
| --- | --- |
| profile not installed | Run init first, then retry with the same --profile-id. |
| explicit profile selection required | Pass --profile-id <id> to runtime, launchd-install, launchd-uninstall, and remove. |
| gh cannot access the repo | Re-run gh auth login and confirm the repo slug in the profile is correct. |
| Setup deferred anchor repo sync | ACP could not reach the repo remote. Fix Git access or the remote URL, then re-run setup or init without --skip-anchor-sync. |
| Backend auth failures | Authenticate the backend before starting ACP. For openclaw/pi, set OPENROUTER_API_KEY. For ollama, ensure the server is running. For opencode/kilo, install and authenticate the CLI. |
| Node older than 18 | Upgrade Node first. ACP's minimum version is 18+. |
| Missing jq | Install jq, then retry the failed command. |
| Runtime or source drift after an update | Run sync, then doctor. |
| Missing tmux, gh, or python3 | Install the dependency, then retry sync or runtime start. |
| Missing codex-quota warning | This is optional. Core ACP and all non-Codex flows do not require it. |
FAQ
Q: Can I run ACP on Windows?
A: Yes! ACP supports native Windows Service mode. See Windows Setup Guide for details on using NSSM, sc.exe, or PowerShell.
Q: Which coding worker should I use?
A: For beginners: start with codex or claude (production-ready). For local/private: use ollama (runs offline). For research: try pi (OpenRouter free tier models).
Q: How do I update ACP?
A:
npm update -g agent-control-plane
npx agent-control-plane@latest syncQ: The dashboard shows "Reconnecting" - what do I do?
A: Check if the dashboard server is running (npx agent-control-plane@latest dashboard status). If not, start it. Also check if port 8765 is available.
Q: Can I run multiple profiles?
A: Yes! Each profile is independent. Just use different --profile-id values when running init, runtime, etc.
Q: How do I stop ACP from consuming all my API quota?
A: Set ACP_CODING_WORKER to a local backend like ollama, or configure ACP_MAX_LAUNCHES_PER_HEARTBEAT to limit concurrent runs.
Q: Where are my agent runs stored?
A: In ~/.agent-runtime/projects/<profile-id>/runs/. Each session has its own directory with logs and metadata.
Q: How do I contribute to ACP?
A: See CONTRIBUTING.md for guidelines. PRs welcome!
Common Workflows
Workflow 1: Automate GitHub Issues
- Label any issue with
agent-keep-open - ACP will automatically pick it up and start working
- Monitor progress at the dashboard (http://127.0.0.1:8765)
- Review the PR when ACP creates one
# Check what ACP is working on
agent-control-plane runtime status --profile-id my-repo
# View recent runs
ls -la ~/.agent-runtime/projects/my-repo/runs/Workflow 2: Switch Coding Worker
# 1. Update profile configuration
nano ~/.agent-runtime/control-plane/profiles/my-repo/control-plane.yaml
# Change: coding_worker: codex -> claude
# 2. Restart runtime
agent-control-plane runtime restart --profile-id my-repoWorkflow 3: Monitor API Usage
# Check provider cooldowns
cat ~/.agent-runtime/projects/my-repo/state/provider-cooldowns.json
# View scheduler metrics (if enabled)
tail -f ~/.agent-runtime/projects/my-repo/state/scheduler-events.jsonlWorkflow 4: Handle Failed Runs
# 1. Check the error
cat ~/.agent-runtime/projects/my-repo/runs/<session-id>/main.log
# 2. Fix the issue (auth, dependencies, etc.)
# 3. Retry the issue
agent-control-plane runtime restart --profile-id my-repoWorkflow 5: Update ACP Safely
# 1. Update package
npm update -g agent-control-plane
# 2. Sync runtime
npx agent-control-plane@latest sync
# 3. Verify
agent-control-plane doctor
# 4. Restart runtime
agent-control-plane runtime restart --profile-id my-repoAdvanced Configuration
Environment Variables
ACP uses these environment variables (prefix: ACP_ or F_LOSNING_):
| Variable | Purpose | Default |
| --- | --- | --- |
| ACP_CODING_WORKER | Default coding worker | codex |
| ACP_MAX_CONCURRENT_WORKERS | Max concurrent workers | 20 |
| ACP_MAX_LAUNCHES_PER_HEARTBEAT | Max launches per heartbeat | 20 |
| ACP_CATCHUP_TIMEOUT_SECONDS | Timeout for catchup phase | 180 |
| ACP_HEARTBEAT_LOOP_TIMEOUT_SECONDS | Timeout for heartbeat loop | 720 |
| ACP_CODEX_QUOTA_AUTOSWITCH_ENABLED | Auto-switch on quota exhaustion | 1 |
| ACP_RETAINED_WORKTREE_AUDIT_ENABLED | Audit worktree retention | 1 |
Profile Configuration
Edit ~/.agent-runtime/control-plane/profiles/<id>/control-plane.yaml:
execution:
coding_worker: codex
ollama:
model: "qwen3.5:9b"
base_url: "http://localhost:11434"
timeout_seconds: 900
scheduler:
max_concurrent_workers: 20
max_launches_per_heartbeat: 20
catchup_timeout_seconds: 180Scheduler Tuning
For busy repos (many issues):
export ACP_MAX_CONCURRENT_WORKERS=50
export ACP_MAX_LAUNCHES_PER_HEARTBEAT=50For slow workers (complex tasks):
export ACP_CATCHUP_TIMEOUT_SECONDS=300
export ACP_HEARTBEAT_LOOP_TIMEOUT_SECONDS=1200Quota Management (Codex Only)
# Enable auto-switch on quota exhaustion
export ACP_CODEX_QUOTA_AUTOSWITCH_ENABLED=1
# Set soft threshold (warning)
export ACP_CODEX_QUOTA_SOFT_THRESHOLD=55
# Set emergency threshold (switch worker)
export ACP_CODEX_QUOTA_EMERGENCY_THRESHOLD=65Community
Join the ACP community for help, discussions, and updates:
| Channel | Link | Purpose | | --- | --- | --- | | GitHub Discussions | Join here | Q&A, ideas, announcements | | GitHub Issues | Report bugs | Bug reports, feature requests | | GitHub PRs | Contribute | Code contributions | | GitHub Sponsors | Support us | Financial support |
Getting Help
- Documentation: Start with README.md and CONTRIBUTING.md
- Common Issues: Check the FAQ section in README
- Discussions: Ask questions on GitHub Discussions
- Bug Reports: Open an issue with reproduction steps
Stay Updated
Benchmarks
Worker Performance Comparison
| Worker | Avg Task Time | Success Rate | API Cost/1k tasks | Setup Difficulty | | --- | --- | --- | --- | --- | | codex | ~2min | 95% | $15-30 | Easy | | claude | ~2min | 96% | $20-40 | Easy | | openclaw | ~2min | 94% | $10-25 | Easy | | ollama (qwen3.5:9b) | ~5min | 85% | $0 (local) | Medium | | pi (mistral) | ~3min | 88% | $0 (free tier) | Easy | | opencode | ~4min | 90% | $0 (local) | Medium | | kilo | ~3min | 89% | $0 (local) | Medium |
Benchmarks run on: 100 mixed tasks (simple to complex), 16GB RAM, 4-core CPU.
Resource Usage (idle vs active)
| Component | Memory (idle) | Memory (active) | CPU (idle) | CPU (active) | | --- | --- | --- | --- | --- | | Dashboard | 45MB | 60MB | 0.5% | 2-5% | | Scheduler | 30MB | 80MB | 0.1% | 10-30% | | Worker (codex) | - | 150-300MB | - | 20-50% | | Worker (ollama) | - | 2-8GB | - | 50-100% |
Tips for Better Performance
- Use local models (ollama) for cost savings
- Limit concurrent workers if resources are tight:
export ACP_MAX_CONCURRENT_WORKERS=5 - Use SSD storage for worktrees and state
- Monitor usage via dashboard at http://127.0.0.1:8765
Quick Tips
For Beginners
- Start with
agent-control-plane setup(wizard mode) - Use
codexorclaudeworkers (most reliable) - Keep dashboard open at http://127.0.0.1:8765
- Label issues with
agent-keep-opento let ACP work
For Power Users
- Set
ACP_MAX_CONCURRENT_WORKERSto limit resource usage - Use
ollamafor free local execution - Monitor
provider-cooldowns.jsonfor API quota - Run
agent-control-plane doctorweekly for health checks
For Contributors
- Read
CONTRIBUTING.mdfirst - Run
bash tools/scripts/verify-package.shbefore submitting PR - Test with
npm testandnpm run doctor - Keep PRs focused on single concerns
Command Summary
| Command | Purpose |
| --- | --- |
| help | Show the full CLI surface. Good first command on a new machine. |
| version | Print the running package version. |
| setup [--dry-run] [--json] | Guided bootstrap wizard. Detects repo, installs deps, scaffolds profile, starts runtime and dashboard, creates starter issues. --dry-run previews. --json emits structured output. |
| sync / install | Stage or refresh the packaged runtime into ~/.agent-runtime/runtime-home. Run after install or upgrade. |
| init ... | Scaffold one repo profile manually. Requires --profile-id, --repo-slug, --repo-root, --agent-root, --worktree-root, --coding-worker. |
| doctor | Inspect runtime and source installation health. |
| profile-smoke [--profile-id <id>] | Validate one profile before trusting it with real work. |
| runtime <status\|start\|stop\|restart> --profile-id <id> | Operate one profile runtime. |
| dashboard [--host] [--port] | Start the local monitoring dashboard. Defaults: 127.0.0.1:8765. |
| launchd-install --profile-id <id> | Install a per-profile LaunchAgent on macOS. |
| launchd-uninstall --profile-id <id> | Remove a per-profile LaunchAgent on macOS. |
| remove --profile-id <id> [--purge-paths] | Remove a profile and its ACP-managed state. --purge-paths also deletes managed directories. |
| smoke | Run the packaged smoke suite for the shared control plane. |
For a lower-level script map, see references/commands.md.
Support the Project
If ACP saves you time or keeps your agent workflows sane, you can support the project via GitHub Sponsors.
The open source core stays free. If you fork or republish this package under
another maintainer account, update the sponsor links in package.json and
.github/FUNDING.yml.
Sponsorship policy: Sponsorships are maintainer-managed project support. They do not transfer ownership, copyright, patent rights, or control over the project. Contributors are not automatically entitled to sponsorship payouts. The maintainer may direct funds toward maintenance, infrastructure, contributor rewards, or other project-related work at their discretion.
Contributing
Contributions are welcome. This repo uses a contributor agreement so the project can stay easy to maintain and relicense if needed.
- Contribution guide: CONTRIBUTING.md
- Contributor agreement: CLA.md
Security
Do not open a public issue for vulnerabilities.
- Security policy: SECURITY.md
- Code of conduct: CODE_OF_CONDUCT.md
Releases
- Release history: CHANGELOG.md
- Maintainer checklist: references/release-checklist.md
