# `ExAthena.Checkpoint`
[🔗](https://github.com/udin-io/ex_athena/blob/v0.7.1/lib/ex_athena/checkpoint.ex#L1)

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).

# `history_dir`

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

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

# `rewind`

```elixir
@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`

```elixir
@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).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
