session

package
v1.3.2 Latest Latest
Warning

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

Go to latest
Published: Sep 7, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package session persists conversations to disk so they survive restarts and can be resumed. Each session is a single JSON file under the sessions directory; file-change checkpoints for a session live in a sibling "<id>.ckpt" directory.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Clear

func Clear(dir string) error

Clear removes all sessions and checkpoints in dir.

func CompactionArchives added in v1.2.0

func CompactionArchives(dir, id string) ([]string, error)

CompactionArchives are the pre-compaction conversations kept for one session.

func Delete

func Delete(dir, id string) error

Delete removes a session file, its checkpoint directory, and every pre-compaction archive belonging to it.

The archives hold the conversation a compaction replaced, so leaving them behind would mean deleting a session that is still readable on disk.

func Hold added in v1.2.1

func Hold(dir, id string) (*lock.File, error)

Hold marks a session as being run by this process, until the returned handle is closed.

An advisory lock rather than a flag in a file, because the interesting case is the one nobody writes code for: a session whose process was killed. The OS drops a lock when the process goes, so a crashed session stops looking live without anything having to notice that it crashed.

Types

type Blocked added in v1.2.2

type Blocked struct {
	ID     string // the permission request's id
	Tool   string
	Detail string
}

Blocked is what a session is waiting for.

func BlockedOn added in v1.2.2

func BlockedOn(dir, id string) (Blocked, bool)

BlockedOn reports whether a session is stopped at an unanswered permission prompt.

"Blocked" is the decisive field on a card: a session waiting on a prompt is not slow, it has *stopped*, and it will stay stopped until a person answers. That is the one thing worth seeing when scanning a list of sessions.

The rule is the doc's: the last `permission.requested` with no matching `permission.resolved`. Requests are correlated by id rather than by position, because answering one prompt does not unblock a later one.

type Card added in v1.2.1

type Card struct {
	ID        string
	Title     string
	Model     string
	Effort    string
	Connector string
	CWD       string
	Updated   time.Time
	State     State
}

Card is one session as a list shows it: who and when, never what was said.

Deliberately not a *Session. Loading a megabyte of transcript to render one line is the difference between a list that can be polled and one that cannot, and a type that cannot carry a transcript cannot accidentally leak one into a view.

func Overview added in v1.2.1

func Overview(dir string) ([]Card, error)

Overview lists every session in dir, newest first, with whether each one is being run right now.

func (Card) Name added in v1.2.1

func (c Card) Name() string

Name is what to show for a session, titled or not.

A card with an empty name is a card nobody can pick out of a list, and an untitled session is the normal state until the fast lane names one.

type FunctionCall added in v1.1.7

type FunctionCall struct {
	Name      string `json:"name"`
	Arguments string `json:"arguments"`
}

FunctionCall is the serialized function invocation.

type Message added in v1.1.7

type Message struct {
	Role       string     `json:"role"`
	Content    string     `json:"content,omitempty"`
	Reasoning  string     `json:"reasoning,omitempty"`
	ToolCalls  []ToolCall `json:"tool_calls,omitempty"`
	ToolCallID string     `json:"tool_call_id,omitempty"`
}

Message is the frozen persisted session message shape on disk.

type Session

type Session struct {
	ID        string    `json:"id"`
	Model     string    `json:"model"`
	Title     string    `json:"title"`
	CreatedAt time.Time `json:"created_at"`
	// CWD is the directory the session was started in. Sessions written before
	// this field existed have none, which is why every match here is explicit
	// rather than a comparison against the empty string.
	CWD string `json:"cwd,omitempty"`
	// Effort is the level the session's dial ran at, persisted so a resume
	// lands at the same width of effort instead of the configured default.
	// Written before this field existed are sessions with none.
	Effort string `json:"effort,omitempty"`
	// Mode is the mode the session was left in — chat, code or agent —
	// persisted so a resume lands in it instead of the default. Plan 06 §3
	// promised this from the start ("written on switch and on save; resume
	// restores it") and nothing had built it: the F7.2 transcript re-issued
	// /mode agent on every wake. Sessions written before this field have none.
	Mode string `json:"mode,omitempty"`
	// Connector records the subscription connector the session ran on, when
	// it ran on one. A plan model re-derives its connector from its name, so
	// this is display state, never routing state.
	Connector string `json:"connector,omitempty"`
	// ProviderState is opaque provider-side state worth resuming: for Claude,
	// the vendor conversation handle. Kolk mints the handle itself, so a later
	// Kolkrabbi process can --resume the same vendor conversation without the
	// child having ever reported anything secret. Names a conversation, never
	// a credential.
	ProviderState string `json:"provider_state,omitempty"`
	// Pause is the limit this session is stopped on, when it is (plan 35 §2.2).
	Pause *continuity.Pause `json:"pause,omitempty"`
	// TitleAuto marks a title Kolkrabbi derived rather than one the user chose.
	TitleAuto bool      `json:"title_auto,omitempty"`
	UpdatedAt time.Time `json:"updated_at"`
	Messages  []Message `json:"messages"`
	// contains filtered or unexported fields
}

func Latest

func Latest(dir string) (*Session, error)

Latest returns the most recently updated session, or nil if none exist.

func LatestForDir added in v1.2.0

func LatestForDir(dir, cwd string) (*Session, error)

LatestForDir resumes this project's most recent session, falling back to the most recent overall.

Standing in a directory and asking to resume means the work done here, not whatever happened to be typed last in another window. A session with no recorded directory belongs to no project and is only ever reachable through the fallback: matching it against every directory would make one old session hijack resume everywhere.

func List

func List(dir string) ([]*Session, error)

List returns all sessions in dir, newest first.

func Load

func Load(dir, id string) (*Session, error)

func New

func New(dir, model string) *Session

New creates a fresh, not-yet-saved session in dir.

func (*Session) AppendMessage added in v1.1.7

func (s *Session) AppendMessage(msg provider.Message)

func (*Session) CkptDir

func (s *Session) CkptDir() string

CkptDir is where this session's file checkpoints are stored.

func (*Session) ConnectorName added in v1.2.18

func (s *Session) ConnectorName() string

func (*Session) CooldownsFile added in v1.3.1

func (s *Session) CooldownsFile() string

CooldownsFile holds this session's own remembered limits (model and endpoint scope); the user-wide ones live with the connectors.

func (*Session) GetMessages added in v1.1.7

func (s *Session) GetMessages() []provider.Message

func (*Session) ModelName added in v1.1.7

func (s *Session) ModelName() string

func (*Session) Paused added in v1.3.1

func (s *Session) Paused() *continuity.Pause

Paused and SetPaused read and record the limit the session is stopped on, under the same lock the messages use, so a save sees a consistent pair.

func (*Session) ProviderStateName added in v1.2.18

func (s *Session) ProviderStateName() string

func (*Session) Save

func (s *Session) Save() error

Save writes the session atomically and durably.

A transcript is the one thing here a person cannot reconstruct, so this goes through internal/atomicfile rather than a hand-rolled tmp-and-rename: that buys an fsync (a rename is atomic against other processes but not against power loss) and a unique temp name (a REPL in one terminal and `kolk -p` in another used to write the same "x.json.tmp" and shred each other).

func (*Session) SessionEffort added in v1.2.18

func (s *Session) SessionEffort() string

func (*Session) SessionID added in v1.1.7

func (s *Session) SessionID() string

func (*Session) SessionMode added in v1.3.1

func (s *Session) SessionMode() string

func (*Session) SessionTitle added in v1.1.7

func (s *Session) SessionTitle() string

func (*Session) SetAutoTitle added in v1.2.0

func (s *Session) SetAutoTitle(title string) bool

SetAutoTitle replaces a derived title with a better derived one, and does nothing to a title the user chose.

func (*Session) SetConnector added in v1.2.18

func (s *Session) SetConnector(n string)

func (*Session) SetEffort added in v1.2.18

func (s *Session) SetEffort(level string)

func (*Session) SetMessages added in v1.1.7

func (s *Session) SetMessages(msgs []provider.Message)

func (*Session) SetMode added in v1.3.1

func (s *Session) SetMode(mode string)

func (*Session) SetModelName added in v1.1.7

func (s *Session) SetModelName(m string)

func (*Session) SetPaused added in v1.3.1

func (s *Session) SetPaused(p *continuity.Pause)

func (*Session) SetProviderStateName added in v1.2.18

func (s *Session) SetProviderStateName(v string)

func (*Session) SetTitle added in v1.2.0

func (s *Session) SetTitle(title string)

SetTitle records a title as chosen rather than derived.

func (*Session) SetTitleFromInput

func (s *Session) SetTitleFromInput(input string)

SetTitleFromInput sets a human-readable title from the first user message. SetTitleFromInput derives a first title from what the user typed. The title is marked automatic so Kolkrabbi may later improve on its own guess without ever overwriting a name a person chose.

func (*Session) TitleIsAuto added in v1.2.0

func (s *Session) TitleIsAuto() bool

TitleIsAuto reports whether the current title was derived rather than chosen.

type SharedCheckout added in v1.2.2

type SharedCheckout struct {
	Dir      string
	Sessions []string
}

SharedCheckout is one directory that more than one live session is working in.

func SharedCheckouts added in v1.2.2

func SharedCheckouts(cards []Card) []SharedCheckout

SharedCheckouts reports the directories where live sessions overlap.

Two sessions in one checkout will edit each other's files, and each one's `/undo` restores over the other's work — the shadow store snapshots a whole tree, so a rewind in one session takes back what the other did in the same tree. Item 27 does not refuse the overlap, because two terminals in one repository is a thing people do on purpose. What it refuses is **silence** about it: this should be something a person is told once, not something discovered when an undo restores someone else's work.

Only live sessions count. An idle one holds no lock and runs no turns, so it is not competing for anything, and a session with no recorded directory cannot be said to share one — guessing would produce a warning about nothing, which is how warnings come to be ignored.

type State added in v1.2.1

type State int

State is whether a process is currently running a session.

const (
	// StateUnknown means this platform cannot say. Reported honestly rather
	// than guessed at: a dashboard that shows "idle" for every session on
	// Windows is worse than one that admits it does not know.
	StateUnknown State = iota
	// StateIdle means nothing is running it.
	StateIdle
	// StateLive means a process holds it right now.
	StateLive
)

func Live added in v1.2.1

func Live(dir, id string) State

Live reports whether a session is being run right now.

It probes the lock without taking or creating it. Taking it would lock out the session being described; creating it would leave a file behind for every session a listing touches, which a benchmark against a real directory of 549 sessions turned into 549 stray files and half a second of syscalls.

func (State) String added in v1.2.1

func (s State) String() string

type ToolCall added in v1.1.7

type ToolCall struct {
	ID       string       `json:"id"`
	Type     string       `json:"type"`
	Function FunctionCall `json:"function"`
}

ToolCall is the serialized tool call.

Jump to

Keyboard shortcuts

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