Skip to content

CLI

View Markdown~13,555 tokens

caudra without a subcommand starts the TUI. Subcommands cover auth, models, MCP OAuth, updates, and a few debug helpers. Many flags only apply to one of three run paths: TUI, one-shot --print, or SDK (--print --input-format stream-json).

Terminal window
caudra [OPTIONS]
caudra <COMMAND>

The first message comes from --prompt, from piped stdin, or from both. Without --print, the TUI opens and that text is sent as the first message. With --print, Caudra runs non-interactively and exits when done.

Caudra takes no positional argument. A bare word is read as a subcommand, so caudra mdoels reports an unknown subcommand and suggests models rather than opening a session named after the typo.

When interactive Caudra starts in a Herdr pane, it automatically reports native caudra lifecycle state through Herdr's inherited environment and public custom-agent API. --print and SDK mode do not claim pane lifecycle authority. The report names the prompt that blocks the agent, and the sidebar shows the focused session's title, model and context usage. Each report also carries a resume command, so Herdr can restore the pane after a restart. It is caudra --session <id> for the focused session once that session is saved, and a bare caudra before then. Herdr receives the command only when caudra is on PATH, because Herdr types it into the pane's shell. Exiting Caudra withdraws it. A hangup or a stopped Herdr server leaves it in place. See Worktrees.

caudra --session <id> opens a local session in the directory it works in, wherever you run the command, so project config, plugins and MCP servers come from that directory. A session left in a removed worktree moves back to a remaining checkout first.

Some flags and subcommands belong to experimental features, which stay off until the global caudra.toml turns them on. While a feature is off, --help does not list them. Using one anyway stops Caudra with an error that names the experimental.* key to set. The exception is --no-jit, which has no effect without Lua. caudra update, caudra rollback, caudra logs, and caudra config do not read settings, so a broken caudra.toml cannot stop them.

Decision log administration needs experimental.decision_engine and does not start an agent:

Terminal window
caudra decisions status
caudra decisions stats --feature permission
caudra decisions export --feature permission > decisions.jsonl
caudra decisions purge --yes

status shows effective configuration without contacting the endpoint. Reachability is not_probed. stats prints JSON with counts, errors, latency percentiles and labelled agreement, using the currently configured thresholds. acted_count counts the rows whose effect is not none, and last_timestamp is the newest row's time in epoch seconds. export writes JSONL with only labelled questions in laya-evals format. These commands do not enable logging or create a database. The decision log uses tables in caudra.db. purge --yes deletes recorded decisions and labels from those live tables, leaving sessions, messages, and shell duration history intact. It does not erase copies in SQLite free pages, WAL files, or backups.

stats and export accept --feature. Log feature names are permission, auto, shell_effect, content, shell_duration, tool_search, skill_suggestions, goal, subagent_routing, and workflow. They differ from some configuration keys. With no database, statistics are empty and export writes nothing. Administration requires local persistent storage and rejects --ephemeral and --workcell.

Labels are partial evidence, not a complete evaluation dataset. Tool-search actual-use labels and shell-effect observed-filesystem labels are not collected. Effect fields are a partial action record. A value of none does not prove that no advice or routing was applied. Redaction is best effort. Review exported states and question text before sharing them. See decision engine advice and configuration.

Sends and reads cross-session messages from scripts. It needs experimental.cross_session_messaging, runs on Linux and macOS, and does not start an agent:

Terminal window
caudra message publish --topic ci.failures "Build 1042 failed"
caudra message broadcast --from release "v2.3.0 is tagged"
caudra message send --to @ci-watcher < report.txt
caudra message log --topic 'ci.*' --limit 50 --json

publish sends to the live sessions subscribed to one concrete topic. broadcast sends to the live sessions that opted in to broadcasts. Both reach at most max_fanout sessions, and the receipt counts the rest as skipped. send sends to the live session that holds a messaging name, given with or without its @. The text is the last argument. Without it, the command reads stdin, which must not be a terminal. The text must be UTF-8 within 32 KiB, and one trailing line ending on stdin is dropped.

FlagDescription
--from <LABEL>The sender name recipients see, script by default. Rate limits and duplicate checks count each label as one sender
--jsonPrint the receipt as one JSON object

Each send prints a receipt with one line per recipient and its delivery status. publish and broadcast exit 0 once the message is recorded, even when no live session receives it. A recorded topic message still serves catch-up. send exits 1 unless the recipient queued or held the message. Usage errors exit 2. Other failures exit 1, such as a disabled experiment, an unknown name, or a history that cannot record the message.

log prints recorded messages oldest first, the newest 20 by default:

FlagDescription
--topic <PATTERN>Only topic messages that a subscription pattern matches
--broadcastOnly broadcasts
--with <NAME>Only direct messages to or from the session that held this messaging name
-n, --limit <COUNT>How many of the newest messages to print, from 1 to 1000
--jsonOne JSON object per message with seq, message_id, sent_ms, kind, topic, sender, text, reply_to, and recipients

The filters exclude each other. Without one, log prints messages of every kind, direct messages included. JSON output leaves out session ids. caudra message uses this machine's persistent storage, so it rejects --ephemeral and remote Workcell selectors.

