Tool · v1.1.0工具 · v1.1.0

Four hooks.
Crash-resistant
by design.
四个 hook,
从设计上
抗崩溃。

Long Claude Code sessions die in messy ways — auto-compact, accidental clear, the laptop reboots, hours of silence with nothing on disk. This tool wires four hooks into Claude Code so the state of work in flight is captured to disk on a 30-minute semantic cadence plus a 60-minute silent machine autosnap, and recovered automatically when the next session starts. 长 Claude Code session 死起来很乱——上下文被自动压缩、手滑 /clear、电脑重启、几小时沉默期没东西落盘。这工具把四个 hook 接到 Claude Code 上,让 当前在做什么的状态 每 30 分钟(语义 checkpoint)+ 每 60 分钟(机器 autosnap)落到磁盘,下次 session 起来时自动接续。

4 hooks个 hook
30 / 60 min · semantic / autosnap分钟 · 语义 / autosnap
~5ms hook overheadhook 开销
Premise为什么

Crashes don't ask politely.崩溃不会提前打招呼。

A long session is dense with state that lives only in the conversation buffer: the task list you've been mentally tracking, the in-flight investigation, the next three steps you'd planned. When that buffer is gone — auto-compacted, cleared, terminated by a kernel oops — none of it is in memory anymore. The next session starts cold.

Skills can't help here. A skill fires when the model recognises a trigger; if the model has already lost context, there is nothing to trigger from. Slash commands need a human to type them. The only thing the harness fires deterministically — regardless of what the model is doing — is a hook. So that is what this tool builds with.

长 session 里塞满了只活在对话缓冲区的状态:你心里在跟踪的任务清单、正在追的调查、计划好的下三步。一旦那个缓冲区没了——被自动压缩、被清空、被 kernel oops 终结——这些就再也不在内存里了。下一个 session 起来时一片空白。

Skill 救不了这种情况。Skill 是看到触发词才被调用;如果模型本身已经丢了上下文,连触发词都没人写。Slash command 要人输入。整个 harness 里**唯一**不依赖模型自己决定就能触发的,是 hook。所以这工具用 hook 实现。

The checkpoint is insurance, not bookkeeping. Five lines of "doing X, next: Y" beats a blank page. checkpoint 是保险,不是流水账。五行"在干 X,下一步 Y"也比一片空白强。
Design principle设计准则
Architecture架构

Four hooks, two checkpoint files.四个 hook,两类 checkpoint。

CLAUDE CODE HARNESS PROCESS user submits prompt session starts startup · resume · clear · compact turn ends stop event · silent about to compact HOOK 1 · USER PROMPT prompt-submit-checkpoint.sh if mtime > 30 min · inject reminder HOOK 2 · SESSION START session-start-resume.sh surface prior checkpoint as context HOOK 3 · STOP · SILENT stop-autosnap.sh if mtime > 60 min · write autosnap HOOK 4 · PRE-COMPACT pre-compact-snapshot.sh copy transcript JSONL · silent CONTEXT INJECTION additionalContext → assistant updates file MEMORY DIRECTORY ~/.claude/projects/<cwd>/memory/ SEMANTIC · CLAUDE WRITES project_session_ ..._status.md tasks · next steps · context MACHINE · HOOK WRITES project_session_ ..._autosnap.md git state · transcript tail TRANSCRIPT SNAPSHOT .snapshots/pre-compact- YYYYMMDD_HHMMSS.jsonl prompt-submit (every prompt) session-start (4 sources) stop (silent · turn-end) pre-compact (transcript copy)
Hook firing model. Each event from Claude Code triggers exactly one of four hook scripts; outputs converge on two checkpoint files (semantic + machine autosnap) inside the project memory directory, plus rotating transcript snapshots before each compaction.Hook 触发模型。Claude Code 的每个事件触发四个 hook 脚本之一;输出汇聚到项目 memory 目录下的两类 checkpoint 文件(语义 + 机器 autosnap),加上每次压缩前轮转的 transcript 快照。
The four hooks四个 hook

What each one does, and when.每个 hook 做什么,什么时候触发。

01 · UserPromptSubmit

The 30-min semantic reminder30 分钟语义提醒

Fires before every user prompt. Reads the mtime of today's _status.md; if older than 30 minutes (configurable), injects a system-reminder asking the assistant to refresh the file before answering. Silent when the snapshot is fresh, so it does not pollute normal conversations. 每次用户提交 prompt 前触发。读今天 _status.md 的 mtime;超过 30 分钟(可配)就注入 system-reminder 让 Claude 在回答前先刷新文件。新鲜时静默——不打扰正常对话。

