Skip to content

CLI Reference

Install from a source checkout with cargo install --path crates/casita. Optional commands need the corresponding Cargo feature. For a first walkthrough, start with the CLI guide.

Task Commands
Store and read import, object show, tree list, cat, checkout
Retain and maintain root, gc, vacuum, fsck, holds
Move data sync, archive
Integrate run, ipc, git
casita [GLOBAL OPTIONS] COMMAND [COMMAND OPTIONS]

Put global options before the command. -h/--help prints command-specific help; -V/--version prints the binary version.

Option Effect
--repository PATH Use this local repository instead of the per-user default. sync uses --from and --to instead.
--log-filter DIRECTIVES Select trace levels; overrides RUST_LOG. Defaults to RUST_LOG, then off.
--log-format compact|json Write compact or newline-delimited JSON trace events to stderr. Default: compact.
--spill-memory-objects OBJECTS, --spill-bytes BYTES Bound temporary traversal state.
--pack-target-bytes BYTES Set the approximate compressed size of an immutable chunk pack.
--pack-cache-bytes BYTES Set the S3 compressed-chunk cache size; 0 disables it.

The pack cache option is intended for S3 endpoints used by sync or remote verified cat. Spill options affect temporary traversal state, not object identity.

For example, casita=info records operation outcomes and casita=debug adds internal decisions and contention. Casita’s own trace fields omit paths, root names, credentials, and payload contents, but dependency traces may have different rules. Use a scoped filter when sharing logs:

Terminal window
$ casita --log-filter casita=info --repository ./cache fsck --dry-run
$ RUST_LOG=casita=debug casita --log-format json \
--repository ./cache gc --dry-run

Without --repository, Casita uses the OS application data directory, falling back to $HOME/.casita and then .casita-data when needed. It also searches the current directory and its parents for a .casita workspace marker. The marker scopes root names by a workspace UUID; bytes stay in the per-user repository. An explicit repository skips workspace scoping. The run command uses the marker only for optional name shortcuts.

casita [--repository PATH] init

Without --repository, creates or reuses the current directory’s .casita workspace marker after opening the global profile. With --repository, creates or opens that local profile and prints its path and current repository revision.

casita [--repository PATH] import [-i IMPORTER] PATH [--root NAME] \
[--retention permanent|evictable] [--filesystem-rehash]

Without -i, Casita recognizes Git repositories from their metadata, probes regular-file headers for Casitar or tar, and otherwise imports a directory as a filesystem tree. Use -i filesystem|tar|git|casitar to select an importer explicitly. Standard input (-) requires -i.

For a filesystem import, --root names the tree. When omitted, Casita derives a name below auto/ from the canonical source path. In a workspace, both explicit and automatic names are scoped by its UUID. Importing the workspace directory omits its .casita marker. --retention publishes the root and policy together for filesystem and tar imports. Roots are permanent by default; omitting the flag keeps an existing root’s policy. Git and Casitar imports do not accept this flag.

The importer prints the directory key and does not follow symlinks. It may reuse a file whose device, inode, size, and timestamps match the previous import. --filesystem-rehash reads every file again. Use --filesystem-concurrency FILES to change the number of files ingested at once (default 16), and --chunk-upload-concurrency CHUNKS to bound uploads per blob writer (default 32). See Import semantics for the reuse assumption.

casita [--repository PATH] import [-i tar] FILE|- --root NAME \
[--retention permanent|evictable] \
[--tar-max-archive-bytes BYTES] [--tar-max-entries COUNT] \
[--tar-max-in-flight-files COUNT] \
[--tar-max-path-bytes BYTES] [--tar-max-file-bytes BYTES] \
[--tar-max-total-file-bytes BYTES] [--tar-max-sparse-expansion-bytes BYTES]

Streams one already-decompressed POSIX tar archive into the canonical filesystem model without extracting it to disk. A tar file is detected from its first valid header; use -i tar for standard input. The command accepts regular files, directories, symlinks, hard links, and old-GNU sparse files; PAX GNU sparse members are rejected. FILE may be - for standard input.

The root name is required and is committed only after complete validation. Defaults bound raw archive bytes (1 TiB), entries (1,000,000), path bytes (4096), individual files (256 GiB), total file bytes (1 TiB), and sparse-hole expansion (256 GiB). The corresponding flags override those bounds.

casita [--repository PATH] object show KEY

KEY must be a full generic object key. Output includes the logical key, physical payload ID, payload size, ordered forward links, and current closure status.

casita [--repository PATH] tree list KEY

Lists the direct entries of a canonical filesystem directory. KEY may be a full casita.directory.v1 key or a short blake3-... directory digest. The command requires a complete valid closure.

Entry output identifies directories (d), regular files (f), executable files (x), and symlinks (l).

casita [--repository PATH] run ROOT [--bin NAME_OR_PATH] [-- ARGS...]

Runs an executable from an existing named directory root. Casita searches the tree recursively and starts its sole executable. With several candidates, use --bin to choose a unique filename (uv) or relative path (release/uv); ./uv selects a root-level file. It fails when no executable is found.

On Unix, candidates need an executable mode bit. On Windows, they need a .exe or .com extension. Internal executable symlinks can be selected, but discovery skips broken links, links outside the tree, and directory symlinks. Selection does not search $PATH or prefer a build profile.

Terminal window
$ casita run cargo/builds/uv -- --version
$ casita run go/builds/server --bin server -- --port 8080

To shorten names, add run settings to the .casita marker created by casita init, keeping its header and workspace UUID:

casita-workspace-v1
workspace = "12345678-1234-4234-8234-123456789abc"
[run]
default-scope = "cargo"
[run.scopes]
cargo = "cargo/builds"
go = "go/builds"
Input Resolved repository root
cargo:uv cargo/builds/uv
go:server go/builds/server
uv cargo/builds/uv, using the optional default scope
cargo/builds/uv cargo/builds/uv, unaffected by the default
/uv Literal root uv, bypassing all shortcuts

Only bare names use the optional default scope. SCOPE:NAME selects a configured prefix, and a leading / requests a literal name. The closest marker wins; invalid scopes or configuration fail instead of falling back to another name.

run resolves the root once and retains that exact graph while the application runs. It materializes the tree under the repository’s runs/ directory and normally removes it on exit. A crash may leave temporary files there. The child inherits the caller’s working directory, environment, and standard streams. Arguments after -- go to the child without a shell. Casita returns its exit code and forwards common termination signals on Unix. Execution uses the caller’s permissions. See the run guide for a complete workflow and binary-selection details.

casita [--repository PATH] ipc [--max-connections COUNT] \
[--frame-timeout-secs SECONDS] [--response-timeout-secs SECONDS]

Starts the local JSON-RPC service for artifact import and restore. Defaults are 64 connections, 60 seconds to receive a request, and 30 seconds to write a response. See Local IPC for the endpoint and protocol.

casita [--repository PATH] cat KEY [--verified [--from ENDPOINT]]

Writes a blob’s exact plaintext payload to standard output. KEY may be a full generic key or a short blake3-... blob digest. Diagnostics go to standard error, so stdout may be redirected safely. --verified authenticates blocks before writing them. With --from, it reads a verified raw blob from a local, SSH, or S3 repository instead of the selected local repository; --from requires --verified and a raw blob key.

casita [--repository PATH] checkout KEY DIR [--no-root]

Materializes a complete canonical directory into DIR. The target is created if absent and must otherwise be empty. Checkout first writes a sibling staging directory on DIR’s filesystem and renames it into place. A target that cannot represent exact stored names, for example because of case folding or Unicode normalization, fails without a partial checkout. KEY accepts a full directory key or a short directory digest.

Every directory, file, and link is created relative to one open handle on the staging root, so a component swapped for a symlink, junction, or other reparse point while the checkout runs cannot redirect a write outside it. DIR itself must be a real directory: a path that is already a link is refused rather than written through. The path leading to DIR is the caller’s own authority, and a link stored inside the materialized tree is created as a link, not followed. Windows refuses to materialize a stored link whose target is absolute.

By default, successful checkout also registers an auto/checkout/... root derived from the canonical destination path. That root retains the materialized closure until explicitly removed. --no-root skips this step.

Roots retain the complete forward closure of one exact object.

casita [--repository PATH] root set NAME TARGET [--retention permanent|evictable]

Atomically sets or replaces NAME. TARGET may be a full object key or a short filesystem digest. A short digest is rejected as ambiguous if matching blob and directory records both exist. The target closure must be complete and valid. Roots are permanent by default. --retention sets the policy in the same commit as the root. Without it, replacing a root keeps its existing policy. Evictable retention requires the local metadata backend.

casita [--repository PATH] root retention NAME permanent|evictable

Changes the policy of an existing local root. A permanent root remains until explicitly removed. An evictable root may be released by local disk-pressure collection, after which its name becomes a cache miss.

casita [--repository PATH] root rm NAME
casita [--repository PATH] root rm --prefix PREFIX

The first form removes one exact name. The second removes every name equal to or below PREFIX on root-name segment boundaries and prints each removed name. The two selectors are mutually exclusive. Removing a root makes data eligible for collection; it does not immediately delete objects.

casita [--repository PATH] root ls [PREFIX] [--long]

Lists targets and names. An optional positional PREFIX restricts output to equal or descendant root names. --long also displays permanent or evictable for each root.

