sessions

package
v0.2.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 36 Imported by: 0

README

Session ingestion

This directory owns transcript readers, session mapping, accounting and local collection for Claude Code, Codex, Cursor and Entire. The appliance imports these packages too; its small adapters select the hosted interpretation and keep persistence and repository-service transport outside this module.

Readers interpret recorded formats; mappers produce a graph and an independent accounting report. Keep record accounting balanced and preserve graph ids, ordering, relationships, file evidence, usage and errors. A balanced report alone does not establish that a graph is valid.

Codex adds record and item types between releases. The Codex reader keeps a line whose record class, response_item type or event_msg type it does not know, and the mapper discards it as unknown/... in the report, so one new type does not fail the whole session. A malformed line of a known type still fails it. An Entire checkpoint whose embedded Codex transcript has an unknown record falls back to its compact transcript instead.

Mapping cache

sessions.Map keeps the graphs it mapped in a process-wide cache. Every caller shares it: Load, the live transcript view and the decision log. A daemon that reads the same transcripts on each refresh therefore decodes each one only once until it changes.

  • Key: the source and, for each file, its name, kind, path, size and modification time. Generated content, such as a Cursor tree, is keyed by its SHA-256 instead.
  • Invalidation: a file that grows or is rewritten gets a new key. Keeping the new mapping drops the one of the same session's files as they were. A file that cannot be statted is mapped without the cache.
  • Failures: a mapping that failed because of the file's content is cached as well, so an unchanged broken transcript is not read again. A file that could not be opened or read is tried again on the next call.
  • Discovery warnings: these come from discovery, not the mapper. They are not cached, and each call adds its own.
  • Size: least recently used entries are evicted once the estimated memory of the graphs held passes DefaultMapCacheBytes (64 MiB). SetMapCacheLimit changes the limit; zero or less turns the cache off. The estimate (graphBytes) adds up the graphs' rows, ids, text and JSON; on a 586 MB Claude Code session tree it gave 88 MB where the heap profile showed 93 MB. A graph takes about a sixth of its transcript's size, so the limit used to count transcript bytes overstated the memory held about six times. The sessions.map_cache.bytes gauge is the estimate and sessions.map_cache.transcript_bytes the transcripts behind it.
  • Memory bound: what sessions keeps after decoding is at most 64 MiB of estimated graph memory (256 MiB while HoldMappings holds it) plus 64 MiB of estimated kept transcript lines (DefaultTailCacheBytes, see "Incremental decoding"): 128 MiB, or 320 MiB during a background pass. The Entire checkpoint cache adds at most another 64 MiB of estimated graph memory (see "Entire checkpoint reuse"). Decoding in progress is bounded separately (see "Decode bound").
  • Sharing: cached graphs are shared between callers, so callers must not change a graph Map or Load returns.
  • Holds: HoldMappings raises the limit to HeldMapCacheBytes (256 MiB) until it is released. The daemon's background pass holds it while it refreshes several pull requests of a clone, so each session is decoded once in the pass.

Incremental decoding

Claude Code transcripts and Codex rollouts are append-only JSONL, and an agent appends to the transcript of a running session all the time. Each append gives the session a new mapping-cache key, so below that cache Map keeps, per transcript file, its decoded lines and the byte offset they end at (claudetranscript.Reading, codextranscript.Reading). When the file grows, only the bytes after that offset are decoded, and the mapper then runs again over all the lines, so the ErrUnbalanced accounting check is unchanged. Cursor sessions arrive as generated content and are always decoded whole.

  • Per file: a Claude Code subagent transcript and a Codex child or fork source rollout each keep their own offset. Claude Code's duplicate uuid and tool use id checks, and the Codex envelope ordinal check, which depends on whether the first line was a paginated session_meta, keep their state across reads, so they reject what a whole read would.
  • Torn lines: a final line without a newline is not counted as read; the next read starts at its first byte. Until then it is decoded on each read as a whole read decodes a last line (a partial write sets TornFinalLine).
  • Whole reads: a file is read from its start when it is another file than last time (a different inode: replaced), shorter than the offset (shrunk), or rewritten: it kept its size but its modification time moved, or the CRC-32C of its bytes before the offset differs from that of the bytes the kept lines were decoded from. That checksum is updated from the bytes each read consumed, never from a second read, and checked again whenever the size or modification time changed; checking reads the prefix but decodes nothing (25–35 ms for a 164 MB transcript in the page cache). A file whose size and modification time did not change is taken as unchanged. A read stops at the size the file had when it was opened. A file that could not be decoded loses its kept lines.
  • What is kept: files of any age may keep their decoded lines. Age alone does not force unchanged transcripts to decode again. The same byte budget and idle eviction bound retention: DefaultTailCacheBytes (64 MiB) of estimated line memory (Reading.Bytes). Files unread for 30 minutes are released on the next read of any file. A new file that does not fit does not evict recently read files, so trees larger than the budget keep what fits instead of thrashing. A kept file that grows evicts the least recently read. SetTailCacheLimit changes the limit; zero or less turns it off.
  • Slim lines: the kept lines leave out the copies of each record the mapper never reads: Line.Raw for Claude Code (only the shape survey reads it, and Map does not survey); for Codex Line.Raw, Line.Payload except on event_msg lines (whose tool completions become tool output), and the Raw of response items, events and turn contexts. The graphs are the same as from a whole read.