A topic publication that feeds consumer groups also lists the work item it queued for each group. Its --json receipt holds them in queued.

caudra message group creates and changes consumer groups, and caudra message work inspects and manages their work. Sessions join a group with --group or /groups, and nothing else creates one:

Terminal window
caudra message group create build-fixes --topic ci.failures --topic 'ci.flaky.*' --concurrency 2
caudra message group list
caudra message work list --group build-fixes --state paused
caudra message work retry bright-calm-river
CommandAction
group create <GROUP> --topic <PATTERN>...Create a group for the given topic patterns. It queues work only for later publications
group update <GROUP>Change the policy flags given. --topic replaces every pattern
group list, group show <GROUP>Show groups with their patterns, policy, and work counts
group pause <GROUP>, group resume <GROUP>Stop handing out work while the queue keeps growing, then start again
group delete <GROUP>Delete a group whose work has all finished. A new group with the same name starts empty
work listShow the newest work items, filtered with --group and --state (repeatable), and paged with -n and --before <WORK>
work show <WORK>Show one item with its message and every attempt
work retry <WORK>Queue a paused, failed, or cancelled item again with a full set of attempts
work pause <WORK>Hold a queued item until it is retried
work cancel <WORK>Give up on a queued, paused, or failed item
FlagDescription
--concurrency <N>Items the group's members work on at once, 1 by default, at most 16
--attempts <N>Attempts an item gets before it fails, 3 by default, at most 10
--backlog <N>Unfinished items the group holds before publications to it fail, at most 1000, which is also the default
--jsonOne JSON object per group or work item, without session ids

A state is one of pending, leased, pausing, paused, completed, failed, or cancelled. work retry warns on stderr when the item already ran, because its earlier attempts may have had effects. A refused change, such as deleting a group with unfinished work, exits 1 with the reason.

FlagTUI--printSDK (stream-json)
--promptyesyesno (messages arrive on the wire)
-m / --modelyesyesyes
--yoloyesyesyes (or --permission-mode bypassPermissions)
--autoyesyesyes (or --permission-mode auto)
--no-plugins / --no-commands / --no-jityesyesyes
--allowed-tools / --disallowed-toolsyesyesyes
--system-prompt-profileyesyesyes
--ephemeralyesyesyes
--no-snapshotsyesyesyes
-c / --continue, -s / --sessionyesno (always new session)yes
--exit-on-doneyesn/a (always exits)n/a
--name, --topic, --receive-broadcasts, --groupyesnono
--automationyesnono
--imageno (use Ctrl+V paste)yesvia wire protocol
--verbose, --output-formatnoyesstream only
--system-prompt, --append-system-promptnonoyes
--max-turns, --session-id, --fork-sessionnonoyes
--permission-modenonoyes
--include-partial-messagesnonoyes
--workcell-profile or direct Workcell selectorsyesyesyes
--sandbox, --sandbox-resumeyesyesyes
FlagDescription
-p, --printNon-interactive run. See Headless Mode
--prompt <TEXT>First message of the session. Piped stdin is appended after it when both are present. Distinct from -p, which selects non-interactive output
--ephemeralStore the session, outputs, file change records, input history, and stash in a temporary root removed at exit. Credentials, trust, and preferences remain persistent
--no-snapshotsTurn off file change recording and file revert for this process, locally and remotely. Also applies to ACP. Records already made stay stored, and an existing file revert can still be unreverted. See Disable change recording
--image <PATH>Attach an image in --print mode (repeatable). Paths must be png, jpeg, gif, or webp
-m, --model <SPEC>Model as provider/model-id. Fallback: last used → provider.default_model in config → auto-detect from available providers
--verboseFull turn-by-turn messages in --print output
-c, --continueResume the most recent session in this directory (TUI / SDK only)
-s, --session / --resume <ID>Resume a specific session (TUI / SDK only)
--output-format <text|json|stream-json>Output shape for --print (default text)
--input-format <text|stream-json>With --print, stream-json enters SDK mode
--no-commandsSkip custom commands from every user and project command directory
--no-pluginsTurn Lua off for this process, even when experimental.lua_plugins is on. No Lua runtime starts, so no init.lua or Lua plugin runs. caudra.toml, permissions.toml, custom commands, and env files load as usual. Use it to recover from a broken init.lua or keymap override
--no-jitRun plugin Lua on the interpreter with full debug info. Hidden, and without effect, while experimental.lua_plugins is off
--yoloSkip permission prompts on gated tools (alias: --dangerously-skip-permissions). Deny rules still apply
--autoStart in Auto mode. Needs experimental.decision_engine. Cannot be combined with --yolo
--exit-on-doneExit when the agent finishes (TUI automation wrappers)
--name <NAME>Give the initial TUI session this messaging name instead of a generated one. Needs experimental.cross_session_messaging
--topic <PATTERN>Subscribe the initial TUI session to a topic pattern, in addition to its saved ones (repeatable). Needs experimental.cross_session_messaging
--receive-broadcastsOpt the initial TUI session in to broadcasts. Needs experimental.cross_session_messaging
--group <GROUP>Let the initial TUI session take work from an existing consumer group, in addition to its saved memberships (repeatable). Startup fails when the group does not exist. Needs experimental.cross_session_messaging
--automation <NAME[=JSON|@FILE]>Arm an automation in the initial TUI session (repeatable, once per name). NAME=JSON gives its args as a JSON object, and NAME=@FILE reads the object from a file. Without args, the stored args or the defaults apply. SDK hosts arm with the automation_arm control instead. Needs experimental.automations
--allowed-tools <LIST>Comma-separated allow list (PascalCase or snake_case)
--disallowed-tools <LIST>Comma-separated deny list
--system-prompt-profile <NAME>Select a profile from the user system-prompts config directory. See System Prompt Profiles
--session-id <ID>Session id for SDK mode
--fork-sessionLoad a session's history under a new id (SDK)
--max-turns <N>Cap agent turns (SDK)
--system-prompt <TEXT>Replace the system prompt (SDK only)
--append-system-prompt <TEXT>Append to the built-in system prompt (SDK only)
--permission-mode <MODE>SDK: default, auto, acceptEdits, plan, or bypassPermissions
--include-partial-messagesStream partial deltas in SDK mode

