sessions

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package sessions defines a provider-neutral catalog of coding-agent sessions: what exists on this machine, what each was doing, when a human last interacted with it, and how to resume it.

Content-access contract: unlike the telemetry collectors in this module, session readers read prompt text and titles from local harness storage so a developer can recognize a session. That content is held in memory and rendered; it is never written to the telemetry event store. Readers do not make network calls.

Index

Constants

View Source
const (
	TitleHarness     = "harness"
	TitleFirstPrompt = "first-prompt"
	TitleCWD         = "cwd"
)

TitleSource records where a session's title came from.

View Source
const ConfigFileName = "config.json"

ConfigFileName is the name of the configuration file inside the OmniDevX directory, ~/.plexusone/omnidevx.

View Source
const DefaultRepoScanDepth = 5

DefaultRepoScanDepth is how many directory levels below a workspace root the index searches for repositories. It is enough for the common <root>/<host>/<org>/<repo> layout.

Variables

This section is empty.

Functions

func DefaultConfigPath

func DefaultConfigPath() (string, error)

DefaultConfigPath returns ~/.plexusone/omnidevx/config.json.

func NormalizeRemote

func NormalizeRemote(remote string) string

NormalizeRemote turns a git remote URL into a stable repository ID of the form host/path, such as github.com/org/repo. It accepts https, ssh, and scp-style remotes, drops credentials, ports, and a trailing .git, and lower-cases the host. It returns "" for an empty remote or a remote that is a local path, which does not identify a repository to anyone else.

func Truncate

func Truncate(s string, n int) string

Truncate shortens s to at most n runes, collapsing whitespace, for single-line display.

Types

type Catalog

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

Catalog merges the sessions of several readers.

func NewCatalog

func NewCatalog(readers ...Reader) *Catalog

NewCatalog returns a Catalog over the given readers.

func (*Catalog) List

func (c *Catalog) List(ctx context.Context, opts ListOptions) ([]Session, []omnidevx.Diagnostic, error)

List returns sessions from every reader, newest activity first. One reader failing does not hide the others: the result is returned together with a joined error naming each failing harness.

type CommitRef

type CommitRef struct {
	// SHA is the commit hash as the session saw it, abbreviated or full.
	SHA string `json:"sha"`
	// Repo is the root of the repository that holds the commit, when it could be resolved.
	Repo string `json:"repo,omitempty"`
	// Relation is created or referenced.
	Relation CommitRelation `json:"relation"`
	// Subject is the commit's first message line, when it could be read from git.
	Subject string `json:"subject,omitempty"`
	// At is when the session created or referenced the commit.
	At time.Time `json:"at,omitzero"`
}

CommitRef is a commit a session created or referenced.

type CommitRelation

type CommitRelation string

CommitRelation says how a session relates to a commit.

const (
	// CommitCreated means the session ran the command that made the commit.
	CommitCreated CommitRelation = "created"
	// CommitReferenced means a prompt named the commit, for example to review it.
	CommitReferenced CommitRelation = "referenced"
)

Commit relations.

type Config

type Config struct {
	// WorkspaceRoots are directories that hold repositories, such as ~/go/src. The repository
	// index scans them for repositories. A leading ~ means the home directory.
	WorkspaceRoots []string `json:"workspaceRoots,omitempty"`
	// WorkRefRules replace the default work-reference rules when present. Omit it to match
	// initiative and roadmap-item IDs.
	WorkRefRules []WorkRefRule `json:"workRefRules,omitempty"`
}

Config is the user's session-catalog configuration. Every field is optional: an empty Config, or no file at all, gives usable defaults.

func LoadConfig

func LoadConfig(path string) (Config, error)

LoadConfig reads the configuration at path. A file that does not exist is not an error and yields the zero Config. A file that cannot be read, is not valid JSON, or has an unknown key is an error that names the path, so a typo cannot silently turn a setting off.

func (Config) ExpandedRoots

func (c Config) ExpandedRoots(home string) ([]string, error)

ExpandedRoots returns the workspace roots as absolute, cleaned paths with a leading ~ replaced by home. A relative path that is not ~-prefixed is an error, because it would depend on where the program happened to run.

func (Config) Extractor

