CLI reference
Karma is an engine with four faces. The Mac app is one of them; the other three are a terminal multiplexer, a browser, and an MCP server — and all of them drive the same command table, so none can drift from the others. This page is the reference for everything you can type. For why the agent surface is shaped the way it is, read the developer docs; if you have not installed Karma yet, start with the quickstart.
Two binaries, one boundary
Karma ships two executables on purpose, and the difference is trust — not convenience.
| Binary | Who holds it | What it can do |
|---|---|---|
| karma-build | Agents Karma launches, and you. | The full local surface: relay, reviews, handoffs, worktrees, the multiplexer, the front ends. Authority comes from being on your machine. |
| karma | Agents that run outside Karma — a cloud assistant, CI, a bot. | Nothing until you mint a credential. Then only the scopes and projects that credential names. Never approve, merge, or push. |
Both ship inside the app. karma cli install links the public one into
~/.local/bin and records a receipt, so karma cli uninstall removes
exactly what it added and nothing else. On the internal side,
karma-build cli which reports which binary is actually resolving and
cli pin fixes it — which matters when a branch build and a released one are both
on the machine.
Command index
| Group | What it covers |
|---|---|
| tui · serve · web · mcp | The four front ends — terminal, daemon, browser, MCP. |
| read | Any Karma surface, addressed as a URL. |
| agent · reply · message · review | Relay messaging, reviews, handoffs, agent control. |
| workspace · peer · check · config | Worktrees, sibling branches, and project gates. |
| skill · home · pr · relay-policy | Skills, the home channel, GitHub, supervision policy. |
access (on karma) | The scoped external control plane. |
| doctor · gate · db · housekeep · purge · events | Operator and maintenance commands. |
The four front ends
One engine owns the agents for a state directory. That engine holds the SQLite database and every PTY. Everything below is a face on it, not a second copy of it — which is why a terminal, a browser, and the desktop can all watch the same agent type the same character at the same moment.
karma-build tui — the terminal multiplexer
Your fleet as live panes. It attaches to the running desktop when there is one; otherwise it starts a daemon. Either way the agents live in the host, so detaching, closing the terminal, or dropping an ssh connection never touches them.
karma-build tui # attach to the fleet (or start a daemon)
karma-build tui . # open THIS folder as a project
karma-build tui ls --json # projects · workspaces · agents · which host is up
karma-build tui attach @implementer # one agent, full width, layout preserved
karma-build tui split @reviewer --direction down
Opening a folder always probes it first: a path that is not a git repository gets an
explicit git init disclosure before anything is written to it.
Keys
Everything below follows the prefix, ctrl-b by default. Press it twice
to send a literal ctrl-b through to a harness that binds it.
| Key | What |
|---|---|
| p : | command palette |
| w | the rail — Fleet, Files, and Changes; tab cycles the three |
| a | next blocked, waiting, failed, or completed agent |
| r | relay queue — approve or block held messages |
| o | open the latest attention notification |
| % | " - | split beside · split below |
| h j k l, arrows | move between panes |
| H J K L | swap the focused pane in that direction (the PTY keeps running) |
| tab shift-tab ; | cycle panes · toggle the previous pane, even across tabs |
| z R , x | zoom · resize mode · rename pane · close pane (the agent keeps running) |
| [ | copy mode — cursor navigation, search, selection, exact yank |
| t n P 0-9 | new tab · next · previous · pick a tab |
| < > ! | move the focused pane to the previous, next, or a new tab |
| c N | open a shell · new project (scratch, open a folder, or clone) |
| d ? | detach — the fleet keeps working · every key |
Mouse works the way you expect: drag to select and copy over OSC 52, double-click to copy
one developer token (a URL, path, flag, handle, or file:line), right-click a pane
for its own menu. Child TUIs still get their own mouse and keyboard protocols —
Shift is the deliberate escape hatch that keeps an event for Karma.
Every action can be rebound, aliased, or disabled in
$KARMA_HOME/tui.yaml, as a prefix key or a direct modified chord. Invalid
bindings are refused with a reason rather than silently dropped, and the in-app help
(prefix ?) renders the effective map — so what you see is what is bound.
Driving agents from a script
These resolve in the host, so they work whether the fleet is on your desktop or a daemon. Waits are event-driven and semantic — no polling, no scraping terminal text.
karma-build tui focus @implementer # bring its pane forward everywhere
karma-build tui read @implementer --lines 40 # its visible screen, parsed
karma-build tui prompt @implementer 'rerun the payment suite' \
--wait --until idle,waiting --timeout-ms 600000
karma-build tui wait @reviewer --until waiting --json
prompt --wait subscribes before it submits and requires a real
post-submit transition, so it cannot be fooled by the state the agent was already in.
karma-build serve — the daemon
The process that owns the PTYs when the desktop is not running. tui starts one
on demand; run it yourself to keep it in the foreground or to inspect the running host.
karma-build serve --status # who owns this state directory?
karma-build serve --detach # background, returns once accepting
karma-build serve --stop # clean PTY shutdown, then exit
karma-build serve --web # + the browser face on 127.0.0.1:7420
karma-build web — the network face
The same engine over HTTP and SSE, which is what makes it reachable from another
machine. karma-build tui remote is its terminal client.
karma-build web --open # serve the UI + open an authenticated URL
karma-build web --no-ui --json # API only; print {url, addr, token, ui}
karma-build tui remote --server http://studio.local:7420
It binds loopback unless --host says otherwise, and every request carries a
bearer token from $KARMA_HOME/runtime/serve-token. Widen the bind deliberately:
every command, including merge and push, is reachable from wherever it is bound.
Running all three at once. Because one engine owns a state
directory, web refuses to start beside an open desktop — and names the process
holding it. Turn on Settings → external control → web access instead: the desktop then
serves, and a browser and a TUI attach to it rather than being locked out.
karma-build mcp — the read-only MCP server
A stdio Model Context Protocol server exposing exactly one tool,
karma_read(url, from?), over the same resolver as karma-build read.
There is no mutation surface: Karma's write lanes stay supervised. It is in the default
build, because an MCP face that only exists in a special build cannot be reachable from
every MCP client.
{
"mcpServers": {
"karma": { "command": "karma-build", "args": ["mcp"] }
}
}
That block works in Zed, Claude Code, Cursor, and anything else that speaks MCP over
stdio. Caller-free URLs need no identity; pass from with an agent id when you
want a participant- or project-scoped read to resolve from that agent's vantage.
Everything is a URL
Rather than growing a subcommand per surface, Karma exposes one reader and a scheme per thing it already owns. New read surfaces land here as schemes, so the command count stays flat.
karma-build read agent://rev/state
karma-build read peer://feat-login/src/auth.rs:40+30
karma-build read workspace://swift-otter/diff/2
karma-build read pr://1428/diff/2 --json
| Scheme | Addresses |
|---|---|
| msg:// | A relay message, or /thread for its whole reply tree. |
| agent:// | An agent: identity, state, lifecycle, and its structured result. |
| workspace:// | A worktree session, its changeset, and numbered diffs. |
| peer:// | A sibling workspace's live files and diff, read-only. |
| skill:// | The skill library, and any skill's full body. |
| pr:// issue:// | GitHub, through your own authenticated gh, cached with stale fallback. |
| event:// check:// | The durable audit trail, and declared project checks. |
A bare scheme lists its collection. Selectors peel off the tail and compose:
:40, :40-90, :40+30, :40-, and
:raw. On a JSON-shaped resource, ?q=.dotted.path extracts one
field — as does a non-reserved trailing path, which is why agent://rev/state
reads the way it does. Provenance notes (cache hits, stale fallbacks) go to stderr, so
stdout stays pipeable.
Agents, relay, and reviews
The surface an agent uses to work with its teammates. The developer docs explain the supervision model behind it; this is the command list.
karma-build agent ctx # the live briefing — role, roster, inbox, skills
karma-build agent inbox # pending + recent messages
karma-build agent wait --json # block until the next message or review event
karma-build agent send @reviewer 'auth is ready' --kind review
karma-build reply msg_89e798fc 'index moved into migrate()'
karma-build agent handoff @implementer --summary '…' --next '…' --acceptance '…'
karma-build agent spawn --role reviewer --task 'review the auth branch'
karma-build agent done 'auth flow shipped' --output result.json
| Command | Purpose |
|---|---|
| agent ctx | The live briefing. Pulling it is also how an agent signals it is oriented. |
| agent list · status | The roster with live lifecycle states; one line about yourself. |
| agent send · reply | Durable relay messages. Kinds: ask, plan, report, handoff, review, note. |
| agent handoff · accept · decline | Work transfer as an explicit contract with acceptance criteria. |
| agent spawn · done | Grow the team when a task splits; finish with a structured result. |
| agent tail · screenshot | Read another agent's terminal without taking it over. |
| agent start · stop · restart · compact | Lifecycle control for a teammate's runtime. |
| review request · add · resolve · reply · list | Native line-anchored review comments an agent must resolve. |
| message ls · show · thread · approve · block | Inspect durable threads; decide messages held for you. |
Worktrees, peers, and gates
karma-build workspace show # where am I · branch · diffstat · progress
karma-build workspace progress 'checking parser · unit tests next'
karma-build workspace merge --title 'feat: login'
karma-build peer ls # sibling workspaces · branch · diffstat
karma-build peer test feat-login -- cargo test
karma-build check run # every gate declared in karma.yaml
karma-build config init # scaffold setup: + checks: for this stack
peer test forks a throwaway worktree, merges the target branch in without
committing, runs your command, reports, and deletes the scratch tree.
workspace progress is one replaceable status line — no inbox fan-out, no reply
debt. Update it on real transitions (start, plan change, blocked, checking, ready), never on
a timer.
Skills, channels, and GitHub
karma-build skill import vercel-labs/skills # lands disabled, for you to review
karma-build skill add my-rule --title 'use tabs' --body '…'
karma-build home send 'nightly run is green' # the channel-agnostic operator surface
karma-build pr ls # through your own authed gh CLI
karma-build relay-policy list # cross-workspace delivery modes
Skills are injected natively per harness — Claude Code plugins, Cursor and OpenCode skill directories, prompt paths elsewhere. An agent talks to home, never to a platform; the binding you configured decides whether that lands in Telegram, Discord, or nowhere.
The karma control plane
For agents that run outside Karma. It does nothing until you mint a credential, and the credential is the whole feature.
karma access grant --name 'review-bot' \
--workspace ws_4c2a91 --scope observe --scope review \
--expires-in-hours 24 --max-live-sessions 2
karma run start --workspace ws_4c2a91 --task 'fix the flaky payment test'
karma event wait --kind agent.waiting
karma access revoke review-bot
| Scope | Grants |
|---|---|
| observe | Read granted projects, agents, diffs, terminal tails, and events. |
| dispatch | Start coding runs and queue durable tasks for agents. |
| control | Start, stop, and restart agents. |
| review | Add review comments. Never approve, merge, or push. |
The token is printed once and stored only as a hash. It belongs in the outside agent's
secret environment as KARMA_CONTROL_TOKEN, never on a command line. Grants are
always bound to named projects, expire on a clock you set, and are re-checked at the moment
work executes — so revoking stops work already in flight. Full detail in the
developer docs.
Operator and maintenance
| Command | What it does |
|---|---|
| doctor [--deep] | Verifies every enabled harness CLI. --deep executes them against the exact flags Karma uses. |
| events --kind --subject | The durable audit trail: what just happened, across the fleet. |
| approvals · clear-approvals | What is waiting on you; dismiss a queue of duplicates. |
| models --harness --resolve | The model catalogue with price and context window, and exactly how one model string resolves for a harness. |
| harnesses · workspaces | The harness catalog; the registered projects. |
| register-workspace --path | Register a repo without a desktop — the first step of any CI job. Idempotent. |
| db [--clean] [--apply] | Row counts, orphans, and a dry-run of what a cleanup would delete. |
| housekeep [--apply] | Reclaim stale worktrees, orphaned agent homes, and aged events. Read-only report by default. |
| purge … | Wipe one rebuildable lane (messages, usage text, checks, connector mirrors, logs, backups). --all --yes is a factory reset. |
| gate [--for M] [--changed] | The honest quality gate: tests then clippy, with real exit codes, scoped to a module or to what you changed. |
| init · seed-demo | Create the state directory; seed example projects to look around. |
Scripting conventions
- JSON where it matters.
--jsonon reads and waits returns a stable shape;read --jsonreturns the full envelope ({url, content_type, content, notes}). - Selectors are explicit. Prefix a target with
id:,agent:,workspace:, orbranch:when a script needs an exact match; shorthand (@handle, a name, a slug) still works interactively.currentresolves the caller's own workspace, and an omitted workspace prefers the current directory. - Exit codes mean something.
checkandgateexit non-zero when a required check fails, so they drop straight into CI. - Waits are event-driven. They subscribe to the durable event cursor rather than polling, and a timeout is reported as a timeout — not as success.
- stdout is data. Provenance and diagnostics go to stderr, including for
long-running hosts like
mcp, whose stdout carries protocol frames only.
Environment
| Variable | Meaning |
|---|---|
| KARMA_AGENT_ID | The agent's identity for every CLI command. Karma sets it at launch. |
| KARMA_WORKSPACE_ID | The registered project. |
| KARMA_SESSION_ID | The isolated worktree session. |
| KARMA_WORKTREE_PATH | Absolute path to the agent's own worktree. |
| KARMA_HOME | Karma's local state directory (default ~/.karma-build). |
| KARMA_SERVER · KARMA_SERVE_TOKEN | Default engine URL and bearer token for tui remote. |
| KARMA_CONTROL_TOKEN | The outside agent's credential for karma. Read only from the environment. |
Everything above runs locally. The relay, reviews, worktrees, and audit trail are SQLite on your machine; every face talks to the engine on your machine, never to a server of ours. That is the whole design — see privacy.