Direct Workcell connections are experimental. These flags need experimental.remote_workcell.

Terminal window
caudra --workcell-profile dev
caudra --workcell-profile dev --continue
caudra --workcell-profile dev -p --prompt "summarize the architecture"
caudra --workcell-profile dev acp
caudra --workcell-endpoint https://workcell.example/mcp \
--workcell-cwd projects/app --workcell-credential-ref credential:dev
FlagDescription
--workcell-profile <NAME>Select [workcell.profiles.NAME] from the local user workcell.toml
--workcell-endpoint <URL>Direct endpoint selection. Requires --workcell-cwd
--workcell-cwd <PATH>Root-relative remote directory, such as . or projects/app. Requires --workcell-endpoint
--workcell-credential-ref <credential:NAME>Saved bearer credential. Requires both direct endpoint and cwd flags

These flags are global. A Workcell profile cannot be combined with any direct selector. A fresh run without a selector uses embedded Workcell. Selection errors and remote failures stop the operation without local fallback. See Remote Workspaces for server setup, endpoint restrictions, and resume identity.

Managed sandboxes are experimental. These flags need experimental.sandboxes, and they work without experimental.remote_workcell.

FlagDescription
--sandbox <NAME>Attach the exact saved sandbox. Never creates a VM implicitly. Conflicts with the --workcell-* selectors
--sandbox-resumeExplicitly permit cold-boot resume of a paused sandbox selected by --sandbox or recovered from session provenance

These selectors also work with ACP. --session ID restores a saved sandbox source before validating the workspace. --continue can recover the last sandbox used from the client directory. A fresh run remains local by default. See Managed Sandboxes for setup, ownership and the current release-dependency limitation.

--allowed-tools / --disallowed-tools accept PascalCase (FileRead,FileEdit,Shell) or snake_case (file_read,file_edit,shell). Caudra converts PascalCase to snake_case and checks the result against the built-in tool names. Unknown names fail with the complete list of valid names.

--disallowed-tools also takes MCP names: github.create_issue for one tool, github.* for a server. Those keep their exact spelling. The persistent form of the same list is agent.disabled_tools, described in Disabling tools.

ModeEffect
defaultNormal permission prompts
autoSame as --auto for the SDK path. Needs experimental.decision_engine
acceptEditsAccepted for Claude Code compatibility; currently same as default
planAgent mode plan with plan file ./plan.md under cwd
bypassPermissionsSame as --yolo for the SDK path

If both --yolo and --permission-mode are set, the explicit mode wins. Unknown mode names warn and fall back to default.

While experimental.decision_engine is off, --permission-mode auto stops Caudra with an error. A set_permission_mode control request for auto returns the same error and leaves the mode unchanged.

Several other Claude Code flags are accepted and ignored so existing scripts keep parsing. Caudra prints a warning when you pass one of them.

On Unix, Workcell uses a host-bound absolute Bash executable with --noprofile --norc -c. It does not search PATH for the shell or implicitly source login files, .bashrc, BASH_ENV, or ENV.

Commands start from a cleared environment. They receive only these variables, each one only when the host has it set:

  • PATH, HOME, USER, LOGNAME, TMPDIR, TMP, TEMP, LANG, LC_ALL, and TERM.
  • HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, and NO_PROXY in uppercase and lowercase, with any credentials in their URLs.
  • HERDR_ENV, HERDR_PANE_ID, HERDR_TAB_ID, HERDR_WORKSPACE_ID, HERDR_SOCKET_PATH, and HERDR_BIN_PATH, so a command sees the Herdr pane Caudra runs in.
  • ComSpec, SystemRoot, and WINDIR on Windows.

Commands also get NO_COLOR=1 and CLICOLOR=0, so tools that honor those conventions print no color codes. An explicit flag such as --color=always still wins. Other host variables and startup hooks are not forwarded.

WORKCELL_BASH_EXECUTABLE selects an absolute Bash path in the execution host's environment. Runtime selection takes precedence over the same build-time variable. With neither set, Workcell tries /bin/bash, then /usr/bin/bash. An explicit empty, relative, missing, or invalid override fails instead of falling back. The selected executable is bound and revalidated before execution. A changed executable requires restarting the shell host.