Terminal window
casita holds PATH [--json]
casita holds s3://BUCKET/PREFIX [--json]

Lists online data pins, released pin history, collector ownership, prune fences, and deletion claims without waiting for repository admission. Local inspection requires an existing repository; S3 additionally requires the s3 feature. --json emits an object with collectors, state, and coordination fields. Each ledger has its own revision and exact tokens. Pin scopes include snapshot generations or closure roots; catalogs are identified by digest and encoded size. S3 collector entries include diagnostic writer names and legacy exclusivity flags. Listing never releases an existing hold or declares its owner dead. See S3 maintenance for diagnosis and explicit recovery.

casita [--repository PATH] gc [--dry-run]

Collection starts from every named root and active data pin. --dry-run takes exclusive ownership, runs the same mark plan, and reports removable logical records, payloads, and chunks without changing state. Without it, Casita first commits the logical prune and then removes unreferenced physical data.

Collection can proceed during mutations, transfers, and retained reads, preserving the data protected by their pins. Collectors serialize with other collectors. Starting a mutation on the standard local profile attempts nonblocking collection when disk usage has reached 80%. After collecting existing garbage, it releases least recently used evictable roots and vacuums until disk usage falls below 75% or no eligible roots remain. Explicit gc and vacuum preserve all named roots regardless of their retention policy.

casita [--repository PATH] vacuum

Runs collection and forces reclamation of garbage deferred inside sparse packs. Use this when ordinary collection has left physical pack space to reclaim.

casita [--repository PATH] fsck [--audit-only | --dry-run] [--source REPOSITORY]

--audit-only checks logical records, root closures, payload identity and size, format relations, manifests, chunks, and unreferenced residue without running the separate repair pass. It is the appropriate mode for routine integrity measurement and is mutually exclusive with --dry-run and --source.

First, fsck verifies every physical payload representation named by the current logical snapshot. It rebuilds a corrupt existing Bao outboard and, when --source names a local replica with the expected fully verified payload, repairs a missing or corrupt local representation. It then checks logical records, root closures, payload identity and size, format relations, manifests, chunks, and unreferenced residue. --dry-run reports physical repairs without writing.

The repair pass never changes object records or roots, never repairs an unrelated I/O failure, and never invents logical state from a payload scan. It pins source and destination data for the operation, preserving replacement inputs while collection and ordinary readers continue. fsck prints a summary and each deterministic finding. Reachable corruption makes the command fail. Collectible residue and unavailable format verifiers are reported but do not, by themselves, make the repository unhealthy. See Errors and Integrity.

All archive commands enforce finite defaults: 1 TiB for the complete stream, 256 GiB for one plaintext payload, 1 TiB for total plaintext payloads, and 1,000,000 each for payload and record frames. Override them with --max-archive-bytes, --max-payload-bytes, --max-total-payload-bytes, --max-payloads, and --max-records. The frozen 4 MiB header and 256 MiB encoded-record ceilings still apply.

Successful commands print the complete-file BLAKE3 digest and structural counts. --json selects the stable casita.archive.v1 report schema.

casita [--repository PATH] archive create \
[--root NAME]... [--object KEY]... \
--output FILE|- [--force] [--json]

At least one selector is required; named roots and exact generic object keys may be mixed and repeated. Casita resolves names and verifies every selected closure through one source snapshot, deduplicates their union, then writes payloads and records in canonical order. Equal root sets and logical closures produce equal archive bytes regardless of selector order or traversal spill.

File output is staged, synced, and atomically published. It refuses an existing destination by default, including one created concurrently; --force selects atomic replacement. --output - writes only archive bytes to stdout and sends the human report to stderr. --json and --force are rejected for stdout output.

casita archive inspect FILE|- [--json]

Consumes and hashes the complete stream, requiring canonical framing, payload identities and lengths, section ordering, record encodings, the explicit end marker, and strict EOF. A successful result is labeled structural: it does not claim namespace reproduction, exact reachability, or complete root closures. This command does not open the configured repository. - reads archive bytes from stdin.

casita archive verify FILE|- [--json]

Runs the full receiver import algorithm in an isolated temporary repository. Success means every payload hash, namespace-produced record, direct-link relation, exact record/payload membership rule, and declared closure verified. The temporary repository is discarded, and the configured durable repository is never opened or mutated. - reads from stdin.

casita [--repository PATH] archive import FILE|- \
(--root NAME... | --root-prefix PREFIX) [--replace] [--json]

Destination naming is always explicit. Repeat --root NAME exactly once per archive root in the canonical order printed by inspect, or use --root-prefix PREFIX to map them to PREFIX/0, PREFIX/1, and so on. There is no default prefix and no digest-derived or auto/ naming.

