Claude FastClaude Fast
Hooks

Claude Code Context Recovery: Never Lose Progress to Compaction Again

Stop losing context when Claude Code compacts. This hook backs up transcripts and automatically injects recovery instructions when your session resumes.

Problem: You are deep in a complex implementation. Claude's context fills up and compacts. Suddenly Claude has forgotten everything - your session file, project rules, what you were building. You spend 10 minutes re-explaining context that should have been preserved.

Quick Win: Add this to .claude/settings.json and Claude will automatically know to re-read critical files after compaction:

{
  "hooks": {
    "PreCompact": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node .claude/hooks/ContextRecoveryHook/pre-compact.mjs"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node .claude/hooks/ContextRecoveryHook/session-start.mjs"
          }
        ]
      }
    ]
  }
}

Why Two Hooks?

Here is the key insight: PreCompact cannot inject context to Claude. It only supports common JSON fields for output. Only SessionStart and UserPromptSubmit can inject additionalContext.

The solution is a marker file pattern:

  1. PreCompact fires before compaction - backs up transcript, creates marker file
  2. Compaction happens - context is reduced
  3. SessionStart fires when session resumes - detects marker, injects recovery instructions, deletes marker
You're working...
     |
Context compacts (auto or manual)
     |
PreCompact: backs up transcript + creates marker
     |
SessionStart: detects marker + injects "Re-read CLAUDE.md..."
     |
Claude knows exactly what to reload

The PreCompact Hook

This hook runs before every compaction (manual /compact or automatic):

// pre-compact.mjs - Key functions only
function backupTranscript(transcriptPath, trigger, sessionId) {
  const backupDir = join(projectDir, ".claude", "backups");
  mkdirSync(backupDir, { recursive: true });
 
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
  const backupName = `${sessionName}_${trigger}_${timestamp}.jsonl`;
  copyFileSync(transcriptPath, join(backupDir, backupName));
}
 
function createCompactionMarker(sessionId, trigger) {
  const markerPath = join(homedir(), ".claude", "claudefast-compaction-marker");
  writeFileSync(
    markerPath,
    JSON.stringify({ sessionId, trigger, timestamp: new Date().toISOString() }),
  );
}

Transcripts save to .claude/backups/ with session ID and timestamp. The marker goes to ~/.claude/ so it persists across projects.

The SessionStart Hook

This hook detects the marker and injects recovery instructions:

// session-start.mjs - The context injection
function checkAndDeleteMarker() {
  const markerPath = join(homedir(), ".claude", "claudefast-compaction-marker");
  if (!existsSync(markerPath)) return null;
 
  const markerData = JSON.parse(readFileSync(markerPath, "utf-8"));
  unlinkSync(markerPath); // Self-cleaning
  return markerData;
}
 
// If marker found, output additionalContext
const output = {
  hookSpecificOutput: {
    hookEventName: "SessionStart",
    additionalContext: `=== CONTEXT RECOVERY ===
Context was just compacted. Re-read:
1. CLAUDE.md for project rules
2. .claude/tasks/session-current.md for session state
Git: branch "${branch}", ${changedFiles} uncommitted changes
=== END ===`,
  },
};
console.log(JSON.stringify(output));

The additionalContext field is what makes this work. Claude receives these instructions as part of its context, prompting it to reload critical files.

When Things Go Wrong

Context recovery not triggering Check if the marker is being created:

ls ~/.claude/claudefast-compaction-marker

Stale marker causing repeated recovery Delete it manually:

rm ~/.claude/claudefast-compaction-marker

Backups not appearing Check the hook logs:

cat .claude/hooks/ContextRecoveryHook/logs/pre-compact.log

Customize the Recovery Message

Edit buildContextRecoveryMessage() in session-start.mjs to add project-specific instructions. Common additions:

  • Active feature branch context
  • Database migration state
  • Test suite status
  • Custom skill loading instructions

Next Steps

Last updated on

On this page

Claude Code ready in seconds.