Terminal window
WORKCELL_BASH_EXECUTABLE=/usr/bin/bash caudra

Set this on the Workcell host for remote execution. It is host configuration, not a model tool argument or a Caudra CLI flag. Nix builds can supply an absolute store path through the build-time variable. See Shell parsing for authorization limits. A predictable shell startup is not a sandbox.

Audit permission events, discover review-only command patterns, inspect stored rules, repair review descriptions, or review an explicit permission transfer without starting an agent. audit and rebind emit JSON. discover, inventory, and repair-review default to human-readable output and accept --json.

For interactive New, Edit, Duplicate, Copy, and Revoke controls, use the TUI's /permissions manager. These are not caudra permissions subcommands.

discover, inventory, repair-review, and rebind accept --database <ABSOLUTE_CAUDRA_DB> before or after the subcommand. The path must name an existing canonical absolute caudra.db file. Symlink and hard-link aliases are rejected. Selecting a database creates no database or directories. Inventory, repair, and rebind reports identify the selected database path. Discovery reports a hashed source identity.

Without --database, commands use this build's data namespace. Development builds default to caudra-debug, not the production caudra namespace. To preview repair of the standard Linux production database with a development binary, select it explicitly:

Terminal window
./target/debug/caudra permissions repair-review \
--database "$HOME/.local/state/caudra/caudra.db" --json

Use the actual production path if your state directory differs. Keep the same --database selection when moving from inspection to apply.

Terminal window
caudra permissions audit
caudra permissions audit --log permission-sample.jsonl \
--since 2026-09-14T00:00:00Z --max-bytes 8388608

audit reads the current canonical log unless --log selects another existing regular file. It rejects --database. It does not create directories, open the permission database, or scan rotated logs or session history.

FlagEffect
--log <JSON_LOG>Read this file instead of the current canonical log
--since <RFC3339>Include prompt and decision events independently at or after this timestamp
--max-bytes <BYTES>Tail-read budget, including the boundary probe. Defaults to 8 MiB and clamps to 1 byte through 32 MiB

The sample covers one file's bounded tail. It processes at most 50,000 complete lines forward within that tail, skipping lines larger than 64 KiB. Output reports skipped partial or oversized lines and complete bytes left unprocessed. Concurrent appends, rotation, or truncation can leave the sample incomplete.

Counts are log events, not deduplicated requests. There is no total-invocation denominator, so they cannot establish a prompt rate. Output separates explicit decisions, rule settlements, policy denials, and abandoned waits. Wait summaries pair manager_id and request_id, falling back to request ID alone when the manager ID is absent. Duplicate or colliding keys are excluded from waits. Time and sample boundaries can leave pairs incomplete. Waits include unattended time and can overlap, so they do not measure active human time. Commands, resources, identifiers, and arbitrary log strings are not emitted.

Terminal window
caudra permissions inventory
caudra permissions inventory --json
caudra permissions inventory --project /work/new --known-root /work/old
caudra permissions rebind --old-root /work/old --new-root /work/new
caudra permissions rebind --old-root /work/old --new-root /work/new \
--candidates candidates.json --select FULL_RULE_ID

inventory includes persistent rules across projects and conversation rules from stored sessions, including revoked rules. Human output shows full IDs, creation and revocation times, binding status, authority, and sanitized review descriptions. Missing inputs and scopes are marked unavailable. Supplied --known-root paths can supply hash-verified scope labels. --json includes the structured constraints and digests. The project defaults to the current directory. Binding eligibility is not a full policy evaluation: it does not decide whether a particular call is allowed. Inspection does not change logical database state, though SQLite may update existing WAL coordination sidecars.

Terminal window
caudra permissions discover
caudra permissions discover --project /work/app --limit 10 \
--since 2026-09-14T00:00:00Z --json
caudra permissions --database "$HOME/.local/state/caudra/caudra.db" \
discover --project /work/app --limit 5

discover reads a bounded sample of local stored tool calls and proposes command patterns for review. It never executes history, installs rules, or changes authorization. There is no apply mode. In the TUI, use Discover's Create permission action to open a draft for current-binding validation and explicit review and Save. A matching live approval prompt can also grant a scope.

FlagEffect
--project <ABSOLUTE_PATH>Match sessions whose current stored project cwd equals this path. Defaults to the current directory
--limit <COUNT>Maximum proposals, default 10 and clamped to 1 through 64
--since <RFC3339>Include history records created at or after this timestamp, based on their UUIDv7 IDs
--jsonEmit pattern definitions, retained literal values, evidence, per-session counts, analysis diagnostics, assumptions, exclusions, and limits
--database <ABSOLUTE_CAUDRA_DB>Read an explicitly selected database instead of the active data namespace

The project path must be bounded absolute UTF-8 without parent components or control characters. Historical paths are interpreted lexically, without resolving them through today's filesystem. A session's current stored cwd only approximates its historical project. Timestamps describe history creation, not execution time. Invalid, missing, or future dates are excluded.

Reports label all history-derived proposals as imported, with unknown outcomes and unverified historical execution context. Analysis assumes standard Bash startup, no aliases, functions, traps, or command-not-found hook, standard builtins and directory variables, empty CDPATH, disabled lastpipe, and a logical PWD matching the initial cwd. context_verified means analysis succeeded under those declared assumptions. It does not prove the old command ran in that environment.

