Skip to content

CLI

Draft

capsule is the command line for a Capsule library. It is the only client that performs the whole data plane end to end — it scans and imports files, seals them locally, opens upload sessions, drains the sync feed, and rebuilds an index from what is on disk — which is why the examples in this documentation are commands rather than HTTP requests. The server never sees a key, so a request transcript would show ciphertext going in and ciphertext coming out; a transcript of capsule shows the operation.

This page is the hand-written half of the CLI reference. Commands is the generated half: every command, argument, and option, emitted from the same clap definitions the binary parses with.

No release has been published yet. From a checkout, cargo run -p capsule-cli -- runs the binary against the working tree; cargo install --path capsule-cli installs it.

A capsule invocation reads at most two pieces of durable state, and it helps to know which:

  • A library — a directory named by --library, holding the encrypted assets, their sidecar metadata, and a SQLite index that can be rebuilt from the sidecars alone (capsule library rebuild). Every offline command operates on one.
  • A session — the token pair capsule auth login persists, owner-readable, under the user’s configuration directory. Every networked command reads it, and capsule reset removes it.

Eleven commands unseal a library, and all eleven take its passphrase: capsule import, capsule push, capsule restore, capsule cull, capsule show, capsule library list, capsule repair capture-time, capsule label, capsule region, capsule edit, and capsule sync reannounce (which capsule sync --library runs itself when the server has rebuilt the library’s index). Each accepts --passphrase-stdin as well as prompting, so each runs unattended. The other capsule library subcommands are not among them — info and rebuild read the version file, the sidecars, and the index, none of which is sealed, so they need no passphrase and offer no flag for one.

Run with no command while stdin and stdout are both terminals, capsule opens a full-screen TUI; q or Ctrl-C leaves it and ? lists its keys. Anywhere else (a pipe, a redirect, a CI runner) bare capsule prints the help on stderr and exits 2, as a missing command always has, so a script never blocks on a screen. While the TUI holds the terminal, log output goes to tui.log in the CLI’s cache directory instead of stderr, replaced each time the TUI opens. A password, passphrase or authenticator code typed into the TUI is masked on screen, and neither it nor an issued share URL is written to that log. Signing out and revoking a share link ask y or n first in the TUI; the subcommands do not ask, so scripts keep working. Every flow the TUI offers stays reachable as a subcommand, with --json where it reports. The library browser’s twins are capsule library list --library PATH [--view timeline|albums|stacks], which lists the same timeline, albums and stacks from the same snapshot, and capsule show ASSET --library PATH, whose --json document carries the asset’s provenance history record by record. The library browser asks the terminal once, at start-up, whether it draws Kitty, Sixel or iTerm2 graphics; where it draws none, the preview pane says so in text and no original is decoded for it. From the browser, the label editor (e) and the time-and-place screen (m) write to the library it has open with the passphrase it was opened with, kept in memory only while it stays open; each edit unlocks the library, writes, and closes it again, through the same code as capsule label, capsule region and capsule edit. Regions are drawn over the preview in half blocks, which every colour terminal shows.

  • The behaviour of the import pipeline is Import Pipeline; what capsule push speaks is the Transfer — Upload, and what capsule sync drains is Sync. capsule restore fetches originals over Transfer — Download and opens them with the library’s album keys: it writes an original only once its ciphertext matches the signed manifest and its plaintext matches the signed metadata’s digest, and an interrupted run resumes from the part files it left in OUT/.capsule-restore/.
  • The server endpoints behind the networked commands are the REST API reference.
  • The CLI and TUI are English-only. The shared error.* codes render through the English catalog described in Internationalization; dropping the remaining locale negotiation is #680. The command tree this reference is generated from is English, so the artifact cannot vary with the machine that emits it.

capsule-cli emits capsule-cli/cli-surface.json — a description of the command tree, read straight from the clap definitions — and mise run cli-surface-check fails the Rust gate if the committed copy disagrees with the code. The documentation build reads that file and nothing else; it never runs cargo. So a new option cannot reach users without either appearing on the generated page or failing CI.

A generated page is never edited. If something on it is wrong, the annotation it came from is wrong: fix the clap about or doc comment, run mise run cli-surface, and commit the artifact. The pipeline and the reasoning behind it are Developer Documentation.