tools
The cox command. This folder is the agent_tools package inside the
coxswain repository; it ships as part of the one coxswain package. To
install Coxswain, see the root README.
Tools are what the agent seats run instead of spending tokens. Anything a seat would otherwise do by reading a file wholesale and reasoning about it — summing a run's cost, counting what a traced node did, cleaning up after a run, landing a branch — is a function here that reads it and answers.
The mould, every time: a pure core with no I/O, the filesystem and the network at the edges, dry-run by default where a write is involved, and tests that never touch a real run.
What is here
agent_tools/ the package: the `cox` CLI, its command table, and every command's pure core and edge
tests/ this folder's suite
docs/ design notes and guides for single features (shared store, forgejo forge)
ops/ operator scripts that sit beside the CLI (store backup)
Tests
From this folder:
cd src/tools && uv run pytest -q
The Postgres cases in tests/test_run_store_backends.py run only when
COX_TEST_POSTGRES_URL names a database where the test may create a schema.
Without it they are skipped.
Commands
Bare cox on a terminal starts cox session: a Claude Code session with the
coxswain plugin loaded, in the profile's workspace. cox home opens towpath.
agent-tools still works as a deprecated alias for cox, removed next release.
The block below is generated from the command table; run
python -m devtools commands render from the repository root to refresh it.
cox runs usage RUN_ID [--runs-dir RUNS_DIR] [--json] usage stats and cost for one run
cox runs trace RUN_ID [--runs-dir RUNS_DIR] [--role ROLE] [-v] the tool-call trace for one run
cox runs clean RUN_ID --repo REPO [--worktree-root WORKTREE_ROOT] [--runs-dir RUNS_DIR] [--profile PROFILE] [--apply] [--force] delete a run's worktree and branches locally
cox runs land RUN_ID --repo REPO [--task TASK] [--phase PHASE] [--label LABEL] [--force] [--no-claim] [--worktree-root WORKTREE_ROOT] [--apply] [--no-merge] [--runs-dir RUNS_DIR] [--profile PROFILE] [--gate ticket|phase|epic|full] merge a run's branch into the target repo
cox runs fetch [--runs-dir RUNS_DIR] [--profile PROFILE] [RUN_ID] [--all] pull an ended remote lane's run directory, log and branches to this machine
cox runs review --pr PR [--profile PROFILE] review a contributor PR with the review graph and post the verdict
cox runs recover RUN_ID TASK_ID --repo REPO [--runs-dir RUNS_DIR] [--profile PROFILE] [--dry-run] merge an approved task's commit into its phase branch after an escalated merge
cox runs series [--runs-dir RUNS_DIR] [--json] [--append APPEND] per-run summary rows across a runs directory
cox runs wait [--runs-dir RUNS_DIR] [--max-seconds MAX_SECONDS] [--interval INTERVAL] [--json] block until a busy lane's run exits, then print its outcome lines
cox runs events [--runs-dir RUNS_DIR] [--follow] [--json] poll a run's log for structured events
cox runs top [--runs-dir RUNS_DIR] [--interval INTERVAL] [--once] live table of busy lanes (runs in flight); --once prints it and exits
cox runs bar [--runs-dir RUNS_DIR] one Waybar JSON line: busy lanes, cost, class idle|running|attention
cox runs notify [--runs-dir RUNS_DIR] [--once] [--interval INTERVAL] [--replay] desktop notifications for exits, quarantines, budget stops and cost
cox runs detail RUN_ID [--runs-dir RUNS_DIR] [--json] one run's timeline, objection and last tool calls
cox runs stranded [--runs-dir RUNS_DIR] [--profile PROFILE] [--json] every approved task record whose work item is not done, with its remedy
cox runs cause RUN_ID TASK_ID ticket|code|harness|unknown [--note NOTE] [--runs-dir RUNS_DIR] [--profile PROFILE] record why one run's attempt at a task was quarantined
cox runs stop RUN_ID [--runs-dir RUNS_DIR] [--profile PROFILE] [--json] stop a run's process, local or remote, and wait for it to exit
cox runs pause RUN_ID [--reason REASON] [--runs-dir RUNS_DIR] [--json] mark a run paused in the store
cox runs resume RUN_ID [--runs-dir RUNS_DIR] [--json] mark a paused run resumed in the store
cox runs move RUN_ID --to TO [--reason REASON] [--runs-dir RUNS_DIR] [--profile PROFILE] [--json] stop a run at its node boundary and relaunch it on another host
cox runs triage TASK_ID [--json] [--profile PROFILE] [--repo PATH] print a quarantined task's facts; reads the store and git only, makes no model call
cox courier send REF --to TO --note NOTE [--profile PROFILE] append a bus entry naming a courier reference
cox courier inbox [--label LABEL] [--profile PROFILE] list this label's unacknowledged bus entries
cox courier ack ID [--profile PROFILE] acknowledge one bus entry by id
cox versions [--root ROOT] [--manifest MANIFEST] component versions against the manifest
cox console [--runs-dir RUNS_DIR] [--work-dir WORK_DIR] [--interval INTERVAL] [--once] [--profile PROFILE] one screen of hosts, drafts, lanes and the chair; keys run cox commands after a y/n
cox dash [--runs-dir RUNS_DIR] [--work-dir WORK_DIR] [--feed] [--once] [--interval INTERVAL] [--detail KIND] a versioned JSON snapshot of the workspace: --feed streams it, --once prints one, --detail drills into one kind
cox settings get [--json] [--profile PROFILE] print every setting, grouped by section; unset keys appear as built-in defaults, which set can override
cox settings set cartridge|profile|host KEY VALUE [--dry-run] [--commit] [--profile PROFILE] change one setting: print the diff and write the file; --commit also commits a git-tracked cartridge
cox install [--root ROOT] [--home HOME] [--manifest MANIFEST] [--provider PROVIDER] [--with FLAG] [--team TEAM] [--workspace WORKSPACE] [--edge] [--dry-run] clone/update coxswain components against the manifest
cox upgrade [--root ROOT] [--home HOME] [--manifest MANIFEST] [--provider PROVIDER] [--with FLAG] [--team TEAM] [--workspace WORKSPACE] [--to TO] [--dry-run] fetch and check out newer pinned versions; refuses dirty checkouts
cox home [--profile PROFILE] the live dashboard: runs, leader, backlog
cox session [--profile PROFILE] [--no-plugin] [--print-argv] [CLAUDE_ARG...] open the coxswain Claude session
cox stats ingest [RUNS_DIR] [--db DB] [--work-store-root WORK_STORE_ROOT] [--cartridges-repo CARTRIDGES_REPO] load usage, task, node and launch records into stats.db
cox stats roles [--db DB] [--runs-dir RUNS_DIR] [--json] [--cartridge-sha CARTRIDGE_SHA] [--provider-profile PROVIDER_PROFILE] landed rate, attempts-to-land and $/landed per role and model
cox stats tiers [--db DB] [--since SINCE] [--min-samples MIN_SAMPLES] [--json] per-role model summaries, a cost-aware pick and the spend it would save
cox stats models [--db DB] [--role ROLE] [--since SINCE] [--json] per-role cost, tokens, turns, $/landed and first-try per model id
cox stats causes [--runs-dir RUNS_DIR] [--since SINCE] [--json] quarantined attempts by cause and kind, with sample reasons
cox stats efficiency [--runs-dir RUNS_DIR] [--days DAYS] [--json] cost per turn, cost per landed task, first-try rate, waste share, per day
cox stats gates [--db DB] [--since SINCE] [--store] [--runs-dir RUNS_DIR] [--min-sample MIN_SAMPLE] [--json] what each review, validation and plan gate costs and how often it changes the outcome
cox stats explain ROLE [--db DB] [--json] the failure-class breakdown behind one role
cox stats series [--db DB] [--json] [--cartridge-sha CARTRIDGE_SHA] [--provider-profile PROVIDER_PROFILE] per-run summary rows read from the stats store
cox stats coverage [--db DB] [--json] known/total provenance rows for runs, calls and tasks
cox stats bounds [--db DB] [--json] [--level strict|moderate|liberal] [--profile PROFILE] [--write WRITE] n/p50/p95/max and strict/moderate/liberal candidate ceilings per role and model
cox stats spend-mix [--db DB] [--json] per-model token counts and cost share by class, plus the build-only split
cox stats chair [RUNS_DIR] [--since SINCE] [--json] [--session SESSION] [--work-store-root WORK_STORE_ROOT] [--projects-dir PROJECTS_DIR] [--profile PROFILE] harness PRs and $, chair $ per PR, hand-finished lands and quarantine $ by cause
cox stats examples [RUNS_DIR] --role ROLE [--out OUT] [--since SINCE] the local system-one backend's training file (JSON lines) from task records
cox stats system-one [RUNS_DIR] [--role ROLE] [--since SINCE] [--json] [--propose] [--plans-dir PLANS_DIR] shadow-to-on graduation report per role, and a proposal for the maintainer to approve
cox stats lanes [--runs-dir RUNS_DIR] [--hours HOURS] [--json] per hour, the average and peak busy lanes and the idle minutes, from the store's run spans
cox lake sync [--runs-dir RUNS_DIR] [--profile PROFILE] [--dry-run] [--json] append new run-store rows and register new trace files; --dry-run writes nothing
cox lake query SQL [--runs-dir RUNS_DIR] [--profile PROFILE] [--json] run DuckDB SQL over the lake tables (runs, phases, ...) and print the rows
cox lake doctor [--runs-dir RUNS_DIR] [--profile PROFILE] [--json] check the lake: catalog, namespace, warehouse and each table; exits 1 on a failed check
cox usage assess [--json] [--runs-dir RUNS_DIR] [--profile PROFILE] the pacing verdict for the current spend window
cox plan serve DIR [--kind KIND] [--check] [--no-open] serve a visual plan through the local bridge
cox epic watch PIDFILE [--log LOG] [--max-seconds MAX_SECONDS] [--interval INTERVAL] [--json] poll a detached run's pidfile until it exits
cox route context [--profile PROFILE] [--json] the routing profile's resolved context
cox route status [--profile PROFILE] [--json] [--all] what is queued or running for this profile
cox route file [--profile PROFILE] [--repo REPO] [--title TITLE] [--body BODY] [--phase PHASE] [--intake] [--from-intake FROM_INTAKE] [--force] file a new ticket for the harness
cox route priority [INITIATIVE] [--profile PROFILE] [--set N] [--up] [--down] [--top] [--bottom] move an initiative up or down the launch order
cox route pull [--profile PROFILE] [--source SOURCE] [--dry-run] file intake tickets from a source, once per link
cox route lint INITIATIVE_DIR [--repo REPO] static ticket lint over a filed initiative, work-shape.md §3
cox route groups [--profile PROFILE] print the newest plans/intake-groups/<date>.md file, work-shape.md §5
cox route drift [--profile PROFILE] [--json] items whose store state and file state differ
cox route import [--profile PROFILE] [--workspace WORKSPACE] load the current work item files into the store's work_items table
cox route paths [--profile PROFILE] [--workspace WORKSPACE] [--apply] [--move ('OLD', 'NEW')] rewrite recorded repo paths to the tilde form, dry run first
cox route store-fill [--profile PROFILE] [--workspace WORKSPACE] fill the store's work_items from the workspace files
cox route approve INITIATIVE [--task TASK] [--by BY] [--profile PROFILE] approve a draft initiative's todo tickets: todo becomes ready
cox route decline INITIATIVE --reason REASON [--by BY] [--profile PROFILE] decline a draft initiative: its todo tickets become dropped
cox route edit ID [--title TITLE] [--body BODY] [--body-file BODY_FILE] [--repo REPO] [--surfaces SURFACES] [--state STATE] [--dry-run] [--profile PROFILE] change a queued intake, an initiative or a task ticket
cox route remove ID --reason REASON [--by BY] [--dry-run] [--profile PROFILE] remove a queued intake or an initiative that has no live run
cox route requeue ID [--dry-run] [--profile PROFILE] requeue the intake of an initiative that has no live tasks
cox route chair take [--profile PROFILE] [--label LABEL] [--pid PID] [--steal] [--hours HOURS] [--model sonnet|opus|haiku] take the chair lock if no live chair holds it
cox route chair extend [--profile PROFILE] [--label LABEL] [--pid PID] [--hours HOURS] move the end of the chair takeover this session holds
cox route chair beat [--profile PROFILE] [--label LABEL] [--pid PID] [--run RUN] refresh the chair lock's heartbeat
cox route chair release [--profile PROFILE] [--label LABEL] [--pid PID] release the chair lock this session holds
cox route chair status [--profile PROFILE] [--json] the chair lock's holder and computed state
cox route chair clear [--profile PROFILE] [--force] remove the chair lock file, refusing a live holder unless --force
cox route chair chat [TEXT] [--profile PROFILE] [--read] [--since SINCE] [--json] [--as-leader] append to or read the leader chat thread (runs/leader.chat.jsonl)
cox route sync [--profile PROFILE] [--item ITEM] [--project PROJECT] [--workspace WORKSPACE] [--dry-run] mirror the work store onto the profile's tracker
cox route launch epic [--profile PROFILE] --initiative INITIATIVE [--repo REPO] [--fix-attempts FIX_ATTEMPTS] [--dry-run] [--run-id RUN_ID] [--on ON] [--include-blocked] [--tier-ceiling cheap|standard|deep] [--effort-ceiling low|high] [--force] [--no-claim] [--label LABEL] launch the epic graph against a filed initiative
cox route launch decompose [--profile PROFILE] --idea IDEA --initiative-id INITIATIVE_ID [--task-ids ordinal] [--dry-run] [--tier-ceiling cheap|standard|deep] [--effort-ceiling low|high] [--force] [--no-claim] [--label LABEL] launch the decompose graph against an idea
cox route launch rescue [--profile PROFILE] --initiative INITIATIVE --task TASK [--repo REPO] [--dry-run] [--run-id RUN_ID] [--tier-ceiling cheap|standard|deep] [--effort-ceiling low|high] [--force] [--no-claim] [--label LABEL] launch the rescue graph against a task
cox route launch cos [--profile PROFILE] [--dry-run] [--tier-ceiling cheap|standard|deep] [--effort-ceiling low|high] [--force] [--no-claim] [--label LABEL] launch the cos graph
cox route launch sweep --idea IDEA --initiative-id INITIATIVE_ID [--label LABEL] [--dry-run] launch the sweep graph against an idea
cox chair run [--once] [--interval INTERVAL] [--dry-run] [--max-overruns MAX_OVERRUNS] [--label LABEL] [--profile PROFILE] beat, gather, plan, perform and report every tick until interrupted
cox chair service [--install] [--status] [--label LABEL] [--interval INTERVAL] [--environment-file ENVIRONMENT_FILE] [--profile PROFILE] [--host HOST] [--apply] write or show the systemd user unit that keeps `cox chair run` alive
cox chair ask QUESTION [--option OPTION] [--context CONTEXT] [--label LABEL] [--profile PROFILE] put a question with its options to the operator on the courier bus
cox chair attach [--profile PROFILE] say whether a live chair loop holds the lease; exit 0 if so, 1 if not
cox chair answer ID OPTION [--profile PROFILE] answer an open decision with one of its options
cox chair decisions [--open] [--answered] [--json] [--profile PROFILE] list decisions asked of the operator and their answers
cox chair watchdog [--idle-minutes IDLE_MINUTES] [--stale-minutes STALE_MINUTES] [--dry-run] [--profile PROFILE] [--install] [--uninstall] [--interval-minutes INTERVAL_MINUTES] one-shot loop check for a five-minute timer; reads only the store
cox chair freeze-lands [--for MINUTES] [--reason TEXT] [--off] [--profile PROFILE] hold every land for a release cut, show the freeze, or lift it
cox host add NAME --ssh SSH --capacity CAPACITY [--weight WEIGHT] [--capabilities CAPABILITIES] add or update a host in the table
cox host list one line per host: state, capacity, beat age, login
cox host drain NAME stop launching on a host; its live lanes finish
cox host remove NAME [--dry-run] delete a drained idle host from the hosts table
cox host activate NAME make a host a lane host again
cox host capacity NAME N [--json] change only a host's capacity, leaving ssh, weight and capabilities as they are
cox host beat [NAME] record this machine's versions and claude login in the table
cox host login NAME {true,false,none} [--reason REASON] [--failures FAILURES] store a host's login state without touching its beat time
cox host doctor NAME the table's line for a host, then its doctor over ssh
cox host sync NAME bring a host's checkouts to the commits this machine runs (fetch, then fast-forward or check out)
cox router select --role ROLE [--db DB] [--profile PROFILE] [--json] the effective tier for a role under the profile's router: off|shadow|on flag
cox steward propose [--db DB] [--profile PROFILE] [--json] write each candidate clearing the evidence bar as a new intake file; never edits a provider profile
cox steward draft [--profile PROFILE] [--json] write each grounded proposal in intake as a draft initiative under work/, list those that exist or could not be grounded
cox setup doctor [--profile PROFILE] [--repo REPO] [--json] [--host HOST] check this machine's profile against what it needs
cox setup install [--root ROOT] --team TEAM [--workspace WORKSPACE] [--home HOME] [--provider-profile PROVIDER_PROFILE] [--skills-root SKILLS_ROOT] [--assume a|r] [--plugins] [--hook] [--force-profile] [--dry-run] [--window-ceiling-usd WINDOW_CEILING_USD] [--weekly-ceiling-usd WEEKLY_CEILING_USD] sync the checkout's venv, install cox and write a profile for this machine
cox setup migrate [--home HOME] [--dry-run] [--apply] [--hosts] [--finish] [--old-root PATH] [--to VERSION] plan moving this host to the one monorepo checkout; --apply migrates
cox setup store switch files|shared [--host HOST] [--port PORT] [--database DATABASE] [--user USER] [--bucket BUCKET] [--endpoint ENDPOINT] [--region REGION] [--password-env PASSWORD_ENV] [--access-key-env ACCESS_KEY_ENV] [--secret-key-env SECRET_KEY_ENV] [--dry-run] copy the run store and traces to the other backend, then record store.mode
Bare cox setup opens towpath; it needs a terminal and towpath, and otherwise
points you at setup doctor and setup install.
The route group reads one profile, ~/.config/agent-tools/profile.yaml (the
directory keeps the deprecated agent-tools name), or the path in
AGENT_TOOLS_PROFILE, or --profile PATH for one command. cox setup install
and cox setup migrate point its harness_dir, skills_roots and
umbrella_dir into the checkout. cox setup install points
provider_profile at the shipped src/cartridges/providers/claude-code.yaml
unless --provider-profile names another; a team's own provider profile
lives outside the checkout, in <home>/providers/ or the workspace, and
cox setup migrate keeps it. cox setup store --store files|shared picks
the run store; see docs/shared-store.md. New to
the profile? docs/getting-started.md walks
through it.
Integrations that name a vendor (intake sources, forges, trackers) live in ppfenning/coxswain-plugins.
Maintainers
Release and docs commands live in devtools/ at the repository root: run
uv run --frozen python -m devtools <command> there. cox dev and
cox release print that pointer and exit 2.
License
MIT. See LICENSE.