Skip to main content

soap — a reference manager (CLI + TUI)

Project description

🧼 soap

A terminal reference manager for papers, books, and PDFs — add a source, fetch its metadata, review what's uncertain, and browse it all from a keyboard-driven TUI.

Point soap at a local file, DOI, arXiv ID, ISBN, directory, or URL. It resolves the metadata (and, for links, best-effort downloads the PDF), queues anything it is unsure about for a quick review, and keeps everything in a plain, readable, version-controllable library on disk. From there you can browse, search, tag, and open it — all without leaving the terminal.

ci release python license pypi homebrew


Overview

Keeping a reference library usually means running a heavyweight desktop application or maintaining a folder of PDFs with names like paper (3) final_v2.pdf. soap is neither. It is a fast, keyboard-first TUI backed by a library in which every record is a plain info.yaml file on disk — so you can read it, diff it, and check it into git.

soap:

  • accepts any source — a local file, a whole directory, a DOI, a bare arXiv ID, an ISBN, or a URL;
  • fetches metadata automatically from Crossref, arXiv, or Open Library, and best-effort downloads the PDF for arXiv and direct-PDF links (and open-access DOIs);
  • queues uncertain records so you can accept, correct, or skip them in a quick review pass rather than trust a bad guess;
  • and lets you browse, search, tag, and open the whole library from a TUI — or drive the same library from the CLI.

The on-disk record is the source of truth; the SQLite index is only a fast, rebuildable view. soap never parses the contents of your PDFs.

Installation

Homebrew (recommended — no Python required):

brew install GhifariArsa/soap/soap-tui

This installs a self-contained binary (embedded CPython 3.14 via PyApp), so no Python or pip is needed. Coverage is Apple-Silicon macOS and Linux (arm64 / x86_64); there is no Intel-macOS binary, so brew install on an Intel mac fails fast with a clear message. Upgrade with brew upgrade soap-tui. The tap and its Intel-mac note live at GhifariArsa/homebrew-soap.

Standalone binary (macOS arm64, Linux arm64 / x86_64) — the installer verifies the download before placing soap in ~/.local/bin:

curl -fsSL https://raw.githubusercontent.com/GhifariArsa/soap/main/install.sh | sh

Set SOAP_VERSION=v0.1.0 to pin a release or SOAP_INSTALL_DIR to change the install directory. The installer requires a published release.

From PyPI (requires uv and Python 3.14+):

uv tool install soap-tui

From a checkout — the simplest way to try it:

git clone https://github.com/GhifariArsa/soap.git
cd soap
uv run soap init

The distribution is named soap-tui (plain soap was taken on PyPI), but the installed command is always soap.

Then set up your library once:

soap init

init creates the library, its SQLite index, and a shell export for SOAP_DIR. The default library is ~/.soap; SOAP_DIR changes the default, and `--path

` overrides both. It writes `config.yaml`, `inbox/`, `documents/`, and `soap.db`, plus a quoted `SOAP_DIR` export to your shell config (or prints a safe export line when no shell can be detected). A fresh library sets `always_review: true`, and re-running `init` never overwrites an existing config.
Option Description
--path <dir> Initialize a different library.
--shell auto|zsh|bash|fish Choose the shell config to update.
--force Reinitialize an existing library; destructive, but backs up the old database.

Usage

The core workflow is straightforward: add a source, review it, then run soap to browse.

From a checkout, prefix commands with uv run; an installed copy uses soap directly.

# An arXiv ID resolves metadata and best-effort downloads its PDF.
soap add 1706.03762

# A fresh `soap init` routes adds through the review queue.
soap inbox review

# Then browse the library.
soap

For a local PDF, supply an identifier or the metadata yourself:

soap add ~/papers/paper.pdf --doi 10.1145/3292500.3330701

# Or work completely offline:
soap add ~/papers/paper.pdf --no-fetch \
  --title "Attention Is All You Need" \
  --author "Vaswani, Ashish" --year 2017

SOURCE can be a local file, directory, URL, DOI, or bare arXiv ID; ISBN metadata comes from --isbn, and identifiers can be passed explicitly with --doi or --arxiv. The most commonly used options:

Option Description
--title, --author, --year, --type Override metadata. --author is repeatable.
--tag, --collection Add repeatable tags or collections.
--no-fetch Skip network metadata lookups.
--recursive Include files below a directory source.
--confirm Correct the core fields inline before saving.
--edit, -e Edit the generated info.yaml in $EDITOR.
--dry-run Preview the add without writing anything.
--force Add even when a duplicate is detected.
--path <dir> Use a library other than $SOAP_DIR or ~/.soap.

Run soap add --help and soap inbox review --help to list every option.

Reviewing the inbox

soap inbox review presents one needs_review record at a time:

  • a — accept it as-is
  • c — correct title, authors, year, type, or venue; Enter keeps a value
  • e — open the complete info.yaml in $EDITOR
  • s — skip it for later
  • d — delete it and its attached files, after confirmation
  • q — quit the walk

