description: Complete AgentSync CLI reference: every command, flag, default, and caveat for init, push, copy, status, key, skill, plugin, vault, and the TUI.¶
Commands¶
Every AgentSync subcommand in one reference: what it does, what it needs, what it produces, and the caveats that bite if you ignore them.
What this page owns¶
This page owns the command contract. It documents every flag, every default, every exit condition. It does not document how the command works internally — that lives in Architecture and is referenced where the contract depends on it.
Install paths¶
Every example below uses the globally installed binary:
The same commands work through bunx without a global install:
When developing from source, replace the binary call with bun run src/cli.ts. The flags are identical.
Two ways to use agentsync¶
- Interactive: run
agentsync(no subcommand) to open the TUI. It is the right entry point for everyday browsing, sync, and migration. - Scripted: every subcommand below runs unchanged from a shell, CI, or a
wrapper script. Bare
agentsyncin a non-TTY context falls back tostatustext output so existing pipelines are not affected.
Command index¶
| Command | Purpose |
|---|---|
(bare) / tui |
Open the interactive tab-based TUI. |
init |
Bootstrap the vault, machine key, and config. |
push |
Snapshot, sanitise, encrypt, and fast-forward this machine's namespace to the vault. |
copy |
Apply an artefact (or subdir) from a machine's vault namespace to local disk (copy self … for your own). |
ls |
List machine namespaces, or the copyable artifact paths in one. |
status |
Compare local snapshot to decrypted vault state (any machine via --machine). |
doctor |
Check the local environment before blaming sync logic. |
key |
Add, list, or remove recipients, or rotate the current machine key. |
config |
View or change vault config (agents, security policy). |
skill |
Remove a skill from the vault. |
plugin |
List or reinstall a machine's Claude plugins from its vault manifest. |
vault |
Migrate an older vault to the current format (vault upgrade). |
migrate |
Translate configuration between agent formats. |
destroy |
Wipe the local vault clone or the remote vault contents (via commit). |
upgrade |
Check GitHub for a newer release and install it when possible. |
tui¶
Why: Browse the vault, inspect what each local agent has on disk, trigger a push, browse other machines and copy their config to this one, and run cross-agent migrations from a single interactive screen.
Usage:
agentsync # bare invocation opens the TUI on a real terminal
agentsync tui # explicit alias, same behaviour
Tabs:
| Tab | What it shows |
|---|---|
| 1 Dashboard | Vault state, agent summary, init / key-rotate launchers, and an update banner when a newer release is available. |
| 2 Sync | Per-artifact rows grouped by sync status (local-changed, local-only, vault-only, unknown, synced). Multi-select with space; push selected with p; bulk-remove any selected vault artifacts with x (y/n confirm) — rows with no vault copy (local-only) are ignored. Enter on a skill drills into its files with per-file diff. |
| 3 Machines | The vault's machines/<name>/ namespaces. Move with ↑/↓; enter copies the selected machine's config to this machine (the same performCopy core as the CLI; never touches the vault). |
| 4 Migrate | From / To / Type form (To and Type are multi-select with sub-cursor). Preview is mandatory before Apply enables. |
| 5 Activity | Session-only ring buffer of TUI actions. |
| 6 Config | View and change vault config (agents enabled, claudePlugins.*, security.*) with ↑/↓ to move, space to toggle a boolean, ←/→ to cycle an enum. Cycling security.secretScan shows a one-line explainer of the selected mode; choosing off first prompts a y/n confirm because it pushes live secrets. Writes go through the same config core (reconcile + commit + push). Also lists the recipients who can decrypt the vault, read-only. |
Global keys (any tab):
| Key | Action |
|---|---|
1 – 6 |
Jump to tab |
Tab / Shift-Tab |
Cycle tabs |
p |
Push vault (honours selection in the Sync tab as a per-file allowlist) |
r |
Refresh current tab |
? |
Toggle the keymap overlay |
q / Ctrl-C |
Quit, restoring the terminal |
Outcome: every state change is additive on the same data the CLI
subcommands operate on. Push runs the same performPush core as agentsync
push; the Machines tab calls the same performCopy core as
agentsync copy; migrate calls the same planner as agentsync migrate; bulk
removal calls the same performVaultRemove core that agentsync skill remove
delegates to, once per selected vault artifact; the Config tab writes through
the same performConfigSet core as agentsync config set.
Caveats:
- The TUI is interactive-only. In a non-TTY context (piped stdin/stdout,
nohup, CI runners) bareagentsyncdeliberately falls back to textstatusoutput so existing scripts continue to work. - The activity log is session-scoped — closing the TUI discards history.
- Push and copy run in-process — the TUI calls the same command cores directly, so there is no background service to start first.
Conventions¶
- Why — when to reach for this command.
- Usage — the typical invocation.
- Flags — supported options.
- Outcome — what the filesystem and the vault look like afterwards.
- Caveats — non-obvious behaviour. Read these.
init¶
Why: Create the local vault workspace, the machine's age keypair, agentsync.toml, and the initial Git wiring to the vault remote.
Usage:
Flags:
| Flag | Default | Description |
|---|---|---|
--remote |
required | Git remote URL for the vault. |
--branch |
main |
Branch in the vault remote that this machine tracks. |
Outcome: a local vault directory exists, the machine's recipient is registered in agentsync.toml, and AgentSync either creates the first remote commit (empty-branch bootstrap) or joins the existing remote history before writing machine-specific changes.
Caveats:
- If the remote branch does not yet exist,
initcreates it viagit push --set-upstreamon the first commit. The remote repository itself must already exist on the host;initdoes not create the repo for you. - An empty remote branch is treated as first-machine bootstrap. An existing remote branch is joined.
- If the local vault already diverged from the configured remote branch,
initstops with a recovery error rather than pushing a local-first history. See Recover from divergence. - The generated private key must be backed up outside the vault. The vault cannot decrypt it for you if the key is lost.
push¶
Why: Snapshot the enabled agents' local configuration, run the sanitiser, encrypt, and fast-forward the result to the vault remote.
Usage:
Flags:
| Flag | Default | Description |
|---|---|---|
--agent |
all enabled | Restrict to one agent (claude, cursor, codex, copilot, vscode). |
--message |
auto | Custom commit message for the vault commit. |
--dry-run |
false |
Show actions and previews without writing or pushing. |
Outcome: every changed artefact for the targeted agent(s) is encrypted and committed to the vault, then fast-forward-pushed to the remote. The vault commit message names the agent(s) and the machine.
Caveats:
- Push is additive: deleting a skill locally does not remove it from the vault. Use
skill removefor explicit removal. - The sanitiser is a hard gate. Literal secrets or never-sync paths abort the entire push before bytes leave the machine. See Push aborts because secrets were detected.
- Reconciliation is fast-forward only. Divergence aborts the push with recovery guidance.
--dry-runexercises the snapshot, sanitiser, and encryption pipeline so previews reflect what would actually be written.
copy¶
Why: Restore an artifact (or a whole subdir) from any machine's vault namespace onto local disk. In v2 the vault is push-only backup, so copy is the only vault→local path. copy self <path> restores your own machine's backup.
Usage:
agentsync copy work-laptop claude/CLAUDE.md.age # from another machine's namespace
agentsync copy self claude/skills/ # restore your own skills subdir
agentsync copy work-laptop claude/ --dry-run # preview the whole claude namespace
Arguments:
| Argument | Description |
|---|---|
<machine> |
Source machine namespace under machines/, or self for this machine. |
<path> |
Logical vault path: a single artifact (claude/CLAUDE.md.age) or a subdir prefix (claude/skills/) to copy every artifact beneath it. |
--dry-run |
Preview each artifact without writing locally. |
Outcome: the named artifacts are decrypted with the local key (encryption is to all recipients) and applied to local agent paths using the same handlers, JSONC merge, and .bak backups as a full restore. copy writes only to local disk — it never writes this machine's vault namespace; the next push captures the change normally. An unknown machine lists the available namespaces; a missing artifact reports the path.
Caveats:
copyis additive: it applies what the source has and never deletes a local file the source omits.- Reconciliation is fast-forward only.
- Plugins are not copyable via
copy— they are reinstalled from the recorded manifest byplugin install.
ls¶
Why: Discover what is in the vault before you copy. copy needs an exact logical path (e.g. claude/CLAUDE.md.age); ls is how you find those paths — especially on a fresh machine where you do not yet know another machine's layout.
Usage:
agentsync ls # list every machine namespace in the vault
agentsync ls work-laptop # list the copyable artifacts in that namespace
agentsync ls work-laptop claude/ # narrow to a path prefix
agentsync ls self # browse this machine's own backup
Arguments:
| Argument | Description |
|---|---|
<machine> |
Machine namespace to browse, or self. Omit to list all machines. |
<path> |
Optional path prefix to narrow the listing. |
Outcome: with no argument, the machine namespaces under machines/. With a machine, the logical .age paths you can hand to copy <machine> <path>. Read-only and key-free — it lists which encrypted files exist without decrypting them, so a machine that is not yet a recipient can still discover what is copyable. It reconciles fast-forward first so the listing reflects the latest backup.
status¶
Why: Compare the local snapshot to the decrypted vault state for the enabled agents — this machine's own backup by default, or another machine's via --machine to preview a copy.
Usage:
agentsync status
agentsync status --verbose
agentsync status --machine work-laptop # diff local config against another machine's backup
Flags:
| Flag | Default | Description |
|---|---|---|
--verbose |
false |
Show per-file hashes alongside each row. |
--machine |
this machine | Compare against another machine's namespace (or self). Needs the private key to decrypt; an unknown name lists the available machines. |
Outcome: a per-agent report covering every enabled agent. Each row carries one of the following status strings, printed verbatim:
synced— local content matches the vault.local-changed— both sides have the file but the content differs. Runpushto publish the local copy, orcopy self <path>to restore the vault copy after backing up the local one.local-only— the machine has content the vault does not. Runpush.vault-only— the source namespace has content the local disk does not. Runcopy <machine> <path>(orcopy self <path>when comparing againstself) to bring it down.unknown— the private key was unavailable, so the vault row could not be decrypted and the comparison is inconclusive. Restore the key and re-run.error— snapshot or decryption failed for that row. The error detail is printed in the same row; address it before trusting the rest of the report.
Caveats:
statusis read-only. It never mutates the vault or local files.- Vault-only entries marked "not on this machine" are normal when another machine snapshots an agent this machine does not enable.
--machinecompares only the agents this machine has enabled. To browse another machine's full namespace (including agents you have disabled), usels.
doctor¶
Why: Check the local environment before blaming sync logic. A clean doctor is the precondition for filing a bug.
Usage:
Outcome: a report covering:
- private key presence and permissions,
- config parseability,
- age-encryption module availability,
- remote reachability,
- obvious unencrypted sensitive files in the vault,
- readability of the per-agent skills directories (
buildSkillsDirCheckswarns if a directory is missing, unreadable, a symbolic link, or exists but is not a directory).
Caveats:
doctordoes not fix anything. It surfaces the failure mode so you can choose the right runbook in Operations.- A
doctorwarning about a sensitive file in the vault is always serious. See Doctor reports a sensitive file in the vault.
upgrade¶
Why: Stay on the latest release without leaving the tool. upgrade asks GitHub for the newest published version and, when it can, installs it for you.
Usage:
agentsync upgrade # check, then install if a newer version exists
agentsync upgrade --check # report only, install nothing
Outcome: depends on how agentsync was installed:
| Install method | What upgrade does |
|---|---|
bun install -g @chrisleekr/agentsync |
Reinstalls the package globally at the latest version. Restart agentsync to run the new code. |
| Standalone binary | Prints the releases page — a running binary cannot replace its own file. Download and verify the new binary against SHA256SUMS yourself. See Verifying release binaries. |
bunx |
Nothing to do — bunx fetches the latest on every run. |
Caveats:
- The check calls the GitHub releases API. Offline or rate-limited, it fails quietly and reports that it could not check (exit code 1).
- The TUI Dashboard runs the same check in the background and shows an
Update availablebanner; pressuthere to upgrade a global install. - The result is cached for 24 hours at
~/.config/agentsync/update-check.json(%APPDATA%/agentsyncon Windows).agentsync upgradealways re-checks and ignores the cache.
key¶
Why: Manage who can decrypt the vault — add a recipient, list recipients, deauthorize (remove) one, or rotate the current machine's keypair.
Usage:
agentsync key add <name> <age-public-key> # authorize a recipient
agentsync key list # audit who can decrypt the vault
agentsync key remove <name> # deauthorize a recipient
agentsync key rotate # new local identity, re-encrypt
Outcome: add, remove, and rotate decrypt every existing vault artefact under the current key and re-encrypt it under the updated recipient set, then commit and push. list is read-only — it prints each recipient alias and public key from agentsync.toml, marking the entry that belongs to this machine with *.
Caveats:
key add,key remove, andkey rotatereconcile against the latest remote state before they rewrite encrypted vault content.- If the vault history has diverged, key-management commands stop until the vault is reset or recloned. See Recover from divergence.
- Rotation depends on the old private key still being available so existing vault files can be decrypted. Back up the old key before rotation if you intend to retire that identity entirely. Rotation is crash-safe: it re-encrypts to both the old and new key, swaps the key file atomically, then drops the old recipient, so an interrupted rotation never leaves a vault no on-disk key can read.
key removere-encrypts forward for the remaining recipients, so the removed key can no longer read future pushes. It cannot retro-purge git history: a removed key still decrypts the vault state already on the remote. For true revocation of a lost machine, also rotate any secrets it could read. See Deauthorize a lost machine.key removerefuses to remove the only remaining recipient (a vault must stay decryptable) and refuses to remove the key of the machine you run it on (you cannot deauthorize yourself — run it from another machine to remove a lost one).- Recipient names are stable config keys and are visible in the vault repository. Use names that describe the machine clearly without leaking sensitive context.
config¶
Why: View or change the vault configuration in agentsync.toml without hand-editing it — which agents are enabled and the secret-handling policy.
Usage:
agentsync config list # print every configurable key
agentsync config get security.secretScan # read one value
agentsync config set agents.vscode true # enable VS Code sync
agentsync config set security.secretScan strict # widen secret detection
agentsync config set security.allowSecretValues '["AKIA-not-a-real-key"]'
Settable keys (dotted paths under these sections):
| Key | Type | Meaning |
|---|---|---|
agents.<claude\|cursor\|codex\|copilot\|vscode> |
boolean | Whether that agent is snapshotted on push. |
claudePlugins.syncPlugins |
boolean | Record the Claude plugin reinstall manifest on push. |
security.secretScan |
standard|strict|redact|off |
Push-time secret-scan mode. standard = built-in credential patterns (abort on hit); strict also flags JWTs; redact replaces ordinary tokens in structured config with a $AGENTSYNC_REDACTED_<FIELD> placeholder and pushes (copy then preserves a real local value over the placeholder); off waives the ordinary patterns. The catastrophic tier (age key, PEM) still blocks in every mode. |
security.allowSecretValues |
string[] (JSON) | Literal values exempt from ordinary-token detection and base64 redaction. Catastrophic-tier values (age key, PEM private keys) are never exemptible. |
security.redactBase64Values |
boolean | When true (default), redact long base64-looking JSON values; set false if a config legitimately stores base64 that must round-trip. |
What the secret scan is — and is not. It matches a fixed set of high-precision credential formats (vendor API-key prefixes, AWS/GitHub/GitLab/Slack/Google tokens, age identities, PEM private-key headers;
strictadds JWTs). It is not a general secret scanner — a plain password, a bespoke token, or a connection string with no recognised shape passes through. Encryption is the real protection; the scan only stops well-known credentials from entering git history.offwaives the ordinary API-token patterns, but the catastrophic tier (age key, PEM private keys) still blocks in every mode, and skill-bundle interiors are always scanned atstandardas a fail-safe.agentsync.tomlitself is committed in plaintext, soallowSecretValuesis for exempting legitimate high-entropy non-secret values — never paste a real credential there.config setrefuses to store a recognised credential in any key other thansecurity.allowSecretValues. See Push aborts because secrets were detected.
Outcome: list and get are read-only. set validates the new value against the full config schema (so an out-of-range debounce or an invalid enum is rejected before anything is written), then — because agentsync.toml is shared across machines — reconciles fast-forward, commits, and pushes the change, exactly like key add.
Caveats:
version,recipients, andremoteare not settable here. Recipients are managed bykey; the remote is fixed atinit; the format version is the old-binary guard.- A value is parsed as JSON first (
true,500,["x"]), falling back to a plain string for bare words (strict). Quote a JSON array in your shell. setreconciles against the remote first, so it fails closed on diverged history like every other vault-writing command.
skill¶
Why: Remove a skill from the vault without affecting the rest of the snapshot. This is AgentSync's only explicit, non-additive operation.
Usage:
Flags:
| Flag | Default | Description |
|---|---|---|
--machine |
this machine | Remove from another machine's machines/<name>/ namespace. Validated against the same path-traversal rules as the resolved machine name. |
Outcome: the vault artefact for that skill is deleted, the change is committed and pushed under the fast-forward reconciliation rule. The local skill directory on the current machine is left untouched.
Caveats:
skill removeis the only non-additive operation in AgentSync. It deletes the vault artefact but does not remove the local skill directory on the current or other machines.- After
skill remove, every machine that copied the skill previously still has the local directory until you delete it manually there. See A skill I deleted reappears after copy on another machine. - To snapshot a single agent's skills, use
push --agent <agent>; to bring one machine's skills onto this one, usecopy <machine> <agent>/skills/. There is no targetedskill push/skill copy; the snapshot for an agent always includes every skill that survives the walker contract.
plugin¶
Why: Reproduce a machine's Claude plugins on another machine. AgentSync does not encrypt the plugin tree; the marketplace is the source of truth. push (with [claudePlugins] syncPlugins = true) records a distilled manifest — each plugin's name@marketplace, scope, and enabled flag — and plugin install reinstalls from it via the local claude CLI.
Usage:
agentsync plugin list <machine> # print the recorded manifest
agentsync plugin install <machine> [name] # reinstall all, or one named plugin
Use self as <machine> to act on this machine's own manifest.
Outcome: install registers each referenced marketplace (claude plugin marketplace add), installs each plugin at its recorded scope (claude plugin install <name>@<marketplace> -s <scope>), then enables or disables it to match the manifest.
Caveats:
- Requires the
claudeCLI onPATH; a missing binary fails loudly rather than skipping silently. - Reinstall fetches the latest version — there is no version pin.
- Local edits to plugin files are not preserved; only the manifest (marketplace + name + scope + enabled) round-trips.
vault¶
Why: Migrate an older flat (v1) vault to the per-machine layout (v2), where every artefact lives under machines/<name>/. This is the vault-format migration — distinct from migrate, which translates config between agents, and from upgrade, which updates the AgentSync binary.
Usage:
Outcome: the existing flat content is assumed to belong to this machine and is git mv'd under machines/<this-machine>/, the config version is bumped to the integer 2, and the change is committed and fast-forwarded to the remote. It reconciles first, so a vault another machine already upgraded is detected and the command is a no-op. Idempotent — running it on a v2 vault prints "already at format v2".
Caveats:
- If the vault format is newer than this binary understands, the upgrade refuses and tells you to run
agentsync upgradeto update AgentSync first. - Old (v1) binaries cannot read a v2 vault at all:
versionis an integer literal, and their string-typed schema rejects it. This is deliberate — it stops an old binary writing flat directories besidemachines/.
migrate¶
Why: Translate configuration between Claude, Cursor, Codex, Copilot, and VS Code without touching the vault.
Usage:
Flags:
| Flag | Required | Values | Description |
|---|---|---|---|
--from |
yes | claude, cursor, codex, copilot, vscode | Source agent. |
--to |
yes | claude, cursor, codex, copilot, vscode, all | Target agent(s). |
--type |
no | global-rules, mcp, commands, skills, rules | Filter to one config type. |
--name |
no | artefact name | Migrate a single artefact (file or skill/rules directory). Requires --type. Hard-errors if not found. |
--dry-run |
no | — | Preview without writing. |
Outcome: the source agent's matching configuration is translated through the format-specific translators and written to the target agent's config location on disk. The vault is not touched.
Caveats:
migrateoperates on local files only. No vault initialisation is required.- See Migrate for the full support matrix per config type, MCP transport translation rules, and per-agent quirks.
destroy¶
Why: Reset vault state when you want to start over — either by removing
the local clone (--scope=local), wiping the remote contents via a normal
commit (--scope=remote), or both (--scope=all).
Agent files are never touched.
agentsync destroydoes not read, modify, or delete a single byte under~/.claude/,~/.cursor/,~/.codex/,~/.copilot/, or your VS Code user directory, regardless of scope. This guarantee is enforced by code (noAgentPaths.*import insrc/commands/destroy.ts) and by test (three sha256+mtime invariants indestroy.test.ts).
Usage:
agentsync destroy # local-only, default
agentsync destroy --scope=remote # wipe remote via commit
agentsync destroy --scope=all # both
Flags:
| Flag | Default | Description |
|---|---|---|
--scope |
local |
One of local, remote, all. local removes the local vault dir. remote pushes a commit that git rm -rfs every tracked file on the remote — not a force-push, so history stays intact and git revert recovers the data on machines that still have it. all does both, remote first. |
--force |
false |
Bypass the agentsync.toml safety check. Use when destroying a half-initialised vault that never got a config file written. Does not bypass the three confirmation gates. |
--yes |
false |
Skip all three confirmation gates. Intended for scripted use; the command otherwise requires an interactive TTY. |
Confirmation gates (when --yes is not passed):
- Preview — prints the exact paths that will be removed and lists
every category of file that will not be touched (including local
agent installations). Press
yto advance, anything else to abort. - Typed phrase — type the exact string the preview tells you to:
--scope=local: typeDESTROY.--scope=remote/--scope=all: typeDESTROY <branch>@<remote-fragment>, where the fragment is the last two path segments of the remote URL (e.g.DESTROY main@chrisleekr/agentsync-vault). This forces you to read the remote URL off the preview before you can confirm.- Final y/n — last chance. Anything other than
yaborts.
Outcome:
| Scope | After destroy |
|---|---|
local |
~/.config/agentsync/vault/ (or %APPDATA%/agentsync/vault/ on Windows) is gone. ~/.config/agentsync/key.txt, the remote, and every ~/.<agent>/ directory are unchanged. Re-init from the same remote restores the clone. |
remote |
Remote branch has a new commit, destroy: clear vault content, that removes every previously-tracked file. Local vault dir keeps its .git/ history. Other machines that still have the data can git revert <sha> to recover. |
all |
Both of the above. Remote is wiped first so a failed push does not leave you with a wiped local that cannot reach the remote. |
Caveats:
- Other recipients are affected by
--scope=remote/--scope=all. Their nextagentsync pushorcopywill reconcile against an empty vault and they lose theiragentsync.tomlconfig — they will need to re-init. key.txtis preserved across every scope. Re-init from the same remote reuses the existing identity so you stay a recipient. Delete the key manually (rm ~/.config/agentsync/key.txton Unix, or remove%APPDATA%/agentsync/key.txton Windows) if you really need a key wipe.- Refuses to run in a non-TTY context without
--yes, to protect against accidental destroys from piped scripts.
Exit codes¶
| Code | Meaning |
|---|---|
| 0 | Success. |
| 1 | Failure. Re-run only after addressing the printed cause. Some failures are not recoverable (a lost private key cannot be re-derived; a divergent vault must be reset or recloned). |
Every command prints a one-line summary on success and an actionable error on failure. If neither is printed, the command was killed externally — a Gatekeeper SIGKILL on the unsigned macOS release binary is the most common case. To avoid it, install via bun install -g @chrisleekr/agentsync, or verify the binary first with gh attestation verify. See Operations → Verifying release binaries.