claude code . PreToolUse hook . APFS clonefile . MIT

claude code's /rewind cannot undo rm -rf.

anthropic's own docs: "Bash commands are not tracked. If Claude runs rm, mv, or cp, those changes are permanent." every horror story on dev.to that ends with "claude lost my four-hour session" traces back to this. bashward closes the loop. it hooks the PreToolUse event, parses the bash command, identifies write paths, snapshots them via APFS clonefile (zero copy on macos) before the command runs.

$ cargo install bashward
$ bashward install
   wrote PreToolUse hook into ~/.claude/settings.json
   snapshots will live under ~/.bashward

# claude runs `rm -rf src/`...

$ bashward list
000018ac  2026-05-03 22:14:07  prebash   1 paths  `rm -rf src/`

$ bashward rewind 000018ac
   restored /Users/me/proj/src
what it catches

the bash patterns claude code's /rewind misses.

claude runs                         bashward action
rm -rf foo/                         snapshot foo/ then let rm run
mv a.txt b.txt                      snapshot both then let mv run
dd of=/tmp/disk bs=1M               snapshot /tmp/disk first
sed -i 's/x/y/' file                snapshot file first
echo important > /etc/foo           snapshot the redirect target first
truncate -s 0 logs.txt              snapshot logs.txt first
tee config.json                     snapshot config.json first
ls / git status / cat / echo        nothing, nothing was at risk
how it works

tiny rust binary plus one hook line.

installed in one command

bashward install patches ~/.claude/settings.json with a PreToolUse hook matched on Bash. idempotent both ways. bashward uninstall removes it cleanly.

APFS clonefile snapshots

on macos snapshots use /bin/cp -c -R, which goes through the filesystem's clone path. snapshotting a 1 GB directory takes a few milliseconds and uses roughly zero disk until something diverges.

heuristic command parser

handles rm, mv, cp, dd, sed -i, tee, truncate, output redirection (>, >>). single-quote and double-quote aware. errs on snapshotting more than less.

never blocks the call

bashward is observe-and-pass-through. the hook always returns {"continue": true}, snapshots happen during the few hundred microseconds before the bash call runs.

append-only transaction log

stored at ~/.bashward/log.jsonl, one line per transaction. bashward list shows the recent ones. bashward prune --days 7 tidies up.

linux is on the roadmap

v0.1 falls back to cp -a on linux (correct but not space-efficient). overlayfs and btrfs snapshot paths in 0.2.

install

two commands.

$ cargo install bashward
$ bashward install

requires claude code with hook support. macos for the fast path; linux falls back to cp -a.