HookStack
Back to catalogue
WorkflowPreCompact

Transcript backup before compaction

Your full transcript survives every compaction

Automatically backs up the JSONL transcript file before every context compaction, to allow auditing or restoration.

What does the Transcript backup before compaction hook do?

Transcript backup before compaction is a Claude Code PreCompact hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Your full transcript survives every compaction.

As a PreCompact hook it runs before the action completes, so it can block or adjust what Claude is about to do. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.

Use cases

  • Keep a full history before compaction
  • Audit long sessions

Tags

#backup#compact#transcript#context#audit

settings.json fragment

{
  "hooks": {
    "PreCompact": [
      {
        "hooks": [
          {
            "command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/pre-compact-backup.mjs",
            "type": "command"
          }
        ],
        "matcher": ""
      }
    ]
  }
}

Script · .claude/hooks/pre-compact-backup.mjs

#!/usr/bin/env node
// @hookstack pre-compact-transcript-backup
// Sauvegarde le résumé de compaction dans un fichier temporaire (PreCompact)
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

export function run(
	input,
	{
		writeFile = writeFileSync,
		mkdir = mkdirSync,
		backupDir = "/tmp/claude-compact-backups",
		now = () => new Date().toISOString(),
	} = {},
) {
	const summary = input.summary ?? "";
	const sessionId = input.session_id ?? `session-${Date.now()}`;
	if (!summary) return null;

	mkdir(backupDir, { recursive: true });
	const file = join(backupDir, `${sessionId}.json`);
	writeFile(
		file,
		JSON.stringify(
			{ session_id: sessionId, saved_at: now(), summary },
			null,
			2,
		),
	);

	return {
		file,
		message: `[pre-compact-backup] Contexte sauvegardé → ${file}\n`,
	};
}

/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
	const input = JSON.parse(readFileSync(0, "utf8"));
	const result = run(input);
	if (result?.message) process.stderr.write(result.message);
}

Learn more

Related hooks