# Progratus
[](LICENSE)
Progratus is a local, provenance-first research knowledge layer. It owns its
storage: importing a paper **copies** the PDF into a portable workspace,
records its SHA-256 and origin in a filesystem-authoritative sidecar, and
keeps immutable parser artifacts next to the paper they were produced from.
There is no database — the file system is the record.
## Requirements
- Node.js 22.6 or newer (`--experimental-strip-types`)
- Zotero 7 is optional (an import adapter only)
- MinerU credentials are required only for parsing
## Quick start
```bash
npm test
export PROGRATUS_WORKSPACE=~/Progratus # or pass --workspace PATH
node --experimental-strip-types packages/cli/src/index.ts add paper.pdf
node --experimental-strip-types packages/cli/src/index.ts list
node --experimental-strip-types packages/cli/src/index.ts show PAPER_ID
```
The CLI has four commands: `add`, `list`, `show`, `serve`. Everything else
(verify, remove, re-parse, import with Zotero metadata) is available over the
HTTP API when `serve` is running. Importing copies the PDF into
`papers/<id>/paper.pdf`, verifies its hash, and attempts MinerU parsing with
the default `vlm` model. Import success is independent of parse success: if
MinerU times out or fails, the PDF and sidecar remain stored and the JSON
result reports `parsing.status: "failed"`. Re-importing the same content is a
no-op that reuses existing artifacts.
## Workspace ownership
The workspace is a single self-contained directory. Copy or move it anywhere
and every paper, record, and artifact travels with it.
```text
Progratus/papers/<id>/paper.pdf owned copy of the PDF (authoritative file)
Progratus/papers/<id>/paper.json authoritative sidecar: metadata, SHA-256, origin
Progratus/papers/<id>/artifacts/ immutable parser outputs, each with manifest.json
Progratus/library/ generated human-readable view (relative symlinks)
Progratus/analyses/ agent analyses and reports
Progratus/config.json source roots (import-source aliases, provenance only)
Progratus/config/providers.json MinerU credentials (owner-only permissions)
```
`library/` is a disposable view with **relative** symlinks, so it survives
moving the workspace. `show` recomputes the stored copy's
SHA-256 against the sidecar record and fails loudly on tampering.
## MinerU
Start the local bridge after editing `~/Progratus/config/providers.json`:
```json
{
"mineru": {
"baseUrl": "https://mineru.net",
"token": "",
"modelVersion": "vlm",
"configHash": "default",
"isOcr": false,
"pollIntervalMs": 2000,
"timeoutMs": 1200000
}
}
```
The token is resolved in order: `providers.json` -> `MINERU_TOKEN` env ->
`~/.mineru/config.yaml` (written by `mineru-open-api auth`). Leaving the
`providers.json` token empty keeps credentials out of the workspace, so a
workspace can be shared or backed up without leaking tokens.
`modelVersion` defaults to `vlm` (higher accuracy on complex layouts); set it
to `pipeline` when zero-hallucination reliability matters more than layout
accuracy.
`providers.json` is created with owner-only permissions and is separate from
`config.json`, which only contains source roots.
```bash
node --experimental-strip-types packages/cli/src/index.ts serve \
--workspace ~/Progratus --port 39120
```
Then parse a tracked paper:
```bash
node --experimental-strip-types packages/cli/src/index.ts parse \
--workspace ~/Progratus --id PAPER_ID
```
MinerU parsing reads `config/providers.json` inside the workspace. The
adapter downloads raw service output into the paper's own `artifacts/`
directory, records output hashes and parser configuration in `manifest.json`,
and never touches any file outside the workspace. Re-running `parse` with the
same source hash and parser configuration reuses the existing artifact.
## Zotero 7 adapter
The plugin is intentionally thin. Start the bridge first, then package the
contents of `packages/zotero-plugin/` as a Zotero 7 bootstrap plugin.
Selecting a Zotero item and choosing **Analyze with Progratus** imports its
PDF through `POST /papers/import` and starts parsing through
`POST /papers/{id}/parse`. The import payload carries the Zotero library ID
and item key, recorded in the sidecar as provenance.
Zotero is one import adapter among possible future ones (directory watchers,
DOI/BibTeX import). Progratus never reads or synchronizes Zotero collections,
tags, or reading state, and never writes into Zotero's storage directory.
Available local endpoints:
```text
GET /health
GET /papers
POST /papers/import
GET /papers/{paper_id}
GET /papers/{paper_id}/status
POST /papers/{paper_id}/parse
POST /papers/{paper_id}/verify
```
The bridge is bound to `127.0.0.1` by default.
## AI-native interface
Progratus is designed to be driven by AI agents. Every CLI command accepts
`--json` and then prints exactly one JSON value to stdout; failures print
`{"error": "..."}` to stderr and exit 1. Commands are idempotent where
possible (`add` dedups by SHA-256 and reuses artifacts), IDs are stable, and
`help --json` emits a machine-readable description of the whole command
surface for discovery. Agent principles and boundaries are codified in
`AGENTS.md`; a ready-made agent skill lives in `skills/progratus/SKILL.md`.
## Contributing
Zero runtime dependencies by design (Node stdlib only). Code runs directly
via `node --experimental-strip-types`, so TypeScript parameter properties,
`enum`, and namespaces are not allowed. Run `npm test` before committing.
See `AGENTS.md` for the full engineering principles.
## License
[MIT](LICENSE) © 2026 Progratus contributors