A portable command-line client for Hindsight memory banks
Project description
Retrosage is a portable Python CLI for
Hindsight memory banks. The published
package provides the retrosage command and has no runtime dependencies.
Optional local OCR support uses ocrmypdf when explicitly enabled.
Install
Python 3.10 or newer is required. Install Retrosage from PyPI as an isolated
command with uv:
uv tool install retrosage
retrosage version
Or install it with pip in a virtual environment:
python3 -m venv ~/.venvs/retrosage
~/.venvs/retrosage/bin/python -m pip install retrosage
~/.venvs/retrosage/bin/retrosage version
The default package has no runtime dependencies. Install the optional OCR extra only when local PDF OCR fallback is required:
uv tool install 'retrosage[ocr]'
# or: ~/.venvs/retrosage/bin/python -m pip install 'retrosage[ocr]'
Development installation
When working from a repository checkout, choose whether the installed command should track live source edits or behave like a fixed release build.
Live edit mode (--editable)
git clone https://github.com/forgegod/retrosage.git
cd retrosage
uv tool install --editable .
The tool environment points back to retrosage.py in this checkout. Source
edits take effect on the next retrosage invocation without reinstalling. Use
this mode while developing or debugging Retrosage.
To include the optional local OCR integration in editable mode:
uv tool install --editable '.[ocr]'
Snapshot mode (--force --from .)
uv tool install --force --from . retrosage
This builds and installs a regular package from the checkout. Later source edits are invisible until the command is reinstalled, which makes snapshot mode useful for testing the checkout as a release-like artifact.
Direct source mode
python3 retrosage.py version
python3 retrosage.py --help
./retrosage --help
Direct mode creates no installed command and needs no virtual environment. It
is the fastest option for core CLI changes because the default implementation
uses only the Python standard library. Optional OCR still needs ocrmypdf in
the selected Python environment and its system dependencies.
Choose an installation mode
| Goal | Command |
|---|---|
| Install the official PyPI release | uv tool install retrosage |
| Develop against live checkout edits | uv tool install --editable . |
| Test the checkout as a fixed package | uv tool install --force --from . retrosage |
| Run the checkout without installing | python3 retrosage.py ... |
| Return to the official release | uv tool install --force retrosage |
--force replaces an existing Retrosage tool environment. It can be omitted
for a clean first installation. For the full contributor environment with
pytest, build tools, and commit hooks, follow DEVELOPMENT.md.
First use after installation
These checks prove the installed command works before making authenticated changes:
retrosage version
retrosage --help
TMPDIR=$(mktemp -d)
printf '# first import\n' > "$TMPDIR/note.md"
retrosage docs import --bank demo --directory "$TMPDIR" --dry-run
rm -rf "$TMPDIR"
For network commands, export the Hindsight API key and select a real bank:
export HINDSIGHT_API_KEY='your-api-key'
retrosage banks list
retrosage memory recall --bank bank-foo --query "What do we know?"
For source checkout setup, tests, and commit hooks, see Retrosage development. Maintainers should use the release guide for PyPI trusted-publisher setup and version releases.
Credentials
| Variable | Purpose |
|---|---|
HINDSIGHT_API_KEY |
Default Hindsight API key. |
HINDSIGHT_API_KEY_PROD |
Example profile key selected with --api-key HINDSIGHT_API_KEY_PROD. |
The key is read from the named environment variable only. Every network
command requires it, including non-dry-run docs import, docs sync, and
docs watch. --help, version, and truthful local --dry-run paths do not
require credentials or contact the API.
Banks
retrosage banks list
retrosage banks create --bank bank-foo --name "Bank Foo"
retrosage banks get --bank bank-foo
retrosage banks update --bank bank-foo --retain-config config.json
retrosage banks stats --bank bank-foo --refresh
retrosage banks config --bank bank-foo --overrides-only
retrosage banks config-set --bank bank-foo --updates config.json
retrosage banks set-disposition --bank bank-foo --skepticism 3 --literalism 3 --empathy 4
retrosage banks consolidate --bank bank-foo
retrosage banks template-export --bank bank-foo
retrosage banks delete --bank bank-foo --yes
Documents
retrosage docs import --bank bank-foo --file notes.pdf
retrosage docs import --bank bank-foo --directory ./documents
retrosage docs import --bank bank-foo --dir ./documents
retrosage docs import --bank bank-foo --directory ./documents \
--extraction-mode iris --ocr-fallback auto
retrosage docs import --bank bank-foo --directory ./documents --dry-run
retrosage docs list --bank bank-foo --query report --tag current --all
retrosage docs get --bank bank-foo --document-id doc_123
retrosage docs update --bank bank-foo --document-id doc_123 --tag current
retrosage docs delete --bank bank-foo --document-id doc_123 --yes
retrosage docs sync --bank bank-foo --directory ./documents
retrosage docs sync --bank bank-foo --directory ./documents --dry-run
retrosage docs sync --bank bank-foo --directory ./documents --state ./sync-state.json --no-recursive
retrosage docs watch --bank bank-foo --directory ./documents --interval 10
retrosage docs watch --bank bank-foo --directory ./documents --dry-run
docs import accepts a single --file or a --directory. --dir is
an alias for --directory on this subcommand only; docs sync and
docs watch keep the canonical --directory flag. Directory mode
follows symlinked directories, including cloud-storage junctions, and uploads
every supported file in one pass. It does not keep a
manifest, so a re-run can create duplicate bank documents; for
incremental, retryable uploads, use docs sync or docs watch.
--extraction-mode {iris,markitdown,markdown,default,concise,bank}
switches the bank's retain_extraction_mode via PATCH for the
duration of the run (read-modify-write) and restores the previous value
on exit. Pass --no-restore-extraction-mode to leave the bank in the
chosen mode. The default value bank is a no-op so the legacy CLI
behaviour is unchanged. --extraction-mode paired with --no-poll is
rejected unless --no-restore-extraction-mode is also passed (PATCH +
no-polling would silently leave the bank changed). Use
--raw-extraction-mode <value> for arbitrary strings the backend
accepts beyond the curated choices.
--ocr-fallback {off,auto,force} handles PDFs the backend cannot
extract. off (default) is the legacy behaviour. force OCRs every
PDF locally before upload. auto tries once, then OCRs only the files
the backend rejects. --ocr-engine {ocrmypdf,auto} (default auto) uses ocrmypdf through
its Python module or CLI. OCR output is temporary and always removed after
upload. Direct tesseract PDF mode is intentionally unsupported because it
cannot reliably consume PDFs and produce the required upload artifact.
--no-recursive scans only the top level; --dry-run lists what would
be uploaded (with the requested extraction_mode and ocr_fallback)
without contacting the API or PATCHing the bank. --dry-run does not
require HINDSIGHT_API_KEY.
Errors are reported per-file; the partial result is still printed and
the exit code is 2 if any file failed. Progress lines are emitted on
stderr (suppress with --quiet).
docs sync keeps a manifest at <directory>/.hindsight-sync.json
(overridable with --state). Files are identified by relative path, size,
and mtime_ns; the manifest also stores the per-file SHA-256 for auditing.
Removed files are dropped from the manifest only — the CLI does not delete
their remote counterparts. Pass --dry-run to preview changes without
contacting the API. Global --no-poll is rejected for sync/watch because a
pending upload cannot safely advance the successful-upload manifest.
docs watch repeatedly runs sync at --interval seconds. It is implemented
as a polling loop (no kernel events) so it works on any platform. SIGINT and
SIGTERM request a clean shutdown between cycles; pass --dry-run to log
candidate changes without writing the manifest. The process exits 2 after
shutdown if any cycle failed.
docs list returns one page by default and supports --query, repeated --tag,
--tags-match, --limit, and --offset; --all follows every page. The pinned
API has no document date filters, so none are invented. docs update replaces
the full tag list; omitting --tag clears it.
Memories
retrosage memory retain --bank bank-foo --text "The deployment is Friday" --tag release
retrosage memory retain --bank bank-foo --file note.txt --document-id note-1
printf '%s' "stdin memory" | retrosage memory retain --bank bank-foo --stdin
retrosage memory recall --bank bank-foo --query "When is deployment?" --budget mid --include-chunks
retrosage memory reflect --bank bank-foo --query "Summarize release risks" --include-facts
retrosage memory list --bank bank-foo --all
retrosage memory get --bank bank-foo --memory-id MEMORY_ID
retrosage memory history --bank bank-foo --memory-id MEMORY_ID
retrosage memory clear-observations --bank bank-foo --memory-id MEMORY_ID --yes
retrosage memory clear --bank bank-foo --fact-type observation --yes
retain requires exactly one explicit source: --text, a UTF-8 --file, or
--stdin. recall and reflect expose the confirmed simple tag, fact-type,
budget, and inclusion controls. list returns one explicit page by default;
--all follows pagination while preserving the first response's top-level
fields. Both clear commands require --yes; individual memory deletion is not
supported by the API and is intentionally absent.
Operations And Diagnostics
retrosage operations list --bank bank-foo --all
retrosage operations list --bank bank-foo --status failed --task-type retain
retrosage operations get --bank bank-foo --operation-id OPERATION_ID --include-payload
retrosage operations cancel --bank bank-foo --operation-id OPERATION_ID --yes
retrosage operations retry --bank bank-foo --operation-id OPERATION_ID
retrosage health
retrosage api-version
Operation list filters are limited to the fields declared by the pinned API:
status, task type, pagination, and parent exclusion. --all follows pagination.
Cancellation requires --yes. Retry uses the same bounded polling and terminal
state handling as document and memory operations unless global --no-poll is
passed. health and api-version query the remote API; local version remains
offline. Metrics are intentionally absent because no practical hosted
automation use case is defined.
Backup And Restore
retrosage backup --output backups/2026-06-30T09-30Z --bank bank-foo
retrosage backup --output backups/2026-06-30T09-30Z --include-observations
retrosage inspect --archive backups/2026-06-30T09-30Z/bank-foo
retrosage restore --archive backups/2026-06-30T09-30Z/bank-foo --bank bank-foo=bank-foo-copy
retrosage --no-poll restore --archive backups/2026-06-30T09-30Z/bank-foo --bank bank-foo=bank-foo-copy
Globals
retrosage --api-base https://api.hindsight.vectorize.io --api-key HINDSIGHT_API_KEY banks list
retrosage --quiet banks get --bank bank-foo
--poll-timeout bounds total operation polling (default: 600 seconds).
docs delete requires --yes.
License
Retrosage is available under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file retrosage-0.4.3.tar.gz.
File metadata
- Download URL: retrosage-0.4.3.tar.gz
- Upload date:
- Size: 44.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fd032cbb9e26ec9ff0019f1eef775ca73704ff3360678e4b0c5cb139b0dd9c7
|
|
| MD5 |
5435b98a8a85d0a0ef4fa20e60ff9278
|
|
| BLAKE2b-256 |
8b177a5efc9f6630ca45019fba79929e970ae08c2daa9d6205b215078b8cb133
|
Provenance
The following attestation bundles were made for retrosage-0.4.3.tar.gz:
Publisher:
publish.yml on forgegod/retrosage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
retrosage-0.4.3.tar.gz -
Subject digest:
9fd032cbb9e26ec9ff0019f1eef775ca73704ff3360678e4b0c5cb139b0dd9c7 - Sigstore transparency entry: 2203129036
- Sigstore integration time:
-
Permalink:
forgegod/retrosage@c8dd6830d2d548df97cbbb13d24ce310bbac8107 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/forgegod
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c8dd6830d2d548df97cbbb13d24ce310bbac8107 -
Trigger Event:
push
-
Statement type:
File details
Details for the file retrosage-0.4.3-py3-none-any.whl.
File metadata
- Download URL: retrosage-0.4.3-py3-none-any.whl
- Upload date:
- Size: 30.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc5905da6c8116e2f3107d17c90d27ee3e6da38d08738abc9fe48f9fd98a5474
|
|
| MD5 |
e1601d7cdfa8cd24d1257cc84bc97df9
|
|
| BLAKE2b-256 |
ff7cb6b129b7ca6e51a8cb610f1bfd814bc6f6dde9c7a0ae3520ebd502d7f762
|
Provenance
The following attestation bundles were made for retrosage-0.4.3-py3-none-any.whl:
Publisher:
publish.yml on forgegod/retrosage
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
retrosage-0.4.3-py3-none-any.whl -
Subject digest:
dc5905da6c8116e2f3107d17c90d27ee3e6da38d08738abc9fe48f9fd98a5474 - Sigstore transparency entry: 2203129083
- Sigstore integration time:
-
Permalink:
forgegod/retrosage@c8dd6830d2d548df97cbbb13d24ce310bbac8107 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/forgegod
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c8dd6830d2d548df97cbbb13d24ce310bbac8107 -
Trigger Event:
push
-
Statement type: