haircut restore
Restore walks a bag's manifest in reverse: files move back where they came from,
symlinks are relinked, and anything it cannot reverse on its own is printed for
the user. It never deletes, and it never overwrites a path that exists again.
1. Find the bag
node "${CLAUDE_PLUGIN_ROOT}/bin/haircut.mjs" status
This lists every bag with its operation count and the restore command for each.
Bags are named after the run that made them. If there is more than one and the
user has not said which, ask before touching anything.
2. Dry run, always
node "${CLAUDE_PLUGIN_ROOT}/bin/haircut.mjs" restore --dry-run
That takes the newest bag. For a specific one:
node "${CLAUDE_PLUGIN_ROOT}/bin/haircut.mjs" restore --bag <bag id> --dry-run
Read the plan and tell the user in plain words what comes back, what is skipped
and why. Skips are normal and not a failure: a path that exists again is never
overwritten, and the manifest records the reason.
3. Restore
The same command without --dry-run, after the user has seen the plan and said
yes.
node "${CLAUDE_PLUGIN_ROOT}/bin/haircut.mjs" restore --bag <bag id>
4. What restore will not do on its own
Three kinds of operation need a word from you:
edit: a config file that trim rewrote, for example a hook removed from a
settings file or a server disabled in a config file. The verbatim original sits
in _originals inside the bag. Restore points at it instead of clobbering the
file, because the user may have edited that file since. Offer
--restore-edits, which copies the original back over it, and say plainly that
any change made to that file since the trim is lost when they do.
cli: trim used the agent's own command line to remove a server or disable
a plugin. Restore prints the reverse command. Show it to the user and run it
only on their go.
- Symlinks and junctions: relinking on Windows needs Developer Mode or an
elevated shell. If it fails for that reason, say so and hand the user the
command rather than retrying.
Rules
- Restore never deletes anything, including on the way back.
- Partial is fine.
--bag picks which bag; inside it, skips are reported rather
than forced.
- Never print a credential. A file coming out of a bag may hold one. Name the
path, not the content.
- Anything that loads at session start will not appear in the current session
after it comes back. Tell the user to start a new session.
- If what the user actually wants is to park something again, that is the
haircut skill, not this one.