func (c Config) Extractor() (*WorkRefExtractor, error)

Extractor returns a work-reference extractor over the configured rules, or over DefaultWorkRefRules when none are configured.

type Evidence

type Evidence struct {
	// Repos are the repositories the session worked in, read, modified, or mentioned.
	Repos []RepoActivity `json:"repos,omitempty"`
	// Files are the files the session read or modified through the harness's own tools.
	Files []FileActivity `json:"files,omitempty"`
	// Commits are the commits the session created or referenced.
	Commits []CommitRef `json:"commits,omitempty"`
	// WorkRefs are work-tracking identifiers, such as initiative and roadmap-item IDs,
	// found in the session.
	WorkRefs []WorkRef `json:"workRefs,omitempty"`
}

Evidence is what a session touched, derived from the structured tool records in its transcript and from git, not from text the model wrote.

It is a lower bound. A harness records file reads and edits made through its own tools, but shell commands can change files without leaving a path to extract, so a repository or file missing from Evidence was not observed, not proven untouched.

type FileActivity

type FileActivity struct {
	// Path is the absolute path of the file.
	Path string `json:"path"`
	// Read is set when the session read the file through a harness tool.
	Read bool `json:"read,omitempty"`
	// Modified is set when the session wrote or edited the file.
	Modified bool `json:"modified,omitempty"`
	// LastSeen is when the session last touched the file.
	LastSeen time.Time `json:"lastSeen,omitzero"`
}

FileActivity says whether a session read or modified one file.

type Harness

type Harness string

Harness identifies the coding-agent tool that owns a session.

const (
	HarnessClaudeCode Harness = "claude-code"
	HarnessCodex      Harness = "codex"
)

Known harnesses.

type ListOptions

type ListOptions struct {
	// Since drops sessions whose last activity is before this time.
	Since time.Time
	// IncludeArchived includes sessions the harness marks archived.
	IncludeArchived bool
	// NoContent suppresses prompt-derived fields (title text, prompts).
	NoContent bool
}

ListOptions scopes a Reader.List call.

type Prompt

type Prompt struct {
	// At is when the prompt was sent.
	At time.Time `json:"at"`
	// Text is the prompt text, truncated.
	Text string `json:"text"`
}

Prompt is a human-authored message, truncated for display.

type Reader

type Reader interface {
	Harness() Harness
	List(ctx context.Context, opts ListOptions) ([]Session, []omnidevx.Diagnostic, error)
}

Reader lists the sessions of one harness. List must be cheap: it may use file metadata, indexes, and bounded head/tail reads, but not full transcript parses. Unparseable sessions become diagnostics, not errors; only failure to read the harness store at all is an error.

type Repo

type Repo struct {
	// Root is the repository's root directory, the one that holds .git.
	Root string `json:"root"`
	// ID identifies the repository, such as github.com/org/repo, derived from its origin
	// remote. It is empty when the repository has no usable remote.
	ID string `json:"id,omitempty"`
}

Repo is a git repository known to a RepoIndex.

type RepoActivity

type RepoActivity struct {
	// Root is the repository's root directory.
	Root string `json:"root"`
	// ID identifies the repository, such as github.com/org/repo, derived from its origin
	// remote. It is empty when the repository has no remote.
	ID string `json:"id,omitempty"`
	// CWD is set when the session started in this repository.
	CWD bool `json:"cwd,omitempty"`
	// Executed is set when a command ran with this repository as its working directory.
	Executed bool `json:"executed,omitempty"`
	// Read is set when the session read a file in this repository through a harness tool.
	Read bool `json:"read,omitempty"`
	// Modified is set when the session wrote or edited a file in this repository.
	Modified bool `json:"modified,omitempty"`
	// Mentioned is set when the repository was named in a prompt but not otherwise observed.
	Mentioned bool `json:"mentioned,omitempty"`
	// FileCount is the number of distinct files read or modified in this repository.
	FileCount int `json:"fileCount,omitempty"`
	// FirstSeen is the earliest observed activity in this repository.
	FirstSeen time.Time `json:"firstSeen,omitzero"`
	// LastSeen is the latest observed activity in this repository.
	LastSeen time.Time `json:"lastSeen,omitzero"`
}

