Skip to main content

pi-sync

Sync pi agent config between hosts over rsync, using your existing ssh config for routing (so ~/.ssh/config aliases just work).

pi-sync tinfoil                  # push config + extensions
pi-sync --config laptop          # only models.json and settings.json
pi-sync --pull --all tinfoil     # fetch the host's config back
pi-sync --dry-run --all a b      # preview against two hosts

Install

# the PyPI package is pi-sync-cli; it installs the `pi-sync` command
pipx install pi-sync-cli
pipx install git+ssh://git@github.com/say4n/pi-sync   # from source (needs access)

Requires Python 3.10+. uv tool install works in place of pipx install.

What syncs

Only the declarative parts of the agent dir:

Group Files
--config models.json, settings.json
--extensions extensions/
--auth auth.json — secrets, opt-in, warns on push

--all is --config + --extensions (also the default when no flag is given).

Host-local state is deliberately never touched: sessions/, npm/, models-store.json (regenerated from the pi.dev catalog), ayu/, bin/, trust.json.

Flags

Flag Effect
--all / --config / --extensions / --auth what to sync
--pull host → local instead of local → host
--delete mirror extensions/ exactly (deletes extras on the destination)
--dry-run report changes, copy nothing
-x, --exclude PATTERN skip matching files (repeatable)
--install install pi on hosts that lack it, without prompting
--uninstall remove pi from the host instead of syncing (config is kept)
--local-dir default $PI_CODING_AGENT_DIR or ~/.pi/agent
--remote-dir default ~/.pi/agent
-v / --verbose print each rsync command and its output

Multiple hosts are accepted: pi-sync a b c. Exits non-zero if any host is unreachable or any transfer fails.

Host preflight

Each host gets one ssh probe that reports reachability and pi's location in the same round trip.

If pi is missing, pi-sync hands the terminal to pi's own installer (curl -fsSL https://pi.dev/install.sh | sh), which keeps full control: its prompts (its install/uninstall/do-nothing menu, a Node.js install, a sudo password) work normally, and the sync continues once it exits. pi-sync does not add a confirmation of its own, because the installer already asks. Without a terminal it runs unattended under --install, stays quiet otherwise, and --dry-run never installs anything.

The installer's exit status is not treated as proof: its "do nothing" choice exits 0, so the host is re-probed afterwards and reported honestly.

A host without pi is skipped — copying into a host that has never run pi is not useful and usually fails anyway, since there is no agent directory to copy into. That covers an installer run that installed nothing, a failed install, and a non-interactive run without --install; a skipped host makes the run exit non-zero. After a successful install pi-sync creates the agent directory, because rsync will not create intermediate directories on its own.

The probe checks command -v pi plus the usual install locations (~/.local/bin, ~/.pi/bin, ~/.pi/agent/bin, linuxbrew, homebrew, /usr/local/bin), because a non-interactive ssh session does not source the host's shell init — on a linuxbrew host command -v pi alone misses it.

Uninstalling

--uninstall removes pi from the host instead of syncing. It runs npm uninstall -g --prefix <prefix> @earendil-works/pi-coding-agent, deriving the prefix from where pi actually lives (as the official installer does), then re-probes to confirm the binary is really gone — npm can exit 0 having removed nothing. ~/.pi/agent is deliberately left untouched, since that is your config rather than the CLI.

This exists because the official installer can only uninstall through its interactive menu: its unattended mode always installs or reinstalls. If the uninstall fails, that is usually a managed install (PI_EXPERIMENTAL=1, under <agent dir>/install) — run curl -fsSL https://pi.dev/install.sh | sh on the host and choose u.

Shell completions

Host arguments complete from ~/.ssh/config, following Include directives and skipping wildcard entries:

# bash
_PI_SYNC_COMPLETE=bash_source pi-sync > ~/.pi-sync-complete.bash
echo 'source ~/.pi-sync-complete.bash' >> ~/.bashrc

# zsh
_PI_SYNC_COMPLETE=zsh_source pi-sync > ~/.pi-sync-complete.zsh
echo 'source ~/.pi-sync-complete.zsh' >> ~/.zshrc

# fish (config.fish)
_PI_SYNC_COMPLETE=fish_source pi-sync | source

Writing the script out (rather than eval "$(_PI_SYNC_COMPLETE=bash_source pi-sync)" on every shell start) keeps shell startup fast, since the eval form runs the binary each time. PowerShell works the same way via powershell_source.

Completions are read from the config at completion time, so new hosts appear without regenerating anything.

Caveats

  • settings.json is machine-written by pi (lastChangelogVersion bumps, UI toggles), so two hosts pushing it will overwrite each other's local preferences. Sync it when you change packages, not reflexively.
  • Extensions that write runtime files inside their own directory (logs, checkpoints) get those files synced too, and each host's copy is overwritten by whichever side pushed last — exclude them with -x '*/logs/*'.
  • Extension versions are whatever each host has installed; pin them in settings.json (npm:pi-lens@1.2.3) if you need hosts identical.
  • --auth copies API keys in the clear. Prefer OPENCODE_API_KEY (and friends) in the environment where you can.
  • Remote paths go through the host's shell, so ~ expands there as usual.

Development

uv sync
uv run pytest
uv run pi-sync --help

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pi_sync_cli-0.3.0.tar.gz (24.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pi_sync_cli-0.3.0-py3-none-any.whl (10.5 kB view details)

Uploaded Python 3

File details

Details for the file pi_sync_cli-0.3.0.tar.gz.

File metadata

  • Download URL: pi_sync_cli-0.3.0.tar.gz
  • Upload date:
  • Size: 24.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pi_sync_cli-0.3.0.tar.gz
Algorithm Hash digest
SHA256 f1bf2c7951c7e788460bba2f90a37dcb000445cfcbf94cc5377ed89e7d4c8d7b
MD5 308f2c6f9eaeab2b9c3605f744211f4e
BLAKE2b-256 ba44e8aa35e2bc57cf6e47269822c65bdb7d558c192123e29625dbf9f9e4a1c1

See more details on using hashes here.

File details

Details for the file pi_sync_cli-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: pi_sync_cli-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 10.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pi_sync_cli-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6c732d5608b951e42e062d463ade03835b71cdbc615beb8a4be5c567ff308e90
MD5 0a652f43d5fc38224cb9c901645f89b3
BLAKE2b-256 5b5e8b2e76e5f28b28011ec06dd84c29cbdf8ed5496c8566a08159c981897d9e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

This release

0.3.0 This release

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page