Codex autorunner CLI per DESIGN-V1
Project description
codex-autorunner
An opinionated autorunner that uses the Codex CLI to work on large tasks via a simple loop. On each loop we feed the Codex instance the last one's final output along with core documents.
- TODO - Tracks long-horizon tasks
- PROGRESS - High level overview of what's been done already that may be relevant for future agents
- OPINIONS - Guidelines for how we should approach implementation
- SPEC - Source-of-truth requirements and scope for large features/projects
Sneak Peak
Run multiple agents on many repositories, with git worktree support
See the progress of your long running tasks with a high level overview
Dive deep into specific agent execution with a rich but readable log
All memory and opinions are markdown files! Edit them directly or chat with the document!
Use codex CLI directly for multi-shot problem solving or /review
Mobile-first experience, code on the go with Whisper support (BYOK)
What it does
- Initializes a repo with Codex-friendly docs and config.
- Runs Codex in a loop against the repo, streaming logs.
- Tracks state, logs, and config under
.codex-autorunner/. - Exposes a power-user HTTP API and web UI for docs, logs, runner control, and a Codex TUI terminal.
- Optionally runs a Telegram bot for interactive, user-in-the-loop Codex sessions.
- Generates a pasteable repo snapshot (
.codex-autorunner/SNAPSHOT.md) for sharing with other LLM chats.
CLI commands are available as codex-autorunner or the shorter car.
Install
PyPI (pipx):
pipx install codex-autorunner
GitHub (pipx, dev):
pipx install git+https://github.com/Git-on-my-level/codex-autorunner.git
From source (editable):
git clone https://github.com/Git-on-my-level/codex-autorunner.git
cd codex-autorunner
pip install -e .
Optional extras
- Telegram bot support:
pip install codex-autorunner[telegram] - Voice transcription support:
pip install codex-autorunner[voice] - Dev tools (lint/test):
pip install codex-autorunner[dev] - Local dev alternative:
pip install -e .[extra]
Dev setup
make setupcreates.venv, installs.[dev], runsnpm install, and setscore.hooksPathto.githooks.
Opinionated setup (macOS headless hub at ~/car-workspace)
- One-shot setup (user scope):
scripts/install-local-mac-hub.sh. It pipx-installs this repo, creates/initializes~/car-workspaceas a hub, writes a launchd agent plist, and loads it. Defaults: host127.0.0.1, port4173, labelcom.codex.autorunner. Override via env (WORKSPACE,HOST,PORT,LABEL,PLIST_PATH,PACKAGE_SRC). For remote access, prefer a VPN like Tailscale and keep the hub bound to loopback; if you bind to a non-loopback host, the script configuresserver.auth_token_env+ a token in.codex-autorunner/.env. - Create/update the launchd agent plist and (re)load it:
scripts/launchd-hub.sh(ormake launchd-hub). - Linux users: see
docs/ops/systemd.mdfor systemd hub/Telegram setup. - Manual path if you prefer:
pipx install .car init --mode hub --path ~/car-workspace- Copy
docs/ops/launchd-hub-example.plistto~/Library/LaunchAgents/com.codex.autorunner.plist, replace/Users/youwith your home, adjust host/port if desired, thenlaunchctl load -w ~/Library/LaunchAgents/com.codex.autorunner.plist.
- The hub serves the UI/API from
http://<host>:<port>and writes logs to~/car-workspace/.codex-autorunner/codex-autorunner-hub.log. Each repo under~/car-workspaceshould be a git repo with its own.codex-autorunner/(runcar initin each).
Refresh a launchd hub to the current branch
When you change code in this repo and want the launchd-managed hub to run it:
- Recommended: run the safe refresher, which installs into a new venv, flips
~/.local/pipx/venvs/codex-autorunner.current, restarts launchd, health-checks, and auto-rolls back on failure:
make refresh-launchd
Important: avoid in-place pip/pipx installs against the live venv. During uninstall/reinstall, packaged static assets disappear and the UI can break while the server keeps running. Use the safe refresher or stop the service before manual installs.
- Manual path (offline only; no rollback): stop launchd first, then reinstall into the launchd venv (pipx default paths shown; adjust if your label/paths differ):
$HOME/.local/pipx/venvs/codex-autorunner/bin/python -m pip install --force-reinstall /path/to/your/codex-autorunner
- Restart the agent so it picks up the new bits (default label is
com.codex.autorunner; default plist~/Library/LaunchAgents/com.codex.autorunner.plist):
launchctl unload ~/Library/LaunchAgents/com.codex.autorunner.plist 2>/dev/null || true
launchctl load -w ~/Library/LaunchAgents/com.codex.autorunner.plist
launchctl kickstart -k gui/$(id -u)/com.codex.autorunner
- Tail the hub log to confirm it booted:
tail -n 50 ~/car-workspace/.codex-autorunner/codex-autorunner-hub.log.
Health checks (recommended)
GET /healthreturns 200 (verifies static assets are present).GET /static/app.jsreturns 200.- Optional:
GET /returns HTML (not a JSON error). If you set a base path, prefix all checks with it.
Quick start
- Install (editable):
pip install -e . - Initialize (per repo):
codex-autorunner init --git-init(orcar init --git-initif you prefer short). This creates.codex-autorunner/config.yml, state/log files, and the docs under.codex-autorunner/. - Run once:
codex-autorunner once/car once - Continuous loop:
codex-autorunner run/car run - If stuck:
codex-autorunner killthencodex-autorunner resume(or thecarequivalents) - Check status/logs:
codex-autorunner status,codex-autorunner log --tail 200(orcar ...)
Configuration
- Root defaults live in
codex-autorunner.yml(committed). These defaults are used when CAR generates.codex-autorunner/config.yml. - Local overrides live in
codex-autorunner.override.yml(gitignored). Use it for machine-specific tweaks; keep secrets in env vars. - Repo config lives at
.codex-autorunner/config.yml(generated). Edit it for repo-specific changes.
Interfaces
CAR supports two interfaces with the same core engine. The web UI is the power user control plane for multi-repo visibility and system control. The Telegram bot is optimized for interactive back-and-forth, mirroring the Codex TUI experience inside Telegram with user-in-the-loop approvals.
Web UI (control plane)
- Ensure the repo is initialized (
codex-autorunner init) so.codex-autorunner/config.ymlexists. - Start the API/UI backend:
codex-autorunner serve(orcar serve) — defaults to127.0.0.1:4173; override viaserver.host/server.portin.codex-autorunner/config.yml. - Open
http://127.0.0.1:4173to use the UI, or call the FastAPI endpoints under/api/*.- The Terminal tab launches the configured Codex binary inside a PTY via websocket; it uses
codex.terminal_args(defaults empty, so it runscodexbare unless you override). xterm.js assets are vendored understatic/vendor. - If you need to serve under a proxy prefix (e.g.,
/car), setserver.base_pathin.codex-autorunner/config.ymlor pass--base-pathtocar serve/hub serve; all HTTP/WS endpoints will be reachable under that prefix. Proxy must forward that prefix (e.g., Caddyhandle /car/* { reverse_proxy ... }with a 404 fallback for everything else). - Chat composer shortcuts: desktop uses Cmd+Enter (or Ctrl+Enter) to send and Shift+Enter for newline; mobile uses Enter to send and Shift+Enter for newline.
- The Terminal tab launches the configured Codex binary inside a PTY via websocket; it uses
Telegram bot (interactive sessions)
- The interactive Telegram bot is separate from
notifications.telegram(which is one-way notifications). - Each operator should create their own Telegram bot token. Multi-user use requires explicit allowlists.
- Quickstart:
- Set env vars:
CAR_TELEGRAM_BOT_TOKEN(and optionallyCAR_TELEGRAM_CHAT_ID). - In config, set
telegram_bot.enabled: trueand fillallowed_user_ids+allowed_chat_ids. - Run
car telegram start --path <repo_or_hub>. - Use
/bind(hub mode) and/newor/resumein Telegram.
- Set env vars:
- How it works (high level):
- The bot polls the Telegram Bot API, allowlists chat/user IDs, and routes each topic to a workspace + Codex thread.
- Messages and media are forwarded to the Codex app-server, streaming responses back to Telegram.
- Approvals can be requested inline, giving a hands-on, TUI-like workflow without leaving Telegram.
- Details:
docs/telegram/architecture.md,docs/ops/telegram-bot-runbook.md, anddocs/telegram/security.md.
Security and remote access
- The UI/API are effectively privileged access and can execute code on your machine (terminal + runner).
- Keep the server bound to
127.0.0.1and use Tailscale (or another VPN) for remote access. - If you must expose it, set
server.auth_token_envand also put it behind an auth-enforcing reverse proxy (basic auth/SSO). - Do not expose it publicly without protections. See
docs/web/security.mdfor details.
Auth token (optional)
If you set server.auth_token_env, the API requires Authorization: Bearer <token> on every request.
- Set the config:
server.auth_token_env: CAR_SERVER_TOKEN. - Export the token before starting the server:
export CAR_SERVER_TOKEN="...". - Browser UI: visit
http://host:port/?token=...once. The UI stores it insessionStorageand removes it from the URL; WebSocket connections send the token viaSec-WebSocket-Protocol: car-token-b64.<base64url(token)>. - CLI: requests automatically attach the token from
server.auth_token_env; if the env var is missing, CLI commands will error.
Git hooks
- Install dev tools:
pip install -e .[dev] - Point Git to the repo hooks:
git config core.hooksPath .githooks - The
pre-commithook runsscripts/check.sh(Black formatting check + pytest). Run it manually with./scripts/check.shbefore committing or in CI.
Commands (CLI)
init— seed config/state/docs.run/once— run the loop (continuous or single iteration).resume— clear stale lock/state and restart;--oncefor a single run.kill— SIGTERM the running loop and mark state error.status— show current state and outstanding TODO count.sessions— list terminal sessions (server-backed when available).stop-session— stop a terminal session by repo (--repo) or id (--session).log— view logs (tail or specific run).edit— open TODO/PROGRESS/OPINIONS/SPEC in$EDITOR.ingest-spec— generate TODO/PROGRESS/OPINIONS from SPEC using Codex (use--forceto overwrite).clear-docs— reset TODO/PROGRESS/OPINIONS to empty templates (type CLEAR to confirm).snapshot— generate/update.codex-autorunner/SNAPSHOT.md(incremental by default when one exists; use--from-scratchto regenerate).serve— start the HTTP API (FastAPI) on host/port from config (defaults 127.0.0.1:4173).
Snapshot (repo briefing)
- Web UI: open the Snapshot tab. If no snapshot exists, you’ll see “Generate snapshot”; otherwise you’ll see “Update snapshot (incremental)” and “Regenerate snapshot (from scratch)”, plus “Copy to clipboard”.
- CLI:
codex-autorunner snapshot(orcar snapshot) writes.codex-autorunner/SNAPSHOT.mdand.codex-autorunner/snapshot_state.json.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codex_autorunner-0.1.0.tar.gz.
File metadata
- Download URL: codex_autorunner-0.1.0.tar.gz
- Upload date:
- Size: 655.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
851a28ecfc77f8e3b598887304c9c0f54fc64b2dfd8cf056bbd74fe064e9d898
|
|
| MD5 |
5a41cb2eb9a8456c71fa3bb0c627b3cf
|
|
| BLAKE2b-256 |
208fc02dc70d672cbc051b2824db8fce8b796c1549cc290d5f2bd58f93691529
|
Provenance
The following attestation bundles were made for codex_autorunner-0.1.0.tar.gz:
Publisher:
release.yml on Git-on-my-level/codex-autorunner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
codex_autorunner-0.1.0.tar.gz -
Subject digest:
851a28ecfc77f8e3b598887304c9c0f54fc64b2dfd8cf056bbd74fe064e9d898 - Sigstore transparency entry: 821283464
- Sigstore integration time:
-
Permalink:
Git-on-my-level/codex-autorunner@f52821286d2265d2f47aa57c823f9e194070cf12 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Git-on-my-level
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f52821286d2265d2f47aa57c823f9e194070cf12 -
Trigger Event:
push
-
Statement type:
File details
Details for the file codex_autorunner-0.1.0-py3-none-any.whl.
File metadata
- Download URL: codex_autorunner-0.1.0-py3-none-any.whl
- Upload date:
- Size: 653.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9e6877893a65b96e1ae0a33dde49d9b2d327a8acf3c705dfcf8bc9ce9ede938f
|
|
| MD5 |
cabc02200f2aac2fb29a97792b1268a3
|
|
| BLAKE2b-256 |
30c5b19e7c9e4c8accce66cbaa27ee3875c8240e4831d55eba32afe5492999bc
|
Provenance
The following attestation bundles were made for codex_autorunner-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Git-on-my-level/codex-autorunner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
codex_autorunner-0.1.0-py3-none-any.whl -
Subject digest:
9e6877893a65b96e1ae0a33dde49d9b2d327a8acf3c705dfcf8bc9ce9ede938f - Sigstore transparency entry: 821283468
- Sigstore integration time:
-
Permalink:
Git-on-my-level/codex-autorunner@f52821286d2265d2f47aa57c823f9e194070cf12 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Git-on-my-level
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f52821286d2265d2f47aa57c823f9e194070cf12 -
Trigger Event:
push
-
Statement type: