Your shell history remembers every secret.
Exported API keys, curl tokens, database passwords and keys pasted into Claude Code or Codex all sit in plain text under your home folder. smash scrubs them out once a day, in place, and leaves the rest of your history alone.
curl -fsSL https://keysmash.website/install.sh | sh
then smash to set up and previewsmash run to scrub nowsmash log to see what changed
: 1729500010:0;export OPENAI_API_KEY=sk-proj-9fK2mQx7Lp4V : 1729500020:0;curl -H "Authorization: Bearer ghp_7Qm2Lx9Vt4Rz" api.github.com : 1729500030:0;mysql -u root -pS3cr3tPass! app : 1729500040:0;git push origin main : 1729500050:0;aws configure set aws_secret_access_key wJalrXUtnFEMI/K7 ✓ 4 secrets redacted · 0 rejected · today's lines untouched
Four steps, once a day.
A background job (launchd on macOS, a systemd timer on Linux) checks only what's new since the last run. Only suspicious lines ever leave your machine, and every answer is checked before a byte changes.
Filter locally
Key formats,
KEY=value, bearer tokens, URL credentials and random-looking strings are spotted on your machine.Model confirms
Suspicious lines go to OpenAI or Anthropic in batches; only lines with a real secret come back, masked.
Verify
An answer is used only if it's your original line with spans replaced by
[REDACTED].Rewrite in place
Atomic rewrite, byte-for-byte except the redactions. Lines added meanwhile are kept.
What ships
- Preview first. Counts per source, and nothing is sent until you confirm.
- Cleans four sources. zsh and bash history, Claude Code and Codex sessions, and both prompt histories.
- Incremental. Only new lines are checked, and clean ones are never re-sent.
- Today stays. Lines dated today wait for tomorrow, and live agent sessions are skipped.
- Catches up. A run missed during sleep or downtime happens afterwards.
- Audit log.
smash logshows files and counts, never the text.
Stay in control
# stop the daily job, keep smash for manual runs launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.smash.daily.plist rm ~/Library/LaunchAgents/com.smash.daily.plist smash run # whenever you like
# stop the daily timer, keep smash for manual runs systemctl --user disable --now smash.timer rm ~/.config/systemd/user/smash.{service,timer} systemctl --user daemon-reload smash run # whenever you like
smash update # install the latest release, checksum verified smash uninstall # removes the job, ~/.smash and the binary; asks first
Redaction is permanent, and smash keeps no backups. Rotate any key it finds: if it was on disk, assume it was read.