agentimport

package
v0.11.4 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: MIT Imports: 36 Imported by: 0

Documentation

Overview

Package agentimport imports a coding agent's pre-existing local transcripts into Entire as read-only, commit-less checkpoints on the v1 metadata branch.

The orchestration (discovery loop, idempotent per-turn IDs, redaction, and the checkpoint write) is agent-agnostic and lives here. Each agent plugs in an Importer that knows where its transcripts live and how to split one into per-user-prompt turns. Claude Code is the only implementation today (see claude.go); others register themselves the same way.

Index

Constants

View Source
const LookbackDays = 30

LookbackDays bounds how far back import reaches. Fixed this pass (no flag).

Variables

View Source
var ErrAnchorRepoConfig = errors.New("read anchor repository config")

ErrAnchorRepoConfig reports that the repository's object format could not be read, so no anchor could be checked. It is separated from the rejections below because it says nothing about the candidate: it fails identically for every one, and a caller looping over candidates must stop rather than mistake it for "this ref's object is missing" and end up blaming the refs.

Functions

func DeriveCheckpointID

func DeriveCheckpointID(sessionID, turnUUID string) id.CheckpointID

DeriveCheckpointID produces a stable 12-hex checkpoint ID for an imported turn: the git-branch format. Re-importing the same (sessionID, turnUUID) yields the same ID, which is how import stays idempotent.

func DeriveULIDCheckpointID added in v0.11.4

func DeriveULIDCheckpointID(sessionID, turnUUID string, createdAt time.Time) (id.CheckpointID, error)

DeriveULIDCheckpointID produces a stable ULID checkpoint ID for an imported turn: the git-refs format, which a git-refs checkpoint must use (see checkpoint.GenerateCheckpointID). Its timestamp is the turn's createdAt, so imported IDs sort by when the turn happened; re-importing the same turn yields the same ID.

func ValidateAnchorCommit added in v0.11.0

func ValidateAnchorCommit(repo *git.Repository, sha string) (string, error)

ValidateAnchorCommit requires a full hexadecimal object ID in the repository's object format (40 hex characters under SHA-1, 64 under SHA-256) naming a commit in repo, and returns its canonical lowercase ID. It never interprets the input as a ref or revision expression, or peels a tag into a commit.

Types

type Importer

type Importer interface {
	// Name is the registry key and the provenance source (e.g. "claude-code").
	Name() string
	// AgentType is the display name stored in checkpoint metadata (e.g. "Claude Code").
	AgentType() types.AgentType
	// Discover returns the agent's transcript files for the repo within the
	// lookback window. overridePath replaces the default transcript dir;
	// sessionFilter, when non-empty, keeps only matching session IDs.
	Discover(repoRoot, overridePath string, now time.Time, sessionFilter []string) ([]SessionFile, error)
	// SplitTurns splits one session's raw transcript bytes into per-turn units.
	SplitTurns(sf SessionFile, full []byte) ([]Turn, error)
}

Importer is the per-agent seam: it locates an agent's transcripts for a repo and splits one into per-turn units. Everything else (idempotency, redaction, writing) is handled generically by Run.

func All

func All() []Importer

All returns every supported importer, sorted by name.

type Options

type Options struct {
	RepoRoot      string
	OverridePath  string
	SessionFilter []string
	Now           time.Time
	DryRun        bool

	// LinkCommitSHA is the required full hexadecimal fallback commit ID written
	// to imported checkpoint metadata as commit_sha — the commit the UI shows
	// imported sessions against. The caller resolves it (the default branch
	// head; see resolveImportLinkCommitSHA); Run validates the exact
	// commit object and canonicalizes its ID before any writes, even on dry-run
	// or fully skipped imports. A turn whose transcript records a resolvable
	// commit that is an ancestor of this fallback anchors to that real commit
	// instead (see turnAnchorResolver).
	LinkCommitSHA string

	// Progress, when non-nil, receives session/turn progress notifications
	// as Run executes. Nil (the default) reports nothing.
	Progress *Progress

	// ReadRemotes is the ordered checkpoint read-candidate chain (see
	// checkpoint.OpenOptions.ReadRemotes) used by the idempotency listing.
	// Without it the listing reads only origin's tracking refs: turns already
	// on the elected sync remote get re-imported, and turns present solely in
	// origin's stale tracking ref get skipped. Callers resolve it via
	// strategy.CheckpointReadRemotes.
	ReadRemotes []string

	// RemoteRefLister, when set, adds the checkpoint refs present only on the
	// remote (names only, no fetch) to the idempotency listing, so a re-import
	// from a fresh clone skips turns imported elsewhere instead of writing them
	// again (under a new ID format, if the primary has since changed). Callers
	// pass the CLI's ListCheckpointRefsOnRemote.
	RemoteRefLister cp.RemoteRefListFunc
}