The TUI review screen shares the same review core: enter/a files, c corrects, e opens $EDITOR, s skips, and q/esc finishes. soap add --confirm provides the same guided field correction during an add.

Keybindings

Run soap with no subcommand to open the TUI. Press ? at any time for the in-app reference; the compact map for the main screen is below.

 j / k · g / G        move · jump to top / bottom
 Ctrl-D / Ctrl-U      half-page down / up
 Tab / Shift-Tab      cycle panes      h / l   focus left / right
 enter / o            open the selected file or URL
 /                    search title, author, tag, or DOI (Enter/Tab → list)
 E                    edit the core fields (title/authors/year/type/venue) in an in-app form
 e                    edit the complete `info.yaml` in $EDITOR (full power option)
 d                    delete the selected document and its files (asks to confirm)
 t                    edit tags (Enter/comma adds · Tab completes · Ctrl-S saves · Esc cancels)
 m                    cycle read status: unread → reading → read
 r                    review the inbox
 Ctrl-R               refresh from disk
 ? / Ctrl-P           keyboard reference / command palette
 Ctrl-T               cycle themes
 q                    quit

How the workflow fits together

  1. Initialize once. soap init creates the library, its SQLite index, and a shell export for SOAP_DIR.
  2. Add sources. soap add takes a file, directory, DOI, arXiv ID, ISBN, or URL. Repeat --author, --tag, or --collection as needed; use --recursive for a directory.
  3. Review. soap inbox review, or the TUI's r action, lets you accept, correct, edit, skip, or delete each needs_review record. --confirm folds the same guided correction into add.
  4. Browse. Run soap with no subcommand. The sidebar filters all documents, the review inbox, read status, tags, and collections; / searches.
  5. Open and mark. enter/o opens the first attached file (or the recorded URL) with the OS default handler. m cycles unread → reading → read.

Metadata lookups use Crossref, arXiv, or Open Library as appropriate. arXiv and direct-PDF URLs download a PDF on a best-effort basis, and an open-access DOI may too; a paywall or failed download still saves the metadata. soap does not parse PDF contents.

Configuration and data

The library path resolves in the following order:

  1. --path <dir> where the option is available (init, add, inbox review)
  2. $SOAP_DIR
  3. ~/.soap

Its important files are laid out like this:

$SOAP_DIR/
├── config.yaml
├── soap.db                         # rebuildable SQLite index
├── inbox/                          # library directory created by init
└── documents/
    └── <citekey>/
        ├── info.yaml               # authoritative document record
        └── paper.pdf               # attached file(s), if any

info.yaml is the source of truth. Every change writes the document file first, then synchronizes the SQLite index — the index is only a fast, denormalized view of the files and metadata. The TUI and CLI therefore read and mutate the same library, and the on-disk record stays readable and version-controllable without the index.

The review inbox is a needs_review status, not a second copy of the document: records and their attachments remain under documents/<citekey>/ until they are filed, skipped, or deleted. A new citekey names both the document folder and its info.yaml; correcting a record during review keeps that citekey, and only a new add derives a fresh key.

Themes

Tags are edited from the selected document with t and double as sidebar filters. The TUI ships with the aqua-slate (default), one-dark, and catppuccin-mocha themes — Ctrl-T cycles them and the choice is saved in config.yaml. User themes live in $SOAP_DIR/themes/.

See the theme format and the example theme to build your own.

Contributing

soap is a standard Python project managed with uv. Run the tests with:

uv run pytest

Issues and pull requests are welcome. The distribution is named soap-tui; the installed command is soap.

License

MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

soap_tui-0.2.41.tar.gz (156.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

soap_tui-0.2.41-py3-none-any.whl (93.5 kB view details)

Uploaded Python 3

File details

Details for the file soap_tui-0.2.41.tar.gz.

File metadata

  • Download URL: soap_tui-0.2.41.tar.gz
  • Upload date:
  • Size: 156.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for soap_tui-0.2.41.tar.gz
Algorithm Hash digest
SHA256 7c1ebda7226c24c0cc6794340f644dfdd84061148bc8f5d5ef03f541f30c1cb7
MD5 c7d69642d879427f51debc51584cbc84
BLAKE2b-256 796a237f7f59ca98d83e31c8878fd1e0221e21fa0be449c4402677d872245b3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for soap_tui-0.2.41.tar.gz:

Publisher: release.yml on GhifariArsa/soap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file soap_tui-0.2.41-py3-none-any.whl.

File metadata

  • Download URL: soap_tui-0.2.41-py3-none-any.whl
  • Upload date:
  • Size: 93.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for soap_tui-0.2.41-py3-none-any.whl
Algorithm Hash digest
SHA256 7a78f11d4cc61f16d3c2637c55aa5f708fba5de2ceb6b9dedd94a6b4c77c142d
MD5 02e1575f54f969618c79d1338c2660bb
BLAKE2b-256 bcbb491badccba83956fb024cba13ba8c0a03f05680d087b2f55e17546a88c7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for soap_tui-0.2.41-py3-none-any.whl:

Publisher: release.yml on GhifariArsa/soap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page