Skip to content

Carrel command reference

Generated from --help of carrel 0.5.0 by scripts/sync_reference.py — do not edit. Regenerate with uv run python scripts/sync_reference.py; CI fails when this file drifts.

Related docs: Install · Quickstart · Configuration · Troubleshooting · Cookbook & snippets

Global options

These live on the root command, before the subcommand (e.g. carrel --json inspect report.pdf):

Usage: carrel [OPTIONS] COMMAND [ARGS]...

  carrel — a library desk for your files — and your agents.

  Every command supports --help; data-producing commands support --json. Run `carrel doctor` to see
  what your environment enables.

Options:
  --version         Show the version and exit.
  --json            Machine-readable JSON output.
  --debug           Show tracebacks on error.
  --root DIRECTORY  Desk root for db-backed commands (default: cwd).
  --help            Show this message and exit.

Commands:
  audiobook       Narrate SRC (txt, md, pdf) into an audiobook.
  batch           Run --run actions over every file in PATH...
  catalog         Export, import and check the desk catalog (tags, notes, meta in...
  color           Color tools: dominant palette, ICC profile conversion, WCAG contrast.
  completion      Print a completion script for SHELL (bash, zsh, or fish).
  convert         Convert SRC...
  dedupe          Report duplicate files under DIRS (recursively; hidden entries skipped).
  desk            Open the interactive desk TUI on ROOT (default: --root, then cwd).
  diff            Compare two files A and B.
  doctor          Report environment health: adapters found, versions, per-command capability.
  edit            Edit files in place-adjacent, non-destructive ways (pdf/image/text/json).
  extract-images  Extract images embedded in / referenced by SRC (pdf, ico, html).
  fields          Extract vendor, invoice number, dates and totals from PATH...
  form            Build HTML forms from JSON specs; list and fill PDF AcroForms.
  index           Index PATH...
  inspect         Show metadata for one file.
  intake          File everything waiting in INBOX into --to, named after what the documents say.
  mail            Attachments, mailbox splitting, threads and Outlook exports for eml/mbox files.
  mcp             Serve the desk as an MCP server on stdio: 14 tools (search, pack, inspect,...
  meta            Typed key/value fields on desk files (.carrel/carrel.db under --root).
  note            Attach notes to files (desk db) and annotations to PDFs (pypdf).
  ocr             OCR an image or PDF into text (txt/md) or a searchable PDF.
  organize        Plan (default) or perform (--apply) sorting DIRECTORY's files.
  pack            Bundle PATH...
  proof           Soft-proof SRC against an ICC PROFILE (simulate print/display output).
  redact          Redact sensitive strings from a text file or PDF.
  refs            Find reference numbers (invoice, PO, IBAN, routing, tracking, …) in PATH...
  rename          Plan (default) or perform (--apply) renaming PATH...
  search          Full-text search the desk index for QUERY (FTS5 syntax, bm25-ranked).
  sign            Sign things: stamp PDFs, hash manifests, verify both.
  tag             Tag files in the desk db (.carrel/carrel.db under --root).
  thumb           Create thumbnails for SRC...
  watch           Watch DIRECTORY and run shell actions on file events.
  • --json — where a command produces data, exactly one JSON object or array goes to stdout and nothing else (progress goes to stderr). Every command also accepts --json after its name; both spellings work.
  • --root PATH — where db-backed commands keep .carrel/carrel.db. See Configuration.
  • --debug — show tracebacks instead of one-line errors.

Commands

33 commands:

audiobook · batch · catalog · color · completion · convert · dedupe · desk · diff · doctor · edit · extract-images · fields · form · index · inspect · intake · mail · mcp · meta · note · ocr · organize · pack · proof · redact · refs · rename · search · sign · tag · thumb · watch

carrel audiobook

Usage: carrel audiobook [OPTIONS] SRC

  Narrate SRC (txt, md, pdf) into an audiobook.

  Markdown is stripped for speech: headings become spoken chapter announcements, code blocks become
  "[code omitted]", links read their text. mp3/ogg need ffmpeg; --format wav works with espeak-ng
  alone. Existing outputs are never overwritten without --force. With --json, prints {src, outputs,
  engine, duration_s, chars}.

Options:
  -o, --output FILE               Output audio file (default: SRC with audio extension).
  --voice TEXT                    Voice: espeak voice name, piper model path, or edge-tts voice.
  --rate INTEGER RANGE            Speech rate in words per minute.  [default: 170; 80<=x<=450]
  --engine [auto|espeak|piper|edge-tts]
                                  TTS engine; auto prefers piper > edge-tts > espeak-ng.  [default:
                                  auto]
  --split-chapters                One file per chapter (markdown H1/H2, or the PDF outline).
  --force                         Overwrite existing output files.
  --format [mp3|ogg|wav]          Audio format (default: from -o extension, else mp3).
  --json                          Machine-readable JSON output.
  --help                          Show this message and exit.

carrel batch

Usage: carrel batch [OPTIONS] PATHS...

  Run --run actions over every file in PATH... (files, or directories walked like `index`).

  Exit 0 when every file succeeded, 1 when any failed (its record carries the rc, stdout and
  stderr), 5 with --fail-empty when nothing matched. JSON output is {"summary": {total, ran, ok,
  failed, skipped, seconds}, "results": [{path, cmd, rc, stdout, stderr, seconds, ok}]} (cmd/rc are
  the failing or last action's, stdout/stderr every action's output in order); --json-lines streams
  the records instead. --manifest + --resume make a long run restartable.

Options:
  --run CMD                     Shell action per file; repeatable, runs in order, stops at the first
                                failure. Substituted (shell-quoted): {path}, {name}, {stem}, {ext},
                                {dir}.  [required]
  --glob PATTERN                Only files whose name matches (e.g. '*.pdf').
  --type T1,T2                  Only these detected types (pdf, md, eml, code, …).
  --recursive / --no-recursive  Walk directories (hidden and .gitignored entries skipped).
                                [default: recursive]
  --jobs INTEGER RANGE          Files to process in parallel.  [default: 1; x>=1]
  --dry-run                     Print the rendered commands without running anything.
  --manifest FILE               Append one JSON record per file to this file.
  --resume                      Skip files whose last --manifest record succeeded with the same
                                --run set.
  --fail-fast                   Stop after the first failing file.
  --action-timeout SECS         Kill an action that runs longer than SECS (rc=124).  [default:
                                300.0; x>0]
  --fail-empty                  Exit 5 when no file matched.
  --json-lines                  Stream one JSON record per file as it completes, then a summary
                                line.
  --json                        Machine-readable JSON output.
  --help                        Show this message and exit.

carrel catalog

Usage: carrel catalog [OPTIONS] COMMAND [ARGS]...

  Export, import and check the desk catalog (tags, notes, meta in .carrel/carrel.db).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  export  Export every file's tags, notes and meta fields as JSON (files with at least one).
  import  Merge FILE (a `catalog export` document) into the desk under --root.
  status  Report the desk db: schema version, row counts, and stale index entries.

carrel catalog export

Usage: carrel catalog export [OPTIONS]

  Export every file's tags, notes and meta fields as JSON (files with at least one).

  Document: {"schema", "product", "version", "exported", "root", "files": [{"path": <root-relative>,
  "tags": [...sorted], "notes": [{"created", "body"}], "meta": [{"key", "value", "kind",
  "source"}]}]}, sorted by path — byte-identical across runs apart from "exported". Without -o the
  document itself is printed (always JSON); with -o a short summary is printed instead. Exit 4 when
  no desk db exists.

Options:
  -o, --out FILE  Write the catalog to FILE instead of stdout (refuses to overwrite without
                  --force).
  --force         Overwrite an existing --out file.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel catalog import

Usage: carrel catalog import [OPTIONS] FILE

  Merge FILE (a `catalog export` document) into the desk under --root.

  Tags already present are kept (INSERT OR IGNORE); notes are deduplicated on (file, created, body);
  meta fields take the document's value (counted only when it changed), so importing the same
  document twice adds nothing. Entries whose path does not exist under the root are counted in
  skipped_missing and not created. Exit 4 for unreadable/invalid JSON or a "schema" newer than this
  build supports. JSON output: {tags_added, notes_added, meta_set, files_touched, skipped_missing,
  tags_removed, notes_removed, meta_removed, skipped_outside}.

Options:
  --replace  Delete ALL existing tags, notes and fields first, then import (prints what was
             removed).
  --json     Machine-readable JSON output.
  --help     Show this message and exit.

carrel catalog status

Usage: carrel catalog status [OPTIONS]

  Report the desk db: schema version, row counts, and stale index entries.

  JSON: {schema_version, db_path, counts: {files, docs, tags, notes, meta}, stale: {changed,
  missing, unindexed}, examples: {changed, missing, unindexed} (up to 5 paths each)}. Always exit 0
  (it is a report); exit 4 when no .carrel/carrel.db exists under --root.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel color

Usage: carrel color [OPTIONS] COMMAND [ARGS]...

  Color tools: dominant palette, ICC profile conversion, WCAG contrast.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  check    WCAG contrast ratio of FG on BG (hex colors, e.g.
  convert  Convert SRC into an ICC profile and embed the profile in the output.
  palette  Dominant colors of SRC as hex + proportion (median-cut quantization).

carrel color check

Usage: carrel color check [OPTIONS] FG BG

  WCAG contrast ratio of FG on BG (hex colors, e.g. #333 #fafafa).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel color convert

Usage: carrel color convert [OPTIONS] SRC

  Convert SRC into an ICC profile and embed the profile in the output.

  CMYK targets are written as JPEG/TIFF (PNG cannot store CMYK).

Options:
  --to-profile P  Target ICC profile: .icc path or builtin alias (cmyk, gray, p3, srgb).  [required]
  -o, --out FILE  Output path [default: <SRC>.<profile>.png/.jpg].
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel color palette

Usage: carrel color palette [OPTIONS] SRC

  Dominant colors of SRC as hex + proportion (median-cut quantization).

  Human mode shows rich color swatches; --json prints one JSON array of {"hex", "proportion"} sorted
  by coverage.

Options:
  --n INTEGER RANGE  Number of colors to extract.  [default: 8; 1<=x<=256]
  --json             Machine-readable JSON output.
  --help             Show this message and exit.

carrel completion

Usage: carrel completion [OPTIONS] {bash|zsh|fish}

  Print a completion script for SHELL (bash, zsh, or fish).

    eval "$(carrel completion bash)"      # ~/.bashrc
    eval "$(carrel completion zsh)"       # ~/.zshrc, after compinit
    carrel completion fish > ~/.config/fish/completions/carrel.fish

  The script is produced in-process by click; an unknown shell exits 2. With --json, emits {"shell":
  ..., "script": ...}.

Options:
  --install-hint  Append, as a comment block, how to enable the script in that shell.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel convert

Usage: carrel convert [OPTIONS] SRC...

  Convert SRC... to another supported type.

  By default the output lands next to each SRC with the new extension. Existing outputs are never
  overwritten without --force. With --json, prints one JSON array of {"src", "dest", "via", "ok"}
  records.

  Office and ebook sources (docx, odt, epub, rtf) are read by pandoc and can go to md/html/txt/pdf
  (pdf also needs weasyprint); md/html/txt can be written as docx or odt, and docx <-> epub round-
  trips. xlsx reads need the `office` extra (openpyxl) and go to csv or json only. Email (eml) goes
  to md/txt/html/pdf and a mailbox (mbox) to md/txt, with no external binary (pdf needs weasyprint).
  eml → html keeps the message's own HTML; eml → pdf renders its text instead, so a conversion never
  fetches remote content the sender referenced.

Options:
  --to EXT             Target type: pdf, md, txt, html, json, xml, csv, png, jpg, ico, docx, odt,
                       epub.  [required]
  -o, --output FILE    Explicit output path (single SRC only).
  --out-dir DIRECTORY  Write outputs into this directory (required for multiple SRC).
  --force              Overwrite existing outputs.
  --pages [first|all]  pdf → png/jpg only: rasterize the first page, or every page as DEST-1..N.
                       [default: first]
  --sheet NAME|N|all   xlsx → csv/json only: pick a sheet by name or 1-based number (default: first;
                       json defaults to every sheet). 'all' with csv writes DEST-<sheet>.csv per
                       sheet.
  --json               Machine-readable JSON output.
  --help               Show this message and exit.

  Supported conversions (SRC type → --to targets):
    csv   → html, json, md
    docx  → epub, html, md, pdf, txt
    eml   → html, md, pdf, txt
    epub  → docx, html, md, pdf, txt
    html  → docx, md, odt, pdf, txt
    ico   → jpg, pdf, png
    jpg   → ico, pdf, png
    json  → csv, html, xml
    mbox  → md, txt
    md    → docx, html, odt, pdf, txt
    odt   → html, md, pdf, txt
    pdf   → html, jpg, md, png, txt
    png   → ico, jpg, pdf
    rtf   → html, md, pdf, txt
    txt   → docx, html, md, odt, pdf
    xlsx  → csv, json
    xml   → json

carrel dedupe

Usage: carrel dedupe [OPTIONS] DIRS...

  Report duplicate files under DIRS (recursively; hidden entries skipped).

  Default is report-only. Deletion needs BOTH --delete newest|oldest AND --apply; without --apply
  the deletions are only planned. The kept member of each group is never deleted. JSON output is a
  list of {hash, files, kept, deleted}.

Options:
  --near                    Perceptual matching for images (64-bit dHash, Hamming distance <= 8)
                            instead of exact content hashing. Non-image files are ignored in this
                            mode.
  --delete [newest|oldest]  Which duplicates to delete per group (by mtime); the other end of the
                            range is kept. Requires --apply to actually remove files.
  --apply                   Actually delete (only together with --delete).
  --json                    Machine-readable JSON output.
  --help                    Show this message and exit.

carrel desk

Usage: carrel desk [OPTIONS] [ROOT]

  Open the interactive desk TUI on ROOT (default: --root, then cwd).

  Three panes: a directory tree of supported files, an inspector (metadata, text preview,
  tags/notes), and an actions list (convert / OCR / thumbnail / pack / index / tag / note). Action
  outputs land in ROOT/carrel-out/. Keys: q quit, / search, t tag, n note.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel diff

Usage: carrel diff [OPTIONS] A B

  Compare two files A and B.

  Modes: text (unified diff), struct (json: dotted-path added/removed/changed; csv: per-row/column
  cell changes; xml: element-path changes), pdf (extracted text diff + page counts), image (Pillow
  pixel diff: dimensions, changed-pixel percentage, mean channel delta; sizes are padded to a common
  canvas and the mismatch reported). auto picks by type pair and falls back to a text diff when both
  files are text-like.

  Exit status:
    0  files are identical
    1  files differ
    2  bad usage
    3  missing optional dependency (pdf mode needs pdftotext)
    4  missing/unsupported input, or no mode fits the type pair

Options:
  --json                          Machine-readable JSON output.
  --mode [auto|text|struct|image|pdf]
                                  Comparison strategy; auto picks by type pair.  [default: auto]
  --out FILE                      Image mode: write a per-pixel delta heatmap PNG here.
  --help                          Show this message and exit.

carrel doctor

Usage: carrel doctor [OPTIONS]

  Report environment health: adapters found, versions, per-command capability.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel edit

Usage: carrel edit [OPTIONS] COMMAND [ARGS]...

  Edit files in place-adjacent, non-destructive ways (pdf/image/text/json).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  image  Resize, rotate, crop, re-encode or strip metadata from an image.
  json   Set or delete values in a JSON file by dotted path (a.b.0.c).
  pdf    Merge, split, extract pages, rotate, linearize or decrypt a PDF.
  text   Find & replace in a text file (txt/md/html/csv/xml/json-as-text).

carrel edit image

Usage: carrel edit image [OPTIONS] SRC

  Resize, rotate, crop, re-encode or strip metadata from an image.

  Operation order: crop → resize → rotate.

Options:
  --resize WxH|N%          Resize to WxH or by percent.
  --rotate DEG             Rotate clockwise by DEG degrees (canvas expands).
  --crop X,Y,W,H           Crop box: left,top,width,height.
  --strip                  Drop EXIF/metadata from the output.
  --quality INTEGER RANGE  JPEG/WebP quality (1-100).  [1<=x<=100]
  -o, --out PATH           Output file. Default: SRC.edited.<ext>.
  --force                  Allow overwriting existing files.
  --json                   Machine-readable JSON output.
  --help                   Show this message and exit.

carrel edit json

Usage: carrel edit json [OPTIONS] SRC

  Set or delete values in a JSON file by dotted path (a.b.0.c).

Options:
  --set PATH=VALUE  Set dotted PATH to VALUE (parsed as JSON, string fallback). Repeatable.
  --del PATH        Delete dotted PATH. Repeatable; applied after --set.
  -o, --out PATH    Output file. Default: SRC.edited.json.
  --force           Allow overwriting existing files.
  --json            Machine-readable JSON output.
  --help            Show this message and exit.

carrel edit pdf

Usage: carrel edit pdf [OPTIONS] SRC

  Merge, split, extract pages, rotate, linearize or decrypt a PDF.

  Pipeline: decrypt → merge → --pages selection → rotate → write (--split writes one file per page)
  → linearize. --pages extracts: the output contains only the selected pages, so --rotate applies to
  that selection.

Options:
  --merge PATH    Append these PDFs after SRC (repeatable, in order).
  --split         Write one PDF per page into OUT (a directory).
  --pages SPEC    Keep only these pages, e.g. '1-3,7' (1-based).
  --rotate DEG    Rotate output pages clockwise (multiple of 90).
  --linearize     Linearize output for fast web view (qpdf).
  --decrypt PW    Decrypt SRC with password (qpdf).
  -o, --out PATH  Output file (or directory with --split). Default: SRC.edited.pdf / SRC-pages/.
  --force         Allow overwriting existing files.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel edit text

Usage: carrel edit text [OPTIONS] SRC

  Find & replace in a text file (txt/md/html/csv/xml/json-as-text).

  Requires -o OUT or an explicit -i/--in-place — never silently rewrites SRC.

Options:
  --find PAT      Text (or regex) to find.  [required]
  --replace REP   Replacement text (may be empty).  [required]
  --regex         Treat PAT as a Python regular expression.
  -i, --in-place  Rewrite SRC itself.
  -o, --out PATH  Output file.
  --force         Allow overwriting an existing output file.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel extract-images

Usage: carrel extract-images [OPTIONS] SRC

  Extract images embedded in / referenced by SRC (pdf, ico, html).

  pdf uses pdfimages, ico uses icotool (or a Pillow fallback), html copies local <img src> files
  that exist next to the document — remote URLs are never fetched. With --json, prints one JSON
  object {"src", "out_dir", "count", "extracted"}.

Options:
  --out-dir DIRECTORY       Output directory [default: <SRC>-images next to the source].
  --min-size INTEGER RANGE  pdf mode: discard images smaller than this on either edge.  [default:
                            32; x>=1]
  --json                    Machine-readable JSON output.
  --help                    Show this message and exit.

carrel fields

Usage: carrel fields [OPTIONS] PATHS...

  Extract vendor, invoice number, dates and totals from PATH... (invoices, receipts, statements).

  Directories are walked like `refs`. Fields: vendor, invoice_no, po, date, due, subtotal, tax,
  total, currency, iban, account_last4 — each with a confidence (high: after its label; medium:
  heuristic; low: fallback) and the evidence line. Amounts are plain decimals, dates ISO. JSON
  output is a list of {path, profile, fields: {name: {value, confidence, evidence}}}.

Options:
  --profile [auto|invoice|receipt|statement]
                                  Document kind; auto picks by keywords.  [default: auto]
  --date-order [mdy|dmy]          How to read an ambiguous slashed date such as 03/04/2026.
                                  [default: mdy]
  --ocr                           OCR images and scanned PDFs (needs tesseract / ocrmypdf).
  --set FIELD=VALUE               Override an extracted field (repeatable).
  --save                          Write the fields into the desk db under --root (source: fields).
  --fail-empty                    Exit 5 when no file yielded any field.
  --json                          Machine-readable JSON output.
  --help                          Show this message and exit.

carrel form

Usage: carrel form [OPTIONS] COMMAND [ARGS]...

  Build HTML forms from JSON specs; list and fill PDF AcroForms.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  build   Render a JSON form spec into clean, standalone, print-friendly HTML.
  fields  List a PDF's AcroForm fields (name, type, current value).
  fill    Fill a PDF's AcroForm fields from a JSON object {field: value}.

carrel form build

Usage: carrel form build [OPTIONS] SPEC.JSON

  Render a JSON form spec into clean, standalone, print-friendly HTML.

Options:
  -o, --out PATH  Output HTML file. Default: SPEC stem + .html.
  --pdf           Also render the HTML to PDF (weasyprint).
  --force         Allow overwriting existing output files.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel form fields

Usage: carrel form fields [OPTIONS] SRC

  List a PDF's AcroForm fields (name, type, current value).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel form fill

Usage: carrel form fill [OPTIONS] SRC DATA.JSON

  Fill a PDF's AcroForm fields from a JSON object {field: value}.

Options:
  -o, --out PATH  Output PDF.  [required]
  --force         Allow overwriting an existing output file.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel index

Usage: carrel index [OPTIONS] [PATHS]...

  Index PATH... (default: the desk root) into .carrel/carrel.db.

  Walks directories for the supported file types plus plain-text source and config files (.py, .rs,
  .toml, .yaml, ... — indexed as type `code`, use --no-source to skip them), honoring .gitignore and
  skipping hidden entries (.carrel, .git, dotfiles). Files unchanged since the last run (same size +
  mtime) are skipped. Text comes from core.textextract; images are registered but only get
  searchable text with --ocr. Progress goes to stderr; the JSON summary is {"indexed", "skipped",
  "pruned", "errors"}. `--status` prints the `carrel catalog status` report instead.

Options:
  --ocr           OCR images and scanned PDFs (needs tesseract / ocrmypdf).
  --prune         Remove index rows whose files no longer exist on disk.
  --update        Treat PATH... as individual files to (re)index — no directory walking; unsupported
                  or missing files are silently skipped.
  --if-indexed    Exit 0 silently when no desk db exists yet under --root (for hooks: only refresh
                  an index someone already created).
  --no-source     Skip plain-text source and config files (.py, .rs, .toml, .yaml, ...); index only
                  the document types.
  --no-gitignore  Do not honor .gitignore files while walking.
  --status        Report index health instead of indexing (alias of `carrel catalog status`); other
                  options are ignored. Exit 4 when no desk db exists under --root.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel inspect

Usage: carrel inspect [OPTIONS] PATH

  Show metadata for one file.

  Always: name, size, mtime, detected type, sha256 (files under 512 MB) and a mime guess. Plus per-
  type detail: pdf (pages, title/author/producer, encryption, form fields, annotations), images
  (dimensions, mode, EXIF summary), json (shape, key count, depth), csv (dialect, columns, rows),
  xml (root tag, element count, depth), html (title, headings outline, link/img counts), md
  (headings outline, word count), txt (lines/words/chars), docx (paragraphs, words,
  title/author/created), epub (title, creator, language, spine items, words), odt/rtf (words), xlsx
  (sheets with row/column counts; needs the `office` extra), eml (from/to/cc, date, subject, message
  id, in-reply-to, parts, attachments), mbox (message count, first/last date, top senders). Word
  counts for office/ebook files use pandoc and are null without it.

Options:
  --json  Machine-readable JSON output.
  --deep  Add exiftool's full tag table when exiftool is installed; without it the output notes 'not
          installed' (never an error).
  --help  Show this message and exit.

carrel intake

Usage: carrel intake [OPTIONS] INBOX

  File everything waiting in INBOX into --to, named after what the documents say.

  Per file: read its fields (vendor, invoice number, dates, totals), find its reference numbers,
  build a name from the --template, move it into --to/YYYY/MM (or FY<year>/Q<n> with --by period),
  then re-index it, save the fields as desk metadata and tag it with every reference — all against
  the desk under the global --root (default: --to).

  Scanned PDFs are OCRed into a searchable copy which becomes the filed document; the untouched
  original moves to --to/_originals. Nothing is overwritten (colliding names get -1, -2, … suffixes)
  and nothing is deleted. JSON: [{src, dest, action: plan|filed|skip|error, fields, refs, tags, ocr,
  reason}]. Exit 3 when a missing optional binary is the reason nothing could be read at all, 1 when
  some files errored during --apply, 5 with --fail-empty when there was nothing to file.

  --apply refuses (exit 2) when INBOX or --to holds files git is tracking, where a new path breaks
  imports, tests and history; --allow-tracked overrides. The refusal happens before anything is
  created or moved, and an untracked inbox inside a repository (the usual ~/Downloads-under-dotfiles
  case) is fine.

Options:
  --to DIRECTORY          Where filed documents land (created if missing).  [required]
  --apply / --dry-run     Perform the intake. Default is a dry-run that only prints the plan.
  --watch                 Keep watching INBOX and file what arrives (implies --apply; refuses --dry-
                          run).
  --once                  With --watch: stop after the first batch.
  --timeout SECS          With --watch: stop after SECS.  [x>0]
  --glob PATTERN          Only take files whose name matches (e.g. '*.pdf').
  --recursive             Take files from subdirectories of INBOX too.
  --stable SECS           With --watch: wait until a file's size and mtime hold still for SECS.
                          [default: 2.0; x>0]
  --template TEXT         Name template (see `carrel rename --help` for the placeholders).
                          [default: {date}_{vendor}_{ref}{ext}]
  --by [ym|period|flat]   Folder layout under --to: ym = YYYY/MM, period = FY<year>/Q<n>, flat = no
                          subfolders.  [default: ym]
  --fiscal-start MM       With --by period: the month the fiscal year starts in.  [default: 1;
                          1<=x<=12]
  --date-order [mdy|dmy]  How to read an ambiguous slashed date in the document.  [default: mdy]
  --ocr / --no-ocr        Force or forbid OCR of scanned PDFs. Default: OCR them when ocrmypdf is
                          installed.
  --refs / --no-refs      Find reference numbers and tag the filed file with them.  [default: refs]
  --index / --no-index    Re-index the filed file in the desk under --root.  [default: index]
  --tag TAG               Extra tag for every filed file (repeatable).
  --fallback TEXT         Use TEXT for a name placeholder that has no value instead of skipping the
                          file.
  --fail-empty            Exit 5 when no file was filed (or planned).
  --allow-tracked         File even when INBOX or --to holds files git tracks (see the description).
  --force                 Deprecated spelling of --allow-tracked; warns when it bypasses the guard.
  --json                  Machine-readable JSON output.
  --help                  Show this message and exit.

carrel mail

Usage: carrel mail [OPTIONS] COMMAND [ARGS]...

  Attachments, mailbox splitting, threads and Outlook exports for eml/mbox files.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  attachments  Save every attachment of FILES (eml or mbox) into --out-dir.
  pst          Convert an Outlook SRC (.pst/.ost) into eml or mbox files via readpst.
  split        Split BOX (an mbox) into one .eml file per message under --out-dir.
  threads      Group the messages in PATHS (eml/mbox files or directories) into threads.

carrel mail attachments

Usage: carrel mail attachments [OPTIONS] FILES...

  Save every attachment of FILES (eml or mbox) into --out-dir.

  File names are sanitised (no separators, no leading dots); collisions get -1, -2, … suffixes
  unless --force. JSON: one record per message with the written paths, sizes and sha256 digests.

Options:
  --out-dir DIRECTORY  Directory to write attachments into (created if missing).  [required]
  --force              Overwrite same-named files instead of suffixing -1, -2, …
  --fail-empty         Exit 5 when no attachment was found.
  --json               Machine-readable JSON output.
  --help               Show this message and exit.

carrel mail pst

Usage: carrel mail pst [OPTIONS] SRC

  Convert an Outlook SRC (.pst/.ost) into eml or mbox files via readpst.

  `--format eml` writes one .eml per message (readpst -e); `--format mbox` writes one `mbox` file
  per mail folder (readpst -r), which `carrel mail split` can then take apart.

  Needs readpst; exit 3 with this platform's install hint otherwise. JSON: {src, out_dir, format,
  files, via}.

Options:
  --out-dir DIRECTORY  Directory readpst writes into (one subfolder per mail folder).  [required]
  --format [eml|mbox]  One .eml per message (readpst -e), or one mbox file per mail folder (readpst
                       -r).  [default: eml]
  --json               Machine-readable JSON output.
  --help               Show this message and exit.

carrel mail split

Usage: carrel mail split [OPTIONS] BOX

  Split BOX (an mbox) into one .eml file per message under --out-dir.

  Names come from --template; messages are numbered in mailbox order and the bytes are written as
  stored. Refuses to overwrite without --force. JSON: [{n, path, subject, date, message_id}].

Options:
  --out-dir DIRECTORY  Directory to write the .eml files into (created if missing).  [required]
  --template TEXT      File name template: {n} index, {date} YYYY-MM-DD, {subject} slug, {id}
                       message id.  [default: {n}_{date}_{subject}.eml]
  --force              Overwrite existing files.
  --json               Machine-readable JSON output.
  --help               Show this message and exit.

carrel mail threads

Usage: carrel mail threads [OPTIONS] PATHS...

  Group the messages in PATHS (eml/mbox files or directories) into threads.

  Threads follow Message-ID / In-Reply-To / References; `depth` is the reply-chain length when the
  parent is present. JSON: [{root_subject, first_date, messages: [{where, message_id, date, from,
  subject, depth}]}].

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel mcp

Usage: carrel mcp [OPTIONS]

  Serve the desk as an MCP server on stdio: 14 tools (search, pack, inspect, tag, note, index,
  convert, diff, redact, doctor, meta, fields, mail, refs) and carrel:// file/search resources.
  Every path a client names is confined to the desk root (--root, default the current directory).

Options:
  --allow-outside-root  Let clients read and write outside the desk root. Off by default: the server
                        refuses any path that resolves outside it.
  --json                Machine-readable JSON output.
  --help                Show this message and exit.

carrel meta

Usage: carrel meta [OPTIONS] COMMAND [ARGS]...

  Typed key/value fields on desk files (.carrel/carrel.db under --root).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  export  Export every file's fields as a table: one row per file, one column per key.
  find    List files whose fields satisfy every CONDITION (paths relative to the desk root).
  get     Print one field of PATH (its value alone in human mode; null when absent).
  ls      List PATH's fields with kind/source, or (without PATH) every key with its file count.
  rm      Remove KEY...
  set     Set KEY=VALUE...

carrel meta export

Usage: carrel meta export [OPTIONS]

  Export every file's fields as a table: one row per file, one column per key.

  Without -o the table goes to stdout as CSV (or as JSON rows with --json); with -o a summary is
  printed instead. Rows are sorted by path, columns by key (or as given with --key); a missing field
  is empty. Exit 4 when no desk db exists under --root.

Options:
  --key KEY       Only these columns, in this order (repeatable).
  -o, --out FILE  Write to FILE (.json → JSON rows, anything else → CSV) instead of stdout.
  --force         Overwrite an existing --out file.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel meta find

Usage: carrel meta find [OPTIONS] CONDITION...

  List files whose fields satisfy every CONDITION (paths relative to the desk root).

  A condition is KEY OP VALUE with OP one of = != > >= < <= ~ (contains), or KEY? (has the field):
  `vendor=acme`, `total>1000`, `due<2026-11` (ISO dates compare chronologically, so a year-month
  prefix works), `invoice_no~2026`, `paid?`. Numbers compare numerically, text case-insensitively.
  JSON: [{path, meta: {key: value}}].

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel meta get

Usage: carrel meta get [OPTIONS] PATH KEY

  Print one field of PATH (its value alone in human mode; null when absent).

Options:
  --fail-empty  Exit 5 when PATH has no such field.
  --json        Machine-readable JSON output.
  --help        Show this message and exit.

carrel meta ls

Usage: carrel meta ls [OPTIONS] [PATH]

  List PATH's fields with kind/source, or (without PATH) every key with its file count.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel meta rm

Usage: carrel meta rm [OPTIONS] PATH KEYS...

  Remove KEY... from PATH (unknown keys/files are a quiet no-op).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel meta set

Usage: carrel meta set [OPTIONS] PATH KEY=VALUE...

  Set KEY=VALUE... on PATH (registers the file in the desk db if needed).

Options:
  --kind [str|num|date|bool]  Force the kind of every field in this call (default: inferred —
                              true/false → bool, 1234.5 → num, an ISO YYYY-MM-DD date → date, else
                              str; digits with a leading zero such as 02134 stay str).
  --source TEXT               Who is writing the field (automation should pass its own name).
                              [default: user]
  --json                      Machine-readable JSON output.
  --help                      Show this message and exit.

carrel note

Usage: carrel note [OPTIONS] COMMAND [ARGS]...

  Attach notes to files (desk db) and annotations to PDFs (pypdf).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  add      Attach TEXT as a sidecar note to PATH (stored in the desk db).
  ls       List PATH's sidecar notes, newest first (ISO timestamps).
  pdf      List PATH's PDF annotations: page, subtype, contents.
  pdf-add  Add TEXT as a FreeText annotation to a PDF page.

carrel note add

Usage: carrel note add [OPTIONS] PATH TEXT

  Attach TEXT as a sidecar note to PATH (stored in the desk db).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel note ls

Usage: carrel note ls [OPTIONS] PATH

  List PATH's sidecar notes, newest first (ISO timestamps).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel note pdf

Usage: carrel note pdf [OPTIONS] PATH

  List PATH's PDF annotations: page, subtype, contents.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel note pdf-add

Usage: carrel note pdf-add [OPTIONS] PATH TEXT

  Add TEXT as a FreeText annotation to a PDF page.

  The result is verified by reading the output back with pypdf and checking the annotation is listed
  (same reader the `pdf` subcommand uses).

Options:
  --page INTEGER  1-based page to annotate.  [default: 1]
  --pos X,Y       Lower-left corner of the note box in PDF points.  [default: 72,72]
  -o, --out FILE  Output PDF (default: PATH with an .annotated.pdf suffix; pass PATH itself to
                  annotate in place).
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel ocr

Usage: carrel ocr [OPTIONS] SRC

  OCR an image or PDF into text (txt/md) or a searchable PDF.

  Images (jpg/png) run through tesseract; PDFs through ocrmypdf, which passes born-digital pages
  through untouched unless --redo is given.

Options:
  -o, --out PATH     Output file. Default: SRC with the target extension (SRC.ocr.pdf for pdf →
                     pdf).
  --lang LANG        OCR language(s), tesseract codes, e.g. eng or eng+deu.  [default: eng]
  --to [txt|pdf|md]  Output: extracted text (txt/md) or a searchable PDF.  [default: txt]
  --redo             Re-OCR PDF pages even if they already have text (ocrmypdf --force-ocr; default
                     skips them).
  --force            Allow overwriting an existing output file.
  --json             Machine-readable JSON output.
  --help             Show this message and exit.

carrel organize

Usage: carrel organize [OPTIONS] DIRECTORY

  Plan (default) or perform (--apply) sorting DIRECTORY's files.

  Only files directly inside DIRECTORY are considered; subdirectories and hidden files stay put.
  Existing files are never overwritten — colliding names get a -1, -2, … suffix. JSON output is a
  list of {src, dest, action} ('move' planned, 'moved' executed, 'skip').

  --apply refuses (exit 2) when it would move files git is tracking, where a new path breaks
  imports, tests and history; --allow-tracked overrides. Untracked files inside a repository are
  fine.

Options:
  --by [type|date|exif-date]  Grouping: 'type' -> pdf/, images/ (jpg, png, ico), data/ (json, xml,
                              csv), docs/ (md, txt, html), mail/ (eml, mbox); 'date' -> YYYY/MM from
                              mtime; 'exif-date' -> YYYY/MM from EXIF DateTimeOriginal, mtime
                              fallback (images only; other files are skipped).  [default: type]
  --into CATEGORY=DIR         Override a type category's destination subdir, e.g. --into images=pics
                              (only with --by type; repeatable).
  --apply / --dry-run         Execute the moves. Default is a dry-run that only prints the plan.
  --allow-tracked             Move files even when they are tracked by git (see the description).
  --force                     Deprecated spelling of --allow-tracked; warns when it bypasses the
                              guard.
  --json                      Machine-readable JSON output.
  --help                      Show this message and exit.

carrel pack

Usage: carrel pack [OPTIONS] PATHS...

  Bundle PATH... (files or directories) into one LLM-ready context document.

  Formats: md (default: header + fenced tree + per-file fenced sections, fences lengthened on
  collision), xml (<context><tree/><file/></context> with CDATA, Claude-friendly), json ({meta,
  tree, files}). Token counts are ceil(chars / 3.6) labeled tokens_est by default; --tokenizer exact
  counts with tiktoken (o200k_base) and labels the field tokens.

  Selection: --query ranks files through the desk index under --root (build it with the `index`
  command) and emits hits in relevance order; --since REF / --changed narrow to what git reports as
  changed (deleted files are listed in the header as removed; --since REF compares REF with the
  working tree). --query combines with either git selector and with the usual --include/--exclude
  filters (intersection); --since and --changed exclude each other.

  .gitignore handling is a deliberately simple per-directory matcher: plain names and `*` globs
  match anywhere below their .gitignore; a trailing `/` restricts a pattern to directories; patterns
  containing `/` match relative to their .gitignore's directory; `!pattern` re-includes, with git's
  ordering rule (last matching line wins) — the negation is honored. `.git` and `.carrel` are always
  skipped. Binaries outside the supported set are listed in the tree as [skipped: binary] with their
  size, never inlined; images are only read (OCR) with --ocr.

Options:
  -o, --output FILE               Write here instead of stdout (with --chunk: OUT.part1..N).
  --format [md|xml|json]          Output format.  [default: md]
  --include GLOB                  Only pack files matching GLOB (repeatable).
  --exclude GLOB                  Drop files/dirs matching GLOB (repeatable).
  --no-gitignore                  Do not honor .gitignore files.
  --max-bytes N                   Stop adding file contents once N total bytes are packed; omissions
                                  are noted in the header.
  --max-file-bytes N              Skip any single file larger than N bytes.
  --chunk TOKENS                  Split into OUT.part1..N, each at most TOKENS tokens under the
                                  active --tokenizer (requires -o). Files are never split mid-file
                                  unless one alone exceeds the budget; then it is split on line
                                  boundaries with (continued) markers.
  --tree-only                     Emit header + tree only, no contents.
  --ocr                           OCR images and scanned PDFs (needs tesseract / ocrmypdf).
  --stats                         Print a per-file token table instead of the pack (the pack is
                                  still written when -o is given).
  --query TEXT                    Pack only files the desk index under --root ranks for TEXT (FTS5
                                  syntax), in relevance order. Requires a prior `index` run.
  --top N                         With --query: consider at most the N best-ranked hits.  [default:
                                  20]
  --since REF                     Pack only files changed since git REF (`git diff --name-only
                                  REF`); deleted files are listed as removed, not packed.
  --changed                       Pack only uncommitted changes: files differing from HEAD plus
                                  untracked files (not --since).
  --dedupe-content                Inline identical file contents once; later copies are tree-listed
                                  as [same as <first path>].
  --tokenizer [heuristic|exact]   Token counting: heuristic = ceil(chars/3.6) labeled tokens_est;
                                  exact = tiktoken o200k_base labeled tokens (needs the
                                  'carrel[tokens]' extra).  [default: heuristic]
  --outline                       Structure instead of contents (tree-only cost): .py top-level
                                  def/class names with line numbers, .md headings; other types show
                                  size only. Not with --chunk.
  --fail-empty / --no-fail-empty  Exit 5 when no file is packed (e.g. --query without hits, --since
                                  with no changes). Default: on under --json, off otherwise — an
                                  agent that packs nothing should not get a valid-looking empty
                                  document back. --no-fail-empty restores exit 0.
  --json                          Machine-readable JSON output.
  --help                          Show this message and exit.

carrel proof

Usage: carrel proof [OPTIONS] SRC

  Soft-proof SRC against an ICC PROFILE (simulate print/display output).

  Writes the proofed image and reports the color shift: mean/max per-channel delta and the share of
  pixels that moved visibly. With --json, prints the report as one JSON object.

Options:
  --profile PROFILE               Path to a .icc file, or builtin alias: cmyk, gray, p3, srgb.
                                  [required]
  --out FILE                      Proofed image path [default: <SRC>.proof.png].
  --intent [perceptual|relative]  Rendering intent.  [default: perceptual]
  --json                          Machine-readable JSON output.
  --help                          Show this message and exit.

carrel redact

Usage: carrel redact [OPTIONS] SRC

  Redact sensitive strings from a text file or PDF.

  Text files get regex replacement (JSON/XML are re-parsed afterwards so they stay valid). PDFs are
  truly redacted: pages are rasterized, matched words are painted over, and the output carries no
  text layer at all. Requires tesseract for PDFs.

Options:
  --pattern REGEX     Custom regex to redact (repeatable).
  --builtin LIST      Builtins to redact: email, phone, ssn, ipv4, cc, invoice, po, order, check,
                      account, tracking, ticket, iban, routing, ein, vat, isbn, gtin, doi, ups,
                      usps. Comma-separated, and repeatable like --pattern (label-driven kinds like
                      invoice keep the label and replace the value).
  --replacement TEXT  Replacement text for matches (text files only).  [default: █]
  -o, --out PATH      Output file. Default: SRC.redacted.<ext>.
  --fail-empty        Exit 5 when nothing matched.
  --force             Allow overwriting an existing output file.
  --json              Machine-readable JSON output.
  --help              Show this message and exit.

carrel refs

Usage: carrel refs [OPTIONS] PATHS...

  Find reference numbers (invoice, PO, IBAN, routing, tracking, …) in PATH...

  Directories are walked like `index` (hidden and .gitignored entries skipped; images only with
  --ocr). Every supported file type works; the text comes from the same spine `pack` and `index`
  use. Values with a check digit (iban, routing, isbn, gtin, cc) are reported only when it verifies.
  JSON output is a list of {path, refs: [{kind, value, count, valid, pages, lines}]} — or, with
  --link, [{kind, value, files, count}]. Kinds are shared with `redact --builtin`.

Options:
  --kind K1,K2          Only these kinds, comma-separated. Default: every reference and identifier
                        kind (invoice, po, order, check, account, tracking, ticket, iban, routing,
                        ein, vat, isbn, gtin, doi, ups, usps); PII kinds (email, phone, ssn, ipv4,
                        cc) only when named.
  --pattern NAME=REGEX  Extra kind to look for (repeatable). A (?P<v1>…) group is the value;
                        otherwise the whole match is.
  --tag                 Tag each file in the desk db under --root with ref:<kind>:<value>.
  --link                Group by reference instead of by file: which files share each value.
  --all                 With --link, also list values seen once.
  --ocr                 OCR images and scanned PDFs (needs tesseract / ocrmypdf).
  --fail-empty          Exit 5 when no reference was found.
  --json                Machine-readable JSON output.
  --help                Show this message and exit.

carrel rename

Usage: carrel rename [OPTIONS] PATHS...

  Plan (default) or perform (--apply) renaming PATH... from the documents' own fields.

  Placeholders: {date} (or {date:%Y-%m}), {yyyy}, {mm}, {vendor}, {ref}, {total}, {fields.NAME},
  {meta.KEY}, {type}, {stem}, {name}, {ext}, {sha8}. Dates come from the document (then the desk,
  then mtime); {ref} is the invoice number or the first reference found. Values are slugified; a
  file with an unresolved placeholder is skipped unless --fallback is given. Renames happen next to
  the source (a literal / in the template files into subfolders), never overwrite (-1, -2, …
  suffixes), and carry the desk row under --root along. JSON: [{src, dest, action:
  rename|renamed|skip, reason, sources}].

  --apply refuses (exit 2) when a PATH would rename a file git is tracking, where a new name breaks
  imports, tests and history. Untracked files inside a repository are fine; --allow-tracked
  overrides.

Options:
  --template TEXT          Name template; see the placeholders in the command description.
                           [default: {date}_{vendor}_{ref}{ext}]
  --apply / --dry-run      Execute the renames. Default is a dry-run that only prints the plan.
  --date-order [mdy|dmy]   How to read an ambiguous slashed date in the document.  [default: mdy]
  --fallback TEXT          Use TEXT for a placeholder that has no value instead of skipping the
                           file.
  --lower                  Lower-case the rendered name.
  --max-len INTEGER RANGE  Cap the stem length.  [default: 120; x>=8]
  --ocr                    OCR images and scanned PDFs to read their fields (needs tesseract /
                           ocrmypdf).
  --allow-tracked          Rename even when a PATH is a file git tracks (see the description).
  --force                  Deprecated spelling of --allow-tracked; warns when it bypasses the guard.
  --json                   Machine-readable JSON output.
  --help                   Show this message and exit.
Usage: carrel search [OPTIONS] QUERY

  Full-text search the desk index for QUERY (FTS5 syntax, bm25-ranked).

  Matched terms are bracketed in the snippet. Filters combine with AND. JSON output is a list of
  {"path", "score", "snippet"} (lower bm25 score = better match). Run the `index` command first to
  build the index under --root.

Options:
  --limit INTEGER   Maximum number of hits.  [default: 20]
  --type T1,T2      Only these file types, comma-separated (e.g. pdf,md).
  --tag TAG         Only files carrying TAG (repeatable — every TAG must match).
  --meta CONDITION  Only files whose fields satisfy CONDITION, e.g. vendor=acme, total>1000,
                    due<2026-11, paid? (repeatable — every one must hold; see `meta find`).
  --fail-empty      Exit 5 when there are no hits.
  --json            Machine-readable JSON output.
  --help            Show this message and exit.

carrel sign

Usage: carrel sign [OPTIONS] COMMAND [ARGS]...

  Sign things: stamp PDFs, hash manifests, verify both.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  manifest  Write a sha256 manifest for PATHS (directories recurse).
  stamp     Stamp a visible signature block onto a PDF page.
  verify    Recompute a sha256 manifest (and its gpg signature, if present).

carrel sign manifest

Usage: carrel sign manifest [OPTIONS] PATHS...

  Write a sha256 manifest for PATHS (directories recurse).

Options:
  -o, --out PATH  Manifest file to write (sha256sum format).  [default: MANIFEST.sha256]
  --gpg           Also write a detached armored signature (OUT.asc).
  --key ID        gpg key id/email to sign with (implies --gpg).
  --force         Allow overwriting an existing manifest.
  --json          Machine-readable JSON output.
  --help          Show this message and exit.

carrel sign stamp

Usage: carrel sign stamp [OPTIONS] SRC

  Stamp a visible signature block onto a PDF page.

Options:
  --text TEXT                     Stamp text. Default: "Signed by <user> on <ISO date>".
  --image PATH                    Signature image (png/jpg) drawn above the text.
  --page PAGE                     Page to stamp: 'first', 'last' or a 1-based number.  [default:
                                  last]
  --pos [top-left|top-right|bottom-left|bottom-right]
                                  Page corner for the stamp.  [default: bottom-right]
  -o, --out PATH                  Output file. Default: SRC.signed.pdf.
  --force                         Allow overwriting an existing output file.
  --json                          Machine-readable JSON output.
  --help                          Show this message and exit.

carrel sign verify

Usage: carrel sign verify [OPTIONS] MANIFEST

  Recompute a sha256 manifest (and its gpg signature, if present).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel tag

Usage: carrel tag [OPTIONS] COMMAND [ARGS]...

  Tag files in the desk db (.carrel/carrel.db under --root).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

Commands:
  add   Add TAG...
  find  List files carrying ALL of TAG...
  ls    List tags of PATH, or (without PATH) every tag with its file count.
  rm    Remove TAG...

carrel tag add

Usage: carrel tag add [OPTIONS] PATH TAGS...

  Add TAG... to PATH (registers the file in the desk db if needed).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel tag find

Usage: carrel tag find [OPTIONS] TAGS...

  List files carrying ALL of TAG... (paths relative to the desk root).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel tag ls

Usage: carrel tag ls [OPTIONS] [PATH]

  List tags of PATH, or (without PATH) every tag with its file count.

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel tag rm

Usage: carrel tag rm [OPTIONS] PATH TAGS...

  Remove TAG... from PATH (unknown tags/files are a quiet no-op).

Options:
  --json  Machine-readable JSON output.
  --help  Show this message and exit.

carrel thumb

Usage: carrel thumb [OPTIONS] SRC...

  Create thumbnails for SRC... (pdf, png, jpg, ico, html).

  Thumbnails land in --out-dir as <name>.<format>, aspect preserved, never larger than --size on
  either edge. With --json, prints one JSON array of {"src", "thumb", "w", "h"} records.

Options:
  --size INTEGER RANGE  Maximum edge length in pixels.  [default: 256; x>=1]
  --out-dir DIRECTORY   Directory for the thumbnails.  [default: thumbs]
  --format [png|jpg]    Thumbnail image format.  [default: png]
  --json                Machine-readable JSON output.
  --help                Show this message and exit.

carrel watch

Usage: carrel watch [OPTIONS] DIRECTORY

  Watch DIRECTORY and run shell actions on file events.

  Events for files an action is currently producing are suppressed via an in-flight set plus an
  output-name heuristic (outputs whose name starts with the source file's stem); other action
  outputs written into the watched directory WILL re-trigger — write outputs elsewhere or use --glob
  to narrow matches. --stable waits for a file to stop growing, --existing processes what is already
  there, --poll works where inotify does not (/mnt/c, shares), --done-dir/--error-dir file sources
  away after their actions, --log keeps a JSON trail. Ctrl-C exits cleanly.

  --done-dir/--error-dir refuse to start (exit 2) when they would move files git is tracking;
  --allow-tracked overrides. Actions themselves are never guarded — what a --run command does is the
  user's business.

Options:
  --on EVENTS                     Comma-separated events to react to: created, modified, deleted,
                                  moved, existing.  [default: created,modified]
  --glob PATTERN                  Only react to file names matching this glob (e.g. '*.pdf').
  --run CMD                       Shell action to run per event; repeatable, runs in order. {path},
                                  {name}, {stem}, {ext}, {dir} are substituted (shell-quoted).
                                  [required]
  --recursive                     Watch subdirectories too.
  --existing                      Queue the files already in DIRECTORY at start (event 'existing').
  --stable SECS                   Act only once a file's size and mtime have not changed for SECS
                                  (scanners, big copies).  [x>0]
  --stable-timeout SECS           With --stable: give up waiting and act after SECS regardless.
                                  [x>0]
  --poll                          Poll instead of inotify (needed on /mnt/c, network shares, some
                                  containers).
  --poll-interval SECS            With --poll: how often to scan.  [default: 1.0; x>0]
  --done-dir DIRECTORY            Move each source here after its actions all succeed.
  --error-dir DIRECTORY           Move each source here after an action fails.
  --log FILE                      Append one JSON record per action (and per move) to FILE.
  --allow-tracked                 With --done-dir/--error-dir: move files even when git tracks them.
  --force                         Deprecated spelling of --allow-tracked; warns when it bypasses the
                                  guard.
  --print-service [systemd|schtasks]
                                  Print a service definition that runs this exact watch at login,
                                  then exit.
  --debounce MS                   Coalesce events per path within this window.  [default: 500; x>=0]
  --once                          Exit after the first triggered action batch.
  --timeout SECS                  Hard stop after SECS seconds.  [x>0]
  --action-timeout SECS           Kill an action that runs longer than SECS (logged as rc=124).
                                  [default: 300.0; x>0]
  --json-lines                    Log one JSON object per action to stdout instead of human lines
                                  (--json implies this).
  --json                          Machine-readable JSON output.
  --help                          Show this message and exit.

Exit codes

Code Name Meaning
0 OK success
1 ERROR general/unexpected error (message to stderr, no traceback unless --debug)
2 USAGE bad usage/arguments
3 MISSING_DEP missing optional dependency (message names the binary + install hint)
4 BAD_INPUT input file not found / unreadable / unsupported type
5 EMPTY operation produced no result (pack --json that packed nothing; elsewhere opt in with --fail-empty)

Note: carrel diff deliberately reuses 1 to mean "inputs differ" — its help text above spells out the full mapping.