Options configures an import run.

type Progress added in v0.10.0

type Progress struct {
	// SessionStart fires once per session, after its transcript has been
	// split into turns and before any of them are written. sessionIndex is
	// 0-based against sessionTotal, the number of sessions Discover
	// returned; turnCount is the number of turns split from this session.
	SessionStart func(sessionIndex, sessionTotal int, agentName, sessionID string, turnCount int)
	// TurnWritten fires once per turn Run actually writes to the checkpoint
	// store — never for a turn skipped as already-imported, nor under
	// DryRun (see TurnSkipped for those). turnIndex is 0-based against
	// turnCount, matching the turnCount reported by this turn's
	// SessionStart call.
	TurnWritten func(sessionIndex, turnIndex, turnCount int)
	// TurnSkipped fires once per turn Run processes without writing: a turn
	// already imported (idempotent re-run) or, under DryRun, every turn
	// (dry runs never write). Index semantics match TurnWritten exactly.
	TurnSkipped func(sessionIndex, turnIndex, turnCount int)
}

Progress reports observable events as Run walks sessions and writes turns. It is UI-agnostic: Run never prints or logs on its behalf, so rendering (a progress bar, log lines, a TUI) is entirely up to the caller. Every field is optional, and a nil *Progress (the default) is a no-op — Run's behavior is byte-identical whether or not one is supplied.

Invariant: for every turn Run processes, exactly one of TurnWritten or TurnSkipped fires — so summing both callbacks' calls across one session always equals that session's turnCount (as reported by SessionStart).

type Result

type Result struct {
	SessionsScanned int
	TurnsImported   int
	TurnsSkipped    int
}

Result summarizes an import run.

func Run

func Run(ctx context.Context, repo *git.Repository, imp Importer, opts Options) (Result, error)

Run imports the given agent's transcripts (within the lookback window) as read-only checkpoints (Kind "imported") in the configured checkpoint store, with IDs in that store's format. It is idempotent: turns whose deterministic ID already exists are skipped.

type SessionFile

type SessionFile struct {
	Path      string // absolute path to the transcript file
	SessionID string // agent session id (used in checkpoint metadata)
}

SessionFile is one discovered agent transcript for a repo.

type Turn

type Turn struct {
	LineStart, LineEnd int
	UUID               string
	Prompt, Model      string
	CreatedAt          time.Time
	// CreatedAtFromModTime reports that CreatedAt is the transcript file's
	// modtime because the transcript records no per-turn time (Cursor,
	// Factory). It changes whenever the file grows, so it must not feed the
	// turn's checkpoint ID.
	CreatedAtFromModTime bool
	// Tokens is this turn's token usage. Every field is a per-turn delta:
	// main-agent fields are scoped to the turn's [LineStart, LineEnd) slice by
	// the token helpers, and SubagentTokens is rescoped from the cumulative
	// snapshot those helpers return to a per-turn increment by
	// rescopeSubagentTokensToDeltas (see linesplit.go). That invariant lets
	// callers sum turns freely: writeSessionState sums them for the session
	// total and each imported checkpoint stores its own turn's delta, so a
	// subagent's tokens are counted exactly once rather than re-added on every
	// turn after it is discovered.
	Tokens *types.TokenUsage
	// CommitSHAs are the commit SHAs (possibly abbreviated) this turn's
	// transcript records creating, in transcript order. Extraction is
	// per-importer (see commitSHAsInRange for Claude Code). Callers must
	// resolve them against the repo before use. Nil when the transcript
	// records no commits (including agents that don't extract them); the
	// anchor then falls back to Options.LinkCommitSHA.
	CommitSHAs []string
}

Turn is one user-prompt turn extracted from a session transcript. Line offsets are in raw-line space (newline-counted), matching transcript slicing and the agent token-usage helpers.

Jump to

Keyboard shortcuts

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