RepoActivity says how a session relates to one repository. The flags are independent: a repository can be the starting directory, be read, and be modified at once.

type RepoIndex

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

RepoIndex maps filesystem paths to the git repository that holds them. It is safe for concurrent use.

func NewRepoIndex

func NewRepoIndex(roots []string, opts RepoIndexOptions) (*RepoIndex, error)

NewRepoIndex scans each root for repositories. A root that cannot be read is skipped and reported in the returned error, which may accompany a usable index, so one stale entry in a configuration does not hide every other repository.

func (*RepoIndex) Lookup

func (x *RepoIndex) Lookup(path string) (Repo, bool)

Lookup returns the repository that holds path, which may be a file or a directory and need not exist. Known repositories are matched by their deepest root. A path outside every known repository is searched upward for a .git entry, and a repository found that way is remembered. Relative paths are not resolved, because the right base is the caller's.

func (*RepoIndex) Repos

func (x *RepoIndex) Repos() []Repo

Repos returns every known repository sorted by root.

type RepoIndexOptions

type RepoIndexOptions struct {
	// MaxDepth is how many levels below each root to search. Zero means DefaultRepoScanDepth.
	MaxDepth int
}

RepoIndexOptions tunes NewRepoIndex.

type ResumeSpec

type ResumeSpec struct {
	// Argv is the command and arguments that resume the session.
	Argv []string `json:"argv"`
	// Dir is the directory to run the command from.
	Dir string `json:"dir"`
}

ResumeSpec says how to resume a session. Readers return it; callers decide how to run it (replace the process, new terminal, tmux).

func (ResumeSpec) Command

func (r ResumeSpec) Command() string

Command renders the spec as a shell command line for display.

type Runtime

type Runtime struct {
	// PID is the operating-system process ID of the harness.
	PID int `json:"pid,omitempty"`
}

Runtime describes the live process attached to a running session.

type Session

type Session struct {
	// Harness is the coding-agent tool that owns the session: claude-code or codex.
	Harness Harness `json:"harness"`
	// ID is the harness's own session identifier, durable across process exit and reboot.
	ID string `json:"id"`

	// CWD is the directory the session was started in. Resuming must happen from here.
	CWD string `json:"cwd"`
	// GitBranch is the git branch recorded for the session, when the harness records one.
	GitBranch string `json:"gitBranch,omitempty"`
	// GitOrigin is the normalized origin remote, such as github.com/org/repo, when recorded.
	GitOrigin string `json:"gitOrigin,omitempty"`

	// CreatedAt is when the session started.
	CreatedAt time.Time `json:"createdAt"`
	// LastActivityAt is the last activity of any kind, including agent work.
	LastActivityAt time.Time `json:"lastActivityAt"`
	// LastHumanActivityAt is the last prompt a person typed. It is absent when none was found.
	// A large gap after LastActivityAt means the agent kept working unattended.
	LastHumanActivityAt time.Time `json:"lastHumanActivityAt,omitzero"`

	// Title names the session. It comes from the harness when it records one.
	Title string `json:"title,omitempty"`
	// TitleSource says where Title came from: harness, first-prompt, or cwd.
	TitleSource string `json:"titleSource,omitempty"`
	// RecentPrompts are the latest prompts a person typed, truncated. They are omitted when
	// prompt content is suppressed.
	RecentPrompts []Prompt `json:"recentPrompts,omitempty"`

	// Archived is set when the harness marks the session archived.
	Archived bool `json:"archived,omitempty"`
	// State is running, resumable, or unknown.
	State State `json:"state"`
	// Runtime describes the live process when State is running.
	Runtime *Runtime `json:"runtime,omitempty"`

	// Resume says how to resume the session.
	Resume ResumeSpec `json:"resume"`

	// Evidence is what the session touched. It is populated only when requested, because it
	// needs a full transcript parse.
	Evidence *Evidence `json:"evidence,omitempty"`
}

Session is one resumable harness session. (Harness, ID) is its identity; everything else describes it.

func Resolve

func Resolve(all []Session, query string) (*Session, error)

Resolve finds one session by full ID or unique prefix of at least four characters. A "harness:" qualifier (e.g. "codex:0199") narrows the search. An ambiguous prefix returns an error listing the candidates.

type State

type State string

State is whether a session currently has a live process.

const (
	// StateResumable means the session exists on disk and no live process
	// was found for it.
	StateResumable State = "resumable"
	// StateRunning means a live process is attached to the session.
	StateRunning State = "running"
	// StateUnknown means liveness could not be determined.
	StateUnknown State = "unknown"
)

Session states.

type WorkRef

type WorkRef struct {
	// ID is the identifier as written, such as RMI-EXAMPLE-012.
	ID string `json:"id"`
	// Kind is the name of the rule that matched it, such as initiative or rmi.
	Kind string `json:"kind"`
	// Sources lists where it was found.
	Sources []WorkRefSource `json:"sources"`
	// Title is the identifier's title when a resolver supplied one.
	Title string `json:"title,omitempty"`
}

WorkRef is a work-tracking identifier found in a session.

func ResolveTitles

func ResolveTitles(ctx context.Context, refs []WorkRef, r WorkRefResolver) ([]WorkRef, error)

ResolveTitles fills in Title on each reference the resolver knows. On a resolver error it returns the references unchanged along with the error, so a lookup failure never loses the references themselves.

type WorkRefExtractor

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

WorkRefExtractor finds work references in text using named rules.

func NewWorkRefExtractor

func NewWorkRefExtractor(rules []WorkRefRule) (*WorkRefExtractor, error)

NewWorkRefExtractor compiles the rules. It returns an error for an empty or duplicate name or a pattern that does not compile, so a bad configuration fails when loaded rather than silently matching nothing.

func (*WorkRefExtractor) NewSet

func (e *WorkRefExtractor) NewSet() *WorkRefSet

NewSet returns an empty accumulator that merges references found in different places.

type WorkRefResolver

type WorkRefResolver interface {
	// Titles returns the title of each identifier it knows. Unknown
	// identifiers are left out of the result rather than treated as errors.
	Titles(ctx context.Context, ids []string) (map[string]string, error)
}

WorkRefResolver supplies titles for work references, for example from a work-tracking system. Nothing implements it by default.

type WorkRefRule

type WorkRefRule struct {
	// Name is the rule's name and the Kind of every reference it matches, such as rmi.
	Name string `json:"name"`
	// Pattern is a regular expression that matches the identifier as written.
	Pattern string `json:"pattern"`
}

WorkRefRule names a pattern that identifies one kind of work reference.

func DefaultWorkRefRules

func DefaultWorkRefRules() []WorkRefRule

DefaultWorkRefRules matches initiative IDs (INIT-<SLUG>-NNN) and roadmap-item IDs (RMI-<REPOSLUG>-NNN). Slugs are upper-case letters and digits, and the number has at least three digits.

type WorkRefSet

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

WorkRefSet accumulates work references. The zero value is not usable; use WorkRefExtractor.NewSet.

func (*WorkRefSet) Add

func (s *WorkRefSet) Add(source WorkRefSource, text string)

Add scans text and records every reference it finds, noting where it was found. When rules overlap, the first rule that matches an identifier names its kind. Repeated sightings merge: an identifier keeps one entry and gains each source it appears in.

func (*WorkRefSet) Refs

func (s *WorkRefSet) Refs() []WorkRef

Refs returns the accumulated references sorted by identifier, each with its sources in a fixed order.

type WorkRefSource

type WorkRefSource string

WorkRefSource says where a work reference was found.

const (
	// WorkRefPrompt means a prompt a person typed.
	WorkRefPrompt WorkRefSource = "prompt"
	// WorkRefBranch means the session's git branch name.
	WorkRefBranch WorkRefSource = "branch"
	// WorkRefCommit means the message of a commit the session created.
	WorkRefCommit WorkRefSource = "commit"
	// WorkRefPath means a path the session touched.
	WorkRefPath WorkRefSource = "path"
)

Work reference sources.

Directories

Path Synopsis
Package schema embeds the generated JSON Schema for sessions.Session, the document "omnidevx sessions --json" prints, so tools can validate it without a copy of the Go types.
Package schema embeds the generated JSON Schema for sessions.Session, the document "omnidevx sessions --json" prints, so tools can validate it without a copy of the Go types.

Jump to

Keyboard shortcuts

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