checkpoint

package
v0.8.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 6, 2026 License: MIT Imports: 54 Imported by: 0

Documentation

Overview

Package checkpoint provides types and interfaces for checkpoint storage.

A Checkpoint captures a point-in-time within a session, containing either full state (Temporary) or metadata with a commit reference (Committed).

See docs/architecture/sessions-and-checkpoints.md for the full domain model.

Index

Constants

View Source
const (
	// ShadowBranchPrefix is the prefix for shadow branches.
	ShadowBranchPrefix = "entire/"

	// ShadowBranchHashLength is the number of hex characters used in shadow branch names.
	// Shadow branches are named "entire/<hash>" using the first 7 characters of the commit hash.
	ShadowBranchHashLength = 7

	// WorktreeIDHashLength is the number of hex characters used for worktree ID hash.
	WorktreeIDHashLength = 6
)
View Source
const BackendTypeGitBranch = "git-branch"

BackendTypeGitBranch is the built-in git-branch checkpoint backend: it stores the committed record on a git branch (entire/checkpoints/v1) in this repo. It is git-backed (see registeredBackend.gitBacked) and is the default primary when no backend is configured.

View Source
const BackendTypeGitRefs = "git-refs"

BackendTypeGitRefs is the built-in git-refs checkpoint backend: it stores the committed record as one git ref per checkpoint (refs/entire/checkpoints/<shard>/ <id>) in this repo. Like git-branch it is git-backed, so it may be the primary; the two can run side by side (git-refs primary + git-branch mirror) during the branch->refs rollout, since the one-of-each-type rule permits distinct git-backed backends in the same topology.

View Source
const CheckpointRefPrefix = "refs/entire/checkpoints/"

CheckpointRefPrefix is the namespace under which the git-refs backend stores one ref per checkpoint: refs/entire/checkpoints/<shard>/<id>. Each ref points at a checkpoint commit whose tree root is that checkpoint's contents. This is distinct from the git-branch backend's single entire/checkpoints/v1 branch.

View Source
const PromptSeparator = "\n\n---\n\n"

PromptSeparator is the canonical separator used in prompt.txt when multiple prompts are stored in a single file.

Variables

View Source
var (
	ErrCheckpointNotFound = apicheckpoint.ErrCheckpointNotFound
	ErrNoTranscript       = apicheckpoint.ErrNoTranscript
)

Sentinel errors (re-exported so errors.Is keeps working across packages).

View Source
var ErrShadowRefBusy = errors.New("shadow branch ref moved (CAS mismatch)")

ErrShadowRefBusy is returned by casUpdateShadowBranchRef when the ref has moved since the caller read it. Callers retry with a fresh parent.

Functions

func ApplyTreeChanges added in v0.4.8

func ApplyTreeChanges(
	ctx context.Context,
	repo *git.Repository,
	rootTreeHash plumbing.Hash,
	changes []TreeChange,
) (plumbing.Hash, error)

ApplyTreeChanges applies multiple file-level changes to a tree efficiently. Changes are grouped by directory and applied in a single recursive pass. Unchanged subdirectories retain their hashes — this is the key optimization over FlattenTree + BuildTreeFromEntries for sparse changes.

func BuildTreeFromEntries

func BuildTreeFromEntries(ctx context.Context, repo *git.Repository, entries map[string]object.TreeEntry) (plumbing.Hash, error)

BuildTreeFromEntries builds a proper git tree structure from flattened file entries. Exported for use by strategy package (push_common.go, session_test.go)

func CreateBlobFromContent

func CreateBlobFromContent(repo *git.Repository, content []byte) (plumbing.Hash, error)

CreateBlobFromContent creates a blob object from in-memory content. Exported for use by strategy package (session_test.go)

func CreateCommit added in v0.5.0

func CreateCommit(ctx context.Context, repo *git.Repository, treeHash, parentHash plumbing.Hash, message, authorName, authorEmail string) (plumbing.Hash, error)

CreateCommit creates a git commit object with the given tree, parent, message, and author. If parentHash is ZeroHash, the commit is created without a parent (orphan commit).

func FlattenTree

func FlattenTree(repo *git.Repository, tree *object.Tree, prefix string, entries map[string]object.TreeEntry) error

FlattenTree recursively flattens a tree into a map of full paths to entries.

func GenerateCheckpointID added in v0.8.0

func GenerateCheckpointID(ctx context.Context) (id.CheckpointID, error)

GenerateCheckpointID mints a new checkpoint ID in the format the configured primary store uses: a ULID under the git-refs store, a legacy 12-hex ID otherwise. It is the single place the backend-coupled ID format is decided — generation sites call it instead of id.Generate() so a git-refs checkpoint is always a ULID, which lets reads route by ID kind (ULID ⟹ ref).

Fail-soft: a missing or malformed checkpoints config resolves to the default hex format rather than blocking ID generation (a bad block already surfaces through checkpoint.Open).

func GetGitAuthorFromRepo added in v0.4.5

func GetGitAuthorFromRepo(repo *git.Repository) (name, email string)

GetGitAuthorFromRepo retrieves the git user.name and user.email, checking both the repository-local config and the global ~/.gitconfig.

func HashWorktreeID

func HashWorktreeID(worktreeID string) string

