Command Reference¶
Every operation on the library is a lit subcommand. This page documents each
one: its purpose, the shapes you call it in, and every flag it accepts. The
commands are grouped as lit --help groups them.
lit <cmd> --help is the always-current authority for any single command. This
page mirrors it but adds the cross-command context the inline help cannot.
Conventions¶
Each entry gives a one-line purpose, a synopsis of the common call shapes,
and a table of that command's own flags. Flags shared by most commands
(--library, --vault, -h) are documented once below and omitted from the
per-command tables.
Global flags. Commands that operate inside a vault accept:
| Flag | What it does |
|---|---|
--library <path> |
Use the vault at this filesystem path. |
--vault <name> |
Use the vault registered under this name. Mutually exclusive with --library. |
-h, --help |
Show that command's help and exit. |
The root command also takes lit --version, and lit help <cmd> prints the
same help as lit <cmd> --help.
A few commands do not take --library / --vault, because they create a
vault, target the registry, or touch no vault at all: init, setup,
install-completion, install-skill, uninstall, self-update, pdf-text,
help, and every lit vault subcommand.
Vault discovery chain. When a command needs a vault and you give no explicit
override, lit resolves one in this order (first hit wins):
--vault <name>flag--library <path>flag$LIT_LIBRARYenvironment variable- the active vault in the registry (set by
lit init/lit vault use) - cwd-walk: walk up from the current directory looking for a
lit-config.yaml
lit init registers and activates your vault, so step 4 normally covers you and
you set nothing. Steps 1–3 are explicit overrides for scripts, CI, or juggling
several vaults.
Registry location. The registry lives at $LITMAN_REGISTRY_DIR/vaults.yaml
when that variable is set (use it to put the registry in a cloud-synced
directory), otherwise the platform config dir: ~/.config/litman/ on
Linux / WSL, ~/Library/Application Support/litman/ on macOS,
%LOCALAPPDATA%\litman\litman\ on Windows.
When a folder has moved. Before any command runs, lit checks that every
registered vault directory and every project directory is still where it was
recorded. If one is not, you are asked about it — one folder at a time, each
with its own answer:
| Answer | What happens |
|---|---|
| the new path | The registration is re-pointed there, the same as lit vault set-path / lit project set-path. A vault path must hold a lit-config.yaml; a wrong path is refused and nothing changes. |
rm |
Hands you to lit vault remove / lit project rm, which show their own warning and ask y/N before anything goes. |
| Enter | Skip. Nothing changes and you are asked again next time. |
Enter never removes anything, so holding Enter through the questions is always safe. Off a terminal — a script, a CI job, an agent — nothing is asked: a warning names the folder and the command that fixes it, and the command you typed carries on.
1. Setup & vaults¶
lit setup¶
Interactive first-run wizard. Chains five optional steps behind simple prompts: (1) shell tab-completion, (2) pick your agent + install its skill, (3) create your first vault, (4) cloud sync, (5) desktop shortcut. The agent you pick becomes the machine-level default. Each step just runs the matching standalone command, so anything the wizard does you can also do or redo directly. TTY-only; for scripted onboarding call the individual commands.
No flags beyond -h.
lit init¶
Create a new vault under <parent_dir>/<name>/ with the standard skeleton
(papers/, codes/, the four views/by-* hubs, a seeded TAXONOMY.md, an
empty INDEX.json, and lit-config.yaml), then register it. The first vault you
create becomes active automatically. PARENT_DIR defaults to the current
directory.
| Flag | What it does |
|---|---|
--name <subdir> |
Vault subdirectory name to create. Default literature_vault. |
--register-as <name> |
Registry name for the new vault. Default: the --name value. |
--no-register |
Create the vault but skip registration (CI / scripts / throwaway). Point lit at it later via --library / $LIT_LIBRARY / lit vault add. |
lit vault¶
Manage the registry of vaults known to litman. Exactly one vault is active at a
time. Subcommands operate on the registry, not on a vault's contents, so they
take no --library / --vault.
lit vault add <name> <path> [--import-from "..."] [--use]
lit vault use <name>
lit vault list [--format json]
lit vault info <name>
lit vault set-path <name> <new-path>
lit vault remove <name> [-y]
| Subcommand | What it does |
|---|---|
add <name> <path> |
Register an existing vault directory (must already contain lit-config.yaml). Does not create a vault — use lit init for that. |
use <name> |
Switch the active vault. |
list |
Show every registered vault; the active one is marked ✓, with path, paper count, and provenance. --format json emits one object per vault. |
info <name> |
Show one vault's path, paper count, on-disk size, provenance, and active flag. |
set-path <name> <new-path> |
Re-point <name> at a vault you have moved. The new path must already hold a lit-config.yaml. The name, the active flag, and the provenance note are kept. |
remove <name> |
Unregister <name>. The directory itself is not deleted. |
lit vault add flags: --import-from <text> (free-form provenance note for a
vault received from elsewhere; auto-fills today's date), --import-at <date>
(override that date), --use (activate the new entry immediately).
lit vault remove takes -y / --yes to skip the confirmation.
lit install-completion¶
Install shell tab-completion for the current user. SHELL is optional and
auto-detected from $SHELL; supported shells are bash / zsh / fish. For
bash/zsh an eval line is appended to ~/.bashrc / ~/.zshrc; for fish a
self-sourcing snippet lands under ~/.config/fish/completions/. Idempotent via a
sentinel comment. Restart the shell (or source) to activate.
No flags beyond -h.
lit install-skill¶
Install the bundled agent skills (lit-library for the write side,
lit-reading for the read side). Both are optional — the CLI is fully usable
without them. Copies files only; does not install an agent or configure any
keys.
Skills go where the agent auto-discovers them: ~/.claude/skills for Claude
Code, the open-standard ~/.agents/skills for Cursor, Codex, and OpenCode, and
~/.gemini/antigravity-cli/skills for Antigravity CLI. With no flags the
command targets your default agent's directory; --agent targets another
agent's.
Safe to re-run after upgrading litman: skills that already match the bundled
content report "up to date", out-of-date ones are offered a refresh ([Y/n],
default yes; non-interactive runs need --force instead). A run without
--agent/--parent-dir also offers to refresh out-of-date litman skills it
finds in the other agents' directories, with the same per-copy [Y/n] /
--force rules. A skill directory that is a symlink is always left
untouched.
| Flag | What it does |
|---|---|
--skill <name> |
Install only this skill. Default: install all bundled skills. |
--agent <name> |
Install into this agent's skills directory (claude, agy, codex, cursor, opencode). Default: your default agent. Mutually exclusive with --parent-dir. |
--parent-dir <path> |
Install into this exact directory instead. Mutually exclusive with --agent. |
--force |
Overwrite files inside an existing target without asking. Files not part of the bundled skill are left in place. |
lit uninstall¶
Reverse of lit setup: remove the bundled skills (from every agent skills
directory litman knows), the desktop shortcut, the
shell-completion block, the vault registry (the list of vault names/paths), the
machine-level agent preferences, and the browser profile the lit gui --window
app window runs against (a sandboxed browser keeps that profile somewhere its
sandbox allows, so both locations are swept). It does not remove the lit CLI
itself — a
running command can't delete its own environment — so it prints the final
CLI-removal step (uv tool uninstall litman or pipx uninstall litman,
depending on how you installed it) for you to run. Your vault directories
(papers, PDFs, notes, annotations) are never touched; only the registry pointers
to them are dropped. Skill directories are removed file by file, so any file you
added next to SKILL.md is left in place.
| Flag | What it does |
|---|---|
--dry-run |
Show what would be removed; change nothing. |
-y / --yes |
Skip the confirmation prompt. |
2. Papers¶
lit add¶
Import a paper PDF into the vault. The metadata source is either --doi
(CrossRef fetch) or --from-llm-json (an LLM-prepared JSON file); exactly one is
required, and the CLI refuses both at once. Derives a canonical id
(<year>_<Family>_<Keyword>), refuses on duplicate DOI, and creates
papers/<id>/ with paper.pdf, metadata.yaml, an empty notes.md, and an
empty discussion.md.
The source PDF is moved, not copied: once the import succeeds, the file you
passed in is gone from where it was. Hand lit add a copy if you want to keep
the original in place. (Dragging a PDF into the Web UI is the one import that
copies — the browser hands over the bytes and never the path, so there is nothing
there to move.)
Two identity fields are guarded at import, because both reach the paper id and an
id outlives the mistake that made it. A first author or title given as a filler —
Unknown, N/A, untitled — is refused, with the value litman read and what to
write instead: for a work with no personal author, name the issuing body; for a
genuinely unattributed one, Anonymous. A title in a script that cannot produce
an ASCII keyword is refused the same way, and --id is how you get past it —
pass the handle yourself rather than let 关于化合物A的合成方法 reduce to
whichever Latin characters happened to sit inside it. None of this touches what
is stored: titles, authors and journals keep whatever script they were written
in, and only the id is ASCII.
lit add <pdf> --doi <doi>
lit add <pdf> --from-llm-json <path>
lit add <pdf> --doi <doi> --id <id>
lit add <pdf> --doi <doi> --auto-suffix
| Flag | What it does |
|---|---|
--doi <doi> |
Fetch metadata from CrossRef. Mutually exclusive with --from-llm-json. |
--from-llm-json <path> |
Read metadata from a JSON file, or - for stdin. Used by the lit-library skill. Mutually exclusive with --doi. |
--id <id> |
Override the auto-derived id, and the way past a title litman cannot turn into one. |
--auto-suffix |
On id collision, auto-append _b / _c without prompting. Required for non-interactive (non-TTY) batch use. |
lit add writes a complete metadata skeleton (all fields, defaults filled); see
3-concepts.md §1.1 for the schema.
lit list¶
List papers, optionally filtered. Filters are AND-combined across flags; within
one flag, comma-separated values are OR-combined. Multi-valued fields
(topics / methods / projects / data) match by list intersection;
--author / --title use case-insensitive substring; --year / --type /
--status / --priority match exact values.
lit list
lit list --year 2024 --status deep-read
lit list --status deep-read,skim --limit 5
lit list --unread --sort recent
lit list --topic transformer --format json
| Flag | What it does |
|---|---|
--year <v> |
Publication year. |
--type <v> |
Paper type (research / review / position / ...). |
--status <v> |
Status (deep-read / skim / inbox / dropped). |
--priority <v> |
Priority (A / B / C). |
--topic <v> |
Match papers whose topics list contains the value. |
--method <v> |
Match against the methods list. |
--project <v> |
Match against the projects list. |
--data <v> |
Match against the data list. |
--author <v> |
Case-insensitive substring against any author. |
--title <v> |
Case-insensitive substring against the title. |
--read-since <YYYY-MM-DD> |
Papers with read-date on or after the date. |
--added-since <YYYY-MM-DD> |
Papers with created-at on or after the date. |
--unread |
Only papers with an empty read-date. |
--sort [id\|recent] |
Order. id (default) ascending, matches INDEX.json. recent = most-recently-engaged first. |
--limit <N> |
Keep only the first N after filtering + sorting. |
--format [table\|json] |
Output format. json emits the same per-paper projection as INDEX.json. |
With --sort recent the table view shows the top 10 by default; raise it with
--limit, or use --format json for the full ranked list. The default sort
caps an interactive table too — a terminal shows the first 30 as
Papers (showing 30 of N) — while piped and --format json output are never
capped.
lit show¶
Print one paper's full metadata plus its PDF / notes paths. Accepts a full id, a
unique case-insensitive id substring, or --paper-doi. With no argument, shows
the paper you engaged with most recently — the one lit list --sort recent puts
at the top — and names it on stderr, so --format json still emits only JSON.
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. Mutually exclusive with the positional id. |
--format [table\|json] |
table (default) renders metadata + file paths; json emits the full metadata dict (every field, not the INDEX.json projection). |
lit search¶
Case-insensitive substring search over your notes.md / discussion.md only —
not the PDF full text, not trashed papers, not the views/ links, and not the
<!-- --> comments litman seeds into those two files. Each hit is one matched
line. Defaults to JSON output ({id, file, line, snippet}).
| Flag | What it does |
|---|---|
--in <notes,discussion> |
Which files to search (comma-separated). Default: both. |
--format [json\|table] |
json (default, agent-facing) or a human-readable table. |
--limit <N> |
Keep only the first N hits. Default: unbounded. |
lit related¶
Find papers related to <id>: author-asserted relation edges (related /
extends / extended-by / contradicts / contradicted-by) first, then papers
sharing topics / methods keys, ranked by shared-key count. Each neighbour
carries a via annotation. Defaults to JSON output.
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. |
--by [edges\|taxonomy] |
Narrow to one neighbour kind. Default: both, edges first. |
--min-shared <N> |
Minimum shared topics / methods keys for a taxonomy neighbour. Default 1. Does not affect edge neighbours. |
--limit <K> |
Top-K cap on the merged list. Default 20. |
--format [json\|table] |
json (default) or human-readable table. |
lit open¶
Open a paper's PDF in the configured viewer (or the platform default). Accepts a
full id, a unique substring, or --paper-doi. Multiple substring matches print
the candidate list and exit. With no argument, opens the paper you engaged with
most recently — the one lit list --sort recent puts at the top.
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. |
The viewer comes from default_pdf_viewer in lit-config.yaml; null falls
back to the platform opener. See 3-concepts.md §1.4.
lit pdf-text¶
Print a PDF's embedded text layer to stdout (pages joined by form feed). Deterministic pypdf extraction — no model, no network, no system tool. A scanned / image-only PDF yields empty output and exit code 3. Operates on a file path, so it takes no vault flags.
| Flag | What it does |
|---|---|
--pages <spec> |
1-based pages to extract, e.g. 1-3, 1, 1-3,5. Omit for the whole document. |
lit cite¶
Print a compact, presentation-ready citation for one paper to stdout as a single
clean line, so lit cite <id> | pbcopy (or | xclip) copies a paste-ready
string. The form is <journal abbrev.> <year>, <volume>, <pages>. — ACS-style,
with no author list or title, the version you drop on a slide. Accepts a full id,
a unique substring, or --paper-doi.
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. Mutually exclusive with the positional id. |
The journal abbreviation comes from a shipped ISO4 table; an unknown journal is printed verbatim with a warning on stderr (never mixed into the piped citation). Other caveats (missing volume/pages, preprint venue) go to stderr too.
lit modify¶
Edit fields on a paper's metadata.yaml. Writes metadata.yaml (refreshing
updated-at) and INDEX.json atomically; views/by-* are rebuilt afterwards.
Accepts a full id, a unique substring, or --paper-doi.
lit modify <id> --set FIELD=VALUE
lit modify <id> --set field= # unset (writes null)
lit modify <id> --add-tag topics=transformer
lit modify <id> --rm-tag topics=transformer
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. |
--set KEY=VALUE |
Set a scalar field. Repeatable. Empty value unsets (writes null). |
--add-tag FIELD=VALUE |
Append to a list field (deduped). Repeatable. |
--rm-tag FIELD=VALUE |
Remove from a list field (silent if absent). Repeatable. |
--set-author "Family, Given" |
Rewrite the whole author list. Repeat once per author; the order the flags appear in is the order stored. |
Tag operations refuse values not registered in the corresponding TAXONOMY dict (register-first). See 3-concepts.md §1.3 for the two-step register-then-tag model and which fields are controlled.
--set accepts any field name (metadata is schemaless), so a singular slip on
a tag field — --set topic=X where you meant --add-tag topics=X — writes a
plain scalar that the taxonomy never validates and no view indexes. The write
still goes through; litman prints a warning pointing at the --add-tag form.
Authors are the one list with an order that means something, which is why they
have their own flag. --add-tag authors=… appends, so using it to correct a
misread name leaves the correction at the end of the list — and if the name you
were fixing was the first author, that is also the name the paper id came from.
--set-author states the whole list at once and is the only way to reorder it.
lit rename¶
Change a paper id, rippling the change everywhere: the renamed paper's metadata
and directory, every other paper's metadata that references it, every notes.md
with a [[<old>]] wikilink, INDEX.json, and views/. <old> accepts a unique
substring; <new> must be the exact target id.
No flags beyond the global ones. This is the only safe way to change a paper id —
a plain mv papers/<old> papers/<new> leaves dangling references in other
papers' relation fields and in notes wikilinks.
lit rm¶
Remove a paper. By default moves papers/<id>/ to <vault>/.trash/ (recoverable
via lit trash restore); --purge deletes permanently. All external links to
the paper (other papers' relation fields, repo bindings, project links) are
torn down atomically; the paper's own fields ride into trash so a later restore
can rebuild them. A y/N prompt guards the delete (default N).
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. |
--purge |
Permanently delete instead of moving to .trash/. |
-y, --yes |
Non-interactive force-delete: skip the prompt and tear down in one step. |
--dry-run |
Preview the full impact set (the paper plus every link that would be cleared / unbound / orphaned), then exit without deleting. |
3. Reading status¶
Five one-keystroke shorthands for the equivalent lit modify --set on the
reading-workflow fields. Each accepts a full id, a unique case-insensitive id
substring, or --paper-doi <DOI>.
lit read <id> [--date YYYY-MM-DD]
lit revisit <id> [--date YYYY-MM-DD]
lit skim <id>
lit promote <id>
lit drop <id>
| Command | Effect | Equivalent |
|---|---|---|
lit read |
Stamp read-date (the first read). |
--set read-date=<date> |
lit revisit |
Stamp last-revisited (a re-read). |
--set last-revisited=<date> |
lit skim |
Set status=skim. |
--set status=skim |
lit promote |
Set status=deep-read. |
--set status=deep-read |
lit drop |
Set status=dropped. |
--set status=dropped |
read and revisit default to today (local timezone) and accept --date to
backdate. read-date and last-revisited are kept semantically separate;
promote does not touch read-date. To reverse a status, use
lit modify <id> --set status=<value>. See 3-concepts.md §1.1
for what each field means.
4. Linking & organization¶
lit link¶
Link a paper to a project: add the projects tag, write a folder link under
<project>/litman_reflib/<id>/, and regenerate
<project>/litman_reflib/REFERENCES.md. The
project must be registered in lit-config.yaml (via lit project add) and its
directory must exist on disk before linking.
lit link <id> --project <name>
lit link <id> --project <name> --relevance "Direct baseline"
lit link --rebuild-all
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI. Mutually exclusive with the positional id and --rebuild-all. |
--project <name> |
Project name (must be registered in lit-config.yaml). |
--relevance <text> |
Set the relevance-<project> field in one shot. Otherwise left untouched. |
--rebuild-all |
Cross-machine recovery: rebuild every project's links + REFERENCES.md from each paper's projects field. Skips <id> / --project. |
lit unlink¶
Reverse a link: drop the projects tag, the folder link, the REFERENCES.md entry,
and (by default) the relevance-<project> field. Code links under the project
are removed only if no other linked paper there still references the same repo.
| Flag | What it does |
|---|---|
--paper-doi <doi> |
Look the paper up by DOI instead of id. |
--project <name> |
Project to unlink from. Required. |
--keep-relevance |
Preserve the relevance-<project> field. Default drops it (the value is echoed in the summary). |
lit project¶
Manage the project registry. A project is a controlled projects value bound to
an on-disk path. Both truth sources — TAXONOMY.md's ## projects section and
lit-config.yaml's projects: map — are kept in sync by every subcommand. Do
not hand-edit either side.
lit project add <name> --path <abs-path>
lit project list [--format json]
lit project rename <old> <new>
lit project set-path <name> <new-path>
lit project rm <name> [-y]
| Subcommand | What it does |
|---|---|
add <name> --path <dir> |
Register a project (dual-write TAXONOMY + config) in one atomic write. --path is required and must already exist (no placeholder registration). |
list |
List every project, each row tagged with a drift marker (✓ / ⚠ path-missing / ⚠ config-only / ⚠ taxonomy-only). --format json emits {name, path, status} per project, with the marker as a bare token. |
rename <old> <new> |
Rename the project across TAXONOMY, the config key, every paper, and INDEX.json. The path carries over. No prompt (semantics-preserving). |
set-path <name> <path> |
Change the on-disk path (config only — papers store names). Offers to rebuild the project's links at the new location (one Enter); a non-interactive run, or declining, gets the lit link --rebuild-all hint instead. |
rm <name> |
Cascade-untag papers and drop from both truth sources. Always prompts y/N — even with no paper referencing it, removing a project drops its path binding and deletes litman_reflib/ + REFERENCES.md from your project folder, which the trash does not cover. -y skips the prompt. |
lit project is the project counterpart to lit taxonomy; projects is not
managed through lit taxonomy (only lit taxonomy list projects works
read-only). See 3-concepts.md §1.3.
lit code¶
Manage code repositories bound to papers. Repos live under
<vault>/codes/<repo-name>/ with repo/ (the git checkout), repo-meta.yaml,
and notes.md. The binding is bidirectional: a paper's code-clones field
lists the repo, and the repo's papers field lists every bound paper (one repo
can bind multiple papers).
lit code add <url> [--name <n>] [--paper <id>] [--depth N]
lit code add <local-dir> --move
lit code list [--paper <id> | --orphan] [--format json]
lit code link <repo-name> --paper <id>
lit code unlink <repo-name> --paper <id>
lit code update <repo-name> [--unshallow]
lit code rm <repo-name> [--cascade] [-y]
lit code restore-all [--dry-run]
| Subcommand | What it does |
|---|---|
add <source> |
Clone (URL source) or copy/move (local-path source) into codes/<name>/repo/, seeding repo-meta.yaml and notes.md. |
link <repo-name> --paper <id> |
Bind an already-present repo to a paper (idempotent if already bound). |
unlink <repo-name> --paper <id> |
Unbind a repo from a paper without deleting the clone. Drops only the named paper's edge; tolerant of an already-deleted clone. |
list |
List repos and their paper bindings. --format json emits each repo's repo-meta.yaml, so the bindings come out as ids rather than a summary cell. |
update <repo-name> |
git pull --ff-only inside the repo. |
rm <repo-name> |
Permanently delete codes/<repo-name>/. Hard delete (re-clonable from the recorded upstream). |
restore-all |
Re-clone every repo whose repo/ checkout is missing (cross-machine recovery). |
Per-subcommand flags:
add:--name <override>,--paper <id>/--paper-doi <doi>(bind on add),--depth N(URL only;0= full history; default fromlit-config.yaml'sdefault_clone_depth),--move(local-import only: move instead of copy).link/unlink:--paper <id>/--paper-doi <doi>(one of the two required;--papertakes a full id or a unique substring).list:--paper <id>/--paper-doi <doi>/--orphan(repos with no bindings) — mutually exclusive.update:--unshallow(promote a shallow clone to full history).rm:--cascade(strip the repo from every paper'scode-clonesfirst; without it,rmrefuses when any paper still references the repo),-y/--yes.restore-all:--depth N,--dry-run. Exit code 1 if any clone failed or any orphan reference was found (CI / cron-gateable).
lit taxonomy¶
Manage TAXONOMY.md, the controlled vocabulary. Governs three user dictionaries:
topics, methods, data. Tagging a paper with a value requires the value to be
registered here first (register-first; no escape hatch on lit modify). All
changes are atomic (TAXONOMY + every referencing metadata.yaml + INDEX.json
in one staged write).
lit taxonomy list [<dict>] [--format json]
lit taxonomy add <dict> <value>...
lit taxonomy rename <dict> <old> <new>
lit taxonomy merge <dict> <src>... --into <dest> [-y]
lit taxonomy rm <dict> <value> [-y]
| Subcommand | What it does |
|---|---|
list [<dict>] |
Show one dict, or all dicts when no name is given. --format json emits {dict, kind, count, values} per dict. |
add <dict> <value>... |
Register one or more values in a user dict. Already-present values are silent no-ops; the dict is kept sorted. |
rename <dict> <old> <new> |
Rename a value and ripple to every referencing paper. No prompt (semantics-preserving). |
merge <dict> <src>... --into <dest> |
Fold sources into a destination value (existing or new), cascading. --into required; -y skips the prompt. |
rm <dict> <value> |
Remove a value, cascading the removal to every referencing paper. Lists them and prompts y/N; -y skips. With zero referencing papers it removes straight away — nothing cascades, and re-adding the value undoes it. |
projects is not managed here — use lit project (it carries an on-disk path).
The three fixed-enum dicts (type, status, priority) are read-only through
lit taxonomy and require a code release to extend. Never hand-edit
TAXONOMY.md to rename or remove a value. See 3-concepts.md §1.3.
5. Maintenance¶
lit health-check¶
Scan the whole vault for inconsistencies: dangling references, schema gaps, stale
staging dirs, missing PDFs, missing discussion logs, dangling wikilinks, dangling
vault-registry entries, missing project directories, and installed agent skills
that are out of date with the running litman. Exits 0 on a clean vault, 1
if any error or warning is found (so it can gate cron / CI). info findings —
notes about the host, such as a drive that cannot hold folder links — are
reported but do not gate: a structurally clean library exits 0.
Three of the checks look for papers that entered the library before litman
guarded the door, so they matter most on one you have been keeping a while. One
reports a title or author still holding a filler value; one reports a paper id
that carries such a filler, which survives correcting the fields because only
lit rename touches an id; and one reports an id whose keyword says nothing
about the paper, the 2018_Zhang_A left behind by a title the derivation could
not read. Each finding comes with the command that fixes it, complete and ready
to paste.
| Flag | What it does |
|---|---|
--fix |
Auto-regenerate all derived artifacts (lossless recompute from metadata), clean stale staging dirs / orphan trash sidecars, create any missing discussion.md (existing ones keep every section they hold), and refresh out-of-date installed agent skills (files you added next to them are kept). Registry / project / taxonomy / code-clone drift stays report-only (it needs a per-case decision). With --fix, the exit code reflects post-fix state. |
--all |
Print every finding instead of the first few per category. |
A library imported before a guard existed can hold hundreds of one kind of
finding, and printing all of them buries everything else, so each category shows
its first five and folds the remainder into a count. The counts are exact either
way and the exit code does not change — --all only decides how much is printed,
and it is what you want when working through one category paper by paper.
lit refresh-views¶
Rebuild every derived artifact from papers/*/metadata.yaml, in order: (1)
INDEX.json (paper summary + by-doi reverse map), (2) views/by-* link hubs
(wiped and rebuilt, so stale tag buckets disappear), (3) each project's
litman_reflib/ links and REFERENCES.md. Per-project failures (missing
project dir on this machine) are skipped, not aborted.
No flags beyond the global ones. Everything it produces is derived and safe to regenerate wholesale.
lit trash¶
Manage the recoverable-delete bin under <vault>/.trash/, capped at 100 entries
(lit rm evicts the oldest when full).
lit trash list [--format json]
lit trash restore <id-or-entry> [-y]
lit trash empty [--dry-run] [-y]
| Subcommand | What it does |
|---|---|
list |
Show trash entries, newest first. --format json adds each entry's path and the repos a restore would re-clone. |
restore <id-or-entry> |
Restore a trashed paper to papers/<id>/ and rebuild its relations (opposite papers' reverse edges, surviving repo bindings, project links + REFERENCES.md). A 1:1 repo hard-deleted at rm time is re-cloned (-y to auto-attempt without prompting). |
empty |
Permanently delete every trash entry. --dry-run lists what would be removed; -y skips the prompt. |
lit sync¶
rclone-backed one-way cloud sync. push mirrors the vault to your remote;
pull reverses it for cross-machine restore. The vault's per-machine sync-state
file and the transient .litman-staging/ directory are always excluded.
lit sync setup [--remote NAME] [--path PATH]
lit sync push [--dry-run] [-y] [-f] [--exclude-repos]
lit sync pull [--dry-run] [--exclude-repos]
lit sync status
| Subcommand | What it does |
|---|---|
setup |
Hand the TTY to rclone config, then record the chosen remote + path in lit-config.yaml. --remote <name> skips the interactive step (point litman at an existing remote); --path <path> sets the mirror path. |
push |
Upload the vault (rclone sync — deletes orphans on the remote). |
pull |
Download the remote into the vault. One-way with deletion — local files absent on the remote are removed. |
status |
Show last-push / last-pull timestamps and local vs. remote file counts. No network mutation. |
push runs a full health-check first as an integrity gate: any error-severity
finding aborts the push, so a corrupted local state never overwrites the cloud
backup. -f / --force bypasses the gate; -y / --yes only skips the
first-push size confirmation and does not bypass the gate. Both push and
pull accept --dry-run and the paired --exclude-repos / --include-repos
(apply codes_ignore_patterns so codes/*/repo/ checkouts are skipped; re-clone
them later with lit code restore-all).
lit export¶
Project the vault out to a .bib file for LaTeX. Cite keys equal paper ids, so
\cite{<paper-id>} works across machines. Re-running on the same file is the
supported update path. One of --project / --all is required.
lit export --project <name>
lit export --all
lit export --project <name> -o path/to/refs.bib
lit export --all --topic transformer --author wang
| Flag | What it does |
|---|---|
--project <name> |
Export every paper linked to the project. Mutually exclusive with --all. |
--all |
Export every paper in the vault. |
-o, --output <file> |
Output path. Default ./refs.bib. |
--priority / --status / --year / --type / --topic / --method / --data / --author |
A subset of lit list's filters (within a flag OR, across flags AND). |
--force |
Overwrite a target file even without the litman sentinel (typically a hand-edited .bib). |
--format [bibtex] |
Output format. Only bibtex is implemented. |
Every generated file's first line is a litman sentinel comment; lit export
refuses to overwrite a target whose first line is not that sentinel, so a
hand-curated .bib at the same path is safe. The exporter uses the bib-oriented
fields filled in by lit add; fill them on older papers with
lit modify <id> --set venue-type=journal-article etc.
venue-type chooses the entry type, so a paper carrying patent is exported as
@patent rather than a bare @misc, and a patent-number on the paper becomes
that entry's number. Both are ordinary metadata fields — set them with
lit modify on a patent that came in without them.
lit config¶
Inspect the active vault's lit-config.yaml.
| Subcommand | What it does |
|---|---|
show |
Print the parsed, validated config, reflecting the effective values after schema defaults fill in any omitted fields. --format [table\|yaml] chooses a Rich table (default) or the canonical YAML form. |
See 3-concepts.md §1.4 for what each config field controls.
lit gui¶
Launch the litman Web UI — a localhost browser app for browsing, reading PDFs,
annotating, and everyday curation. It serves the active vault and binds
127.0.0.1 only. When your session has a display, the UI also opens in your
browser automatically; on a headless box (HPC) it never tries — it prints a
ready-to-paste ssh -L tunnel line so you can open the printed URL in your
local browser. If the default port is busy it walks upward to the next free
one (Jupyter-style) and prints the port it landed on.
lit gui
lit gui --port 9000
lit gui --window # standalone app window (no address bar)
lit gui --make-shortcut # create a desktop shortcut, then exit
| Flag | What it does |
|---|---|
--port <n> |
Port to bind. Default 8765; auto-increments if busy. |
--no-browser |
Don't open a browser automatically. |
--window |
Open a standalone app window (no address bar) instead of a browser tab. On macOS the window is litman's own; elsewhere it borrows a Chrome-family browser, falling back to a normal tab if none is installed. |
--make-shortcut |
Create a desktop shortcut — Desktop (Windows), applications menu (Linux), /Applications (macOS; falls back to ~/Applications when that is not writable) — that runs lit gui --window, then exit without starting the server. Re-running refreshes it. The install script runs this for you, so a fresh install already has the shortcut. |
In --window mode the app window is the application: closing it stops the
server (on Windows and Linux, Ctrl-C stops the server and closes the window
too). When a browser holds the window it runs against a browser profile of its
own, not your everyday one (lit uninstall removes that profile). A plain
lit gui in a terminal keeps the ordinary contract — the tab is just a tab,
and Ctrl-C in the terminal is what stops the server. On Windows the desktop
shortcut targets litw, the console-less twin of lit, so double-clicking it
opens no console box.
On macOS the window is litman's own — WebKit ships with the system, so nothing
needs installing. Elsewhere only a Chrome-family browser can hold such a
window: --app is their flag and Firefox has no equivalent. On a machine with
none installed, --window opens an ordinary tab and carries on. That is the
usual state of a fresh Linux desktop, and sudo snap install chromium — or
Chrome, or Edge — settles it; litman borrows the browser only to hold its
window, so it need not be the one you browse with.
On a fresh install with no vault yet, lit gui still starts and shows a welcome
page that creates your first library right in the browser — no terminal step. It
also appears if the active vault's folder has moved, letting you create a new
library or open a registered one.
Beyond browsing and reading, the window carries a few things worth knowing about
here. Dragging a PDF onto it imports the paper, running lit add's own code with
one difference: the browser can only hand over a copy of the bytes, so your
original file stays where it is. The pencil in the METADATA header edits the
bibliographic fields and the author list. Clicking a paper's status dot pins it to
the top of the browse list — a per-library convenience kept outside the vault,
which is why it has no lit command. And the first time the app opens on a new
version it shows a short "What's new" card; the litman mark in the top-left corner
reopens it whenever you want it again.
The Web UI drives a growing subset of the commands on this page through the same
code paths — this page (the CLI) stays the complete surface. The web server
(fastapi + uvicorn) ships as a core dependency; a corrupted install missing it
prints a reinstall hint (uv tool install --force litman or pipx install
--force litman).
lit agent¶
Start your AI agent inside the vault — one command instead of opening a
terminal, cd-ing to the vault, and running the agent by hand. It launches
the agent's command with the active vault as working directory and hands the
session fully over to the agent (Ctrl-C and exit belong to the agent, not to
lit).
lit agent # launch the default agent
lit agent cursor # launch a named agent from the catalog
lit agent --set-default claude # record the machine-level default agent
| Argument / Flag | What it does |
|---|---|
NAME (optional) |
Which agent to launch. Omitted, it launches the default agent. |
--set-default NAME |
Record NAME as the machine-level default agent (used by a bare lit agent and the GUI agent button), then exit. Only a supported agent is accepted. |
The default agent is machine-level, not per-vault: it is recorded in
preferences.yaml next to the vault registry, set by lit setup, the GUI
agent panel, or lit agent --set-default. Claude Code, Antigravity CLI
(agy), Codex, Cursor, and OpenCode are the supported agents.
Two things fail with a one-line error: a NAME that is not in the catalog, and an
agent whose command is missing from PATH. The Web UI's agent button launches the same default agent: on a machine
with a display it opens the agent in a new terminal window; when the server
runs on a remote box (HPC) it shows the lit agent line to copy into your own
terminal.
lit self-update¶
Upgrade litman to the latest release on PyPI, through whichever tool installed
it. It prints current → latest, asks once, then runs uv tool upgrade litman
or pipx upgrade litman.
Three installs it will not upgrade: an editable (development) checkout, a plain
pip install, and a conda environment. Each one prints the command to run by
hand instead. It never runs pip install --upgrade into the interpreter it is
running in.
On Windows the upgrade starts the moment the command exits, so the prompt comes
back before it has finished — give it a few seconds and check lit --version.
The command prints the path of the log it writes.
The Web UI does the same job without a terminal: when a new release is out, a chip with its version number appears next to the logo, and Update & restart closes litman, upgrades it, and reopens it. The same three installs are refused there, with the reason shown in the chip.
| Flag | What it does |
|---|---|
-y / --yes |
Skip the confirmation prompt. |
The daily check. Once a day, any lit command may ask PyPI for the newest
version number and print a line when yours is older. The answer is cached for
24 hours at <registry dir>/update-check.json, the request times out after two
seconds, and a failure — offline, slow, malformed — is swallowed silently.
That line appears once a day, so it cannot trail every command in a working
session. lit hello is the exception: it reports a newer release every time
you run it, and it is the one command that reports it to a coding agent as
well — so an agent working on your library can pass a new release on to you.
Set LITMAN_NO_UPDATE_CHECK=1 to switch it off, cache and all. litman sends no
telemetry: the request asks PyPI for a version number and says nothing about
you.