Restore is the only operation that writes outside the backup directory, so it
is deliberately conservative. This document describes the guarantees and the
order in which claude-restore enforces them (see lib/restore.sh).
-
Select the archive.
--from <archive>if given, otherwise the newestclaude-code-backup-*.tar.gzin the backup directory. Missing/invalid paths abort immediately. -
Validate the archive listing.
tar -tzfis inspected before anything is extracted. The restore is refused if any entry:- is an absolute path (
/...), or - contains a parent reference (
..,../x,x/../y,x/..).
Entries outside the expected
manifest.txt/home//project/trees are warned about and ignored on restore. - is an absolute path (
-
Extract to a temporary directory. Files are unpacked into a fresh
mktemp -d, never straight into$HOMEor the project. The temp dir is removed via atrap … EXITon every exit path. -
Reject escaping symlinks. After extraction, every symlink in the tree is checked; if its target is absolute or contains
..(i.e. it could point outside the staging dir), the restore is refused. This blocks the classic "symlink then write through it" escape. -
Show the plan. Each target is listed as
create:(new) oroverwrite/merge:(already exists). With--dry-runthe command stops here and changes nothing. -
Confirm. Unless
--forceis given, you must confirm interactively. When stdin is not a TTY (e.g. inside an automation),confirm()returns no, so an un-forced restore safely cancels rather than proceeding blindly. -
Pre-restore backup. Unless
--no-backup-existingis given, the current state of everything about to change is archived to…/pre-restore/pre-restore-<timestamp>_<host>.tar.gzfirst, so you can roll back. -
Apply by merging. Directories are copied with
cp -R "$src/." "$dest/"— i.e. contents are merged into the destination. Files present locally but absent from the backup are left in place; the tool never silently deletes your data.
--home-onlyrestores only~/.claudeand~/.claude.json.--project-onlyrestores only the current project's files.- The two are mutually exclusive.
Archives are platform-neutral (relative paths, plain tar/gzip), so a backup made
on macOS restores on Linux and vice versa. Only file_mtime/file_size
reporting differs by OS, and that is handled in lib/platform.sh.
Some credentials do not live inside the backed-up files and therefore cannot be restored:
- OS keychains / credential stores (macOS Keychain, libsecret, etc.)
- OAuth tokens managed by external helpers
- values that exist only in environment variables
- secrets in external files you did not include (
.env.claude,.envrcare only included with--include-env)
After a restore, if Claude Code or an MCP server reports an auth error, simply re-authenticate — your other settings, commands, agents, hooks and skills are already back in place.
Plugins. Backups prune installed plugin code and marketplace clones by
default but keep the manifests (plugins/installed_plugins.json,
plugins/known_marketplaces.json). On a fresh machine Claude Code will report
cache-miss for those marketplaces until they are re-added. To make this easy,
claude-restore reads the restored manifests and writes
<backup-dir>/restore-plugins.txt containing ready-to-paste commands:
/plugin marketplace add anthropics/claude-plugins-official
/plugin marketplace add https://github.com/you/your-marketplace.git
/reload-plugins
# …and explicit `/plugin install name@marketplace` lines as a fallback
Paste those into Claude Code, then run /reload-plugins. A backup made with
--full includes the plugin code and marketplace clones, so no recovery is
needed in that case.