claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[Feature Request] Session Checkpointing and Branching

Open StephenBadger opened this issue 7 months ago • 1 comments

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.)

StephenBadger avatar May 29 '25 18:05 StephenBadger

+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.

gswangg avatar May 30 '25 07:05 gswangg

Please add this

jacobhallgren avatar Jul 31 '25 10:07 jacobhallgren

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.

  1. "matcher": "Edit|NotebookEdit|MultiEdit|Write"

This ensures that no matter how Claude Code modifies the project, this hook will be called.

  1. IFS= read -r PAYLOAD
  • read splits 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.
  • -r prevents backslashes from acting as escape characters.
  • JSON object from stdin is then placed into $PAYLOAD.
  1. SESSION_ID=$(jq -r .session_id <<<"$PAYLOAD")
  • <<<"$PAYLOAD" feeds the contents of $PAYLOAD into jq stdin.
  • jq -r .session_id parses the JSON and outputs just the session_id field, raw (no quotes).
  • $( … ) captures that output into $SESSION_ID.
  1. "$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.
  1. "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!

aretrace avatar Jul 31 '25 22:07 aretrace

Didn't find this issue. Would love if this feature is added. Similar to Cline & Copilot.

harshpreet931 avatar Sep 01 '25 11:09 harshpreet931

In the meantime, you can use Serena MCP to achieve this: https://github.com/oraios/serena

PaulRBerg avatar Sep 05 '25 22:09 PaulRBerg

Seems a bit complex, personally just want to be able to fork a session into a new one quickly, eg

Image

PS: claude code is sooooooooo slow to start (like 3s, on the most expensive mac)

louis030195 avatar Sep 22 '25 00:09 louis030195

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.

github-actions[bot] avatar Oct 07 '25 14:10 github-actions[bot]