Hibernate your running Claude Code sessions before shutdown; wake them after reboot.
Claude Code does not record which sessions are currently running — a machine
shutdown kills every session process, and after reboot you're left
reconstructing what was open where. claude-hibernate is OS hibernation for
those sessions: write the running set to disk before power-off, restore it at
boot.
$ claude-hibernate hibernate --all
Hibernated 8 session(s) (scope=all) to ~/.local/state/claude-hibernate/snapshot.json
... reboot ...
$ claude-hibernate wake
Waking sessions as a 2-column pane grid in a new iTerm2 window...
Each session comes back in its original directory, on its original session
id, with its original launch flags (--model,
--dangerously-skip-permissions, ...), in your terminal of choice.
Why not just claude --continue? It resumes only the most recent session per
directory — so it can't bring back the dozen sessions you had spread across a dozen
repos, and it can't disambiguate several concurrent sessions in one worktree. wake
restores all of them, unattended, each on its own id (more in the FAQ).
Install
Homebrew (via tap):
brew install SteveVitali/tap/claude-hibernate
curl:
curl -fsSL https://raw.githubusercontent.com/SteveVitali/claude-hibernate/main/install.sh | bashManual — it's one self-contained bash script:
git clone https://github.com/SteveVitali/claude-hibernate.git
cp claude-hibernate/scripts/claude-hibernate.sh ~/.local/bin/claude-hibernateRequires bash 3.2+ (macOS system bash works), python3, and standard Unix
tools. Then:
claude-hibernate doctor # verify your environment end-to-endQuick start
# --- Before shutdown --- claude-hibernate hibernate --all # capture every session on the machine claude-hibernate hibernate # ... or just this repo's worktrees claude-hibernate hibernate --dry-run # preview the table; writes nothing # --- After reboot --- claude-hibernate list # see what's in the snapshot claude-hibernate wake --dry-run # print the resume commands first claude-hibernate wake # reopen + resume everything # --- Optional: set and forget --- claude-hibernate hooks install # exact session tracking (see below) claude-hibernate auto enable # snapshot every 10 min, forever
Commands
| Command | What it does |
|---|---|
hibernate |
Capture running sessions to the snapshot file |
wake |
Reopen + resume every snapshotted session |
list |
Show the snapshot (--live: currently-running sessions) |
doctor |
Verify environment assumptions; ok/warn/FAIL per check |
hooks install|uninstall|status |
Exact session tracking via Claude Code hooks |
auto enable|disable|status |
Periodic auto-snapshot (launchd/systemd/cron) |
Scope flags (hibernate, list --live, wake --live): --repo (current
repo's worktrees, default), --here ($PWD only), --all (whole machine).
Wake flags: --dry-run (print commands), --fork (resume with
--fork-session, fresh ids), --live (source running sessions instead of the
snapshot), --launcher <name> (force a terminal backend), --quiet.
How detection works
Finding "running Claude Code sessions" is genuinely tricky — pgrep -x claude
misses most real installs. The process is named after the version (e.g.
2.1.202) for native installs, and on Linux Claude rewrites both the process
name and command line. claude-hibernate layers four classification rules:
- Name — the process basenames to
claude(Homebrew/npm on macOS). - Binary path — a version-shaped name whose executable path contains
claude(native installer). - Project correlation — a version-shaped name whose working directory
maps to a real
~/.claude/projects/<mangled-cwd>directory. - Args — the command line starts with
claude(belt and braces).
Each surviving process is mapped to its cwd (lsof / /proc), git branch,
and session id. Session ids are resolved with three precedence levels:
- Hook records (exact) — if you ran
claude-hibernate hooks install, Claude Code itself reports each session's id at startup via aSessionStarthook. Zero guessing. --resume <uuid>in the process args (exact) — visible on macOS.- Newest transcript heuristic — the N newest
.jsonltranscripts in the project directory map to the N processes running there. Right in practice; ambiguous only when several sessions share one directory.
hibernate records all of it to the snapshot; wake reads only the snapshot
(the processes are gone by then). The SRC column in list/--dry-run
output tells you which method resolved each session (hook vs heuristic).
Terminal launchers
wake auto-detects your terminal, or force one with --launcher /
CLAUDE_HIBERNATE_LAUNCHER:
| Launcher | Platform | Behavior |
|---|---|---|
tmux |
anywhere | Windows in your current session, or a detached claude-wake session |
iterm2 |
macOS | 2-column pane grid in one new window |
terminal |
macOS | One Terminal.app window per session |
kitty / wezterm / alacritty |
any | OS windows / native tabs per session |
gnome-terminal / konsole |
Linux | Tabs per session |
print |
anywhere | Just prints the cd … && claude --resume … commands |
Inside tmux, tmux always wins. Everything falls back to print — wake never
strands you.
Auto-snapshot
claude-hibernate auto enable # every 10 minutes claude-hibernate auto enable --interval 5 claude-hibernate auto status claude-hibernate auto disable
Installs a launchd agent (macOS), systemd user timer, or crontab entry
(Linux) running hibernate --all --quiet. Snapshots are cheap, atomic, and
keep 10 timestamped generations in history/ — so even an unplanned power
loss costs you at most the last interval.
State layout
${XDG_STATE_HOME:-~/.local/state}/claude-hibernate/
├── snapshot.json # current snapshot (schema 2, atomic writes)
├── history/ # last 10 timestamped snapshots
└── live/ # hook-maintained per-pid session records
Overrides: CLAUDE_HIBERNATE_STATE_DIR, CLAUDE_HIBERNATE_FILE,
CLAUDE_CONFIG_DIR, CLAUDE_HIBERNATE_HISTORY_KEEP. A legacy v0 snapshot
(~/.local/state/claude-hibernate.json) is still read if no new-style
snapshot exists.
Using as an Agent Skill
The repo doubles as a skill directory (SKILL.md),
so Claude Code can drive it conversationally:
ln -s /path/to/claude-hibernate ~/.claude/skills/claude-hibernateThen: "hibernate my sessions" / "wake my sessions" in any conversation.
Related projects
| needs tmux? | needs pre-setup? | rescues already-running sessions? | exact session ids? | platforms | |
|---|---|---|---|---|---|
| claude-hibernate | no | no (hooks optional) | yes | yes with hooks; heuristic otherwise | macOS + Linux, 9 terminal backends |
| tmux-resurrect / continuum | yes | yes (plugin) | no | n/a (restores panes, not Claude sessions) | anywhere tmux runs |
| tmux-assistant-resurrect | yes | yes (plugin) | no | yes (parses pane content) | tmux only |
| agent-resume-style wrappers | no | yes (must launch claude through the wrapper) | no | yes | varies |
If you already live entirely inside tmux with resurrect/continuum configured,
a tmux-centric tool restores your whole layout and is the better fit — pair it
with claude --continue per pane. claude-hibernate is for everyone else:
no wrapper, no plugin, works on sessions that are already running when you
first install it.
FAQ
Why not just claude --continue? It resumes only the most recent session
per directory, you must remember which directories were live, and it can't
disambiguate N concurrent sessions in one worktree. wake restores all of
them, unattended.
Will this break when Claude Code updates? Possibly — transcript internals
are an unsupported surface. That's why doctor exists, why hook-tracked
sessions bypass the heuristics entirely, and why every heuristic degrades
soft (empty summary, heuristic source tag) rather than failing.
macOS asked me to allow Automation on first wake. That's the one-time osascript → iTerm2/Terminal permission prompt; approve it and wake proceeds.
Why bash? Zero-install portability: one file, runs on the macOS system bash (3.2) and any Linux, with python3 only for JSON.
Does hibernate stop the sessions? No — it's a snapshot, not a freeze.
Your shutdown kills the processes; the snapshot is what lets wake bring
them back.
What about Codex / other agents? Out of scope for 1.0 — see Roadmap.
Roadmap
Deliberately out of scope for 1.0, candidates for later: waking into the previous model/permission state beyond captured flags, Ghostty automation (not scriptable yet — use tmux inside Ghostty), Codex/other-agent support, Windows/WSL, and restoring full terminal layouts (use tmux-resurrect for that).
Caveats
- Unsupported surface: Anthropic documents transcript internals as subject
to change on any release. This tool touches them minimally (filenames for
session ids, best-effort summaries), and
hooks installavoids the heuristics entirely — but a Claude Code update can still break detection.claude-hibernate doctorafter upgrades tells you exactly what still works. - Waking while the original sessions still run would attach two processes to
one session id —
wakedetects this and skips those sessions (--forkoverrides by branching to fresh ids). - Flag capture reads process args, which Linux Claude rewrites — on Linux, flags come back only for sessions tracked via hooks.
Uninstall
claude-hibernate auto disable # remove launchd/systemd/cron job, if enabled claude-hibernate hooks uninstall # remove Claude Code hooks, if installed rm -f ~/.local/bin/claude-hibernate # or: brew uninstall claude-hibernate rm -rf ~/.local/state/claude-hibernate # snapshots + history
Development
shellcheck -x scripts/claude-hibernate.sh # lint bats tests/ # 44 tests, fully isolated
See CONTRIBUTING.md and docs/SPEC.md for architecture and design decisions, and RELEASING.md for the release process.
Related
Extracted from agent-skills, a collection of research-grounded, harness-agnostic process skills for AI coding agents — this tool is Claude Code-specific by nature, so it lives on its own.
