Documentation
Quiver is a CLI sync layer for the global skills your AI agents share. One command pushes, one command pulls — and your skills follow you to every machine you sign in on.
Introduction
Most AI coding agents — Claude Code, Cursor, Gemini CLI, GitHub Copilot — read from a shared global skill registry at ~/.agents/.skill-lock.json. When you set up skills on one machine, they live in that file. Move to another machine and you're starting from scratch.
Quiver fixes that. It writes your lock file to a private GitHub Gist and replays the installs on any other machine you sign in on. There is no Quiver server, no new account, and no proprietary backend — the Gist on your own GitHub account is the source of truth.
Install Quiver. Run quiver login once. On every machine after that, run quiver sync.
Install
Quiver is distributed via npm and requires Node.js 18 or newer.
Verify the install:
Prefer not to install globally? You can also run it with npx: npx usequiver sync. The CLI behaves identically; only the invocation differs.
Quick Start
From a machine that already has the skills you want to back up:
Then, on every other machine you log into:
That's the whole loop. Run quiver push when you add new skills, quiver sync on machines that need to catch up.
Authentication
Quiver authenticates through GitHub's device flow — the same OAuth dance the official gh CLI uses. You'll be given a short code and a URL to paste it into. Quiver never sees your password, and the token never leaves your machine.
Required scopes
Quiver requests the minimum scopes needed to read and write a private Gist:
gist— to create and update thequiver-skill-lock.jsonGist on your account.read:user— to display your username inquiver whoami.
Tokens are stored in your OS keychain via keytar — never in a plaintext file. To revoke access, visit github.com/settings/applications.
Commands
Quiver exposes six commands. None of them take more than one or two flags. The signatures below use <required> for positional arguments and [--optional] for flags.
login
push
sync
What happens
- Fetches the remote lock from your private Gist
- Computes the diff: skills present remotely but missing locally
- Groups missing skills by
sourceUrl— onenpx skills addinvocation per repo - Runs all groups in parallel with a live progress line per source
- Re-reads the local lock file and upserts only the skills that succeeded
- Prints a summary:
N skills added, M already up to date
If one source group fails, the others still complete and their skills are written to the lock file. The command exits with an error listing which sources failed.
Example output
In non-TTY environments (CI, piped output) listr2 falls back to plain line output — one line per source group, no spinner characters.
status
remove
whoami
Lock file
Quiver does not invent a new file format. It reads and writes the same ~/.agents/.skill-lock.json that npx skills already produces. A typical entry looks like this:
Quiver only writes to the skills object and the updated timestamp. It never touches keys it doesn't recognize, so it's safe to use alongside future skill-lock extensions.
Gist as storage
On first push, Quiver creates a single private Gist named quiver-skill-lock.json on your account. Every push is a new Gist revision, which gives you a free audit log: visit the Gist on github.com and you can browse every change.
There is exactly one Gist per user. Quiver finds it by listing your Gists and matching the filename — so renaming it on GitHub will break sync until you rename it back.
Conflicts
Quiver is intentionally simple: last push wins. If two machines push within the same minute, the later revision overwrites the earlier one in the Gist. The earlier revision is still visible in the Gist's history and can be recovered manually.
Sync is the safer direction. It never deletes local skills unless you pass --prune, so pulling stale data can only add — never lose — skills.
Config
Quiver reads optional configuration from ~/.config/quiver/config.json:
| Key | Type | Default | Description |
|---|---|---|---|
deviceName | string | os.hostname() | Friendly name shown in whoami output. |
lockFilePath | string | ~/.agents/.skill-lock.json | Where to read/write the local lock file. |
gistFilename | string | quiver-skill-lock.json | Filename of the remote Gist. |
autoPushOnAdd | boolean | false | Watch the lock file and push on every change. |
Environment variables
| Variable | Description |
|---|---|
QUIVER_TOKEN | Override the keychain token. Useful in CI. |
QUIVER_GIST_ID | Pin to a specific Gist instead of auto-discovering by filename. |
QUIVER_LOCK_FILE | Override lockFilePath from config. |
NO_COLOR | Disable colored output. Standard no-color.org behavior. |
DEBUG=quiver:* | Verbose debug logging. |
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | Generic failure. Check stderr. |
2 | Not authenticated — run quiver login. |
3 | Lock file missing or unreadable. |
4 | Remote Gist not found. |
5 | Network error reaching GitHub API. |
10 | Sync produced conflicts that need manual resolution. |
FAQ
Can I share a lock file with my team?
Not yet. Quiver is built around your Gist on your GitHub account. Team-shared skill sets are tracked in issue #14 — open to design feedback.
Is my data private?
Yes. The Gist is created private. Quiver requests the gist scope (which covers both public and private), but only ever writes private Gists. You can verify this in gist.github.com/mine.
Does it work on Windows?
Yes — Quiver runs on macOS, Linux, and Windows (PowerShell and WSL). Paths are normalized internally, so a lock file pushed from macOS replays cleanly on Windows.
What happens if I'm offline?
quiver sync and quiver push exit with code 5 and a clear error message. Your local lock file is never touched on network failure.