The command streams every payload through BLAKE3, reuses exact physical payloads when possible, stages records through the registered namespace verifiers, checks the exact declared union closure, and publishes every mapped root together in one repository revision. By default all names must be absent. --replace captures their values before ingestion and replaces them only if every value remains unchanged at publication. Failure publishes no mapped root and may leave only receiver-verified unrooted residue for ordinary collection.

casita [--repository PATH] import [-i casitar] FILE|- \
(--casitar-root NAME... | --casitar-root-prefix PREFIX) [--casitar-replace]

This is the common importer-command form of Casitar restoration. A file with the Casitar header is detected automatically; use -i casitar for standard input. It has the same all-or-nothing destination mapping and verification behavior as archive import, but every Casitar-specific option is namespaced: --casitar-root, --casitar-root-prefix, --casitar-replace, --casitar-max-archive-bytes, --casitar-max-payload-bytes, --casitar-max-total-payload-bytes, --casitar-max-payloads, and --casitar-max-records. It does not accept --root; use the Casitar mapping options instead. See Import a Casitar Archive for examples and Rust usage.

casita sync --from ENDPOINT --to ENDPOINT \
[--from-blobs ENDPOINT] [--writer NAME] \
[--object KEY]... [--root NAME]... \
[--path PATH [--destination-root NAME]] [--shallow] [--incremental]

--from supplies roots and object records. --from-blobs, when present, supplies payloads from a second Casita repository; it must contain the exact bytes required by those records. Sources accept local paths, S3 URLs (s3://BUCKET/PREFIX), or SSH URLs (ssh://[user@]host[:port]/absolute/path). Destinations accept local paths or S3 URLs. S3 needs the s3 feature; SSH sources need ssh on both machines and a remote casita on the SSH user’s PATH. --writer sets the diagnostic WAL writer name for S3; otherwise CASITA_WRITER or a generated name is used.

Select at least one --object or --root; both are repeatable. Objects use full keys and copy their complete forward closure unless --shallow is set. Roots always copy complete closures and move under the same names only after receiver verification. --incremental reuses complete destination closures without auditing their descendants at the source. Intermediate object batches may remain after failure, but requested roots do not move. Sync does not remove destination data.

--path PATH requires exactly one filesystem root and cannot be combined with --object or --shallow. Only the selected file or directory closure is copied; verified path ancestors stay at the source. Without --destination-root, the copied closure is unrooted and collectible. Inline symlinks have no standalone key and cannot be rooted.

See Synchronize Repositories for examples and failure behavior.

casita [--repository PATH] import [-i git] SOURCE \
[--git-view VIEW] \
[--git-ref FULL_REF]... \
[--git-max-cached-pack-bytes BYTES] \
[--git-concurrency COUNT] [--git-max-buffered-bytes BYTES]

Requires cli,git. SOURCE is a local working tree or bare repository and is detected from its metadata. When auto-detected, an omitted --git-view uses the source directory basename. Each --git-ref is a full canonical name such as refs/heads/main. With no explicit refs, Casita selects local branches and tags. The command verifies native objects, publishes one immutable view, and atomically sets git/VIEW. When one verified source pack exactly matches that view, Casita retains packs up to 8 GiB by default as a rebuildable, byte-for-byte full-clone cache. This can substantially accelerate large clones but may nearly double stored bytes for incompressible repositories. Set --git-max-cached-pack-bytes 0 to disable the cache or lower the limit to fit the storage budget. --git-concurrency bounds staged objects (default 16); --git-max-buffered-bytes bounds decoded bytes held by staging futures (default 64 MiB). An object larger than the budget runs alone.

casita [--repository PATH] git show VIEW

Prints the selected view key, object format, optional default ref, and every direct or symbolic ref. It is available in the standard cli build.

casita [--repository PATH] git checkout TREE DIR [--skip-gitlinks]

Safely materializes one exact type-qualified native Git tree into an empty directory, under the same handle-rooted containment as checkout above. Gitlinks fail by default; --skip-gitlinks materializes them as empty directories. This command is available in the standard cli build.

casita [--repository PATH] git serve VIEW \
[--listen ADDRESS] [--max-pack-bytes BYTES] \
[--pack-compression-level 0..9]

Requires cli,git-http. The default listen address is 127.0.0.1:9418. The command binds one immutable view for read-only Git smart HTTP, prints its clone URL as http://<address>/<view>.git, and serves until stopped. Generated packs default to a 512 MiB limit and zlib compression level 6.

Successful commands return exit status 0. Usage errors return 2; runtime failures return 1. There are no per-category exit codes.

Runtime failures are written to stderr as:

error[<category>]: <detail>

Usage errors use error: <detail>. Programs should prefer the Rust API’s typed errors when they need richer classification or retry guidance rather than parsing CLI display text.