Proposals keep the executable, fixed arguments, argument count, and workdir bound. Variable slots start with observed literal values and their observed joint combinations, without wildcards. An unknown-role argument after a fixed flag can select a program operation. Its position does not prove it is data. See the argument pattern inspector before widening a slot.

The scan samples recent sessions first, with limits of 256 sessions, 10,000 history rows, 16 MiB of history, 4,096 calls, and 4 MiB of command analysis. Each parent session has a shared cap of 128 rows across main and subagent history. Reaching that cap skips the parent's remaining rows and advances to the next session. Duplicates, invalid records, and skipped rows count toward the cap. A row is limited to 256 KiB and a command to 8 KiB.

The per-parent cap prevents one large session from consuming the entire row allowance. Global byte, call, and time budgets can still end the scan earlier. Reports include visited parent-session row and byte counts, per-session cutoff flags, and the number of parents cut short. This is a bounded prefix sample, not representative coverage or a count of all omitted rows.

The two-second budget reserves half for sampling, one quarter for admitting observations, and the final quarter for suggestions and evidence. Checks run between bounded operations, so one in-flight operation can finish after its deadline. Phase cutoffs retain partial results, while cancellation discards all proposals. --limit changes the proposal cap, not these scan limits. Check the reported phase limits, timeout, storage availability, and exclusions before drawing conclusions.

Imported proposals require at least two observations across two independent parent sessions. Recognizer admission is first-come and capacity-bounded, so input order can change retained evidence and proposals. Capacity exclusions are reported.

Only structurally stored native shell calls and shell calls inside native batches are eligible. A call that permissions refused before it ran is skipped, including a refused command inside a batch, and reports count it as the refused_call exclusion. History saved by earlier versions does not record refusals, so its refused calls still count. Tool names alone do not authenticate historical identity. Text, tool outputs, MCP calls, unsupported expressions, sensitive-looking values, and interpreted payloads are excluded. Archives and deleted history are not scanned. Repeated history IDs count once, conflicting copies are excluded, and subagents do not count as independent parent sessions. Support counts describe sampled records, not authoritative execution or success statistics.

Analysis reports aggregate omitted-command reasons and source/effect obligations, plus counts of calls with incomplete source or context. These totals precede history quarantine and recognizer admission, so observed-command counts are not retained proposal support. A matching pattern does not establish full-call authorization. Source/operator obligations and unassessed program effects can remain outside that match. Counts and matches cannot establish a safe-approval percentage.

Read-only SQLite access can update existing WAL coordination sidecars without changing logical database state. Caudra retains these sidecars after its last writer closes and truncates the WAL after a successful close checkpoint. An older offline database without sidecars is inspected only while Caudra holds exclusive storage access. Incomplete sidecars or conflicting access make the scan unavailable rather than ignoring WAL data.

Retained literals can still contain private information, so inspect JSON before sharing it. The TUI's background discovery and Suggested list use imported proposals too and never grant them automatically.

Terminal window
caudra permissions repair-review
caudra permissions repair-review --json
caudra permissions repair-review --retry-unavailable --json
caudra permissions repair-review --apply

The default is a read-only dry run. This explicit, one-off repair reads old review metadata across all persistent rules and stored conversation rules. It scans bounded local session history for tool inputs and resource candidates, then verifies them against existing constraints before storing sanitized descriptions. It never executes recovered commands, resolves historical paths through the current filesystem, or changes authorization. IDs, lifetimes, effects, revocations, and project bindings remain unchanged. Already typed reviews are skipped by default.

--retry-unavailable also retries typed unavailable reviews and incomplete recovered reviews. Approved reviews remain untouched. Existing verified labels are retained when the new scan still cannot recover those fields. Review the retry dry run, then retain --retry-unavailable and the same --database selection when adding --apply.

Output reports the database path, retried, repaired, recovered, and unavailable reviews, missing scope labels and inputs, scan limits, truncation, and invalid history rows. JSON includes the path in database. A recovered review can still have unavailable fields. Check those counts before applying. History limits, redaction, and missing history can prevent full recovery. The command does not invert hashes or invent missing values.

Before applying, stop every Caudra session and close all storage readers using this database, including old Caudra versions and sessions in other projects. Run caudra storage path with the production binary to locate its database, and check the repair report's database path. Apply requires exclusive administrative access and rechecks the stored metadata before committing the replacements atomically.

When there are reviews to repair, apply automatically creates an owner-only, checked SQLite backup beside the database, named caudra.db.permission-review-<ID>.bak. Human output prints its exact path after SQLite backup:. JSON output reports it in backup. A no-op apply creates no backup. Keep the backup private because it contains the full database, including the old metadata, session history, messages, and decision records.

After a successful apply, restart Caudra with the updated version and inspect /permissions or caudra permissions inventory against the same database. A failed access check requires closing the remaining readers and rerunning the dry run before applying again. No permission re-approval is needed for a metadata-only repair.

rebind defaults to a read-only preview and selects nothing automatically. Use a normalized historical absolute --old-root and an existing canonical destination directory for --new-root. The old root's current symlink is irrelevant. Repeat --select with full rule IDs, including affected global rules and restrictive rules you intend to transfer.

The optional candidate file is bounded to 1 MiB and uses this shape:

{"paths":["/work/old","/work/old/src"],"values":["git status --short"]}

paths supplies historical absolute filesystem or workdir spellings. values supplies exact non-path resource text, such as a reviewed command. Candidates must match the stored hashes. They are never executed or persisted as recovered display metadata. Root paths alone cannot identify arbitrary descendant hashes. There is no automatic history recovery, hash inversion, or rewriting of paths inside command text. Exact-input and selected-input constraints require fresh grants.

Preview rows are classified as verifiable, needs candidate, unaffected, unsupported, or restrictive-policy blocker. Review the old and new authority, reasons, partial_policy_transfer, and can_apply. Unresolved or unselected affected deny/ask rules block related allows. A selected restrictive rule is copied while its original remains active at the source. Only replaced allow originals are retired. A subset transfer is not equivalent to moving the whole policy.

To apply, close every session and storage reader using this database, including sessions in other projects. Repeat the reviewed command with the same roots, candidates, and selections, adding:

Terminal window
--apply --confirm PREVIEW_FINGERPRINT

Use the top-level confirmation value from that selected preview, not the inventory fingerprint. Apply rechecks the preview fingerprint, destination identity, resource aliases, and database access guards. It inserts replacements and retires selected allow originals atomically, retaining source-record provenance. Changed inventory or destination identity requires a fresh preview. Rules remain path-bound after commit, not inode-bound.

This is fresh destination authorization. It never transfers project-config trust or YOLO, and it never automatically rebinds stored grants through symlinks. See Permissions for runtime matching and prompt behavior.

Unlike CLI rebind, the TUI manager's Copy action leaves all source rules active. Revoking a copied source is a separate reviewed action. The CLI's selected-allow retirement behavior is unchanged.

Managed sandbox administration needs experimental.sandboxes:

Terminal window
caudra sandbox doctor --provider local --local
caudra sandbox create dev --profile rust
caudra sandbox attach dev
caudra --sandbox dev

create and attach verify Workcell and print the saved instance record. --sandbox opens the workspace session. The sandbox subcommand also provides List, Inspect/Reconcile, Pause, Resume, Extend, Delete, Detach, Cancel create, Acknowledge failure, Network, Images and reviewed Transfer actions. Use the exact lifecycle commands, image-admin request schema and transfer commands and prompts. Transfers require explicit file selection and plan consent, with no --yes shortcut.

Inspect or recover the selected remote workspace without running a model:

Terminal window
caudra --workcell-profile dev remote status
caudra --workcell-profile dev remote pending
caudra --workcell-profile dev remote reconnect
caudra --workcell-profile dev remote reconcile
caudra --workcell-profile dev remote acknowledge OPERATION_ID --accept-possible-effects

A remote selector is required. remote is available when experimental.sandboxes or experimental.remote_workcell is on, and the selector needs its own feature: --sandbox needs sandboxes, and the --workcell-* selectors need remote_workcell. With no action, remote shows status. Pending operations never block tool calls. Acknowledgement clears an operation from the pending report and accepts that it may have had effects or may still be running. It does not cancel, undo, or resend the operation. See recovery commands for the TUI and SDK forms and the inspection steps to take first.

Terminal window
caudra auth login [provider] [--method oauth|api-key]
caudra auth logout <provider>
caudra auth status
caudra auth workcell set <NAME> [--stdin]
caudra auth workcell list
caudra auth workcell delete <NAME>
caudra auth sandbox generate <NAME>
caudra auth sandbox set <NAME> [--stdin]
caudra auth sandbox list
caudra auth sandbox delete <NAME>

login stores credentials under the state directory and can write plan or base URL choices into providers.toml (see Configuration for the platform path). The picker asks for subscription OAuth or an API key when you choose Anthropic or OpenAI. Named Anthropic and OpenAI logins default to OAuth. Pass --method api-key to store a key instead.

Anthropic OAuth is experimental. The command explains the Anthropic terms limitation before opening the browser. OpenAI uses a device authorization flow. xAI and Copilot retain their dedicated named login flows. Other providers prompt for an API key and a plan when more than one plan exists. The interactive picker can also create custom providers.

The TUI /login command offers the same method choice for Anthropic and OpenAI. status distinguishes saved OAuth, saved API keys, environment credentials, configured endpoints, and missing credentials.

auth workcell set reads a bearer token from a hidden terminal prompt, or from stdin with --stdin. It stores or replaces a named credential, referenced as credential:NAME. list shows names and update times without bearer values. Credentials are stored in owner-only local files, without OS-keyring encryption. They are separate from provider login and MCP OAuth credentials. auth workcell needs experimental.remote_workcell.

auth sandbox needs experimental.sandboxes and manages lifecycle keys in a separate purpose store, referenced as sandbox-api:NAME. generate saves a new 256-bit key without printing it. set uses a hidden prompt or bounded stdin, and list omits secret values. Deleting a credential does not delete sandbox resources. See sandbox configuration.

Terminal window
caudra models
caudra models --jobs
caudra models --jobs --model anthropic/claude-sonnet-4-6

The plain command streams every model Caudra currently knows about from built-ins, discovery, and catalogs. Each line starts with its model spec and may end with a Small, Fast, or Best supply marker. Warnings from discovery go to stderr.

