feat: restore claude code sessions via --resume <session-id>#571
Open
manueltarouca wants to merge 2 commits into
Open
feat: restore claude code sessions via --resume <session-id>#571manueltarouca wants to merge 2 commits into
manueltarouca wants to merge 2 commits into
Conversation
`claude` re-launch starts a fresh conversation. Resuming requires
`claude --resume <session-id>`. Adds a restore strategy that picks the
most recent session for the pane's saved cwd under
`~/.claude/projects/<encoded-cwd>/<uuid>.jsonl` (encoded cwd is the
absolute path with `/` replaced by `-`), and emits the matching
`--resume` command. Falls back to the originally captured command when
no session exists for the cwd.
Opt-in. Not added to the default process list.
set -g @resurrect-processes 'claude'
set -g @resurrect-strategy-claude 'default'
2 tasks
Basic mode picks "newest .jsonl in cwd by mtime" at restore time, which
collapses parallel sessions to one when multiple panes ran `claude` in
the same directory.
Adds two pieces that together capture per-pane session identity at save
time:
- extras/claude/track-session.sh: SessionStart hook that records
{sessionId, cwd, ppid} to ~/.claude/runtime/<pid>.json at session
start. Garbage-collects sidecars older than 7 days.
- save_command_strategies/claude_aware.sh: drop-in replacement for the
default `ps` save strategy. Behaves like ps.sh for every command,
diverges only for `claude` panes: looks up the sidecar by claude PID
and rewrites the captured command to `claude --resume <uuid>`.
strategies/claude_default.sh now detects an explicit --resume/--continue
in the captured command and passes it through unchanged, so the
per-pane path is honored at restore. Falls back to newest-mtime when no
explicit flag was captured.
Enable per-pane mode by installing the hook in ~/.claude/settings.json
and:
set -g @resurrect-save-command-strategy 'claude_aware'
Long-term, the right fix lives upstream in Claude Code (expose session
ID via process env or runtime file). Tracked at
anthropics/claude-code#63758.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
claudere-launch starts a fresh conversation. Resuming requiresclaude --resume <session-id>. Adds two paths to make tmux-resurrect resurrectclaudepanes correctly:~/.claude/projects/and emits the matching--resumecommand.How
Basic mode. Claude Code stores sessions at
~/.claude/projects/<encoded-cwd>/<uuid>.jsonl, where the encoded cwd is the absolute path with/replaced by-.strategies/claude_default.shreproduces that encoding, picks the newest*.jsonlby mtime, strips the extension to recover the UUID, and emitsclaude --resume <uuid>. Falls back to the originally captured command when no session exists.Per-pane mode. Basic mode collapses parallel same-cwd sessions to one. To map each pane to its own session:
extras/claude/track-session.sh: aSessionStarthook installed in~/.claude/settings.json. At session start it readssession_idandcwdfrom the hook payload and writes~/.claude/runtime/<claude-pid>.json. Garbage-collects sidecars older than 7 days. Requirespython3.save_command_strategies/claude_aware.sh: drop-in replacement for the defaultpssave strategy. For non-claude commands it behaves identically tops.sh. Forclaudepanes it looks up the sidecar by claude PID and rewrites the captured command toclaude --resume <uuid>, so the resurrect record stores explicit session identity per pane.strategies/claude_default.shdetects an existing--resume/--continuein the captured command and passes it through unchanged, so per-pane mode survives restore.Configuration
Opt-in. Not added to the default process list.
Basic mode:
Per-pane mode (in addition):
Plus the
SessionStarthook in~/.claude/settings.jsonpointing atextras/claude/track-session.sh. Setup walked through indocs/restoring_claude_code_sessions.md.Caveats
$PPID. Wrapper scripts between claude and the hook can throw this off./to-encoding tracks Claude Code's current on-disk layout. A future Claude Code release that changes the scheme breaks basic mode (per-pane mode is unaffected).Upstream
The right long-term fix is for Claude Code to expose the running session ID externally (process env or runtime state file). Filed at anthropics/claude-code#63758. Once that lands, the hook becomes unnecessary.
Testing
clauderunning in a pane, save (prefix + Ctrl-s), kill tmux server, restart, restore (prefix + Ctrl-r): pane comes back attached to the prior session (basic mode, verified).~/.claude/projects/<encoded>/entry: strategy emits bareclaude.claude --dangerously-skip-permissionswith no prior session: flags preserved on fallback.--resume <id>,--continue, and combined-with-flags forms: verified.