Trigger触发 Every prompt submission每次 prompt 提交 Output输出 JSON additionalContext (or none)JSON additionalContext(或无) Writes to disk写盘 No — Claude writes _status.md否 — Claude 写 _status.md
02 · SessionStart

The resume gate接续门

Fires on every session boundary — startup, resume, clear, compact. Surfaces the path of today's checkpoint plus the most recent prior-day file as context to the model so the new session begins with knowledge of where the last one stopped. Most useful after resume and compact. 每次 session 边界都触发:startup / resume / clear / compact 四种 source。把今天 checkpoint 的路径 + 最近一份历史 checkpoint 作为上下文喂给模型,新 session 一起来就知道上一次停在哪。在 resume 和 compact 后最有用。

Trigger触发 4 sources (startup/resume/clear/compact)4 种 source Output输出 JSON additionalContextJSON additionalContext Writes to disk写盘 None — read-only ls无(只读 ls)
03 · Stop · v1.1.0

The silent autosnap静默 autosnap

Fires at every turn-end. If today's _autosnap.md is older than 60 minutes (configurable), the hook silently writes a small machine snapshot — git branch, HEAD, working tree, transcript pointer, last 5 turns. Never injects context, never blocks, never consumes model tokens. Closes the silence-period gap that the prompt-submit hook cannot reach. 每个 turn 结束时触发。若今天的 _autosnap.md 超过 60 分钟(可配),hook 静默写一份机器快照——git 分支 / HEAD / 工作树 / transcript 指针 / 最近 5 轮。不注入上下文、不阻塞、不消耗 model token。专门补 prompt-submit 够不到的"沉默期"。

Trigger触发 Turn-end (every Claude response)每个 turn 结束 Output输出 None — silent (zero stdout)无(zero stdout) Writes to disk写盘 _autosnap.md (overwrite, ~1 KB)_autosnap.md(覆盖,~1 KB)
04 · PreCompact

The transcript safety nettranscript 兜底

Fires before auto-compact or manual /compact. Cannot inject context (protocol limitation), so it works silently: copies the full transcript JSONL to the project's .snapshots/ directory, retains the last five, lets the compact proceed. If compaction loses something important, the raw transcript is still on disk. 在自动压缩或手动 /compact 前触发。协议限制:这个 hook 不能注入上下文,所以走静默路径——把完整 transcript JSONL 复制到项目 .snapshots/ 目录,保留最近 5 份,然后让压缩继续。压缩丢了什么,原始 transcript 还在磁盘上。

Trigger触发 Auto-compact + manual /compact自动压缩 + 手动 /compact Output输出 None (block-only protocol)无(协议只允许 block) Writes to disk写盘 cp transcript.jsonl → .snapshots/cp transcript.jsonl → .snapshots/
Storage model存储模型

Slots into Claude Code's existing memory layout.嵌进 Claude Code 现有记忆体系。

Each Claude Code project has its own auto-memory directory at ~/.claude/projects/<sanitized-cwd>/memory/. Hooks resolve this path from $CLAUDE_PROJECT_DIR at runtime, so the same Claude Code instance running in different projects keeps separate checkpoints — never confused, never overwriting each other. 每个 Claude Code 项目有自己的 auto-memory 目录 ~/.claude/projects/<sanitized-cwd>/memory/。hook 运行时从 $CLAUDE_PROJECT_DIR 解析路径——同一个 Claude Code 实例在不同项目下跑,checkpoint 各自独立,互不混淆。

# What a project's memory directory looks like
~/.claude/projects/<project>/memory/
├── user_role.md                            ← existing auto-memory
├── feedback_doc_style.md                   ← existing auto-memory
├── project_sdk_status.md                   ← existing auto-memory
├── reference_build_commands.md             ← existing auto-memory
├── project_session_20260501_status.md      ← Claude writes (semantic)
└── project_session_20260501_autosnap.md    ← Stop hook writes (machine)

Two files, one purpose split into two layers. Both sit next to your existing memory entries — auto-memory reads them like any other project memory. Your user_*.md, feedback_*.md, project_*.md, reference_*.md are all left alone. 两个文件,一种用途拆成两层。都跟你现有的 memory 条目放在同一个目录里——auto-memory 读它们跟读其他 project memory 一样。你的 user_*.md / feedback_*.md / project_*.md / reference_*.md 一概不动。

_status.md is the curated narrative — task list, in-progress action, next steps, key context. Refreshed when you talk to Claude and the 30-min reminder fires. _autosnap.md is the objective fallback — written by a shell script with whatever git, jq, and tail can see. Refreshed at most once every 60 minutes by the Stop hook, regardless of whether you are talking. Recovery prefers _status.md; falls back to _autosnap.md when the status file is stale or missing. _status.md 是精炼的叙述——任务列表、进行中、下一步、关键上下文。user 说话且 30 分钟 reminder 触发时刷新。_autosnap.md 是客观兜底——shell 脚本拿 git / jq / tail 能看到的全部信息写下来。Stop hook 最多每 60 分钟重写一次,跟 user 说不说话无关。崩溃恢复时先看 _status.md;它过期或丢了再看 _autosnap.md。

How a new session picks up where the last one left off 新 session 怎么接上上次的进度

Open Claude Code (or resume a paused session, run /clear, or auto-resume after compact). The SessionStart hook fires before the model sees your first message. It injects a system-reminder telling Claude where today's checkpoint is and where the most recent prior-day checkpoint is, so Claude reads them on its own — no user action needed. 打开 Claude Code(或恢复暂停的 session、跑 /clear、压缩后自动恢复),SessionStart hook 在模型看到你第一条消息之前自动触发。它注入 system-reminder 告诉 Claude 今天 checkpoint 在哪、最近一份历史 checkpoint 在哪——Claude 自己会去读,你什么都不用做。

In the same project directory, prior context is automatically re-established. The 30-minute reminder hook then keeps the file fresh as work continues. 在同一个项目目录下,上次的上下文自动接续。然后 30 分钟提醒 hook 让文件随着工作进展持续刷新。

vs /resume对比 /resume

Where /resume stops, this tool starts./resume 到不了的地方,这工具补上。

Claude Code already ships /resume (and --continue): replays the previous session's transcript and picks up the conversation. For same-session continuation that is enough. The failure modes below are where transcript replay does not reach — and this tool was built for exactly those. Claude Code 自带 /resume(和 --continue):重新加载上一个 session 的 transcript,把对话续上。同 session 续接的场景,/resume 足够了。下面这些是 transcript 重放够不到的失效模式——这工具就是为这些设计的。

Failure mode失效场景
/resume alone只用 /resume
+ this tool+ 本工具
Same-session continuation 同 session 续接
Full transcript replay — works as designed. 完整 transcript 重放——按设计工作。
Redundant here. /resume is enough on its own. 本工具在这里多余。/resume 单独就够。
After auto-compact 自动压缩之后
Partial. The compact step has already summarised 200 KB of detail down to a 5 KB synopsis; the original cannot be rebuilt from the compacted transcript. 部分。压缩动作已经把 200 KB 细节砍成 5 KB summary,原始细节回不来。
PreCompact hook backs up the full transcript JSONL before compaction. Original detail recoverable offline. PreCompact hook 在压缩前把整份 transcript JSONL 备份。原始细节离线可恢复。
Accidental /clear 手滑 /clear
No. The transcript is gone — there is nothing to resume from. 不行。transcript 没了,没东西可 resume。
_status.md stays on disk untouched. The SessionStart hook surfaces it to the new session before the first user message. _status.md 留在磁盘上不动。SessionStart hook 在新 session 第一条消息前把它透给 Claude。
Cross-day continuation 跨天接续
Weak. Each day is a different session; long transcripts replay everything including dead ends and abandoned approaches. 弱。每天都是不同 session;长 transcript 重放所有内容,包括死路和废弃尝试。
_status.md is a 30–80 line summary of current work. Reads in seconds; skips the abandoned threads automatically. _status.md 是 30-80 行的当下工作摘要。秒读完,废弃线索自动略过。
Long silence period (hours) 长沉默期(数小时)
Nothing happens. /resume only fires when you start a new session; mid-session silence has no on-disk persistence. 什么都不会发生。/resume 只在新起 session 时触发;session 中段的沉默期不落盘。
Stop hook writes _autosnap.md at every turn-end past the 60-min threshold. Disk has fresh state without you talking. Stop hook 在每个 turn-end 超过 60 min 阈值时写 _autosnap.md。你不说话磁盘也有新状态。
Transcript file lost or corrupt transcript 文件丢失或损坏
No. /resume needs the JSONL intact. 不行。/resume 要 JSONL 完整。
_autosnap.md still has git HEAD, working tree, and the last 5 turns — enough to bootstrap a new session manually. _autosnap.md 仍有 git HEAD、工作树、最近 5 轮——足够手动接续到新 session。
Cross-machine handoff 跨设备接续
No. Transcripts are local to the machine. 不行。transcript 留在原机器上。
The memory directory can sit in a synced folder or git repo. Open the new machine, the checkpoint follows. memory 目录可以放在同步盘或 git 仓库里。换台机器打开,checkpoint 跟着走。

Bottom line: the tool is the complement of /resume, not a replacement. If your sessions are short, you never auto-compact, never /clear, never cross days, and never lose a machine — /resume alone is fine. If any of those happen with any frequency, /resume leaves a hole that this tool fills. 底线:这工具是 /resume 的补集,不是替代品。如果你的 session 短、从不被自动压缩、从不 /clear、从不跨天、机器从不丢——/resume 单独就够。这些场景哪怕偶尔发生,/resume 都会留洞,这工具补上。

