Shelve
Shelve is an open-source team secrets platform: web app + CLI. Store variables per team, project, and environment; inject at runtime without committing .env files.
Security rules (read first)
- Prefer
shelve run -- <cmd> — secrets stay in the child process; no .env on disk.
- Avoid
shelve pull in agent shells — writes plaintext secrets agents can read. Use --yes only if the user explicitly needs a disk file; run shelve init first.
- Never commit
SHELVE_TOKEN, .env, or ~/.shelve/ cache.
- Never print secret values in logs, JSON, or commits. CLI
--json excludes values by design.
- Run
shelve init once per workspace before secret operations.
- Protect production: use
sync.protectedEnvironments in shelve.json and/or project Settings → Sync policy.
Platform (teams, tokens, UI)
| Concept |
CLI / config |
| Team |
slug in shelve.json, SHELVE_TEAM_SLUG |
| Project |
project, SHELVE_PROJECT |
| Environment |
--env, defaultEnv, SHELVE_DEFAULT_ENV |
| API token |
SHELVE_TOKEN — create at https://app.shelve.cloud/user/tokens (shown once; scope read/write + team/project/env) |
CLI vs UI: bulk edit and audit logs → UI; local dev and CI → CLI run. Details: platform.md.
Non-interactive / agents
Run shelve doctor --json first in automation.
| Variable |
Purpose |
SHELVE_TOKEN |
API token |
SHELVE_TEAM_SLUG |
Team slug |
SHELVE_PROJECT |
Project name |
SHELVE_DEFAULT_ENV |
Default environment |
SHELVE_URL |
Instance (default https://app.shelve.cloud) |
| Flag |
Effect |
--json |
Machine-readable stdout; JSON errors on stderr |
--quiet / -q |
No spinners |
--yes / -y |
Skip confirmations |
--non-interactive |
Fail instead of prompt |
--debug |
Verbose (SHELVE_DEBUG=1) |
Auto non-interactive when CI=true, agent shell detected, or AI_AGENT is set.
Command cheat sheet
# Preferred: inject secrets
shelve run -- pnpm dev
shelve run --env preview -- pnpm build
shelve run dev # package.json script shortcut
shelve init # agent ignores + .gitignore block
shelve login # browser device flow (humans)
shelve login --token "$SHELVE_TOKEN" # CI / automation
shelve doctor --json
shelve --json config
# Sync
shelve diff --env staging
shelve push --env development --yes
shelve pull --env development --yes # risky in agent shells
shelve sync --dry-run --env production
# Monorepo: from the root these four run once per package
shelve pull --path apps/web # ...or target a single package
shelve create --name my-app --slug my-team
shelve generate --type env-example
shelve run flags
| Flag |
Purpose |
--env |
Environment |
--template |
.env.template with shelve:// refs |
--offline |
Encrypted cache only |
--no-cache |
Disable cache |
--cache-ttl |
e.g. 15m, 24h default |
--watch |
Reload on remote changes |
--restart-on-change |
Respawn child instead of SIGHUP |
Sync policies (shelve.json)
{
"$schema": "https://shelve.cloud/schema.json",
"slug": "my-team",
"project": "my-app",
"defaultEnv": "development",
"sync": {
"protectedEnvironments": ["production"],
"environments": {
"development": { "sourceOfTruth": "local" },
"production": { "sourceOfTruth": "remote", "allowPush": false, "pullMode": "merge" }
}
}
}
See sync-policies.md and https://shelve.cloud/docs/cli/sync-policies
Monorepos
From a workspace root, push / pull / diff / sync run once per package that has its own shelve.json; the root itself and packages without one are skipped. --path <dir> targets a single package. run never fans out.
- Root
shelve.json holds shared settings (slug, defaultEnv, …); project stays per-package and is never inherited.
- Give the root a
project to opt out and treat it as one project.
- With
--json, data becomes { "packages": [...] }, one entry per package with its path.
- A failing package stops the run; the error carries
context: { failedPackage, completedPackages }.
Details: agent-workflows.md
Error codes
| Code |
Meaning |
AGENT_BLOCKED |
pull in agent shell without --yes |
AUTH_REQUIRED |
Missing token |
MISSING_ENV |
No --env / defaultEnv |
FETCH_FAILED |
API/cache failure in run |
PUSH_BLOCKED / PULL_BLOCKED |
Sync policy |
SYNC_CONFLICT |
onPushConflict: fail or prompt in CI |
ENV_PROTECTED |
Server blocked push to protected env |
INVALID_INPUT |
Bad flag value, e.g. --path with no shelve.json there |
Reference files (read when needed)
| File |
Contents |
cli-commands.md |
All commands, JSON shapes, config keys |
agent-workflows.md |
CI, GitHub Actions, monorepo, templates, watch |
platform.md |
Teams, tokens, encryption, UI flows |
sync-policies.md |
Push/pull conflict rules, diff / sync |
Common mistakes
| Mistake |
Fix |
shelve pull in Cursor/Claude |
shelve run -- <cmd> |
| CLI hangs |
SHELVE_* + --non-interactive |
| Push overwrites prod |
protectedEnvironments + shelve diff first |
| Secrets in git |
shelve init; never commit .env |
1---2name: shelve3description: Complete guide to Shelve — team secrets platform, CLI (@shelve/cli), sync policies, scoped tokens, shelve run for agents/CI, push/pull/diff, and the web app. Install with npx skills add https://shelve.cloud4---56# Shelve78Shelve is an open-source **team secrets platform**: web app + CLI. Store variables per team, project, and environment; inject at runtime without committing `.env` files.910- **Docs:** https://shelve.cloud/docs11- **CLI docs:** https://shelve.cloud/docs/cli12- **Install / update this skill:** `npx skills add https://shelve.cloud`13- **Catalog:** https://shelve.cloud/.well-known/skills/index.json1415## Security rules (read first)16171. **Prefer `shelve run -- <cmd>`** — secrets stay in the child process; no `.env` on disk.182. **Avoid `shelve pull` in agent shells** — writes plaintext secrets agents can read. Use `--yes` only if the user explicitly needs a disk file; run `shelve init` first.193. **Never commit** `SHELVE_TOKEN`, `.env`, or `~/.shelve/` cache.204. **Never print secret values** in logs, JSON, or commits. CLI `--json` excludes values by design.215. Run **`shelve init`** once per workspace before secret operations.226. **Protect production:** use `sync.protectedEnvironments` in `shelve.json` and/or project Settings → Sync policy.2324## Platform (teams, tokens, UI)2526| Concept | CLI / config |27|---------|----------------|28| Team | `slug` in `shelve.json`, `SHELVE_TEAM_SLUG` |29| Project | `project`, `SHELVE_PROJECT` |30| Environment | `--env`, `defaultEnv`, `SHELVE_DEFAULT_ENV` |31| API token | `SHELVE_TOKEN` — create at https://app.shelve.cloud/user/tokens (shown once; scope read/write + team/project/env) |3233**CLI vs UI:** bulk edit and audit logs → UI; local dev and CI → CLI `run`. Details: **`platform.md`**.3435## Non-interactive / agents3637Run **`shelve doctor --json`** first in automation.3839| Variable | Purpose |40|----------|---------|41| `SHELVE_TOKEN` | API token |42| `SHELVE_TEAM_SLUG` | Team slug |43| `SHELVE_PROJECT` | Project name |44| `SHELVE_DEFAULT_ENV` | Default environment |45| `SHELVE_URL` | Instance (default `https://app.shelve.cloud`) |4647| Flag | Effect |48|------|--------|49| `--json` | Machine-readable stdout; JSON errors on stderr |50| `--quiet` / `-q` | No spinners |51| `--yes` / `-y` | Skip confirmations |52| `--non-interactive` | Fail instead of prompt |53| `--debug` | Verbose (`SHELVE_DEBUG=1`) |5455Auto non-interactive when `CI=true`, agent shell detected, or `AI_AGENT` is set.5657## Command cheat sheet5859```bash60# Preferred: inject secrets61shelve run -- pnpm dev62shelve run --env preview -- pnpm build63shelve run dev # package.json script shortcut6465shelve init # agent ignores + .gitignore block66shelve login # browser device flow (humans)67shelve login --token "$SHELVE_TOKEN" # CI / automation68shelve doctor --json69shelve --json config7071# Sync72shelve diff --env staging73shelve push --env development --yes74shelve pull --env development --yes # risky in agent shells75shelve sync --dry-run --env production7677# Monorepo: from the root these four run once per package78shelve pull --path apps/web # ...or target a single package7980shelve create --name my-app --slug my-team81shelve generate --type env-example82```8384## `shelve run` flags8586| Flag | Purpose |87|------|---------|88| `--env` | Environment |89| `--template` | `.env.template` with `shelve://` refs |90| `--offline` | Encrypted cache only |91| `--no-cache` | Disable cache |92| `--cache-ttl` | e.g. `15m`, `24h` default |93| `--watch` | Reload on remote changes |94| `--restart-on-change` | Respawn child instead of SIGHUP |9596## Sync policies (`shelve.json`)9798```json99{100 "$schema": "https://shelve.cloud/schema.json",101 "slug": "my-team",102 "project": "my-app",103 "defaultEnv": "development",104 "sync": {105 "protectedEnvironments": ["production"],106 "environments": {107 "development": { "sourceOfTruth": "local" },108 "production": { "sourceOfTruth": "remote", "allowPush": false, "pullMode": "merge" }109 }110 }111}112```113114See **`sync-policies.md`** and https://shelve.cloud/docs/cli/sync-policies115116## Monorepos117118From a workspace root, `push` / `pull` / `diff` / `sync` run once per package that has its own `shelve.json`; the root itself and packages without one are skipped. `--path <dir>` targets a single package. `run` never fans out.119120- Root `shelve.json` holds shared settings (`slug`, `defaultEnv`, …); `project` stays per-package and is never inherited.121- Give the root a `project` to opt out and treat it as one project.122- With `--json`, `data` becomes `{ "packages": [...] }`, one entry per package with its `path`.123- A failing package stops the run; the error carries `context: { failedPackage, completedPackages }`.124125Details: **`agent-workflows.md`**126127## Error codes128129| Code | Meaning |130|------|---------|131| `AGENT_BLOCKED` | `pull` in agent shell without `--yes` |132| `AUTH_REQUIRED` | Missing token |133| `MISSING_ENV` | No `--env` / `defaultEnv` |134| `FETCH_FAILED` | API/cache failure in `run` |135| `PUSH_BLOCKED` / `PULL_BLOCKED` | Sync policy |136| `SYNC_CONFLICT` | `onPushConflict: fail` or prompt in CI |137| `ENV_PROTECTED` | Server blocked push to protected env |138| `INVALID_INPUT` | Bad flag value, e.g. `--path` with no `shelve.json` there |139140## Reference files (read when needed)141142| File | Contents |143|------|----------|144| **`cli-commands.md`** | All commands, JSON shapes, config keys |145| **`agent-workflows.md`** | CI, GitHub Actions, monorepo, templates, watch |146| **`platform.md`** | Teams, tokens, encryption, UI flows |147| **`sync-policies.md`** | Push/pull conflict rules, `diff` / `sync` |148149## Common mistakes150151| Mistake | Fix |152|---------|-----|153| `shelve pull` in Cursor/Claude | `shelve run -- <cmd>` |154| CLI hangs | `SHELVE_*` + `--non-interactive` |155| Push overwrites prod | `protectedEnvironments` + `shelve diff` first |156| Secrets in git | `shelve init`; never commit `.env` |