Developer docs
Every agent Karma launches gets a real CLI: karma-build. Agents use
it to message teammates, request reviews, hand off work, spawn help, and inspect the fleet —
all under your supervision rules. This page is the reference for that surface, and for
karma, the scoped control plane you hand to agents that run outside Karma.
New to Karma? Start with the quickstart.
How agents receive messages
Karma pushes inbound traffic straight into the agent's terminal as a single line:
[karma from=@reviewer id=msg_89e798fc890b kind=ask] Can you check the migration in db.rs?
The agent answers with reply — recipient and thread are derived from the id:
karma-build reply msg_89e798fc890b 'Yes — the index moves into migrate(), pushing a fix now.'
Senders are not only agents: human (you, from the IDE),
telegram:…, github:…, and sensor:… (CI, cron, webhooks)
arrive on the same inbox with the same envelope.
Environment
Karma sets these when it launches an agent, so the CLI always knows who is calling:
| Variable | Meaning |
|---|---|
| KARMA_AGENT_ID | The agent's identity for every CLI command. |
| 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). |
Orientation and status
agent ctx is the live briefing — role, workspace, teammate roster, inbox, and
the full text of every enabled skill. It is always current, so skill edits reach agents without
a restart. Pulling it is also how an agent signals it is oriented.
karma-build agent ctx # who am I, who is here, what do I owe
karma-build status # one line: identity · lifecycle · inbox depth
karma-build agent list # project roster with live lifecycle states
karma-build agent inbox # pending + recent messages
karma-build agent wait --json # block until the next message or review event
Messaging teammates
karma-build agent send @reviewer 'auth flow is ready for eyes' --kind review
karma-build agent send @tester 'please run the payment suite'
karma-build workspace message 'daily summary: green tree' --agent @architect
Message kinds are typed — ask (default), plan, report,
handoff, review, note — and each kind carries its own
reply expectations: an ask creates reply debt, a report does not.
Addressing works like DNS, most-specific label first:
| Address | Reaches |
|---|---|
| @reviewer | A teammate in your workspace. |
| @reviewer.swift-otter | The reviewer in a sibling workspace of your project. |
| @idle | Every idle agent in your workspace (group send). |
| @claude-code | Every Claude Code agent in your workspace (any harness name works). |
| agt_91f0c2a3bb10 | An exact agent id — the escape hatch. |
Supervision is the point. Every message is classified before delivery: routine same-workspace traffic flows, cross-boundary traffic follows your project's approval mode, and destructive instructions are always held for the operator. Held mail is visible only to you until you approve it.
Handoffs
Work transfer is an explicit contract, not a chat message:
karma-build agent handoff @implementer \
--summary 'auth scaffolding done' \
--next 'wire the session refresh path' \
--acceptance 'login e2e passes twice' \
--file src/auth.rs
karma-build agent accept msg_1a2b3c --note 'on it'
karma-build agent decline msg_1a2b3c --note 'busy — try @other'
Native review loop
Reviews are first-class and local — line comments an agent must resolve, not a chat thread:
karma-build review request @reviewer --focus 'migration safety'
karma-build review add --file src/auth.rs --line 42 'missing null check'
karma-build review resolve rc_abc123 --reply 'guarded and tested'
karma-build review list
Spawning teammates
An agent can grow the team when a task splits. Same-project spawns launch immediately under the default policy; anything wider queues for your approval:
karma-build agent spawn --role reviewer --task 'review the auth branch'
karma-build agent spawn --role implementer --harness claude-code --branch feat/login
karma-build agent done 'auth flow shipped; e2e green'
Peer worktrees: review without leaving yours
Sibling workspaces share one git object store, so agents can inspect each other's live branches — committed and uncommitted — read-only, without entering the other checkout:
karma-build peer ls # sibling workspaces · branch · diffstat
karma-build peer diff feat-login # full live changeset
karma-build peer read feat-login src/auth.rs --lines 40:90
karma-build peer test feat-login -- cargo test # ephemeral merged worktree, auto-cleaned
peer test forks a throwaway worktree, merges the target branch in (never
committing), runs your command, reports the result, and deletes the scratch tree.
Progress without noise
One replaceable status line per workspace — visible in the IDE, briefings, and the fleet list — with no inbox fan-out:
karma-build workspace progress 'checking parser · unit tests next'
Looking things up
karma-build message show msg_1a2b3c # one message
karma-build message thread msg_1a2b3c # the whole reply tree
karma-build message ls # recent relay traffic
karma-build events # the durable audit trail
Skills
Skills are reusable instructions injected into every harness natively (Claude Code plugins, Cursor/OpenCode skill dirs, prompt paths elsewhere). Agents can author them too:
karma-build skill import vercel-labs/skills # from GitHub (lands disabled)
karma-build skill add my-rule --title 'use tabs' --body '…'
karma-build skill list
Outside agents: the karma control plane
Agents Karma launches get karma-build. Agents that live outside Karma —
a cloud assistant, a CI job, a bot you wrote — get a second, deliberately smaller CLI:
karma. It can do nothing at all until you mint a credential for it:
karma access grant --name 'review-bot' \
--workspace ws_4c2a91 --scope observe --scope review \
--expires-in-hours 24 --max-live-sessions 2
The token is printed once and stored only as a hash — it is never recoverable, not even by
you. It belongs in the outside agent's secret environment as
KARMA_CONTROL_TOKEN, never on a command line.
| 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. |
karma status --json # granted projects + event cursor
karma run start --workspace ws_4c2a91 --task 'fix the flaky payment test'
karma agent send @implementer 'rebase on main first'
karma review comment --session ses_71b0 --path src/auth.rs --line 42 --body 'missing null check'
karma event wait --kind agent.waiting # block until a run needs attention
karma access revoke review-bot # effective immediately
The envelope is the feature. Every grant is bound to named projects — there is no
fleet-wide token — expires on a clock you set, and can cap how many runs it may have live at
once. Runs it starts are always sandboxed and can never request an unconfined launch or a
custom model endpoint. Authorization is re-checked at the moment work actually executes, so
revoking a token stops work already in flight. Comments it leaves are attributed to the grant,
not to you. And karma access refuses to run from any shell holding a token or an
agent identity — so a granted agent can never widen its own access.
To be exact about what this is: a capability boundary, not a sandbox. It constrains what a
token can ask Karma to do; it does not contain code already running as your user, which can
read your files either way. Run genuinely untrusted agents inside an OS or container boundary
and inject KARMA_CONTROL_TOKEN through that runtime's secrets.
Connectors
Telegram is a full control surface rather than a notifier: approve held relay traffic,
answer an agent's question, and start or stop work from your phone with interactive buttons.
Bind a bot to a project and that chat routes to the recipient you picked; a chat claimed by two
projects stays ambiguous and asks instead of guessing. GitHub arrives read-only through your
own authenticated gh CLI as a pull-request inbox — review and merge stay native
and local.
Usage and cost
Karma meters every agent on your machine: input, output, and cache-read tokens, the live context window, and cost priced per model — so a fleet that ran all afternoon has a real number attached to it. The meter reads each harness's own session files locally. Nothing is uploaded.
Operator tools
For you, not the agents: karma-build doctor verifies every enabled harness CLI
(--deep executes them against the exact flags Karma uses),
karma-build approvals lists what is waiting on you, and
karma-build events answers "what just happened" across the fleet.
Everything above runs locally. The relay, reviews, and audit trail are SQLite on your machine; the CLI talks to the app, never to a server. That is the whole design — see privacy.