Commands¶
# fetch to disk only
uv run paperful run --collection interesting --no-attach
# several collections, or the whole library (resumable; Ctrl-C any time, rerun to continue)
uv run paperful run -C BBNJ -C AO
uv run paperful run --library
# attach previously downloaded PDFs
uv run paperful attach
# what happened
uv run paperful report
uv run paperful report --last-run # latest run summary only
uv run paperful report --json # agent-friendly (manifest + last run)
uv run paperful report --not-found
uv run paperful report --status error
# policy-sensitive runs (OA + campus EZProxy; no Scholar / Sci-Hub)
uv run paperful run -C BBNJ --preset eoi --dry-run
# items with only a linked PDF URL in Zotero are skipped by default
uv run paperful run --library --upgrade-linked
# retry items marked not_found / no_identifier (e.g. after EZProxy login)
uv run paperful run --library --retry-failed
uv run paperful run --collection BBNJ --retry-failed
uv run paperful run --collection BBNJ --try-all # ignore source_routing when metadata is unreliable
# restrict / reorder sources for one run, or cap the number of items processed
uv run paperful run -C hoops --sources unpaywall,openalex,ezproxy
uv run paperful run --library --limit 50
# Sci-Hub is off unless you opt in (config `sources`, or this flag)
uv run paperful run --library --scihub
# session (optional)
uv run paperful session login ezproxy # headed Chromium, campus SSO
uv run paperful session login scholar # same profile; solve Scholar CAPTCHA here
uv run paperful session status
uv run paperful ezproxy --no-open # probe the EZProxy session
uv run paperful scholar --no-open # probe Scholar
uv run paperful mirrors # which Sci-Hub mirrors are up (Sci-Hub itself stays off)
# identifiers vs PDFs (read-only); metadata writes are a separate step
uv run paperful lint --library --json
uv run paperful lint -C BBNJ --strict # exit 1 if any finding
uv run paperful fix-metadata --library # dry-run → state/metadata-patches.jsonl
uv run paperful fix-metadata --library --apply # write DOI/title/date/venue into Zotero 10+
uv run paperful fix-metadata --library --apply --overwrite # also replace title/date/venue
Command |
Purpose |
|---|---|
|
Environment check (Zotero, paths, email, sessions, pdftotext, grey-lit packs). Green / amber / red. |
|
Find and download missing PDFs ( |
|
Read-only identifier / PDF-DOI findings ( |
|
Propose patches on disk; |
|
Collection tree with “No PDF” counts |
|
Manifest summary + latest run report ( |
|
Attach already-downloaded PDFs into Zotero |
|
Local Chromium vault: `login scholar |
|
Wrapper: headed login (or Netscape fallback) / |
|
Wrapper: headed login (or Netscape fallback) / |
|
Ping configured Sci-Hub mirrors |
|
Print the package version |
Collections can be given as a path (BBNJ/not undermine), a unique name, or
a key. Subcollections are always included. Items in several selected
collections are written once and hard-linked into the other folders.
Doctor¶
paperful doctor prints one line per check.
Colour |
Meaning |
|---|---|
green |
Ready |
amber |
Degraded but you can continue (empty |
red |
Fatal if the check is |
Unpaywall needs a real email. Missing sessions: paperful session login ezproxy or scholar. Missing pdftotext: Poppler; pypdf is the fallback.
Dry-run¶
paperful run … --dry-run talks to Zotero only (no PDF fetches). The table’s
Would-hit column is the source lane for that item, in order. --try-all
(or source_routing = false) lists every configured source.
Exits¶
Code |
When |
|---|---|
0 |
Success (including empty dry-run) |
1 |
User error (unknown collection, bad preset, |
2 |
Environment: Zotero unreachable on |
Run summary¶
After a real run, a Run summary table lists PDFs downloaded, attached,
deferred/skipped, sources checked, and typed errors. paperful report reprints
it. JSON: paperful report --json — field list in architecture.
Output¶
out/<collection path>/Author - Year - Title.pdfstate/manifest.jsonl— one line per item attempt; the latest line per item key wins. Statuses:ok(on disk),attached(on disk + in Zotero),not_found,no_identifier,captcha,error,attach_failed.ok/attachedare never retried;not_found/no_identifieronly with--retry-failed; the rest are retried on every run. Extra fields:library_doi(DOI as stored in the manager),doi(DOI used for this attempt),doi_verified(ok/suspect/swapped/unknown/missing),pdf_doi(extracted from the file on disk after a successful download).state/metadata-patches.jsonl— proposed bibliographic patches fromfix-metadata(dry-run and--applyboth append here first).state/pdf-cache/— PDFs exported from the manager so lint can read text on disk (pdftotext, thenpypdf).state/last-run.json— latest auditablerunreport (summary + per-item outcomes). Historical copies land instate/runs/<timestamp>-<command>.json(run, orfix-metadataafter--apply).fix-metadata --applydoes not overwritelast-run.json.state/sessions/— Chromium profile (chromium/) plusmeta.json(no passwords). Gitignored;chmod 700. Netscape dumps also land here and asezproxy-cookies.txt/scholar-cookies.txtfor httpx.state/zotero-local-api-key.json— the Zotero write key if you chose “Always Allow”.