-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Problem
Updating PAI to a new release currently requires manual effort and carries risk of losing user data.
1. The migrate command misses most user data
Running migrate on a backup only identifies:
_-prefixed skills (most users don't use this convention)- Settings identity fields
- MEMORY subdirectory names
It completely misses:
PAI/USER/content (TELOS, identity, contacts, security patterns)- Non-prefixed custom skills, Packs installed after setup
- User-modified system files (tweaked hooks, skills)
projects/(Claude Code auto-memory), user knowledge bases, user-generated skills, installed Packs, pluginssettings.jsonhook/statusLine customizations- Claude Code generated data (
file-history/,Plans/,tasks/,History/)
And it only produces a text report — it doesn't actually restore anything. Users must manually copy files from the backup.
2. No way to preview what a release update will change
Users run cp -r new-release/.claude ~/ blindly. There's no way to see which local files will be overwritten, which are unchanged, or which are new — until after it's done.
3. No automated restore after release update
After cp -r overwrites files, users must manually find their modifications in the backup directory and copy them back. This is error-prone and tedious, especially for users who have customized hooks, skills, or PAI/USER/ content.
Related: #893 (settings.json overwrite during update)
Proposed Solution
Three new capabilities added to the existing Tools/BackupRestore.ts. All existing commands (backup, restore, list, migrate) are completely unchanged.
1. diff --release <path> — Preview before updating
Compare every file in a release against the local ~/.claude/ using SHA-256 hashes:
bun Tools/BackupRestore.ts diff --release ./Releases/v4.1.0/.claudeShows:
- New files — in the release but not locally (will be added)
- Unchanged — identical content (safe to overwrite)
- Conflicts — exist locally with different content (user modifications that will be lost)
Automatically excludes from conflict reporting:
PAI/USER/*,MEMORY/*— always user data, always preserved separatelysettings.json— always preserved separately, handled by install.sh mergePAI-Install/*— always replaced by releaseCLAUDE.md— regenerated by BuildCLAUDE.ts
2. backup --user-only --release <path> — Smart backup
Back up only user data, using the release directory as reference:
bun Tools/BackupRestore.ts backup --user-only --release ./Releases/v4.1.0/.claudeCaptures three categories:
- Always-backup data —
PAI/USER/*,MEMORY/*,settings.json,CLAUDE.md - Modified system files — files in the release that the user has changed (SHA-256 differs)
- User-generated files — everything in
~/.claude/that doesn't exist in the release (user-generated skills, installed Packs, knowledge bases,projects/with Claude Code auto-memory, plugins, etc.)
Users can review the diff output first, then exclude specific conflict files they don't want to keep:
bun Tools/BackupRestore.ts backup --user-only --release ./Releases/v4.1.0/.claude \
--exclude 'skills/SomeSkill/SKILL.md' \
--exclude 'PAI/SomeDoc.md'The existing full backup command is unchanged and remains the recommended safety net.
3. migrate --auto — Automated restore
After applying a new release (cp -r), restore user data from a user-only backup:
bun Tools/BackupRestore.ts migrate --auto --release ./Releases/v4.1.0/.claude- Automatically finds the latest user-only backup (or specify
--backup <path>) - Restores all user files on top of the new release
- Skips
CLAUDE.md(regenerated by BuildCLAUDE.ts in the next step) - Restores
settings.jsonso thatinstall.sh's merge logic can read the user's existing config
Without --auto, migrate works exactly as before (text analysis report).
Complete Migration Flow
# 1. Full backup (safety net — required)
bun Tools/BackupRestore.ts backup --name "pre-v4.1"
# 2. Preview what the release will change
bun Tools/BackupRestore.ts diff --release ./Releases/v4.1.0/.claude
# 3. Smart backup of user data
bun Tools/BackupRestore.ts backup --user-only --release ./Releases/v4.1.0/.claude
# 4. Apply new release
cp -r ./Releases/v4.1.0/.claude ~/
# 5. Auto-restore user data
bun Tools/BackupRestore.ts migrate --auto --release ./Releases/v4.1.0/.claude
# 6. Merge settings (install.sh reads restored settings.json)
cd ~/.claude && bash install.sh
# 7. Rebuild CLAUDE.md
bun ~/.claude/PAI/Tools/BuildCLAUDE.tsHow It Works
The release directory itself serves as the reference — no manifest file needed.
diff compares each release file against the local copy using SHA-256:
- Not in local → new file
- Same hash → unchanged
- Different hash → conflict (user modified)
backup --user-only collects:
- Everything in
PAI/USER/andMEMORY/(explicitly, regardless of release content) settings.jsonandCLAUDE.md(always)- All local files not present in the release (user-generated)
- Release files where local hash differs (user modifications)
migrate --auto copies the backup contents back into ~/.claude/, skipping only CLAUDE.md which is regenerated by BuildCLAUDE.ts.
Scope of Changes
| File | Change |
|---|---|
Tools/BackupRestore.ts |
Add diff, backup --user-only, migrate --auto |
All existing commands (backup, restore, list, migrate) are unchanged. No new files, no changes to release structure. Usage documentation is included in the tool's built-in help (bun BackupRestore.ts).
Future Work
- PR 2: Integrate migration flow into
install.shwizard — detect existing user-only backups and offer to restore during installation migrate --auto --dry-runto preview what would be restored- Interactive conflict resolution (per-file keep/overwrite choice)