ExAthena.Checkpoint (ExAthena v0.4.2)

Copy Markdown View Source

File-history checkpointing + rewind.

Before Tools.Edit and Tools.Write modify a file, the prior contents are saved to <cwd>/.exathena/file-history/<session_id>/<sha>/<version>.bin where <sha> is the SHA-256 of the absolute file path and <version> increments on each edit.

rewind/3 restores files (and optionally truncates the JSONL session log) to the state at a given event UUID.

Adapted from Claude Code's ~/.claude/file-history/<session_id>/ layout. 30-day TTL is enforced by ExAthena.Checkpoint.Sweeper.

Modes

  • :code_and_history — restore files to checkpoint AND truncate the session log to the chosen UUID.
  • :history_only — restore session log only; leave files as-is (useful when files have evolved since but you want to drop the conversation context).

Summary

Functions

Path to the file-history directory for session_id under cwd.

Snapshot the prior contents of path before an edit. Returns the version directory + version number for telemetry / debugging.

Functions

history_dir(cwd, session_id)

@spec history_dir(String.t(), String.t()) :: String.t()

Path to the file-history directory for session_id under cwd.

rewind(session_id, mode, opts \\ [])

@spec rewind(String.t(), atom(), keyword()) :: {:ok, map()} | {:error, term()}

Rewind a session.

  • mode = :code_and_history — restore each file's contents to its most-recent checkpoint at-or-before to_uuid, AND truncate the session JSONL to that uuid.
  • mode = :history_only — only truncate the JSONL.

Returns {:ok, %{files_restored: n, events_dropped: m}}. Best-effort on file restoration; partial failures are logged.

snapshot(cwd, session_id, file_path)

@spec snapshot(String.t(), String.t(), String.t()) ::
  {:ok, %{version: non_neg_integer(), path: String.t()}} | {:error, term()}

Snapshot the prior contents of path before an edit. Returns the version directory + version number for telemetry / debugging.

Idempotent: if the file's contents match the most-recent checkpoint version exactly, the existing version is reused (no duplicate write).