--jobs prints a table with Job, Binding, and Resolved columns for Chat, Plan, Subagent, Compact, Title, Goal, Extract, Fast, and Best. The optional global --model sets the anchor used to resolve the table and may appear before or after models. Without it, the normal saved, configured, or detected model becomes the anchor. It resolves from configuration and locally available model metadata, avoiding the all-provider discovery pass used by the plain command. See Providers for bindings, defaults, and marker meanings.

Terminal window
caudra mcp auth <server> # OAuth for an HTTP MCP server
caudra mcp logout <server> # drop stored tokens

Server names come from your MCP config. On a machine without a browser, auth prints a URL you open elsewhere and paste back.

Terminal window
caudra update # install latest release
caudra update -y # skip confirmation
caudra update --no-color
caudra rollback # previous version

Uses the same install locations as the install scripts.

Terminal window
caudra acp
caudra acp -m anthropic/claude-sonnet-4-6
caudra acp --yolo
caudra --ephemeral acp
caudra --no-jit acp

Starts an ACP server on stdio for editors like Zed. Subcommand flags are only -m / --model and --yolo. --ephemeral must come before the subcommand. -m, --no-jit, --no-plugins, --no-rtk, --allowed-tools, and --disallowed-tools work on either side.

Terminal window
caudra index path/to/file.rs

Runs the native file_index tool and prints its compact file skeleton or directory listing. It honors plugins.index.enabled and plugins.index.max_file_size_mb. --no-plugins skips only Lua, so these settings still apply from caudra.toml.

Terminal window
caudra prompt # rendered system prompt (default: system variant)
caudra prompt research
caudra prompt general
caudra prompt --plan # system prompt + plan-mode reminder (system only)
caudra prompt --tools # tool definitions as JSON
caudra prompt --tools --names # tool names only, one per line

Debug helper for inspecting the prompt and tool surface the agent sees. The research and general variants include the selected system prompt profile and their final host mode contract. --plan previews an active main-agent plan target without creating a document or changing session mode. It is rejected on non-system variants.

--tools applies the selected profile, model, audience, tool flags, and execution policy. It connects MCP servers and prints the initial request schemas, with one combined catalog for eligible lazy tools. --names lists declared schemas, including tool_search when needed, rather than expanding the pending catalog. Use caudra tools --enabled-only --names to include lazy tool names too.

Terminal window
caudra tools # every tool, on, lazy, or off, with the reason
caudra tools --enabled-only # only the tools the model can reach
caudra tools --names # names, one per line
caudra tools --json # full records
caudra tools --schemas # definitions as the provider receives them
caudra tools --disallowed-tools shell # preview a change before you run it
caudra --system-prompt-profile researcher tools --schemas

Resolves config the way a real run does, so the output reflects agent.disabled_tools, the plugin table, --allowed-tools, --disallowed-tools, the selected system prompt profile, and the model you select with -m. Built-in tools come first, then MCP tools grouped by server. MCP servers connect on every run, so a slow or failed server shows its status instead of its tools.

A tool that is off carries the rule that turned it off: --disallowed-tools, disabled by config, not in --allowed-tools, model has no vision support, model uses the other editing tool, or no ChatGPT subscription. A deny or allow default from Permissions appears next to the tool it applies to. See Disabling tools.

A tool marked lazy is available and starts outside the request array. The model can discover it through tool_search or call it directly by its known name. Without profile loading overrides, a small or supply-unknown model defers eligible built-ins, while a known non-small model lists them on with the note declared upfront on a known non-small model. Explicit profile loading choices take precedence over those preferences. See Tools loaded on demand.

These commands inspect a fresh tool view rather than restoring an open session's loaded schemas. caudra tools uses Build mode with no session, so plan is off with the reason requires a session plan. Use caudra prompt --plan --tools for a Plan preview. Inside a session, /tools provides a mode-aware inventory: selected mode while idle, committed mode during an active turn, and the task's own snapshot in a task view. Schemas and catalogs omit unavailable tools even when a profile requests them.

Terminal window
caudra skills # every skill with its scope and file
caudra skills git-release # one skill's body, exactly as the model receives it
caudra skills --names # names, one per line
caudra skills --json # full records
caudra skills --dirs # candidate directories: selected, superseded, or missing

Applies the same directory precedence a real run does, including the builtin skills that plugins.skill and the experimental features leave on. A caudra-docs address loads one page, one section or one search, as the model would. Quote it, because #, ? and spaces mean something to your shell:

Terminal window
caudra skills 'caudra-docs/permissions#plan-mode'
caudra skills 'caudra-docs?shell timeout'

--dirs answers why a skill is missing: a directory reads superseded when a higher-priority one exists, and missing when nothing is there. See Skills.

Terminal window
caudra config files # every config file, where it lives, and whether it is there
caudra config example # every caudra.toml setting, commented out
caudra config example mcp # every mcp.toml key, commented out
caudra config example > caudra.example.toml # keep a copy to read or diff

files lists every file Caudra reads settings from. For each one it shows what the file holds, the experimental switch it needs, each global and project path with whether the file is there, its docs page, and its example command. It follows CAUDRA_NAMESPACE and debug builds, and it creates nothing.

