CLI reference
Command help generated from Balladeer 1.0.19, reviewed 2026-10-01. Setup explains which path to choose and how to verify readiness.
After supported installation, use the installed balladeer command. The npx forms below bootstrap the latest published release and remain the fallback when the executable is unavailable. Check the live setup instructions for current version advice.
The help lists available flags; it does not authorize repository enrollment, an invitation, or a lifecycle action. In particular, --force keeps the earlier client alongside this installation and is not a generic permission-error repair.
Current setup behavior#
Setup connects your laptop and registers Claude Code and Codex at user scope. With the durable command installed, it includes the report-mode push check; Codex must trust the hooks under /hooks. Agreed promises are tied to their code automatically. See setup and agentic code review on push. Sealed CI qualification is separate.
Commands and options#
balladeer 1.0.19
npx -y balladeer@latest install [--json]
Install this exact release as the durable balladeer command, and register
Balladeer once for every Claude Code and Codex session on this machine:
it decides per folder, from the git remote, which connection applies.
Pairs nothing and changes no workspace, repository, or CI configuration.
balladeer update
Move the durable balladeer command to the latest published release. The
hooks and MCP entries already run the latest release on their own.
balladeer remove-earlier
Take the earlier Balladeer (the July client) off this machine and out of
this repository: its MCP server under the same name, its hooks and status
line, its guidance blocks and managed files (under your home and in this
repository's CLAUDE.md or AGENTS.md), and its 0.x command. A file git
does not track is copied beside itself first; a tracked one is for you
to commit. setup runs this itself when it finds one.
npx -y balladeer@latest setup [--repository owner/name]... [--json] [--wait] [--no-open] [--control-plane <url>]
[--create-workspace <name>] [--choose-workspace] [--refresh] [--force]
[--client codex|claude]
[--existing]
[--claude-desktop | --no-claude-desktop]
Pair this session, add this repository, connect this coding agent and CI,
and report what a person still has to do. Name --repository more than once
to add other repositories to the same workspace; each of those is added and
nothing more, because connecting an agent and CI happens in a checkout.
--client codex writes project .codex/config.toml and AGENTS.md.
Trust the project in Codex and start a fresh session to load its tools.
--client claude (the default) preserves the Claude setup behavior.
For --refresh only, a lone managed Codex entry selects Codex automatically.
If both clients have Balladeer entries, choose --client explicitly.
--choose-workspace starts fresh browser pairing for this control plane,
preserving other saved agent connections. Use it with --existing to
reconnect an existing workspace. --create-workspace also starts fresh
pairing instead of reusing the previously selected workspace.
--create-workspace carries a name to the approval page, where a person
signs in and creates the workspace themselves; this command never creates
one.
--existing is for an invited teammate and never enrolls repositories or changes CI.
If this repository is already connected, connect this machine; otherwise
continue in the browser while an administrator connects it.
--refresh repairs the durable command if needed, then rewrites this
selected client's project MCP entry and Balladeer instructions block
(and Claude desktop entry for Claude) to the current form, leaves every
other entry in those files alone, and prints what it changed. Installing
the command may contact npm; refresh never contacts Balladeer. Run it when
Balladeer says a newer version is available.
At a terminal with a person at it, the approval page opens in their
browser and the run waits for the approval; --no-open prints the link
instead. An agent shell, or --json, always prints the link and returns.
--force sets up alongside an earlier Balladeer instead of removing it.
Without it, a run that finds the older client takes it off first, with a
copy of every file it changes kept beside the file.
Claude desktop chat is connected too, under a key named for this
repository, wherever the app is installed. --claude-desktop asks for it by
name, so a machine with no Claude desktop on it says so instead of
skipping quietly; --no-claude-desktop leaves that file alone entirely.
Quit and reopen the app afterwards: it reads its configuration at startup.
If setup cannot access its private credential folder, allow this command
to access the folder named in the error, then repeat the same setup command.
Keep existing saved credentials; do not delete the store to retry.
npx -y balladeer@latest repositories [--json] [--control-plane <url>]
List the repositories this machine's GitHub account can see, marking the
one you are standing in and the ones Balladeer already has.
npx -y balladeer@latest invite <email>... [--role contributor|viewer|administrator] [--json]
Invite teammates into this workspace by email, and say per address whether
the invitation went. Inviting is an administrator's act.
npx -y balladeer@latest status [<promise id>] [--repo owner/name] [--repository <uuid>] [--json]
[--control-plane <url>]
Report this repository over its agent connection, and every repository in
the workspace when a setup session is still live. Named with a promise id,
report that one promise instead: whether it is holding, and if it is not,
the commit the failing run checked, the bounded reason, and the cases in
the agreed meaning that run was checking. That is the form the line on a
broken promise tells a person to run first.
npx -y balladeer@latest propose --file <path> [--repo owner/name] [--repository <uuid>] [--json]
Propose one promise from a proposal file, over this repository's agent
connection. A named person still agrees to it.
npx -y balladeer@latest prepare <promise id> [--again] [--repo owner/name] [--repository <uuid>]
[--json] [--control-plane <url>]
Prepare the one-time qualification setup for a promise whose meaning is
agreed and which nothing is checking yet, and write it to
.continuity/qualification/<promise id>.json, which is where the sealed run
reads it. No sign-off and no code: agreeing the meaning was the person's
act, and building the check that proves it is yours. Then build the
verifier, seal it, and push to the default branch; protection starts by
itself when that run qualifies. It is one-time, so while nobody has
published against the packet already prepared this refuses and says who
prepared it and when. --again prepares a replacement and invalidates that
earlier packet: a run publishing its identities afterwards is refused.
npx -y balladeer@latest discover --file <path> [--repo owner/name] [--repository <uuid>]
[--owner <membership id>] [--json]
Propose a whole discovered catalog, up to ten promises from one file, each
owned by whoever paired this machine, and print one link that opens all of
them. A named person still agrees to every one.
npx -y balladeer@latest check-seals [--json] [--runner <path>] [--install-hook]
Say whether what you are about to push would break a promise's seal. It
prints nothing and exits 0 when it would not, and names the promise, its
owner, its page and the line that seals it again when it would. It runs
offline, over the runner this repository is pinned to. --install-hook
writes .git/hooks/pre-push so every push asks first; nothing installs it
for you, and deleting that file removes it.
npx -y balladeer@latest touch-map [--json]
Run this repository's promise verifiers under coverage and write down
which files each one actually executed, to .continuity/touch-map.json.
It runs offline and the map stays on this machine: Balladeer is never
sent it. Node verifiers only in this release.
npx -y balladeer@latest affected <paths...> [--json]
Say which promises the named files touch, out of that map, marking any
answer whose verifier has changed since the map was built. It reads one
local file and contacts nothing.
npx -y balladeer@latest map <promise id> | --all | --check | --stale
[--from-file <promise.json>] [--repo <root>] [--out <dir>]
[--client auto|claude|codex] [--timeout <seconds>] [--json]
npx -y balladeer@latest map --link-test <promise id> <test file>
[--name <test name>] [--case <case id>]... [--repo <root>] [--json]
Build a behavior map for a promise with your own coding agent: where its
behavior starts, the code on its path, what it depends on, the tests that
exercise it and where each failing case would show. The agent works in a
throwaway read-only checkout, on the Claude Code or Codex login already on
this machine, and the map is written to .continuity/behavior-maps/<id>.json
for your team to commit. It never leaves this machine. --all maps every
agreed promise; --check reports maps whose code or meaning has moved
(exit 1 when any has) and --stale prints just their ids, both without a
model. --from-file reads the promise from a file instead of Balladeer.
--link-test adds a test in this repository to a promise's existing map,
naming the cases it covers (passing-1, failing-2), so later judges run it
and a change to it counts as risk to the promise. It changes nothing else
in the map, calls no model and sends nothing anywhere.
npx -y balladeer@latest anchor [<promise id> | --all] [--json] [--repo <root>]
[--client auto|claude|codex]
Anchor this repository's agreed promises to the code that realizes them,
at HEAD: the files and names where each one's behavior lives, picked by
one small call on your own Claude Code or Codex login from a list of
this repository's files, and shared through Balladeer with your team.
Only paths and names are sent, never code. A promise with a behavior map
for its current meaning is anchored from the map, with no call. The push
check does this by itself; this does it now. With no argument or --all,
every promise without current anchors, or whose anchored code is gone;
with a promise id, that one again. At most 20 calls a day on this
laptop (set BALLADEER_ANCHOR_DAILY_BUDGET to change it).
npx -y balladeer@latest judge [--promises <id,id>] [--top <k>] [--base <ref>] [--head <ref>]
[--report-only | --block] [--wait] [--json] [--client auto|claude|codex]
[--from-file <promise.json> [--map <map.json>]]
[--hook claude|codex|git] [--install-hook [claude|codex|git]]
[--push-check on|off]
Judge whether this change keeps the promises it could break, one promise
at a time, on your own Claude Code or Codex login. A break counts only
with a command that fails with the change and passes without it, and
this command runs it both ways itself; anything unproven is "could not
tell". Report mode prints one line per promise and never stops anything;
--block exits 2 on a reproduced break, and when judges are still running
at the time limit it holds the push rather than letting it through.
--wait runs without the time limit. Promises come from --promises, else
every agreed promise whose anchored code the change edits, and every
promise with a behavior map whose own code or tests it edits (with
"select": "ranked" in .continuity/judge.json, the top of the maps'
ranking and a small random sample); plus that file's alwaysJudge. A
promise with no anchors yet is anchored first, by one small call on
your own login (see `balladeer anchor`), at most 20 a day on this
laptop, and a line says what that cost. Verdicts are kept in
.continuity/judge-log/, which git ignores. --install-hook adds the push
hook to .claude/settings.json and .codex/hooks.json, before and after
each shell command: report mode judges after a push has landed, so the
push never waits, and block mode judges before it. With git it writes
.git/hooks/pre-push, which judges before the push in both modes. With
"offers": true in .continuity/judge.json, the push hook also reads the
change for rules no promise records and offers at most three to
whoever is pushing; it records nothing and never holds a push (see
`balladeer offers`). Setup also writes the same pair of entries at
each host's user scope, running `judge --hook <host> --user-scope`,
so the check runs in every connected repository with agreed promises
and says nothing anywhere else; a checkout with its own entry keeps
the check to that entry. --push-check off turns the user-scope check
off on this laptop, and --push-check on turns it back on.
npx -y balladeer@latest offers [--base <ref>] [--head <ref>] [--json] [--repo <root>]
[--promises-dir <dir>] [--client auto|claude|codex] [--timeout <seconds>]
Read this change for rules it establishes that no promise records yet,
on your own Claude Code or Codex login, and list at most three, each with
the files in the change that show it. It records nothing and stores
nothing: to keep one, ask your coding agent to record it as a promise for
your review. The promises already recorded come from --promises-dir,
else this repository's Balladeer connection, else the promises sealed or
mapped in this checkout. The change runs from the fork point with the
remote default branch to HEAD unless named. --json prints the result.
npx -y balladeer@latest risk [--base <ref>] [--head <ref>] [--json] [--maps <dir>]
Rank the promises this change could put at risk, with the evidence for
each: a mapped function or test it changes, a table, route or file it
shares, what imports what, and what its commit messages say. It reads
the behavior maps in .continuity/behavior-maps/ and the change from git,
from the merge base with this branch's upstream (else origin/main) to
HEAD unless named. Runs offline; nothing is sent. --json prints the report.
npx -y balladeer@latest session [--new] [--record] [--repo owner/name] [--repository <uuid>] [--json]
[--control-plane <url>]
Print the id for this piece of work, and the one line to write into the
commit it produces. Pass the id to every promise read you make, so a check
that goes red later can be read back against what Balladeer told you
before you started. --new starts a different session; --record reads the
Balladeer-Session line out of the commit at HEAD and tells Balladeer which
commit this session wrote. Your commit message never leaves this machine:
only the session id and the commit SHA are sent.
npx -y balladeer@latest explain [--control-plane <url>]
Print, word for word, what Balladeer can and cannot see, where to watch
your promises, and what leaving costs.
npx -y balladeer@latest whoami [--json] [--control-plane <url>]
Report the stored setup session's workspace, role, scopes, and expiry.
npx -y balladeer@latest agent rotate [--control-plane <url>]
Replace this repository's agent credential. A setup session cannot do this,
because rotating revokes the connections the repository already has.
npx -y balladeer@latest mcp [--repository <uuid>] [--control-plane <url>]
Forward one MCP session over stdio using this repository's agent connection.
Exit codes: 0 progress reported truthfully, 2 pairing expired or denied or already
claimed, 3 this copy is too old for the server, 4 usage or credential store problem,
5 transport or server failure, 6 an earlier Balladeer is still installed on this
machine and part of it could not be removed.