Measured on this repository's largest Claude Code session (a 164 MB main transcript and 154 subagent transcripts, 586 MB in all) after appending 1 MB: the kept lines covered 349 MB of transcript in 75 MB of heap (estimate 67 MB), and the map took 2.0 s instead of 4.3 s, decoding 22,676 lines instead of 75,577; the files that did not fit were decoded whole. A 10.7 MB Codex rollout mapped in 60 ms instead of 219 ms; its kept lines took 19 MB (estimate 18 MB), since Codex lines keep typed payloads about as large as the records.

The graphs themselves are not slimmed. Their callers read more than session evidence does: commit linkage reads the output of commit commands' tool results (linkage/sessioncorrelate), the transcript views render tool output and assistant content, decision capture reads the transcript text, and analytics reads every usage row.

workstats counts sessions.map.decoded_bytes and sessions.map.decoded_lines (what was actually decoded, appended bytes for a continued read), sessions.tail.reads.full and .appended, and sessions.tail.restarts.shrunk, .replaced and .rewritten. The sessions.tail_cache.bytes (estimated memory), .transcript_bytes and .entries gauges give what is kept.

Decode bound

A decode holds a whole transcript and its decoded lines, and transcripts reach over 150 MB, so decoding is bounded two ways.

  • Parallelism: Load maps, and reads Entire checkpoints, up to min(GOMAXPROCS, 8) sessions at once. A context marked with WithBackground (the daemon's background pass sets it) allows BackgroundParallel (2) instead; interactive loads keep the larger bound.
  • Bytes: a process-wide weighted semaphore of DefaultDecodeBudgetBytes (256 MiB) is acquired with a session's transcript size before it is decoded, less the bytes its kept lines cover (see "Incremental decoding"), and with a fixed estimate for each checkpoint read. A session larger than the budget is clamped to it, so it runs alone rather than waiting forever. Waiting ends when the context is cancelled. Cache hits, of mapped sessions and of checkpoint reads, take no budget.

Entire checkpoint reuse

Entire checkpoints are named by git objects, which never change, so a process reads each one once:

  • Listings. entire.Listing remembers, per clone, what List, Touched, Sessions and Located learned: the branch's checkpoints by the branch commit, the branch's dates by the branch commit and the clone's shallow boundary, each ref's tree and date by the ref's commit, and each checkpoint's metadata by its tree. When neither the branch nor any ref moved, they run no git. When the branch only moved forward, Touched reads only <old>..<new> (after git merge-base --is-ancestor) and merges it into the dates it had; a rewritten branch is read whole. A ref that is added or moved is asked about alone, and what a removed ref named is dropped. Only answers git gave in full are kept: an object a partial clone lacks is asked for again next time, and never fetched. sessions keeps one listing per clone root, for up to 32 clones; a listing costs about 100 bytes per checkpoint.
  • Whole reads. A checkpoint read whole (git archive, then parsing and mapping) is kept in a process-wide cache keyed by the clone and the checkpoint's tree, as the sessions it maps to, or the error parsing or mapping it gave. The checkpoint's files themselves, the transcripts, are not kept. An entry costs the estimated memory of the graphs it keeps (the same graphBytes estimate as the mapping cache, plus 1 KiB, which is also the cost of an error); least recently used entries go first once DefaultCheckpointCacheBytes (64 MiB) is held, and an outcome larger than that is not kept. The sessions.checkpoint_cache.bytes gauge is that estimate. SetCheckpointCacheLimit changes the limit; zero or less turns the cache off. A checkpoint whose export failed, such as one with objects a partial clone never downloaded, is not kept, so it is reported again on the next read. Cached graphs are shared between callers, as Map's are.
  • One private repository. Discovery.Load and Discovery.Checkpoints read the stores Discover resolved, in the private repository of the clone Discovery.ShareRepo gives them, or of one they open themselves.

Load is Discover followed by Discovery.Load. Discover reads directories, file metadata and the Entire refs, and never a transcript. Discovery.Fingerprint describes everything Load would read, so a caller can tell whether anything changed before paying for the decode. Codex discovery indexes the whole Codex store (every rollout's first record), because a session's children and fork sources can be anywhere in it. The collector keeps what it read in a codex.Cache keyed by rollout path, size and modification time, so an unchanged rollout is not opened again and a deleted one is dropped by the next scan; FindOptions.CodexCache selects the cache, and by default the process-wide codex.Shared is used. Discovery returns the same sessions with or without it. Within a Cache.BeginPass/EndPass pair the store is scanned once however many clones look it up, and so does not see a rollout added during the pass. The parent and child lookups are built once per scan, not once per session. Cursor is the exception to "never a transcript": it keeps every conversation in one database, so discovery reads the store's conversation index and builds the tree of each repository conversation for its payload. Options.Since bounds that: a conversation last updated before it is skipped on the index's update time, before its tree is read. Options.SessionIDs keeps only the sessions with those native session IDs; the others are never mapped, so a caller that needs a few sessions does not decode every transcript of the repository. An Entire session is dropped when the agent's own store holds its ID, as without the option. Options.StartedBefore drops sessions the agent's own store says began after it. Claude Code's start comes from its first records and Codex's from its session_meta; a session with no known start is kept.

Reusing sessions a caller already read

Each session Load returns carries a Key naming what its graph was mapped from. For a session from the agent's own store, the key is a digest of the mapping cache's key. A file modified in the last 2 seconds, or in the future, gives its session no key at all: a rewrite at the same size within one modification-time tick would look unchanged. For an Entire session, the key is the clone, the checkpoint's tree and the session's id. A tree names its content, so the key never goes stale. The clone is part of the key, as in the checkpoint cache's key, so that one clone's reads never answer for another's. Discovery.LoadReusing takes a callback that says which keys the caller already holds what it needs from. Those sessions are not mapped. They come back Unmapped, with no graph, and Transcript says whether their graph has a transcript, so Fuller still compares them. Everything else is what Load returns. locallink uses this to map only the sessions that changed.

Choosing an Entire session's snapshot needs only each checkpoint's session ids, dates, warnings and whether each mapped and has a transcript. The process remembers these by clone and checkpoint tree (8,192 checkpoints). They are small, so they outlive the whole-read cache's evictions. After the first read, a checkpoint is read whole again only when a session chosen from it has to be mapped, and that read goes through the whole-read cache. If the read now fails, the choice is made again from what the read found, as a load that remembered nothing would make it.

Product profiles

traceprocessing.Local is the zero value and the default of existing public entry points. Hosted is passed explicitly to BuildWith, checkpoint parsing and archive reading. It never changes another build's behavior. Claude's Build still requests its transcript shape survey; BuildWith keeps the independent Survey option, including the local mapping path's Survey: false.

Area Local interpretation Hosted interpretation
Claude agent messages Existing local input classification and tool results Agent messages are system inputs; waiting calls receive child reports and detail metadata
Claude attributes Avoid duplicate timestamps per key Advance every change past the preceding timestamp per key
Codex Normalize code-mode shell commands, preserve local result and report interpretation Normalize code-mode shell commands, attach child reports and detail metadata
Cursor Existing payload decoder and error wording Validate uploaded tree nodes and retain hosted error wording
Portable and compact tools Existing tool aliases and patch-line limits Lowercase grep/bash aliases and patch scanning past long lines
Entire reader Existing checkpoint parsing Bound session entries, reject repeated sources, discover tasks and read Pi toolCall blocks
Entire mapper Recorded source hash and existing metadata token handling Hash mapped source bytes, graft Claude tasks, reject negative aggregate usage and fill Cursor models
Reports Existing local fields Include hosted task and rejected-usage accounting, even when zero
Collection Local Git environment, Windows path folding and modification-time filtering Repository-service snapshots and case-sensitive Claude project-directory matching
Archives Existing local errors and byte filesystem Preserve hosted sentinel errors and directory discovery for task transcripts

Both profiles preserve Codex code-mode programs and extract static shell commands from them, including compact Entire transcripts. This supplies independent commit-creation evidence locally. Programs without static shell commands remain unchanged. The local analytics index rebuilds after this evidence change.

These differences preserve current product contracts. They are not upgrade paths, and neither profile changes the local application's database.

For the local image reader, an ordinary Claude image-only user envelope is a prompt with human origin even though it has no text. Meta, system-injected, peer and unknown-source records remain system inputs; child-session asks keep their agent origin. The hosted interpretation is unchanged.

Verification

Run commands in the configured development containers from the monorepo root:

just oss-go test ./sessions/...
just platform::test ./internal/traceprocessing/... ./internal/traceingest/... ./internal/entireingest/...
just platform::update-goldens

The standalone OSS module runs the same go test ./sessions/... command inside its development or CI environment. Its tests need no appliance source checkout or database. Hosted pure cases use TestHosted names and retain their own expected output under testdata/hosted; local cases retain their original fixtures. Captured appliance Entire transcripts and goldens remain in the appliance test suite; public policy tests use synthetic inputs. Optional corpus reconciliation tests remain opt-in. Platform corpus storage tests stay at the persistence boundary.

Golden updates are for intentional behavior changes. A consolidation must produce no expected-output changes: compare all existing local and hosted fixture bytes before and after the update recipe, and investigate differences instead of accepting refreshed files as evidence.

Documentation

Overview

Package sessions finds the coding-agent sessions recorded for a repository on this machine and maps each into the normalised session.Graph.

Claude Code, Codex and Cursor sessions are read from their stores in the home directory; Entire sessions from the checkpoint branch in the clone. Each vendor's parser lives in its own package; this one only decides which stores to read and which trees are trustworthy enough to return.

Index

Constants

View Source
const BackgroundParallel = 2

BackgroundParallel is how many sessions a background pass decodes at once. A pass is not latency-sensitive, so it trades speed for memory.

View Source
const DefaultCheckpointCacheBytes = 64 << 20

DefaultCheckpointCacheBytes bounds the estimated memory (graphBytes) of the mapped sessions the checkpoint cache keeps, the same measure and size as DefaultMapCacheBytes. The estimate is closer to a lower bound than to the heap, so the cache's resident cost is somewhat above this.

View Source
const DefaultDecodeBudgetBytes = 256 << 20

DefaultDecodeBudgetBytes bounds the transcript bytes decoded at once across the process. A decode holds the whole transcript and its decoded lines, so this is a few times its resident cost. Sessions wait for budget; one larger than the whole budget runs alone. It sits beside DefaultMapCacheBytes, which bounds what is kept after decoding.

View Source
const DefaultMapCacheBytes = 64 << 20

DefaultMapCacheBytes bounds the estimated memory of the mapped graphs Map keeps (graphBytes). A graph takes about a sixth of its transcript's size, so this holds the graphs of several hundred MB of transcripts.

View Source
const DefaultTailCacheBytes = 64 << 20

DefaultTailCacheBytes bounds the estimated memory of the decoded lines Map keeps so it can read only what a transcript appended. Kept Claude Code lines take about a third of their transcript's size, so this holds the lines of a 150 MB transcript, the largest seen growing.

View Source
const Entire vendors.Slug = "entire"

Entire is the source slug of sessions read from Entire checkpoints. It is a recorder rather than an agent, so vendors does not list it; Session.Vendor names the agent that ran.

View Source
const GenerationRunMarker = "<!-- baum:generation-run -->"

GenerationRunMarker starts the prompt of every agent run baum itself starts to generate a review. Such a run is recorded in the same stores as the developer's own sessions, in a worktree of the same clone, so the marker is what keeps it from being taken as evidence about the pull request it reviews.

View Source
const HeldMapCacheBytes = 256 << 20

HeldMapCacheBytes is the cache's limit while HoldMappings holds it.

Variables

View Source
var ErrUnbalanced = errors.New("mapper did not account for every record")

ErrUnbalanced reports a tree whose mapper could not account for every record it read. Such a tree understates what happened and is not returned.

Sources lists every source Load reads, in the order it reads them.

Functions

func Fuller

func Fuller(a, b Session) bool

Fuller reports whether a is a better reading of a session than b: one with a transcript over one without, and otherwise the one written later.

func HasTranscript

func HasTranscript(graph *session.Graph) bool

HasTranscript reports whether a graph records anything the agent did: a model call, an assistant message or a tool use. A snapshot Entire wrote with only its metadata and the prompt has none.

func HoldMappings added in v0.2.0

func HoldMappings() (release func())

HoldMappings lets the cache keep up to HeldMapCacheBytes until release is called, then trims it back to its limit. A caller about to load the same sessions several times in a row, such as a background pass refreshing several pull requests of one clone, holds it so each session is decoded once in the pass, at the cost of that memory for the pass's duration.

func IsGenerationRun

func IsGenerationRun(graph *session.Graph) bool

IsGenerationRun reports whether graph is one of baum's own generation runs: a user input of its top-level session begins with GenerationRunMarker. A prompt that only mentions the marker further in does not count.

func Load

func Load(ctx context.Context, dir string, opts Options) ([]Session, Report, error)

Load returns every session recorded for the git repository containing dir, mapped and ordered by modification time.

A session belongs to the repository when it was recorded in any of the clone's working trees, the main checkout or a linked worktree, whichever of them dir is in; git's own list of worktrees says which those are. Each Entire session is returned once, from the newest checkpoint that recorded it, and not at all when the agent's own store holds it.

func Map

func Map(s collector.Session) (*session.Graph, []string, error)

Map turns one discovered session into its graph. The notes are the mapper's remarks; an error means the tree must not be used.

A session whose files have not changed since it was last mapped is not read again: the graph comes from a process-wide cache (see mapCache) and is shared with every other caller that mapped the same files, so callers must not change it.

func ParseSource

func ParseSource(name string) (vendors.Slug, error)

ParseSource accepts a source slug as typed on the command line.

func Root

func Root(graph *session.Graph) *session.Session

Root returns the top-level session of a graph, or nil.

func SetCheckpointCacheLimit added in v0.2.0

func SetCheckpointCacheLimit(limit int64)

SetCheckpointCacheLimit changes how many estimated bytes of mapped sessions the checkpoint cache keeps; zero or less turns it off and empties it.

func SetMapCacheLimit added in v0.2.0

func SetMapCacheLimit(limit int64)

SetMapCacheLimit changes the estimated memory of the mapped graphs Map keeps; zero or less turns the cache off and empties it.

func SetTailCacheLimit added in v0.2.0

func SetTailCacheLimit(limit int64)

SetTailCacheLimit changes the estimated memory of the decoded lines Map keeps; zero or less turns that off and empties it, so every transcript is decoded whole each time it is mapped.

func WithBackground added in v0.2.0

func WithBackground(ctx context.Context) context.Context

WithBackground marks ctx as a background pass: loads under it decode at most BackgroundParallel sessions at once. A context value is used because the pass reaches Discovery.Load through several packages that already pass the context down, so no signature changes.

Types

type Checkpoints

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

Checkpoints is the checkpoints of a clone, opened once for several lookups. It reads the per-checkpoint refs (refs/entire/checkpoints/*) and the local checkpoint branch or a remote-tracking copy of it, a checkpoint in both being read from its ref, in a private repository, and never fetches. Close releases it.

func OpenCheckpoints

func OpenCheckpoints(ctx context.Context, dir string) (*Checkpoints, error)

OpenCheckpoints opens the checkpoints of the clone containing dir. It returns nil and no error when the clone has neither checkpoint refs nor a checkpoint branch.

func (*Checkpoints) Close

func (c *Checkpoints) Close()

Close releases the private repository, unless it was shared (Discovery.ShareRepo).

func (*Checkpoints) Load

func (c *Checkpoints) Load(ctx context.Context, id string) ([]Session, []Failure, error)

Load maps the sessions one checkpoint in the clone records, as Load maps an Entire session, with no Since applied. A session that cannot be mapped is a Failure; an error is a checkpoint that could not be read at all.

func (*Checkpoints) Located

func (c *Checkpoints) Located(ctx context.Context, ids []string) (map[string]bool, error)

Located reports which of ids the clone holds, by canonical id, whether or not its metadata can be read: a checkpoint Sessions leaves out that Located reports is unreadable, and one it does not report is not in the clone.

func (*Checkpoints) Sessions

func (c *Checkpoints) Sessions(ctx context.Context, ids []string) (map[string][]string, error)

Sessions returns, for each of ids that is a checkpoint in the clone, keyed by its canonical id (entirecheckpoint.CanonicalID), the ids of the sessions it records, each once, in the order it lists them. It reads checkpoint metadata only. A checkpoint the clone does not hold, or whose metadata cannot be read, is absent from the result.

type Discovery added in v0.2.0

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

Discovery is what Load finds before it reads any session: the clone's worktrees, the session files recorded in them and the checkpoint store's branch commit and refs. Finding them reads directories, file metadata and git refs, never a transcript, so a caller can tell from Fingerprint whether anything Load reads changed before paying for it.

func Discover added in v0.2.0

func Discover(ctx context.Context, dir string, opts Options) (*Discovery, error)

Discover finds what Load would read for the repository containing dir.

func (*Discovery) Checkpoints added in v0.2.0

func (d *Discovery) Checkpoints(ctx context.Context) (*Checkpoints, error)

Checkpoints opens the checkpoints of the clone as Discover found them, for several lookups. It returns nil and no error when the clone has neither checkpoint refs nor a checkpoint branch. The caller closes it.

func (*Discovery) Fingerprint added in v0.2.0

func (d *Discovery) Fingerprint() (string, bool)

Fingerprint describes everything Load would read: the worktrees, each session file's path, size and modification time (or the hash of generated content), and the Entire store's branch commit and refs. Two discoveries with the same fingerprint load the same sessions. ok is false when a file cannot be described, and nothing should be assumed unchanged.

func (*Discovery) Load added in v0.2.0

func (d *Discovery) Load(ctx context.Context) ([]Session, Report, error)

Load maps the discovered sessions and reads the Entire checkpoints, as Load does.

func (*Discovery) LoadReusing added in v0.2.0

func (d *Discovery) LoadReusing(ctx context.Context, reuse Reuse) ([]Session, Report, error)

LoadReusing is Load, except that a session whose Key reuse accepts is not mapped: it is returned Unmapped, without its graph or mapper notes (its discovery warnings are kept), and an Entire checkpoint is not read when what Load needs from it is already known. Which sessions are returned, their order and every other field are what Load returns. A nil reuse maps everything.

func (*Discovery) ShareRepo added in v0.2.0

func (d *Discovery) ShareRepo(repo *gitlocal.Repo)

ShareRepo has Load and Checkpoints read Entire checkpoints in repo's private repository instead of opening one of their own. repo must be a clone of the same repository, and stay open until they are done.

func (*Discovery) Worktrees added in v0.2.0

func (d *Discovery) Worktrees() []string

Worktrees are the clone's working trees git listed, empty when it could not list them.

type Failure

type Failure struct {
	Source vendors.Slug
	Path   string
	Err    error
}

Failure is one session discovery found but could not map. It never costs its siblings: Load returns the sessions it could map alongside these.

type Options

type Options struct {
	// PreviousPaths are directories the repository used to live at, so
	// sessions recorded there still count.
	PreviousPaths []string
	// Sources restricts the stores read; empty means Sources.
	Sources []vendors.Slug
	// Since drops sessions last modified before it.
	Since time.Time
	// StartedBefore drops sessions their agent's own store says began after
	// it. A session whose start discovery does not know (Cursor) is kept,
	// and Entire checkpoints are not filtered by it.
	StartedBefore time.Time
	// SessionIDs, when not empty, keeps only the sessions whose own ID (the
	// agent's native session ID, Session.ID) is listed. The others are never
	// mapped, and Entire sessions with other IDs are dropped.
	SessionIDs []string
	// Store overrides, mainly for tests. Empty means the vendor default.
	ClaudeProjectsDir string
	CodexSessionsDir  string
	CursorStorePaths  []string
}

Options narrows what Load reads. Zero values mean everything.

type Report

type Report struct {
	// Skipped are files discovery could not read.
	Skipped []model.SkippedFile
	// Failures are sessions that were found but did not map.
	Failures []Failure
	// EntireCommit is the checkpoint branch commit read, empty when the clone
	// has none (checkpoints held only in refs/entire/checkpoints/* leave it
	// empty).
	EntireCommit string
}

Report is what Load dropped along the way.

type Reuse added in v0.2.0

type Reuse func(key string) (transcript, ok bool)

Reuse tells LoadReusing which sessions it need not map. Given a session's Key, ok says the caller already holds everything it needs from the graph that Key names, and transcript whether that graph has a transcript (HasTranscript). It is called from one goroutine at a time.

type Session

type Session struct {
	// Source is the store the session was read from; Vendor the agent that
	// ran. They differ for Entire, which records other agents' sessions.
	Source vendors.Slug
	Vendor string
	ID     string
	// Path is the transcript file, the Cursor store plus composer id, or the
	// Entire checkpoint id.
	Path         string
	RepoRoot     string
	WorktreeRoot string
	ModifiedAt   time.Time
	Graph        *session.Graph
	// Notes are the mapper's remarks about the tree: a subagent nothing
	// spawned, a rollout that could not be read.
	Notes []string
	// CreatedCommits is independent, durable Git-hook evidence supplied by
	// the local resolver. It never changes the mapped transcript graph.
	CreatedCommits []string
	// Key identifies what the graph is mapped from: the session's files as
	// they stood (see mapKey), or the content of the Entire checkpoint it was
	// read from and the session's id there. Two sessions with the same Key
	// map to the same graph. It is empty when that cannot be described.
	Key string
	// Unmapped is set on a session LoadReusing did not map because its
	// caller already holds what it needs from the graph Key names. Graph is
	// then nil, and Transcript says whether that graph has a transcript.
	Unmapped   bool
	Transcript bool
}

Session is one mapped session tree.

func (Session) HasTranscript added in v0.2.0

func (s Session) HasTranscript() bool

HasTranscript reports whether the session's graph records anything the agent did, as HasTranscript does; for an unmapped session, whether the graph its Key names does.

func (Session) Root

func (s Session) Root() *session.Session

Root is the session's top-level session row, or nil for an empty graph.

Directories

Path Synopsis
Package claudetranscript reads Claude Code transcripts as typed, classified lines.
Package claudetranscript reads Claude Code transcripts as typed, classified lines.
entire
Package entire finds Entire checkpoints in the user's own clone.
Package entire finds Entire checkpoints in the user's own clone.
entirearchive
Package entirearchive reads bounded checkpoint archives independently of Git transport.
Package entirearchive reads bounded checkpoint archives independently of Git transport.
Package cursorsession maps Cursor's typed SQLite records into the shared session model.
Package cursorsession maps Cursor's typed SQLite records into the shared session model.
Package cursortranscript reads Cursor's global SQLite conversation store as typed records.
Package cursortranscript reads Cursor's global SQLite conversation store as typed records.
Package entirecheckpoint reads one Entire checkpoint tree without assigning session-model meaning to its records.
Package entirecheckpoint reads one Entire checkpoint tree without assigning session-model meaning to its records.
Package entiresession maps Entire checkpoint snapshots into shared session graphs, delegating native transcripts where a mapper exists.
Package entiresession maps Entire checkpoint snapshots into shared session graphs, delegating native transcripts where a mapper exists.
Package prompttext decides what part of a recorded user turn is a prompt somebody actually typed.
Package prompttext decides what part of a recorded user turn is a prompt somebody actually typed.
Package session defines the vendor-agnostic session model.
Package session defines the vendor-agnostic session model.
Package sessionimages reads retained images from native coding transcripts.
Package sessionimages reads retained images from native coding transcripts.
Package sourcepath handles filesystem paths recorded on a machine whose OS may differ from the process reading them.
Package sourcepath handles filesystem paths recorded on a machine whose OS may differ from the process reading them.
Package sqliteread reads local SQLite stores that agents keep their session data in — today, Cursor's `state.vscdb` chat store.
Package sqliteread reads local SQLite stores that agents keep their session data in — today, Cursor's `state.vscdb` chat store.
Package vendors holds the canonical agent slugs the platform stores and groups by.
Package vendors holds the canonical agent slugs the platform stores and groups by.

Jump to

Keyboard shortcuts

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