example prints every setting of one TOML file with its type, default, allowed range, environment variable, and description. FILE names one of the TOML files that caudra config files lists, with or without .toml, and defaults to caudra. Everything is commented out apart from version and the table headers a file needs, so the whole output is a valid file that changes nothing. To use a setting, copy its line into your file under the same table and remove the #. For a record such as [mcp.NAME], copy the header too and put your own name in it.

Neither command needs your settings, so both work even when caudra.toml has an error. Reference configs shows what example prints for every TOML file, with a download for each. See Config files.

Terminal window
caudra logs # the last 200 records at info and above
caudra logs -f # keep printing as records arrive
caudra logs -n 50 -l warn # the last 50 warnings and errors
caudra logs --json | jq 'select(.fields.event == "retry")'

Prints the same structured log the /logs modal shows, formatted for a terminal and coloured by level when stdout is a TTY. --json writes the stored line back unchanged, one object per line, which is the form to pipe into jq. Reading the log never writes to it. See Logging.

Terminal window
caudra storage path # session database path
caudra storage stats [--json] # rows, bytes, artifacts, pending cleanup
caudra storage check # integrity check
caudra storage sessions [--directory DIR] # list sessions with activity, size, state
caudra storage snapshots [--json] [--records] # change record stores, largest first
caudra storage trim [POLICY | ID...] [--dry-run]
caudra storage forget [POLICY | ID...] [--dry-run] [--prune]
caudra storage prune [--dry-run]
caudra storage pin <ID>...
caudra storage unpin <ID>...
caudra storage checkpoint [--truncate]
caudra storage vacuum [--pages N]
caudra storage usage [--group-by GROUP] [--since DURATION] [--json]
caudra storage usage --prune-older-than DURATION

Application state, peer-message history, and decision logs share caudra.db. The remote-operation recovery journal remains separate at recovery/remote-operations.db.

snapshots lists the file change record stores largest first, one row per workspace directory with its size, object count, records, holding sessions, open records, and pending reverts. A store whose directory is gone, or that no session works in any more, shows its key instead, and --json always gives both. --records also lists each holding session with its record count. A store that no existing session holds is reported as orphaned rather than skipped.

trim demotes sessions to the transcript tier and forget deletes them. Both take a keep policy in restic forget terms and fall back to the configured storage.retention policy when no --keep-* flag is given. Both release the local change records of the sessions they trim or delete, and records that no other session holds are deleted. prune reclaims space that no session references. It releases the change records of deleted sessions older than seven days, trims each change store to its size budget, removes stores left empty and unused for seven days once no session's file revert reads them, and deletes the session-snapshots/ and workspace-snapshots/ directories of earlier versions. Its --json output reports the bytes it reclaimed from the change stores as record_bytes_reclaimed. In the --json output of trim and forget, snapshot_garbage_bytes reports the bytes that a prune would then reclaim from the change stores. See Sessions for the policy rules and what each tier keeps.

Both also take session IDs instead of a policy. caudra storage trim <ID> releases one session's local change records by hand while its conversation stays resumable. Records that another session, such as a fork, still holds stay in the store. IDs and --keep-* rules cannot be combined, pinned sessions are still refused, and a session open in another process is skipped rather than raced.

FlagDescription
--keep-last <N>Keep the N most recently active sessions
--keep-hourly, --keep-daily, --keep-weekly, --keep-monthly, --keep-yearly <N>For the last N periods that contain sessions, keep the newest session of each
--keep-within <DURATION>Keep every session active within the duration, for example 90d or 2y5m7d3h
--keep-within-hourly ... --keep-within-yearly <DURATION>Keep one session per period within the duration
--group-by <directory|none>Evaluate the policy per working directory (default) or across every session
--directory <DIR>Only sessions for one working directory
--dry-runPrint the plan and change nothing
--jsonEmit the plan and outcomes as JSON
--pruneforget only: run prune when at least one session was forgotten
--unsafe-allow-remove-allAllow an empty policy, which keeps nothing. Requires --directory

A session is kept when any rule matches. Pinned sessions, sessions open in any Caudra process, and sessions with a pending revert are never trimmed or forgotten by policy. forget <ID> refuses pinned sessions. Trimming or forgetting a local session with a pending file revert by ID ends that revert, and the files stay as reverted.

usage reports spend from a ledger that outlives the sessions that produced it, so trimming and forgetting leave the numbers intact. Group by model (default), provider, project, purpose, day, month, or total, narrow with --since 30d, and trim the ledger itself with --prune-older-than, which takes no other flag. Token Economy explains what the columns mean.

The Hit column is the share of prompt tokens each group read from cache, and --json carries it as cache_hit_rate. Cache hit rate defines it.

Terminal window
# TUI on a project
cd ~/code/my-app && caudra
# One-shot with YOLO and a model pin
caudra -p --yolo -m anthropic/claude-sonnet-4-6 --prompt "summarize the architecture"
# Resume yesterday's session
caudra --continue
# List models, then log in
caudra models
caudra auth login
# Inspect tools without starting a session
caudra prompt --tools --names

For JSON / stream-json output, stdin prompts, and SDK wire mode, see Headless Mode.

Website privacy and analytics