-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Problem
I use Claude Code on multiple machines (laptop, desktop, VPS). Each has its own ~/.claude/ with independent USER/, MEMORY/, skills, and learnings. So my DA knows me on one machine but starts fresh on the next. I end up re-teaching context and losing continuity between devices.
I imagine this is a common pain point as PAI adoption grows, since a lot of us work across multiple computers.
Why PAI is already well-suited for this
The architecture makes sync surprisingly doable:
- Plain text files: Git-friendly
- USER/ vs SYSTEM/ split: portable identity is already a design goal
- CLI-first: sync commands fit the existing patterns
- Append-only history: JSONL logs merge trivially
The main missing piece is a config split to separate machine-specific from universal concerns, plus tooling to automate the sync.
Proposed Solution
1. Config split
Introduce local override files that are gitignored, merged at SessionStart:
settings.local.json→ machine-specific overrides (merged on top ofsettings.json).mcp.local.json→ machine-specific MCP servers (merged on top of.mcp.shared.json)
This is useful independently of sync since it lets users maintain machine-specific config without touching shared files.
2. pai-sync skill
A new skill using Git as the default backend:
skills/Sync/
├── SKILL.md
├── workflows/
│ ├── setup.md # Interactive setup wizard
│ ├── push.md # Commit + push
│ ├── pull.md # Pull + merge
│ └── status.md # Show sync state
└── tools/
├── sync-init.ts # Create private repo, configure remote, git-crypt
├── sync-push.ts # Smart commit + push
├── sync-pull.ts # Pull + auto-resolve
├── sync-status.ts # Show divergence across devices
└── sync-resolve.ts # AI-assisted conflict resolution
What syncs vs. what stays local:
| Synced | Local (gitignored) |
|---|---|
| USER/, MEMORY/ | .env (encrypted via git-crypt) |
| skills/, agents/, hooks/ | .mcp.local.json |
| history/sessions/, learnings/, decisions/ | history/raw-outputs/ |
| settings.json | settings.local.json |
| voice-server/, Observability/ |
3. SessionStart/SessionEnd hooks
Auto-pull on session start, auto-push on session end. Silent failure, never blocks a session.
4. Conflict handling
Three layers:
- Prevention: auto-sync hooks keep the window for conflicts near zero
- Auto-resolution: custom Git merge drivers for append-only files (JSONL: concatenate + deduplicate by timestamp)
- AI-assisted resolution: when real conflicts occur (e.g., two edits to TELOS), the DA reads both versions, shows the diff in plain language, proposes a semantic merge.
Implementation
I’d split this into incremental PRs:
- PR 1: Config split:
settings.local.json+.mcp.local.jsonmerge logic +.gitignoretemplate - PR 2: Sync skill: core
sync-init,sync-push,sync-pulltools - PR 3: Hook automation: SessionStart/SessionEnd auto-sync
Happy to build this. Wanted to get feedback on the approach first — especially the config split, since that touches load-core-context.ts.