@shelftrove/cli
v0.1.0
Published
Trove: the command line client and agent skills for Shelf, the artifact workspace.
Downloads
19
Maintainers
Readme
trove
trove is the command line client for Shelf, an artifact workspace for storing, finding, editing and sharing text files. It ships with the agent skills that teach Claude Code, Codex, Cursor, Gemini CLI, Windsurf and opencode how to use it.
The binary is trove. The workspace it talks to is Shelf. Two names, on purpose — a rebrand may unify them later.
npm install -g @shelftrove/cli
trove auth login
trove skills installNode 20.11 or newer. No runtime dependencies, so npx @shelftrove/cli works in a container with nothing else in it.
Why it exists
An agent finishes an investigation and the writeup dies in the terminal scrollback. trove gives it somewhere durable to put the result, and gives you a way to find it three weeks later.
trove put ./writeup.md work/incidents/2026-09-18-dataflow-backlog.md \
--description "Pub/Sub backlog traced to an unacked batch in the enrichment worker" \
--keyword incident --keyword dataflow
trove find "identity resolution" --prefix research/ --json
trove share work/incidents/2026-09-18-dataflow-backlog.md --email [email protected] --role viewEvery command accepts --json. Agents parse that; humans read the table. The JSON is the stable contract, not the table.
Commands
| | |
| --- | --- |
| trove ls [prefix] · trove tree | List artifacts, or render the folder tree |
| trove cat <path> · trove get <path> -o f | Read content; cat verifies the sha256 it downloaded |
| trove put <file\|-> <path> | Create or overwrite. Reads stdin when the source is - |
| trove info <path> · trove versions <path> | Metadata and version history |
| trove find <query> | Search path, title, description and keywords |
| trove mv · trove cp | Move or copy, including across profiles |
| trove rm · trove trash · trove restore | Soft delete into a 30-day trash, and back out |
| trove labels … · trove label add · trove star · trove color | Organization |
| trove share · trove unshare · trove shares · trove shared | Access by verified email |
| trove me · trove health · trove prefs | Account, quota and readiness |
| trove skills install\|status\|plan\|emit\|uninstall | Agent skills |
| trove completion bash\|zsh\|fish | Shell completion |
trove --help, and trove <command> --help, for the rest.
Writing safely
put reads the artifact before it writes, so an overwrite that omits --title, --description or --keywords carries the existing values forward instead of silently erasing your search metadata. If content and metadata already match, nothing is written.
| Flag | What it buys |
| --- | --- |
| --if-none-match | 412 instead of overwriting something that already exists |
| --if-match <sha256> or --if-match auto | Compare-and-swap against the version you read |
| --idempotency-key <k> | An identical retry replays the original outcome rather than writing twice |
| --force | Skip the read-before-write; faster, but metadata becomes exactly what you passed |
JSON content is parsed locally first, so a truncated file fails in milliseconds with a byte offset rather than after a round trip.
Authentication
trove auth login # emailed six-digit code
trove auth login --token # bearer token, prompted without echo
trove auth statusSign-in sends a code to your address and exchanges it for a session. Credentials go in the macOS Keychain or libsecret where those exist, and in a 0600 file at ~/.trove/credentials.json otherwise — which is what happens on a headless box or in a container. TROVE_NO_KEYRING=1 forces the file.
~/.trove/config.json holds named profiles: endpoint, app origin, default prefix. It contains no secrets.
trove auth login --profile work
trove profile use work
trove ls --profile personal
trove cp work:reports/q3.md personal:archive/q3.mdResolution order is --profile, then TROVE_PROFILE, then the configured default.
Agent skills
trove skills install writes three skills into every coding agent on the machine:
| Skill | What it encodes |
| --- | --- |
| shelf | Path conventions, when to write versus search, why description and keywords decide whether anything is ever found again |
| shelf-capture | Ending a working session by writing the result to a dated path with usable metadata |
| shelf-index | Turning research into a structured JSON or CSV artifact and sharing it in one step |
| Agent | Target | Form |
| --- | --- | --- |
| Claude Code | ~/.claude/skills/<skill>/SKILL.md | Full |
| Codex CLI | ~/.codex/AGENTS.md | Managed block |
| Gemini CLI | ~/.gemini/GEMINI.md | Managed block |
| Cursor | ~/.cursor/rules/shelf.mdc | MDC rule, compressed |
| Windsurf | ~/.codeium/windsurf/memories/global_rules.md | Managed block |
| opencode | ~/.config/opencode/AGENTS.md | Managed block |
| Anything else | trove skills emit --format agents-md | Printed to stdout |
Writing to global agent configuration is intrusive, so:
- Detect, never assume. Only agents whose config directory already exists are touched. Installing
trovedoes not create a Cursor directory. - Never clobber. Everything lands in its own file, or between
<!-- shelf:begin -->and<!-- shelf:end -->. Re-running replaces only that block, andtrove skills uninstallleaves the surrounding file byte-identical. - Ask first. One screen listing every path, then a yes or no.
--yesfor CI.TROVE_NO_SKILLS=1opts out for good. - Two lengths. Agents with progressive disclosure get the full skill; agents that load rules into every prompt get a twenty-line version.
- Versioned with the binary, so the prose can never describe a flag the CLI does not have.
trove skills plan # exactly which files would change
trove skills install --agent claude-code --agent cursor
trove skills status # what is installed, and whether it is current
trove skills uninstallErrors and exit codes
Failures are {"error":{"code","message","retryable","hint"}} on stderr, with a stable code and an exit code.
| Exit | Meaning | | --- | --- | | 0 | Success | | 1 | Generic failure | | 2 | Usage, invalid path, unsupported type, malformed content | | 3 | Not signed in, or access denied | | 4 | Not found | | 5 | Conflict or failed precondition | | 6 | Too large, or over quota | | 7 | Rate limited or upstream unavailable |
Retryable failures are retried three times with jitter before you see them. Nothing else is retried, so an agent never loops on a 400.
Environment
| Variable | Effect |
| --- | --- |
| TROVE_TOKEN | Bearer token; overrides stored credentials |
| TROVE_PROFILE | Profile to use |
| TROVE_API_URL | API base URL |
| TROVE_CONFIG_DIR | Config and credential directory (default ~/.trove) |
| TROVE_NO_KEYRING | 1 to always use the file credential store |
| TROVE_NO_SKILLS | 1 to disable skill installation entirely |
| TROVE_DEBUG | 1 to print stack traces |
The SHELF_-prefixed spellings of each are also accepted.
Status
Built against the deployed Shelf API. What the API does not have, the CLI does not pretend to have:
- No rename.
trove mvcopies to the destination and trashes the source, so the destination is a new artifact at version 1 and the history stays with the original. The command says so when it runs. - No version rollback.
trove versionslists history;trove restorerestores from trash. Rolling a file back to an earlier version is not an API operation yet. - No public or anonymous links. Sharing is by verified email only, and no invitation email is sent — tell the recipient yourself.
- Text only, up to 1 MB per artifact:
md txt json js ts py rs go yaml toml css sql csv. - Sign-in is an emailed code, not the OAuth 2.1 device grant the PRD describes; the CLI will move to the device grant when the API serves one.
Development
npm test # node --test, no install step
node src/cli.js --helpSee AGENTS.md for architecture and contribution rules.
MIT licensed.
