Overview
File checkpointing tracks file modifications made through the Write, Edit, and
NotebookEdit tools during an Agent SDK session, so you can rewind files to a
previous state. It is useful for undoing unwanted changes, exploring
alternatives, and recovering from errors before a risky refactor.
Enable checkpointing
Set enableFileCheckpointing (TS) / enable_file_checkpointing (Python), and add
the replay-user-messages extra arg so each user message in the stream carries a
checkpoint UUID:
const opts = {
enableFileCheckpointing: true,
permissionMode: "acceptEdits" as const,
extraArgs: { "replay-user-messages": null },
};
Capture the checkpoint and session id
Each user message in the response stream has a uuid that serves as a checkpoint;
capture the first one to restore all files to their original state. Capture
session_id too if you want to rewind after the stream completes.
for await (const message of response) {
if (message.type === "user" && message.uuid && !checkpointId) checkpointId = message.uuid;
if ("session_id" in message && !sessionId) sessionId = message.session_id;
}
Rewind files
After the stream completes, resume the session with an empty prompt and call
rewindFiles() (TS) / rewind_files() (Python):
const rewindQuery = query({ prompt: "", options: { ...opts, resume: sessionId } });
for await (const msg of rewindQuery) {
await rewindQuery.rewindFiles(checkpointId);
break;
}
You can also rewind during the stream (keep the latest UUID and rewind on a revert
condition), or from the CLI:
claude -p --resume <session-id> --rewind-files <checkpoint-uuid>.
Multiple restore points
Store each user-message UUID in an array to rewind to an intermediate state (for
example, keep a refactor but undo later test changes).
Limitations
- Write/Edit/NotebookEdit tools only; Bash-driven changes are not tracked.
- Checkpoints are tied to their session.
- File content only; directory create/move/delete is not undone.
- Local files only.
Troubleshooting
- No UUIDs on user messages: add the
replay-user-messages extra arg.
- "ProcessTransport is not ready for writing": rewinding after the loop finished;
resume with an empty prompt, then call rewind on the new query.
Source