Documentation
¶
Overview ¶
Package snapshot owns ~/.lightcode/sessions/<id>/ — meta.json, snapshots/<turn>/, and turns/<turn>/ (message persistence). It backs both the conversation-anchored revert and the sessions foundation: session lifecycle (active / archived / deleted), message persistence, and session resume.
On-disk layout:
~/.lightcode/sessions/<session-id>/
├── meta.json
├── tokens.json # monotonic, untouched by revert
├── snapshots/
│ └── <turn>/
│ └── <path-hash>/
│ ├── original # pre-edit bytes, absent if file didn't exist
│ └── meta.json # {original_path, tool_name, existed}
└── turns/
└── <turn>/
├── messages.jsonl # one serialized message per line
└── complete # empty marker written on turn_end
Turn numbers are integers starting at 1. A turn without a `complete` marker is considered interrupted by a crash and is discarded on session load.
Index ¶
- Constants
- Variables
- func ArchiveSession(sessionsRoot, id string) error
- func DeleteSession(sessionsRoot, id string) error
- func LoadMostRecent(root, projectPath string) (string, error)
- func Sweep(root string, cfg LifecycleConfig, onDelete func(sessionID string)) (int, int, error)
- func SweepAllProjects(projectsRoot string, cfg LifecycleConfig, onDelete func(sessionID string)) (int, int, error)
- type CompactionRecord
- type LifecycleConfig
- type SessionInfo
- type SessionMeta
- type SnapshotMeta
- type Store
- func (s *Store) Active() bool
- func (s *Store) AppendMessage(turn int, msg []byte) error
- func (s *Store) AttachSessionsRoot(sessionsRoot, projectsRoot, projectID string) error
- func (s *Store) BeginChildSession(projectRoot, parentSessionID string) error
- func (s *Store) BeginNewSession(projectRoot string) error
- func (s *Store) BeginTurn() int
- func (s *Store) Close() (bool, error)
- func (s *Store) CurrentTurn() int
- func (s *Store) Dir() string
- func (s *Store) DiscardSnapshotEntry(turn int, entryID string) error
- func (s *Store) ForkInto(toTurn int) (string, string, error)
- func (s *Store) ListTurns() ([]TurnEntry, error)
- func (s *Store) LoadCompaction() (*CompactionRecord, error)
- func (s *Store) LoadCompactionForSession(id string) (*CompactionRecord, error)
- func (s *Store) LoadCompleteTurns() ([]TurnMessages, error)
- func (s *Store) LoadCompleteTurnsAfter(after int) ([]TurnMessages, error)
- func (s *Store) LoadCompleteTurnsAfterForSessionReadOnly(id string, after int) ([]TurnMessages, error)
- func (s *Store) LoadCompleteTurnsAfterReadOnly(after int) ([]TurnMessages, error)
- func (s *Store) LoadCompleteTurnsForSessionReadOnly(id string) ([]TurnMessages, error)
- func (s *Store) LoadCompleteTurnsReadOnly() ([]TurnMessages, error)
- func (s *Store) LoadSession(id string) error
- func (s *Store) MarkTurnComplete(turn int) error
- func (s *Store) Meta() (SessionMeta, error)
- func (s *Store) ProjectPath() string
- func (s *Store) RetainSnapshotEntry(turn int, entryID string)
- func (s *Store) RevertCode(toTurn int) ([]string, error)
- func (s *Store) RevertHistory(toTurn int) error
- func (s *Store) Root() string
- func (s *Store) SaveCompaction(rec CompactionRecord) error
- func (s *Store) SessionID() string
- func (s *Store) SetModel(provider, model string) error
- func (s *Store) SetState(state string) error
- func (s *Store) Snapshot(turn int, absPath string) error
- func (s *Store) SnapshotResolved(turn int, originalPath, canonicalPath string) error
- func (s *Store) SnapshotResolvedEntry(turn int, originalPath, canonicalPath string) (string, bool, error)
- func (s *Store) TouchActivity() error
- type TurnEntry
- type TurnMessages
Constants ¶
const ( StateActive = "active" StateArchived = "archived" )
SessionState values stored in meta.json.
Variables ¶
var ErrNoSession = errors.New("snapshot: no session open")
ErrNoSession is returned by any Store method that needs an active session when none is open.
Functions ¶
func ArchiveSession ¶
ArchiveSession flips a session's state to archived on disk, same effect as the sweep's active→archived branch. No-op if already archived.
func DeleteSession ¶
DeleteSession removes a session's dir entirely, same effect as the sweep's archived→deleted branch.
func LoadMostRecent ¶
LoadMostRecent returns the most recently active session for projectPath, restricted to state == active. Returns ("", nil) if none.
func Sweep ¶
Sweep walks every session dir and applies state transitions per cfg. Returns (archived, deleted) counts.
func SweepAllProjects ¶
func SweepAllProjects(projectsRoot string, cfg LifecycleConfig, onDelete func(sessionID string)) (int, int, error)
SweepAllProjects runs Sweep over every project's sessions/ dir under projectsRoot. Returns combined counts across all projects.
Types ¶
type CompactionRecord ¶
type CompactionRecord struct {
Summary string `json:"summary"`
BoundaryTurn int `json:"boundary_turn"`
CompactedAt string `json:"compacted_at"`
SummarizerModel string `json:"summarizer_model"`
SummarizerProvider string `json:"summarizer_provider,omitempty"`
}
CompactionRecord is persisted to compaction.json when context lifecycle management summarizes the conversation.
type LifecycleConfig ¶
LifecycleConfig controls Sweep's archive/delete thresholds. Days are counted in 24-hour units.
type SessionInfo ¶
type SessionInfo struct {
ID string `json:"id"`
CreatedAt string `json:"createdAt"`
LastActivity int64 `json:"lastActivity"`
State string `json:"state"`
ArchivedAt int64 `json:"archivedAt"`
ProjectPath string `json:"projectPath"`
ParentSessionID string `json:"parentSessionId,omitempty"`
}
SessionInfo is the summary returned by List for the session switcher.
func List ¶
func List(root, projectPath, state string) ([]SessionInfo, error)
List returns sessions under root, filtered to projectPath (empty = no project filter) and state (empty = any state). Sorted by LastActivity descending.
type SessionMeta ¶
type SessionMeta struct {
ID string `json:"id"`
CreatedAt string `json:"created_at"` // RFC3339
ProjectPath string `json:"project_path"`
ProjectHash string `json:"project_hash"`
LightcodeVersion string `json:"lightcode_version"`
State string `json:"state"` // "active" | "archived"
ArchivedAt int64 `json:"archived_at"` // unix seconds, 0 if active
LastActivity int64 `json:"last_activity"` // unix seconds of last user message
Provider string `json:"provider,omitempty"`
Model string `json:"model,omitempty"`
ParentSessionID string `json:"parent_session_id,omitempty"`
}
SessionMeta is persisted to the session directory's meta.json. The project_hash lets the session list filter sessions by project without re-resolving paths. state / archived_at / last_activity drive the lifecycle sweep.
type SnapshotMeta ¶
type SnapshotMeta struct {
OriginalPath string `json:"original_path"`
CanonicalPath string `json:"canonical_path,omitempty"`
Existed bool `json:"existed"`
}
SnapshotMeta is written alongside each snapshotted file. OriginalPath is the user-facing path shown in history and affected-file output. CanonicalPath is the hidden restore target for new snapshots. Old metadata without CanonicalPath falls back to OriginalPath. Existed is false when the snapshot represents a file that did not exist before the turn — on revert, that file is deleted.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store owns one session directory at a time. Its session may be swapped (Close + BeginNewSession / LoadSession) while tool and loop references to the Store remain valid — they call methods on the same pointer, which now transparently refer to whichever session is active.
A Store with no active session rejects Snapshot / AppendMessage / MarkTurnComplete with ErrNoSession. BeginTurn and CurrentTurn return 0 in that state. This supports lazy session creation: a fresh launch opens a Store, and the first user prompt calls BeginNewSession.
func NewForSessionsRoot ¶
NewForSessionsRoot returns a Store rooted at an explicit sessions directory (typically ~/.lightcode/projects/<pid>/sessions). The projectsRoot + projectID are recorded so TouchActivity can bump the project's last_activity.
func (*Store) AppendMessage ¶
AppendMessage appends one serialized message (one JSON object + \n) to turns/<turn>/messages.jsonl. Creates the turn dir if needed.
func (*Store) AttachSessionsRoot ¶
AttachSessionsRoot swaps the store's sessions root and project bookkeeping. Used for the lazy project-creation path: a Store built with NewEmpty gets its real root once the first session is created. Must not be called while a session is active.
func (*Store) BeginChildSession ¶
BeginChildSession creates a fresh session linked to a parent session.
func (*Store) BeginNewSession ¶
BeginNewSession creates a fresh session directory, writes meta.json, and makes this Store refer to it. The Store must not already have an active session.
func (*Store) BeginTurn ¶
BeginTurn scans turn dirs (both snapshots/ and turns/), picks the next integer, creates empty turn dirs on both sides, and stores it as currentTurn. Returns 0 if no session is active.
func (*Store) Close ¶
Close detaches the Store from its current session. If the session has no complete turns, the entire session dir is deleted (orphan cleanup for "opened a new session, switched away without using it"). Returns (wasDiscarded, err). A Store with no session is a no-op.
func (*Store) CurrentTurn ¶
CurrentTurn returns the last BeginTurn result, 0 if unset.
func (*Store) DiscardSnapshotEntry ¶
DiscardSnapshotEntry releases a pre-mutation snapshot user. The entry is removed only if no concurrent user retained it or still depends on it.
func (*Store) ForkInto ¶
ForkInto copies turns 1..toTurn (both snapshots and messages) into a new session directory. The current session is untouched. Returns the path of the new session dir. Caller is responsible for switching to it.
func (*Store) LoadCompaction ¶
func (s *Store) LoadCompaction() (*CompactionRecord, error)
LoadCompaction reads the compaction record, or returns nil if none exists.
func (*Store) LoadCompactionForSession ¶
func (s *Store) LoadCompactionForSession(id string) (*CompactionRecord, error)
LoadCompactionForSession reads another session's compaction record without switching the active session.
func (*Store) LoadCompleteTurns ¶
func (s *Store) LoadCompleteTurns() ([]TurnMessages, error)
LoadCompleteTurns returns every complete turn's messages in turn order. Incomplete turns are deleted from disk as a side effect.
func (*Store) LoadCompleteTurnsAfter ¶
func (s *Store) LoadCompleteTurnsAfter(after int) ([]TurnMessages, error)
LoadCompleteTurnsAfter returns complete turns with turn number > after.
func (*Store) LoadCompleteTurnsAfterForSessionReadOnly ¶
func (s *Store) LoadCompleteTurnsAfterForSessionReadOnly(id string, after int) ([]TurnMessages, error)
LoadCompleteTurnsAfterForSessionReadOnly returns another session's complete turns after the boundary without switching the active session or attempting crash recovery.
func (*Store) LoadCompleteTurnsAfterReadOnly ¶
func (s *Store) LoadCompleteTurnsAfterReadOnly(after int) ([]TurnMessages, error)
LoadCompleteTurnsAfterReadOnly returns complete turns after the boundary without attempting crash recovery. It is safe for display reads while a turn is still in progress.
func (*Store) LoadCompleteTurnsForSessionReadOnly ¶
func (s *Store) LoadCompleteTurnsForSessionReadOnly(id string) ([]TurnMessages, error)
LoadCompleteTurnsForSessionReadOnly returns another session's complete turns without switching the active session or attempting crash recovery.
func (*Store) LoadCompleteTurnsReadOnly ¶
func (s *Store) LoadCompleteTurnsReadOnly() ([]TurnMessages, error)
LoadCompleteTurnsReadOnly returns complete turns without attempting crash recovery. It is safe for display reads while a turn is still in progress.
func (*Store) LoadSession ¶
LoadSession attaches this Store to an existing on-disk session. Discards any incomplete turn dirs (crash recovery).
func (*Store) MarkTurnComplete ¶
MarkTurnComplete writes the empty `complete` marker in turns/<turn>/.
func (*Store) Meta ¶
func (s *Store) Meta() (SessionMeta, error)
Meta reads the session's meta.json.
func (*Store) ProjectPath ¶
ProjectPath returns the project path recorded in session meta, or "".
func (*Store) RetainSnapshotEntry ¶
RetainSnapshotEntry keeps a snapshot entry once any user starts mutating.
func (*Store) RevertCode ¶
RevertCode restores every file snapshotted in turns > toTurn to its pre-turn state and deletes those snapshot turn dirs. Message history and turn dirs are NOT touched — conversation stays intact.
func (*Store) RevertHistory ¶
RevertHistory deletes message turn dirs strictly greater than toTurn and updates currentTurn. Files on disk are NOT touched.
func (*Store) SaveCompaction ¶
func (s *Store) SaveCompaction(rec CompactionRecord) error
SaveCompaction writes a compaction record to the session directory.
func (*Store) Snapshot ¶
Snapshot captures the pre-turn state of absPath. First-write-wins per (turn, path).
func (*Store) SnapshotResolved ¶
SnapshotResolved captures canonicalPath while preserving originalPath for UI/history display. First-write-wins per canonical path.
func (*Store) SnapshotResolvedEntry ¶
func (s *Store) SnapshotResolvedEntry(turn int, originalPath, canonicalPath string) (string, bool, error)
SnapshotResolvedEntry is SnapshotResolved plus the concrete entry id and a created flag. Mutation callers must either retain the entry once mutation starts or discard their pre-mutation claim if validation fails first.
func (*Store) TouchActivity ¶
TouchActivity updates LastActivity in meta.json to now. Called on every user message. Also bumps the owning project's meta.json when the store is project-aware.
type TurnEntry ¶
type TurnEntry struct {
Turn int `json:"turn"`
Files []SnapshotMeta `json:"files"`
}
TurnEntry describes one snapshot turn for UI display.
type TurnMessages ¶
TurnMessages is one turn's persisted messages, in append order.