CLI reference
The ctrlrelay console script is a Typer app
defined at
src/ctrlrelay/cli.py.
This page is generated by hand from that source — when in doubt, read the file.
Run any command with no arguments (or --help) to see Typer’s auto-generated
help.
ctrlrelay [--version] <command> ...
| Top-level | Purpose |
|---|---|
ctrlrelay --version / -v |
Print the package version and exit. |
ctrlrelay version |
Same, as a subcommand. |
ctrlrelay status |
Show active locks and the 5 most-recent sessions. |
ctrlrelay config ... |
Configuration helpers. |
ctrlrelay skills ... |
Skill discovery / audit. |
ctrlrelay bridge ... |
Manage the Telegram bridge daemon. |
ctrlrelay run ... |
Run a pipeline interactively. |
ctrlrelay ci ... |
CI helpers used by the dev pipeline prompt. |
ctrlrelay poller ... |
Manage the issue-poller daemon. |
Note: the
repos,export,import,team-export,team-import,setup,manifest,codex-export,codex-import, andcodex-installcommands are shell-script subcommands of the legacy./syncwrapper, not the PythonctrlrelayCLI. See the README for those.
Every command that reads config accepts --config / -c to point at a
non-default orchestrator.yaml (default: config/orchestrator.yaml).
ctrlrelay config
config validate
ctrlrelay config validate [-c PATH]
Loads config/orchestrator.yaml, validates the pydantic schema, prints the
parsed node_id, timezone, transport type, and repo count. Exits non-zero on
validation errors.
config repos
ctrlrelay config repos [-c PATH]
Lists configured repositories in a table (name, local path, deploy provider).
ctrlrelay skills
skills audit
ctrlrelay skills audit [-p SKILLS_DIR] [-c PATH]
Audits each skill under paths.skills (or --path) for orchestrator
readiness — checks shape, required metadata, common pitfalls. Exits non-zero if
any skill fails.
skills list
ctrlrelay skills list [-p SKILLS_DIR] [-c PATH]
Lists discovered skills as a table (name, path).
ctrlrelay bridge
See Telegram bridge for the full setup walkthrough.
bridge start
ctrlrelay bridge start [-c PATH] [-F|--foreground]
Starts the bridge listening on transport.telegram.socket_path. Reads the
bot token from the env var named in transport.telegram.bot_token_env
(default CTRLRELAY_TELEGRAM_TOKEN). Daemonizes by default — forks a
detached process, writes a PID file alongside the socket, and returns to
the shell. Pass --foreground / -F under launchd/systemd or when
debugging interactively; the process runs in the foreground and still
writes its PID file so ctrlrelay bridge status works.
Fails if transport.type is not telegram, the token env var is unset, or a
PID file already exists for a live process.
bridge stop
ctrlrelay bridge stop [-c PATH]
Reads the PID file and sends SIGTERM.
bridge status
ctrlrelay bridge status [-c PATH]
Reports running / not-running by consulting the PID file. If the PID file is
missing but the socket exists (e.g. the bridge was started by an older
launchd plist that pre-dates the PID-file change), exits non-zero with a
hint to restart the bridge — a restart on the new version will regenerate
the PID file and let status work.
bridge test
ctrlrelay bridge test [-m "MESSAGE"] [-c PATH]
Connects to the bridge socket as a client and sends a one-off message. Useful for confirming end-to-end delivery to your Telegram chat without waiting for a real pipeline run.
ctrlrelay run
run dev
ctrlrelay run dev -i ISSUE [-r REPO] [-c PATH]
| Flag | Required | Default | Description |
|---|---|---|---|
--issue / -i |
yes | — | GitHub issue number. |
--repo / -r |
when more than one repo is configured | — | Limit to a single owner/repo. |
--config / -c |
no | config/orchestrator.yaml |
Config path. |
Acquires the per-repo lock, creates the worktree, spawns Claude with the
issue’s title/body in the prompt, and reports the result. If Claude blocks and
the Telegram transport is configured, posts the question to your chat and
waits for a reply (up to DEFAULT_MAX_BLOCKED_ROUNDS rounds).
run secops
ctrlrelay run secops [-r REPO] [-c PATH]
Runs the secops pipeline across configured repos (or one repo with --repo).
Each repo’s run is serialised by the per-repo lock; the overall sweep runs in
parallel across repos. Reports per-repo success/failure and exits non-zero if
any repo failed.
ctrlrelay ci
ci wait
ctrlrelay ci wait --pr N --repo OWNER/REPO [--timeout 600] [--interval 15]
| Flag | Default | Description |
|---|---|---|
--pr / -p |
— (required) | PR number to wait on. |
--repo / -r |
— (required) | Repository as owner/name. |
--timeout / -t |
600 |
Hard timeout in seconds. |
--interval / -i |
15 |
Seconds between polls. |
Polls gh pr checks until every check has left the pending bucket (or the
hard timeout is hit), then exits with:
- 0 — all checks passed (or the repo has no CI configured)
- 1 — at least one check failed / cancelled / timed_out
- 2 — hard timeout while checks were still pending
Exists specifically so the dev pipeline’s prompt can point Claude at one
correct command instead of asking it to improvise a bash until / while
loop — every attempt at improvising those has been inverted-semantics or
pipe-swallowed the exit code (see issue #85).
ctrlrelay poller
poller start
ctrlrelay poller start [-c PATH] [-F|--foreground] [-i SECONDS]
| Flag | Default | Description |
|---|---|---|
--interval / -i |
300 |
Seconds between polls. |
--foreground / -F |
off | Run in the foreground. Default is to daemonize (fork + return to shell). Pass this under launchd/systemd. |
--config / -c |
config/orchestrator.yaml |
Config path. |
Polls each configured repo for issues assigned to your GitHub user (resolved
via gh api user --jq .login). On the first run, seeds the seen-issue set
with current assignments so it does not replay your existing backlog.
For each newly assigned issue, runs run_dev_issue(...) (i.e. the dev pipeline)
in-process. If transport.type: telegram is configured and the bridge socket
exists, sends notifications: 🔔 New issue on detection, ⏸️ Blocked on
question, ✅ PR ready on success, ❌ Failed otherwise.
State is persisted to <state_db_dir>/poller_state.json.
poller stop
ctrlrelay poller stop [-c PATH]
Sends SIGTERM to the daemon PID.
poller status
ctrlrelay poller status [-c PATH]
Reports running / not-running.
ctrlrelay status
ctrlrelay status [-c PATH]
Opens the SQLite state DB at paths.state_db and prints:
- Active locks —
(repo → session_id)for each held repo lock. - Recent sessions — the 5 most-recent rows from the
sessionstable (id,pipeline,repo,status).
status values: running, done, blocked, failed.
If the DB doesn’t exist yet, prints a hint to run a pipeline first.
ctrlrelay version
ctrlrelay version
Prints the package version (same as ctrlrelay --version).