Honest caveats老实说的限制

Claude Code reads settings.json once at process startup; it does not hot-reload. Installing this tool does not affect the session you're currently in — restart Claude Code for hooks to take effect. Both timers are also reactive, not absolute: the 30-min reminder fires on the next prompt after the threshold is crossed, and the 60-min autosnap fires on the next turn-end. There is no timer-based hook in Claude Code, so neither can guarantee tighter than event-boundary granularity. Claude Code 在进程启动时读一次 settings.json,不会热重载。装这个工具不影响你当前正在跑的 session——必须重启 Claude Code,hooks 才生效。两个阈值也是反应式的、不是绝对定时:30 分钟 reminder 在跨过阈值后的下一个 prompt 触发,60 分钟 autosnap 在下一个 turn-end 触发。Claude Code 没有定时器型 hook,两条都做不到比事件边界更细的粒度。

Install安装

Three commands. Done.三条命令搞定。

What gets written装到哪里

The installer is safe to re-run: running it again refreshes hooks without duplicating entries, and it preserves any other hooks you've already configured. Backups land beside every file it touches (*.bak). One-line rollback any time.

installer 重跑安全:再跑一次只刷新不重复条目,保留你其他 hook。每个被改的文件都留 *.bak 备份。一行命令随时回滚。

Repository on GitHubGitHub 仓库

# 1) Clone
git clone https://github.com/TbusOS/claude-code-memory-checkpoint.git
cd claude-code-memory-checkpoint

# 2) Install (preview first if you like)
./install.sh --dry-run
./install.sh

# 3) Restart Claude Code, then check
claude /doctor
Technical details技术细节

For people who like specifics.给关心细节的人。

Hook protocolHook 协议

All four hooks consume JSON on stdin (cwd, session_id, event-specific fields). UserPromptSubmit and SessionStart emit JSON on stdout with hookSpecificOutput.additionalContext. PreCompact returns block-only — it cannot inject context, so this tool uses it for transcript backup. Stop is silent by design: zero stdout, never returns decision:"block", never injects context (forcing the model to keep working would pollute the user's turn). Reference: Claude Code Hooks documentation. 四个 hook 都从 stdin 读 JSON(cwd / session_id + 事件相关字段)。UserPromptSubmit 和 SessionStart 从 stdout 输出带 hookSpecificOutput.additionalContext 的 JSON。PreCompact 协议上只能 block,不能注入——所以拿它做 transcript 备份。Stop 按设计静默:零 stdout、绝不返回 decision:"block"、绝不注入上下文(强制模型继续干活会污染 user 的 turn)。参考:Claude Code Hooks 文档。

Install location安装位置

Hook scripts and template at ~/.claude/hooks/memory-checkpoint/. Hook entries merged into ~/.claude/settings.json. A discipline rule fragment appended to ~/.claude/CLAUDE.md between BEGIN/END markers. Backups at *.bak. Hook 脚本和模板在 ~/.claude/hooks/memory-checkpoint/。Hook 条目合入 ~/.claude/settings.json。一段约束规则追加到 ~/.claude/CLAUDE.md 的 BEGIN/END marker 之间。备份在 *.bak。

Configuration配置

Five env vars read by hooks at runtime — no reinstall needed: CCMC_INTERVAL_MIN (semantic reminder cadence, default 30), CCMC_AUTOSNAP_INTERVAL_MIN (machine autosnap cadence, default 60), CCMC_MEMORY_DIR (override memory location), CCMC_SNAPSHOT_KEEP (transcripts retained, default 5), CLAUDE_HOME (override ~/.claude). 5 个环境变量,hook 运行时读,不用重装:CCMC_INTERVAL_MIN(语义 reminder 间隔,默认 30)、CCMC_AUTOSNAP_INTERVAL_MIN(机器 autosnap 间隔,默认 60)、CCMC_MEMORY_DIR(memory 位置覆盖)、CCMC_SNAPSHOT_KEEP(保留几份 transcript,默认 5)、CLAUDE_HOME(覆盖 ~/.claude)。

Compatibility兼容性

Linux and macOS, Bash 4 or newer, jq 1.6 or newer. Tested with Claude Code 2.1.x. The hook protocol shape is documented and stable; this tool will keep working as long as Claude Code accepts the documented hook event types. Linux 和 macOS、Bash 4 或更新、jq 1.6 或更新。在 Claude Code 2.1.x 上测过。Hook 协议形态有文档、稳定;只要 Claude Code 还接收文档里那几种 hook event,这工具就一直能用。