HashWorktreeID returns a short hash of the worktree identifier. Used to create unique shadow branch names per worktree.

func ParseRef added in v0.8.0

func ParseRef(name plumbing.ReferenceName) (id.CheckpointID, bool)

ParseRef extracts the checkpoint ID from a per-checkpoint ref name, reporting whether name is a well-formed checkpoint ref. A ref is well-formed when it has the CheckpointRefPrefix, exactly a <shard>/<id> tail, and the shard matches the ID's own ShardFor — so refs the resolver did not write (mismatched shard, extra path segments) are rejected rather than silently resolved to the wrong bucket. It does not require the ID to be a recognized kind, so a future ID format still parses as long as it shards consistently.

func ParseShadowBranchName

func ParseShadowBranchName(branchName string) (commitPrefix, worktreeHash string, ok bool)

ParseShadowBranchName extracts the commit prefix and worktree hash from a shadow branch name. Input format: "entire/<commit[:7]>-<worktreeHash[:6]>" Returns (commitPrefix, worktreeHash, ok). Returns ("", "", false) if not a valid shadow branch.

func PrimaryIsRefs added in v0.8.0

func PrimaryIsRefs(cfg *settings.CheckpointsConfig) bool

PrimaryIsRefs reports whether the configured primary backend is the git-refs per-checkpoint store. It centralizes the topology check so push/pre-push code does not compare backend-type strings itself. A nil config (default) is the git-branch backend, so this returns false.

func ReadRawSessionLogForCheckpoint added in v0.6.3

func ReadRawSessionLogForCheckpoint(ctx context.Context, reader interface {
	CheckpointReader
	SessionReader
}, checkpointID id.CheckpointID) ([]byte, string, error)

func RedactBlobBytes added in v0.7.8

func RedactBlobBytes(ctx context.Context, content []byte, treePath string, usePrivacyFilter bool) []byte

RedactBlobBytes redacts a single blob's content given its tree path. JSON-shaped files (.jsonl or .json) get JSON-aware redaction (falling back to plain bytes on parse failure so regex/credential layers still apply); other files get plain byte redaction. When usePrivacyFilter is true the full 8-layer pipeline (including OPF) runs; otherwise the 7-layer pipeline.

.json is handled alongside .jsonl because checkpoint metadata files (metadata.json, per-session metadata.json) carry free-form fields like Summary.Intent / Summary.Outcome / ReviewPrompt that can contain PII the regex layers miss. The JSON-aware redactor extracts string leaves and applies OPF only to those, preserving the JSON structure.

Post-commit condensation uses false (fast path). The pre-push rewrite (strategy/manual_commit_opf_rewrite.go) uses true.

func RedactedJoinedPrompts added in v0.7.8

func RedactedJoinedPrompts(prompts []string) string

RedactedJoinedPrompts joins prompts and runs the 7-layer redaction pipeline. OPF runs exclusively in the pre-push rewrite (not here), so the writer's hot path stays predictable. Exported so alternate persistent backends produce identically-redacted prompt blobs.

func RefName added in v0.8.0

func RefName(cid id.CheckpointID) (plumbing.ReferenceName, error)

RefName returns the per-checkpoint git ref for a checkpoint ID: refs/entire/checkpoints/<shard>/<id>, where <shard> is id.ShardFor() (the first two chars for legacy hex IDs, the last two for ULIDs). The full ID is always the leaf, so the ref round-trips through ParseRef.

It errors on an empty or unrecognized checkpoint ID rather than returning a malformed ref (e.g. "refs/entire/checkpoints//"), so callers at trust boundaries — and future ones — can't silently push, fetch, or look up a bad ref.

func Register added in v0.7.8

func Register(typ string, f Factory)

Register adds a non-git-backed backend factory under typ. Such backends can serve as mirrors but not as the primary (see registeredBackend.gitBacked). Git-backed backends are built in and not registered through this path. It panics on a duplicate type to surface wiring mistakes.

func ShadowBranchNameForCommit

func ShadowBranchNameForCommit(baseCommit, worktreeID string) string

ShadowBranchNameForCommit returns the shadow branch name for a base commit hash and worktree identifier. The worktree ID should be empty for the main worktree or the internal git worktree name for linked worktrees. Format: entire/<commit[:7]>-<hash(worktreeID)[:6]>

func SignCommitBestEffort added in v0.5.6

func SignCommitBestEffort(ctx context.Context, commit *object.Commit)

SignCommitBestEffort signs the commit using an on-demand object signer. If signing is disabled, no signer can be created, or signing fails, the commit is left unsigned and the error is logged.

func SplitPromptContent added in v0.5.4

func SplitPromptContent(content string) []string

SplitPromptContent deserializes prompt.txt content into individual prompts.

func UpdateSubtree added in v0.4.8

func UpdateSubtree(
	repo *git.Repository,
	rootTreeHash plumbing.Hash,
	pathSegments []string,
	newEntries []object.TreeEntry,
	opts UpdateSubtreeOptions,
) (plumbing.Hash, error)

UpdateSubtree replaces or creates a subtree at the given path within an existing tree. It walks the tree path, replacing only the entries along the modified path. All sibling entries at each level retain their original hashes — no re-reading needed.

pathSegments is the directory path split into segments (e.g., ["a3", "b2c4d5e6f7"]). newEntries are the files/dirs to place at the leaf directory. Returns the new root tree hash.

func WalkCheckpointShards added in v0.5.4

func WalkCheckpointShards(ctx context.Context, repo *git.Repository, tree *object.Tree, fn func(cpID id.CheckpointID, cpTreeHash plumbing.Hash) error) error

WalkCheckpointShards iterates over the two-level shard structure (<id[:2]>/<id[2:]>/) in a checkpoint tree, calling fn for each checkpoint found. It skips non-directory and non-shard entries at both levels, such as legacy generation.json files or other metadata kept outside shard directories. The callback receives the parsed checkpoint ID and the tree hash of the checkpoint subtree.

Types

type Attribution added in v0.7.8

type Attribution = apicheckpoint.Attribution

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type Author

type Author struct {
	Name  string
	Email string
}

Author contains author information for a checkpoint.

type AuthorReader added in v0.7.8

type AuthorReader interface {
	GetCheckpointAuthor(ctx context.Context, checkpointID id.CheckpointID) (Author, error)
}

AuthorReader provides optional checkpoint author lookup. It stays in the implementation package: GetCheckpointAuthor is a git-log operation and Author is an implementation type, not part of the storage contract.

type BlobFetchFunc added in v0.5.1

type BlobFetchFunc func(ctx context.Context, hashes []plumbing.Hash) error

BlobFetchFunc fetches missing blob objects by hash from a remote.

type Checkpoint

type Checkpoint struct {
	// ID is the unique checkpoint identifier
	ID string

	// SessionID is the session this checkpoint belongs to
	SessionID string

	// Timestamp is when this checkpoint was created
	Timestamp time.Time

	// Type indicates temporary (full state) or committed (metadata only)
	Type Type

	// Message is a human-readable description of the checkpoint
	Message string
}

Checkpoint represents a save point within a session.

type CheckpointAttribution added in v0.7.8

type CheckpointAttribution = apicheckpoint.CheckpointAttribution

type CheckpointInfo added in v0.7.8

type CheckpointInfo = apicheckpoint.CheckpointInfo

type CheckpointReader added in v0.7.8

type CheckpointReader = apicheckpoint.CheckpointReader

Reader/writer interfaces and the Write request union. Reads are tiered by scope: CheckpointReader (checkpoint-level) and SessionReader (session-level), composed with Writer into PersistentStore.

type CheckpointSummary

type CheckpointSummary = apicheckpoint.CheckpointSummary

func ReadCheckpoint added in v0.7.8

func ReadCheckpoint(ctx context.Context, reader CheckpointReader, checkpointID id.CheckpointID) (*CheckpointSummary, error)

type CodeLearning

type CodeLearning = apicheckpoint.CodeLearning

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type EphemeralCheckpointInfo added in v0.7.8

type EphemeralCheckpointInfo struct {
	// CommitHash is the hash of the checkpoint commit
	CommitHash plumbing.Hash

	// Message is the first line of the commit message
	Message string

	// SessionID is the session identifier from the Entire-Session trailer
	SessionID string

	// MetadataDir is the metadata directory path from trailers
	MetadataDir string

	// IsTaskCheckpoint indicates if this is a task checkpoint
	IsTaskCheckpoint bool

	// ToolUseID is the tool use ID for task checkpoints
	ToolUseID string

	// Timestamp is when the checkpoint was created
	Timestamp time.Time
}

EphemeralCheckpointInfo contains information about a single commit on a shadow branch. Used by ListCheckpoints to provide rewind point data.

type EphemeralInfo added in v0.7.8

type EphemeralInfo struct {
	// BranchName is the full branch name (e.g., "entire/abc1234")
	BranchName string

	// BaseCommit is the short commit hash this branch is based on
	BaseCommit string

	// LatestCommit is the hash of the latest commit on the branch
	LatestCommit plumbing.Hash

	// SessionID is the session identifier from the latest commit
	SessionID string

	// Timestamp is when the latest checkpoint was created
	Timestamp time.Time
}

EphemeralInfo contains summary information about a shadow branch.

type EphemeralStore added in v0.7.8

type EphemeralStore interface {
	Write(ctx context.Context, req EphemeralWriteRequest) (WriteEphemeralResult, error)
	Read(ctx context.Context, baseCommit, worktreeID string) (*ReadEphemeralResult, error)
	List(ctx context.Context) ([]EphemeralInfo, error)
	ListCheckpoints(ctx context.Context, baseCommit, worktreeID, sessionID string, limit int) ([]EphemeralCheckpointInfo, error)
	ListCheckpointsForBranch(ctx context.Context, branchName, sessionID string, limit int) ([]EphemeralCheckpointInfo, error)
	ListAllCheckpoints(ctx context.Context, sessionID string, limit int) ([]EphemeralCheckpointInfo, error)
	GetTranscriptFromCommit(ctx context.Context, commitHash plumbing.Hash, metadataDir string, agentType types.AgentType) ([]byte, error)
	ShadowBranchExists(baseCommit, worktreeID string) bool
}

EphemeralStore provides the production shadow-branch checkpoint surface.

func NewEphemeralStore added in v0.7.8

func NewEphemeralStore(repo *git.Repository, refs PersistentRefs) EphemeralStore

NewEphemeralStore constructs the git shadow-branch (temporary) checkpoint store. Most callers reach it via Open(...).Ephemeral(); this direct constructor exists for benchmarks and tests that exercise the shadow-branch surface without the full facade.

type EphemeralWriteRequest added in v0.7.8

type EphemeralWriteRequest interface {
	// contains filtered or unexported methods
}

EphemeralWriteRequest is a single shadow-branch (ephemeral) write command. The set is closed via the unexported marker; the store dispatches on the concrete type, mirroring the persistent WriteRequest union.

type Factory added in v0.7.8

type Factory func(ctx context.Context, env OpenEnv, cfg json.RawMessage) (PersistentStore, error)

Factory constructs a persistent store for one backend type. cfg is the backend-specific JSON "config" block from settings (nil when absent).

type FetchingTree added in v0.5.1

type FetchingTree struct {
	// contains filtered or unexported fields
}

FetchingTree wraps a git tree to automatically fetch missing blobs on demand. After a treeless fetch (--filter=blob:none), tree objects are available locally but blob objects are not. Each File() call checks whether the target blob exists locally and fetches it from the remote if missing, using FindEntry to locate the blob hash without resolving the blob itself.

Because go-git's ObjectStorage caches the packfile index and never refreshes it, blobs fetched by external git commands (e.g. git fetch-pack) may not be visible to go-git's storer. As a fallback, File() reads the blob via "git cat-file" which always sees the current on-disk object store.

For best performance, call PreFetch before reading files. PreFetch walks the tree, identifies locally-missing blobs, and batch-fetches them in a single network round-trip instead of one fetch per File() miss.

func NewFetchingTree added in v0.5.1

func NewFetchingTree(ctx context.Context, tree *object.Tree, s storer.EncodedObjectStorer, fetch BlobFetchFunc) *FetchingTree

NewFetchingTree wraps a git tree with on-demand blob fetching. The storer is used to check if blobs exist locally, and fetch is called to download any that are missing. If fetch is nil, File() behaves identically to the underlying tree.

func (*FetchingTree) CollectMissingBlobs added in v0.6.0

func (t *FetchingTree) CollectMissingBlobs() []plumbing.Hash

CollectMissingBlobs returns the hashes of every blob entry in this tree (recursively) that isn't present in the local object store. Useful for callers that want to decide whether network work is needed before running PreFetch (e.g., to avoid showing a spinner in fast no-op cases).

func (*FetchingTree) File added in v0.5.1

func (t *FetchingTree) File(path string) (*object.File, error)

File returns the file at the given path. Resolution order:

  1. go-git's storer (fast path, in-memory).
  2. `git cat-file -p` against the on-disk object store (handles partial-clone-filtered blobs that go-git can't see, plus packfiles created by external git commands after this process opened the repo).
  3. Remote fetch via the configured fetcher, then cat-file again.

Trying cat-file BEFORE the remote fetch is critical: in partial-clone repos, blobs are commonly on disk but invisible to go-git's storer (filtered out, or in a packfile not in go-git's index cache). Without this short-circuit, every File() would burn a multi-second network round-trip even though the blob is already local.

func (*FetchingTree) PreFetch added in v0.5.1

func (t *FetchingTree) PreFetch() (int, error)

PreFetch walks the tree recursively, identifies blob entries that are missing from the local object store, and batch-fetches them in a single call to t.fetch. This avoids per-blob network round-trips during subsequent File() calls. It is safe to call even when all blobs are already local (no-op). Returns the number of blobs fetched.

func (*FetchingTree) RawEntries added in v0.5.1

func (t *FetchingTree) RawEntries() []object.TreeEntry

RawEntries returns the direct tree entries (no blob reads needed).

func (*FetchingTree) Tree added in v0.5.1

func (t *FetchingTree) Tree(path string) (*FetchingTree, error)

Tree returns the subtree at the given path, wrapped with the same fetching behavior.

type FileOpener added in v0.5.1

type FileOpener interface {
	Reader() (io.ReadCloser, error)
}

FileOpener provides access to a file's content reader. *object.File implements this interface.

type FileReader added in v0.5.1

type FileReader interface {
	File(path string) (*object.File, error)
}

FileReader provides read access to files within a git tree. Both *object.Tree and *FetchingTree implement this interface.

type GitStore

type GitStore struct {
	// contains filtered or unexported fields
}

GitStore is the committed (persistent) checkpoint store. Writes target refs.Primary; committed reads resolve against refs.Read. The temporary shadow-branch surface lives in ephemeralStore. It embeds *treeWriter for the shared subtree-building machinery.

func NewGitStore

func NewGitStore(repo *git.Repository, refs PersistentRefs) *GitStore

NewGitStore creates a checkpoint store backed by the given git repository and committed-metadata topology. Pass DefaultV1Refs() for the v1-only default or ResolveRefs(ctx) in code paths that honor settings.

func (*GitStore) GetCheckpointAuthor

func (s *GitStore) GetCheckpointAuthor(ctx context.Context, checkpointID id.CheckpointID) (Author, error)

GetCheckpointAuthor retrieves the author of a checkpoint from the configured committed-read ref history. Finds the commit whose subject matches "Checkpoint: <id>" and returns its author. Returns empty Author if the checkpoint is not found or the sessions branch doesn't exist.

func (*GitStore) GetSessionLog

func (s *GitStore) GetSessionLog(ctx context.Context, cpID id.CheckpointID) ([]byte, string, error)

GetSessionLog retrieves the session transcript and session ID for a checkpoint. This is the primary method for looking up session logs by checkpoint ID. Returns ErrCheckpointNotFound if the checkpoint doesn't exist. Returns ErrNoTranscript if the checkpoint exists but has no transcript.

func (*GitStore) GetTranscript

func (s *GitStore) GetTranscript(ctx context.Context, checkpointID id.CheckpointID) ([]byte, error)

GetTranscript retrieves the transcript for a specific checkpoint ID. Returns the latest session's transcript.

func (*GitStore) List added in v0.7.8

func (s *GitStore) List(ctx context.Context) ([]CheckpointInfo, error)

func (*GitStore) PersistentReadRef added in v0.7.8

func (s *GitStore) PersistentReadRef() plumbing.ReferenceName

PersistentReadRef returns the ref that committed-checkpoint reads resolve against.

func (*GitStore) Read added in v0.7.8

func (s *GitStore) Read(ctx context.Context, checkpointID id.CheckpointID) (*CheckpointSummary, error)

Read reads a committed checkpoint's summary by ID from the entire/checkpoints/v1 branch. Returns only the CheckpointSummary (paths + aggregated stats), not actual content. Use ReadSessionContent to read actual transcript/prompts/context. Returns nil, nil if the checkpoint doesn't exist.

The storage format uses numbered subdirectories for each session (0-based):

<checkpoint-id>/
├── metadata.json      # CheckpointSummary with sessions map
├── 0/                 # First session
│   ├── metadata.json  # Session-specific metadata
│   ├── full.jsonl     # Raw agent transcript
│   └── transcript.jsonl  # Compact transcript (referenced by metadata.json)
├── 1/                 # Second session
└── ...

func (*GitStore) ReadLatestSessionContent

func (s *GitStore) ReadLatestSessionContent(ctx context.Context, checkpointID id.CheckpointID) (*SessionContent, error)

ReadLatestSessionContent is a convenience method that reads the latest session's content. This is equivalent to ReadSessionContent(ctx, checkpointID, len(summary.Sessions)-1).

func (*GitStore) ReadSessionContent

func (s *GitStore) ReadSessionContent(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*SessionContent, error)

ReadSessionContent reads the actual content for a specific session within a checkpoint. sessionIndex is 0-based (0 for first session, 1 for second, etc.). Returns the session's metadata, transcript, prompts, and context. Returns ErrCheckpointNotFound if the checkpoint or session doesn't exist. Returns ErrNoTranscript if the session exists but has no transcript.

func (*GitStore) ReadSessionContentByID

func (s *GitStore) ReadSessionContentByID(ctx context.Context, checkpointID id.CheckpointID, sessionID string) (*SessionContent, error)

ReadSessionContentByID reads a session's content by its session ID. This is useful when you have the session ID but don't know its index within the checkpoint. Returns ErrCheckpointNotFound if the checkpoint doesn't exist. Returns an error if no session with the given ID exists in the checkpoint.

func (*GitStore) ReadSessionMetadata added in v0.5.4

func (s *GitStore) ReadSessionMetadata(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*Metadata, error)

ReadSessionMetadata reads only the metadata.json for a specific session within a checkpoint. This is a lightweight read that avoids fetching transcript/prompt blobs. sessionIndex is 0-based.

func (*GitStore) ReadSessionMetadataAndPrompts added in v0.6.3

func (s *GitStore) ReadSessionMetadataAndPrompts(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*Metadata, string, error)

ReadSessionMetadataAndPrompts reads session metadata and prompt text without requiring the raw transcript blob.

func (*GitStore) ReadSessionPrompts added in v0.6.3

func (s *GitStore) ReadSessionPrompts(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (string, error)

func (*GitStore) Refs added in v0.7.6

func (s *GitStore) Refs() PersistentRefs

Refs returns the committed-metadata topology the store was constructed with.

func (*GitStore) Repository

func (s *GitStore) Repository() *git.Repository

Repository returns the underlying git repository.

func (*GitStore) SetBlobFetcher added in v0.5.1

func (s *GitStore) SetBlobFetcher(f BlobFetchFunc)

SetBlobFetcher configures the store to automatically fetch missing blobs on demand when reading from metadata trees.

func (*GitStore) Write added in v0.7.8

func (s *GitStore) Write(ctx context.Context, req WriteRequest) error

Write dispatches a persistent write request to the matching git operation. The request types and Writer interface are defined in the api/checkpoint contract (re-exported here via aliases). Unknown request types are a programmer error, surfaced rather than ignored.

type Info

type Info struct {
	// ID is the checkpoint identifier
	ID string

	// SessionID identifies the session
	SessionID string

	// Type indicates temporary or committed
	Type Type

	// CreatedAt is when the checkpoint was created
	CreatedAt time.Time

	// Message is a summary description
	Message string
}

Info provides summary information for listing checkpoints. This is the generic checkpoint info type.

type LearningsSummary

type LearningsSummary = apicheckpoint.LearningsSummary

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type MergeMode added in v0.4.8

type MergeMode int

MergeMode controls how entries at the leaf directory are handled by UpdateSubtree.

const (
	// ReplaceAll replaces the entire leaf directory contents with the new entries.
	ReplaceAll MergeMode = iota
	// MergeKeepExisting merges new entries into the existing leaf directory,
	// keeping existing entries that are not overwritten (unless in DeleteNames).
	MergeKeepExisting
)

type Metadata added in v0.7.8

type Metadata = apicheckpoint.Metadata

Persisted document types.

type OpenEnv added in v0.7.8

type OpenEnv struct {
	Repo        *git.Repository
	BlobFetcher BlobFetchFunc
	RefFetcher  RefFetchFunc
	Refs        PersistentRefs
}

OpenEnv carries the construction context a backend factory may need. Git-backed backends require Repo and use Refs/BlobFetcher/RefFetcher; other backends ignore the git-shaped fields and read their own configuration from cfg.

type OpenOptions added in v0.7.8

type OpenOptions struct {
	// BlobFetcher is the CLI-level on-demand blob fetcher. The checkpoint
	// package cannot resolve it itself, so the CLI layer injects it here and
	// Open attaches it to the constructed store(s). nil leaves on-demand
	// fetching off.
	BlobFetcher BlobFetchFunc

	// RefFetcher is the CLI-level on-demand checkpoint-ref fetcher, used by the
	// git-refs backend to resolve a checkpoint ref missing locally. nil leaves
	// reads local-only; ignored by the git-branch backend.
	RefFetcher RefFetchFunc

	// Refs overrides the default committed-ref topology. A non-nil value wins,
	// e.g. attach pins reads to Primary via PrimaryAsRead().
	Refs *PersistentRefs
}

OpenOptions configures Open. The zero value uses the default committed-ref topology and attaches no blob fetcher.

type PersistentRefs added in v0.7.8

type PersistentRefs struct {
	Primary plumbing.ReferenceName
	Read    plumbing.ReferenceName
	Push    []plumbing.ReferenceName
}

PersistentRefs is the committed-metadata ref topology.

func DefaultV1Refs added in v0.7.6

func DefaultV1Refs() PersistentRefs

DefaultV1Refs returns the v1-only topology.

func ResolveRefs added in v0.7.8

func ResolveRefs(_ context.Context) PersistentRefs

ResolveRefs returns the committed metadata topology.

func (PersistentRefs) PrimaryAsRead added in v0.7.8

func (r PersistentRefs) PrimaryAsRead() PersistentRefs

PrimaryAsRead returns a copy of r with Read pinned to Primary.

func (PersistentRefs) PrimaryFetchableFromOrigin added in v0.7.8

func (r PersistentRefs) PrimaryFetchableFromOrigin() bool

PrimaryFetchableFromOrigin reports whether Primary has an origin-tracking shadow.

func (PersistentRefs) ReadBootstrappableFromOrigin added in v0.7.8

func (r PersistentRefs) ReadBootstrappableFromOrigin() bool

ReadBootstrappableFromOrigin reports whether reads can be bootstrapped from origin: true when reads target Primary and Primary is fetchable from origin.

type PersistentStore added in v0.7.8

type PersistentStore = apicheckpoint.PersistentStore

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type PrecomputedTranscriptBlobs added in v0.5.6

type PrecomputedTranscriptBlobs = apicheckpoint.PrecomputedTranscriptBlobs

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

func PrecomputeTranscriptBlobs added in v0.5.6

func PrecomputeTranscriptBlobs(ctx context.Context, repo *git.Repository, transcript redact.RedactedBytes, agentType types.AgentType) (*PrecomputedTranscriptBlobs, error)

PrecomputeTranscriptBlobs chunks the given transcript and writes each chunk plus the content-hash blob to the object store once, returning the resulting hashes for reuse across multiple backfillTranscript calls that share the same transcript content.

type PushQueue added in v0.8.0

type PushQueue struct {
	// contains filtered or unexported fields
}

PushQueue is a flock-protected JSONL list of checkpoint refs awaiting push, stored in the git common dir. Entries are removed only after a confirmed push (Remove), so an interrupted or failed push leaves them for the next pre-push. Duplicates are tolerated on disk and collapsed by Drain.

func NewPushQueue added in v0.8.0

func NewPushQueue(gitCommonDir string) *PushQueue

NewPushQueue returns the push queue rooted at gitCommonDir.

func PushQueueForRepo added in v0.8.0

func PushQueueForRepo(ctx context.Context, repo *git.Repository) (*PushQueue, error)

PushQueueForRepo resolves the git common dir for repo and returns its queue.

func (*PushQueue) Drain added in v0.8.0

func (q *PushQueue) Drain() ([]plumbing.ReferenceName, error)

Drain returns the de-duplicated refs currently queued, in first-seen order. It does NOT remove them; call Remove after a confirmed push so a failed push retries next time. A missing queue file yields no refs.

It compacts the file in place: when the on-disk queue held redundant lines (duplicate enqueues of the same ref, or malformed/blank lines), Drain rewrites it to the de-duplicated set. Enqueue only ever appends, so without this the file would grow unboundedly between the Removes that are otherwise the sole compaction point (e.g. a long-lived session that keeps re-enqueuing the same checkpoint ref but never pushes).

func (*PushQueue) Enqueue added in v0.8.0

func (q *PushQueue) Enqueue(ref plumbing.ReferenceName) error

Enqueue appends a ref to the queue. It is safe to enqueue a ref already present (or already pushed): Drain collapses duplicates and the batch push is idempotent. Enqueue takes the lock so concurrent writers never interleave a partial line.

func (*PushQueue) Remove added in v0.8.0

func (q *PushQueue) Remove(refs []plumbing.ReferenceName) error

Remove deletes the given refs from the queue, preserving any entries appended after a Drain (e.g. a write that landed during the push). Called after a confirmed push.

type ReadEphemeralResult added in v0.7.8

type ReadEphemeralResult struct {
	// CommitHash is the hash of the checkpoint commit
	CommitHash plumbing.Hash

	// TreeHash is the hash of the tree containing the checkpoint state
	TreeHash plumbing.Hash

	// SessionID is the session identifier from the commit trailer
	SessionID string

	// MetadataDir is the metadata directory path from the commit trailer
	MetadataDir string

	// Timestamp is when the checkpoint was created
	Timestamp time.Time
}

ReadEphemeralResult contains the result of reading a temporary checkpoint.

type RefFetchFunc added in v0.8.0

type RefFetchFunc func(ctx context.Context, ref plumbing.ReferenceName) error

RefFetchFunc fetches a single checkpoint ref from the remote into the local ref of the same name. The git-refs store uses it to resolve a checkpoint ref that is not present locally (e.g. written on another machine). The checkpoint package cannot resolve the remote target itself, so the CLI layer injects it.

type Session added in v0.7.8

type Session = apicheckpoint.Session

Write request union: session-level (Session, SessionTranscript, SessionSummary) and checkpoint-level (CheckpointAttribution).

type SessionContent

type SessionContent = apicheckpoint.SessionContent

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

func ReadLatestSessionContent added in v0.6.3

func ReadLatestSessionContent(ctx context.Context, reader SessionReader, checkpointID id.CheckpointID, summary *CheckpointSummary) (*SessionContent, error)

type SessionFilePaths

type SessionFilePaths = apicheckpoint.SessionFilePaths

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type SessionMetrics added in v0.5.0

type SessionMetrics = apicheckpoint.SessionMetrics

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type SessionReader added in v0.7.8

type SessionReader = apicheckpoint.SessionReader

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type SessionSummary added in v0.7.8

type SessionSummary = apicheckpoint.SessionSummary

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type SessionTranscript added in v0.7.8

type SessionTranscript = apicheckpoint.SessionTranscript

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type Step added in v0.7.8

Step captures working-tree changes as an ephemeral (shadow-branch) checkpoint for a session step.

type Stores added in v0.7.8

type Stores struct {
	// Persistent is the committed store that serves permanent reads and writes.
	Persistent PersistentStore
	// contains filtered or unexported fields
}

Stores is the facade returned by Open: the persistent store plus the git-only ephemeral (shadow-branch) capability and resolved committed-ref topology.

func Open added in v0.7.8

func Open(ctx context.Context, repo *git.Repository, opts OpenOptions) (*Stores, error)

Open resolves the checkpoint storage topology and constructs the backing store(s). It keeps ref resolution, backend selection, and blob-fetcher wiring in one place. The primary is built through the backend registry; with no checkpoints config it resolves to the git-branch backend with no mirrors, so default behavior is unchanged. When mirrors are configured, the persistent store is a fan-out wrapper (reads from primary, best-effort writes to mirrors).

Backend selection is read via settings.LoadCheckpointsConfig, which resolves like settings.Load: from the context's worktree root if set, else relative to the current working directory — not from repo. Callers opening a repository that is not the cwd should wrap ctx with that worktree root (as dispatch does). Resolution is fail-soft: a missing or unreadable settings file yields the default git-branch backend with no mirrors, preserving default behavior.

func (*Stores) Ephemeral added in v0.7.8

func (s *Stores) Ephemeral() EphemeralStore

Ephemeral returns the git-backed shadow-branch (temporary) store.

func (*Stores) Refs added in v0.7.8

func (s *Stores) Refs() PersistentRefs

Refs returns the resolved committed-ref topology.

type Summary

type Summary = apicheckpoint.Summary

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

func RedactSummary added in v0.7.8

func RedactSummary(s *Summary) *Summary

RedactSummary returns a copy of the summary with text fields redacted. Structural fields (Path, Line, EndLine) are preserved. Exported so alternate persistent backends redact summaries the same way the git store does. NOTE: When adding new text fields to Summary, LearningsSummary, or CodeLearning, update this function to include them in redaction.

type TaskStep added in v0.7.8

TaskStep captures a completed subagent task as an ephemeral (shadow-branch) checkpoint for a task step.

type TreeChange added in v0.4.8

type TreeChange struct {
	// Path is the full path within the tree (e.g., "src/pkg/handler.go").
	Path string
	// Entry is the new tree entry. Nil means delete the file at Path.
	Entry *object.TreeEntry
}

TreeChange represents a single file change within a tree. Use a nil Entry to indicate deletion.

type Type

type Type int

Type indicates the storage location and lifecycle of a checkpoint.

const (
	// Ephemeral checkpoints contain full state (code + metadata) and are stored
	// on shadow branches (entire/<commit-hash>). Used for intra-session rewind.
	Ephemeral Type = iota

	// Persistent checkpoints contain metadata + commit reference and are stored
	// on the entire/checkpoints/v1 branch. They are the permanent record.
	Persistent
)

type UpdateOptions added in v0.7.8

type UpdateOptions = apicheckpoint.UpdateOptions

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type UpdateSubtreeOptions added in v0.4.8

type UpdateSubtreeOptions struct {
	// MergeMode controls how entries at the leaf directory are handled.
	MergeMode MergeMode
	// DeleteNames lists entry names (at the leaf directory level) to delete.
	// Only applicable when MergeMode is MergeKeepExisting.
	DeleteNames []string
}

UpdateSubtreeOptions configures the behavior of UpdateSubtree.

type WriteEphemeralOptions added in v0.7.8

type WriteEphemeralOptions struct {
	// SessionID is the session identifier
	SessionID string

	// BaseCommit is the commit hash this session is based on
	BaseCommit string

	// WorktreeID is the internal git worktree identifier (empty for main worktree)
	// Used to create worktree-specific shadow branch names
	WorktreeID string

	// ModifiedFiles are files that have been modified (relative paths)
	ModifiedFiles []string

	// NewFiles are files that have been created (relative paths)
	NewFiles []string

	// DeletedFiles are files that have been deleted (relative paths)
	DeletedFiles []string

	// MetadataDir is the relative path to the metadata directory
	MetadataDir string

	// MetadataDirAbs is the absolute path to the metadata directory
	MetadataDirAbs string

	// CommitMessage is the commit subject line
	CommitMessage string

	// AuthorName is the name to use for commits
	AuthorName string

	// AuthorEmail is the email to use for commits
	AuthorEmail string

	// IsFirstCheckpoint indicates if this is the first checkpoint of the session
	// When true, all working directory files are captured (not just modified)
	IsFirstCheckpoint bool
}

WriteEphemeralOptions contains options for writing a temporary checkpoint.

type WriteEphemeralResult added in v0.7.8

type WriteEphemeralResult struct {
	// CommitHash is the hash of the created or existing checkpoint commit
	CommitHash plumbing.Hash

	// Skipped is true if the checkpoint was skipped due to no changes
	// (tree hash matched the previous checkpoint)
	Skipped bool
}

WriteEphemeralResult contains the result of writing a temporary checkpoint.

type WriteEphemeralTaskOptions added in v0.7.8

type WriteEphemeralTaskOptions struct {
	// SessionID is the session identifier
	SessionID string

	// BaseCommit is the commit hash this session is based on
	BaseCommit string

	// WorktreeID is the internal git worktree identifier (empty for main worktree)
	// Used to create worktree-specific shadow branch names
	WorktreeID string

	// ToolUseID is the unique identifier for this Task tool invocation
	ToolUseID string

	// AgentID is the subagent identifier
	AgentID string

	// ModifiedFiles are files that have been modified (relative paths)
	ModifiedFiles []string

	// NewFiles are files that have been created (relative paths)
	NewFiles []string

	// DeletedFiles are files that have been deleted (relative paths)
	DeletedFiles []string

	// TranscriptPath is the path to the main session transcript
	TranscriptPath string

	// SubagentTranscriptPath is the path to the subagent's transcript
	SubagentTranscriptPath string

	// CheckpointUUID is the UUID for transcript truncation when rewinding
	CheckpointUUID string

	// CommitMessage is the commit message (already formatted)
	CommitMessage string

	// AuthorName is the name to use for commits
	AuthorName string

	// AuthorEmail is the email to use for commits
	AuthorEmail string

	// IsIncremental indicates this is an incremental checkpoint
	IsIncremental bool

	// IncrementalSequence is the checkpoint sequence number
	IncrementalSequence int

	// IncrementalType is the tool that triggered this checkpoint
	IncrementalType string

	// IncrementalData is the tool_input payload for this checkpoint
	IncrementalData []byte
}

WriteEphemeralTaskOptions contains options for writing a task checkpoint. Task checkpoints are created when a subagent completes and contain both code changes and task-specific metadata.

type WriteOptions added in v0.7.8

type WriteOptions = apicheckpoint.WriteOptions

Operation option types.

type WriteRequest added in v0.7.8

type WriteRequest = apicheckpoint.WriteRequest

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

type Writer added in v0.7.8

type Writer = apicheckpoint.Writer

The persistent-checkpoint contract (persisted document types, option types, reader/writer interfaces, and the Write request union) lives in the api/checkpoint package so storage backends can depend on it without the CLI's agent/git machinery. These aliases re-export it under this package so existing CLI call sites are unaffected; the git implementation (GitStore, Open, the facade, and the ephemeral shadow-branch surface) stays here.

Directories

Path Synopsis
Package fsstore is a reference, test-only persistent checkpoint backend that stores checkpoints as JSON files on disk.
Package fsstore is a reference, test-only persistent checkpoint backend that stores checkpoints as JSON files on disk.
Package id provides the CheckpointID type for identifying checkpoints.
Package id provides the CheckpointID type for identifying checkpoints.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL