checkpoint
Save and restore task state for long-running operations. Use when: - User says "checkpoint", "save state", "save progress" - User says "restore checkpoint", "list checkpoints" - Context window is runn
SKILL.mdskills/checkpoint/SKILL.md
GitHubCheckpoint: Save & Restore Task State
Product-aware runner
Set these once for the active host. checkpoint.ts uses claudePath, so pass
the matching state root on every invocation.
# Standalone Codex
CHECKPOINT_RUNNER="${CODEX_HOME:-$HOME/.codex}/darkroom/source/src/scripts/checkpoint.ts"
CC_STATE_ROOT="${CODEX_HOME:-$HOME/.codex}/darkroom/state"
# Claude Code instead uses:
# CHECKPOINT_RUNNER="$HOME/.claude/src/scripts/checkpoint.ts"
# CC_STATE_ROOT="$HOME/.claude"
Subcommands
save [label]
Save current state with an optional label.
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" save "Completed phase 3 migration"
list
List all checkpoints for the current project.
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" list
show [checkpoint-id]
Show details of a specific checkpoint.
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" show chk-20240115-103000
restore [checkpoint-id] [--force]
Real, opt-in rollback — restores tracked files (working tree + index) to
exactly what they were at save time, then reapplies whatever uncommitted
changes existed at that moment (captured as a binary-complete patch when the checkpoint was
saved). Untracked content is not captured; files untracked at save time are
listed as a warning. A forced restore across commits can overwrite a currently
untracked path that was tracked in the saved commit. Move that content outside
the repository before using --force; the safety checkpoint cannot recover it.
Scope note: restore reconstructs file content only — anything that was
staged at save time comes back as unstaged working-tree changes (the patch
reapplies to the worktree; index state is intentionally not reconstructed).
Safety rails:
- Validate before reset. The saved commit and patch are checked against a temporary Git index before tracked files are changed. A missing, unreadable, or non-restorable patch (including an old text-only binary diff) refuses restoration without resetting the working tree.
- Auto safety-checkpoint first. Before anything is touched, the current
state is saved as its own checkpoint and its id is printed —
tracked content is recoverable by restoring that id (with
--force). This safety checkpoint also excludes untracked content. - Branch/sha guard. If the current branch or HEAD differs from what the
checkpoint recorded, restore refuses and tells you to check out that branch
or pass
--force. - Legacy checkpoints (no recorded patch) have no diff to restore from. Restoring one prints "legacy checkpoint: metadata only, nothing restored" and falls back to print-only behavior — review the dumped JSON and continue manually.
# Restore latest
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" restore
# Restore specific
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" restore chk-20240115-103000
# Restore across a branch/sha mismatch
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" restore chk-20240115-103000 --force
clean
Remove old checkpoints, keeping the last 10.
CC_SETTINGS_HOME="$CC_STATE_ROOT" bun "$CHECKPOINT_RUNNER" clean
Storage
Checkpoints are stored under $CC_STATE_ROOT/checkpoints/<project-name>/ as
JSON files with a latest symlink pointing to the most recent. Each checkpoint
with uncommitted changes at save time also gets a sibling chk-<id>.patch file
(git diff --binary --full-index HEAD output) — this is what makes restore a real rollback instead
of a metadata dump. A checkpoint without patch metadata restores in
metadata-only (legacy) mode. A checkpoint that declares
a patch but has lost that file is an error, not a metadata-only checkpoint.