[Feature Request] Session Checkpointing and Branching
Problem Statement: When working on complex development tasks in Claude Code, users invest significant time getting Claude situated with project context, coding standards, and workflow understanding for an epic. However, as the context window fills up, this valuable context is lost when compaction or clearing becomes necessary. Regardless of the method used, Claude will not quite be at that same stage he was before - requiring reminders of requirements or corrections to get back on track. This degrades Claude's ability to iterate effectively on a set of related tasks.
Proposed Solution: Leverage the existing session ID system to enable checkpointing and branching: Within Claude Code REPL:
/checkpoint [optional-name] - Save current session state as a checkpoint
/list-checkpoints - Show available checkpoints with their session IDs
From command line:
claude-code --branch <session-id> - Start new session branched from the checkpointed session
Use Cases:
Epic Implementation: Get Claude situated with epic context and workflow, checkpoint that session, then branch new sessions for implementing individual tickets while maintaining that established understanding
SDK Workflows: Maintain established patterns and configurations across multiple related tasks (N8N workflows, API integrations, etc.)
+1 for supporting more sophisticated session checkpointing/forking.
the poor man's version of this that you can do in the latest version is, in the session that contains your desired context, press escape twice on the empty prompt, go back to an earlier message and fork the conversation at the first message that diverges from your desired context. but, as you mention, compacting and clearing destroys the conversation history -- you'd need to prepare the conversation history and execute the fork before compacting. doing this proactively one can stash checkpoints that can be resumed with claude -r.
Please add this
Git Checkpoints Hook
Place the following JSON into your Project settings (.claude/settings.json) or User settings (~/.claude/settings.json):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|NotebookEdit|MultiEdit|Write",
"hooks": [
{
"type": "command",
"command": "IFS= read -r PAYLOAD; SESSION_ID=$(jq -r .session_id <<<\"$PAYLOAD\"); \"$HOME/.claude/local/claude\" --dangerously-skip-permissions -p -r \"$SESSION_ID\" \"Look at all the changes made using git diff and then git add -A && git commit -m 'short message' -m 'detailed body'. The short message should be under 75 chars like 'fix(auth): correct login validation' and use the conventional commit format - type(scope): description where type is feat/fix/docs/refactor/chore/etc. Consider the user's intent of these changes when crafting the short message. The body should comprehensively describe everything that changed.\""
}
]
}
]
}
}
see here for config details
How does it work?
Whenever a hook event fires (PostToolUse), Claude Code launches /bin/sh -c '…your command…' and injects a JSON object into the shell’s stdin.
This JSON includes the current conversation ID from the Claude Code instance that invoked the hook along with additional metadata.
"matcher": "Edit|NotebookEdit|MultiEdit|Write"
This ensures that no matter how Claude Code modifies the project, this hook will be called.
IFS= read -r PAYLOAD
readsplits on any characters in$IFS(space, tab, newline),IFS=clears the Input Field Separator.- clearing $IFS ensures we grab the entire JSON line intact. if we didn’t, leading spaces or nested whitespace could cause the line to split into multiple words instead of one big string.
-rprevents backslashes from acting as escape characters.- JSON object from stdin is then placed into
$PAYLOAD.
SESSION_ID=$(jq -r .session_id <<<"$PAYLOAD")
<<<"$PAYLOAD"feeds the contents of$PAYLOADintojqstdin.jq -r .session_idparses the JSON and outputs just thesession_idfield, raw (no quotes).$( … )captures that output into$SESSION_ID.
"$HOME/.claude/local/claude" ...
- calls local Claude Code binary installation.
--dangerously-skip-permissions, skips confirmation prompts so the hook can run git commands automatically.-p, signals that the next argument is a prompt string.- the magic:
-r "$SESSION_ID"resumes the existing session.- this enables Claude to “remember” the full context of the edits it (more specifically, the invoking Claude Code instance) has made.
"Look at all the changes ..."
- Given that this Claude Code instance now has the full context of your currently running Claude Code (instead of being stateless), it's passed in prompt will execute within this context. The current prompt is tailored to take advantage of this to generate relevant commit messages.
Now every change in your project is automatically tracked. To do anything with the history (undo, summarization, search, comparisons, etc...), just start your prompts with Using Git, ... and you're good to go!
Didn't find this issue. Would love if this feature is added. Similar to Cline & Copilot.
In the meantime, you can use Serena MCP to achieve this: https://github.com/oraios/serena
Seems a bit complex, personally just want to be able to fork a session into a new one quickly, eg
PS: claude code is sooooooooo slow to start (like 3s, on the most expensive mac)
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.