ReferenceRead as Markdown

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.