Land on any machine and everything's already there.
perch makes any working directory follow you between machines — your code, your encrypted secrets, and (if you code with an AI assistant) its memory and journal — so you can stop on one computer and pick up on another mid-thought. One repo or a fleet of them. Nothing held by a third party; the key stays in your pocket.
# on the machine you're working on now:
perch init && perch save
# on any other machine:
perch bootstrap
# …and you're in sync.Git gets your code onto another machine. It leaves everything that makes the machine actually yours behind. perch carries the rest — safely.
- Your secrets travel (encrypted). Git ignores
.envfor good reason — so on the other machine your app boots with no API keys and breaks in a way that eats your evening. ("I swear I added that key this morning." You did — on the other laptop.) perch age-encrypts your envs, commits only the ciphertext, and lays them back down on arrival. - Your AI assistant keeps its memory. If you pair with an AI, everything it knows — the shape of the codebase, the decisions, "where we left off" — lives outside git. Plain git = amnesia: you spend an hour teaching it on your work laptop, get home, open your desktop, and it chirps "Hi! What are we building today?" 😩 perch carries the memory + journal, so it opens with "Right — we were mid-refactor on auth, want to keep going?"
- No commit/push/pull ceremony. No "did I push? did I pull? is this the latest?" Hooks sync on open and close. Return to a machine that sat idle for a week and it auto-heals — pulls the code, refreshes stale secrets — without ever clobbering edits you hadn't saved yet.
- One repo or many. A single repo, or an umbrella that shepherds a fleet of independent project repos — and you can open the umbrella or any one project directly and it still just works.
- You own all of it. Encrypted secrets in your private repo, the key in your pocket. No SaaS,
no third party holding your
.env.
Think of it as your workspace's carry-on bag: your code, your keys, your memory, your journal — packed once, and it follows you everywhere. And because it's MIT and just one readable shell script, fork it, rename it, bend it into whatever you want.
1. Hand it to your AI assistant. Point your coding assistant at ASSISTANT-SETUP.md and it will do the setup for you — set things up on the computer you're on, hand you your key to carry to the next machine, and give you the exact commands for there (or finish it there too, if you let it).
2. Run a few commands yourself. Follow HOWTO.md — step by step, per machine, nothing assumed. If you've never touched a terminal in anger, start there.
curl -fsSL https://raw.githubusercontent.com/pxspaces/perch/main/install.sh | sh # global install (optional)
cd ~/path/to/your-project
perch init # scaffolds sync structure, vendors ./perch, git-inits
# → put real values in your .env files, then create a PRIVATE sync repo and push:
gh repo create my-project-sync --private --source "$PWD" --remote origin --push
perch save # encrypts .env → secrets/*.age, commits, pushes
# ⚠ BACK UP the age key it created (~/.config/age/keys.txt) — you need it on every machine# install perch (or use ./perch after cloning) · put the SAME age key at ~/.config/age/keys.txt
git clone <my-project-sync remote> ~/anywhere/you-like
cd ~/anywhere/you-like
perch bootstrap # re-clones sub-projects, links memory, decrypts secrets
# → identical to the source. Start working.The folder can be anywhere, named anything, on each machine. perch finds your workspace by a
.perch.rootmarker and re-wires everything to this machine's path — the only thing that must match across machines is your age key.
Add a third or fourth machine the same way. Every day, just work — or run perch pull when you sit
down and perch save when you leave.
| How you run it | You install… | |
|---|---|---|
| Global | perch … (any folder) |
the command once per machine (install.sh → ~/.local/bin) |
| Per-project | ./perch … |
nothing — perch init vendors a ./perch into the workspace; it travels with your sync repo |
- Use global when you'll sync several projects, or just want to type
perchwithout./. One small install per machine, benefits every workspace. - Use per-project when you want the workspace fully self-contained and to install nothing on
the box — ephemeral containers, shared/locked-down machines, "don't pollute this computer." The
tool rides inside the repo, so on a destination you just
git clone …and run./perch bootstrap. - You can mix them: a machine can have global
perchand workspaces that also carry./perch.
The only asymmetry: to run perch init the very first time in per-project mode you need the script
once — either do a one-off global install, or grab just the file:
curl -fsSL https://raw.githubusercontent.com/pxspaces/perch/main/perch -o perch && chmod +x perch && ./perch init.
perch init— once per workspace, on the first machine (turns a folder into a synced workspace).perch bootstrap— once per workspace on each new machine (clone → bring it to life).perch pull/perch save— the daily rhythm (mostly automatic; see below).
Run perch help for the full command list, or see FEATURES.md.
perch init writes Claude Code SessionStart/Stop hooks so sync happens automatically: pull +
auto-resync when you open the workspace, encrypt + commit + push when you close it. Don't use Claude
Code? Everything works manually — perch pull / perch save.
- Real
.envfiles are never committed — only their age-encryptedsecrets/*.env.age. - The age private key (
~/.config/age/keys.txt) is the one thing that isn't in git. Back it up in a password manager and place it on each machine. It's what decrypts your secrets everywhere.
- Claude memory lives outside your project folder and is keyed by the machine-specific path —
memory won't follow you by itself; perch's symlinks are what carry it (re-wired per machine on
bootstrap). - Never commit plaintext
.envor your private key. perch's.gitignorehandles this; keep it. - Rotated a shared secret (a token)? Run
perch savepromptly so the new value leads — the returning-machine guard protects un-saved local edits, but an older ciphertext shouldn't linger. - Don't sync chat transcripts — memory + journal are the continuity layer. Keep a short "where
we are / next step" note current in
memory/MEMORY.mdso a fresh session on any machine can reconstruct the plan.
git, age (+ age-keygen); gh (GitHub CLI) for private clones. Claude Code is optional (only for
the auto-sync hooks).
MIT — see LICENSE. Fork it, rename it, make it yours.