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 ¶
const LookbackDays = 30
LookbackDays bounds how far back import reaches. Fixed this pass (no flag).
Variables ¶
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. Re-importing the same (sessionID, turnUUID) yields the same ID, which is how import stays idempotent.
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.
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
}
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 ¶
Result summarizes an import run.
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
// 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.