Documentation
¶
Overview ¶
Package session provides shared entry parsing utilities for session recordings. These functions handle the multiple JSONL formats that session entries can take: imported format (root-level fields), standard format (nested data.*), and legacy format.
Package session provides storage and management for agent session recordings. This file implements markdown generation from stored sessions.
Package session provides storage and management for agent session recordings. Sessions are stored in the XDG cache directory under context/<repo-id>/sessions/ using a session-folder structure for organized storage of multiple output formats.
TODO(server-side): move session file creation to server-side for MVP+1. Currently client writes all session files; server should own ledger writes.
Session folder structure:
sessions/
└── <session-name>/
├── raw.jsonl # unprocessed session capture
├── summary.md # ai-generated summary
├── session.md # markdown session
└── session.html # html session
Session name format: YYYY-MM-DDTHH-MM-<username>-<sessionID> Example: 2026-01-06T14-32-ryan-Ox7f3a
Package session provides subagent session capture and aggregation.
When a parent agent spawns subagents, the parent's session can capture subagent sessions and include them in the parent session's output. This enables comprehensive session capture for complex multi-agent workflows.
Subagent capture flow:
- Parent starts recording: `ox agent <id> session start`
- Subagent spawns and inherits parent session ID (via environment or flag)
- Subagent completes work and reports: `ox agent <id> session subagent-complete`
- Parent stops recording: `ox agent <id> session stop`
- Parent session includes references to all subagent sessions
Package session provides subagent session capture during recording stop.
When a parent session ends, this module scans the session for Task tool calls, matches them with completed subagent sessions (by timestamp correlation), and enriches the session entries with subagent references.
Output structure for Task tool entries:
{
"type": "tool",
"tool_name": "Task",
"tool_input": {...},
"tool_output": "...",
"subagent": {
"session_id": "abc123",
"session_path": "sessions/2026-01-06T14-35-history-Oxdef/",
"entry_count": 47
}
}
Index ¶
- Constants
- Variables
- func BuildSummaryPrompt(entries []Entry, rawPath, ledgerSessionDir string) string
- func ClearNeedsSummaryMarker(sessionCacheDir string) error
- func ClearRecordingState(projectRoot string) error
- func ClearRecordingStateForAgent(projectRoot, agentID string) error
- func ConsumeExplicitStop(projectRoot, agentID string) bool
- func CountSubstantiveEntries(rawPath string) int
- func EnrichEntriesWithSubagents(entries []map[string]any, matches map[int]*SubagentReference)
- func ExtractAllMermaidFromEntries(entries []SessionEntry) []string
- func ExtractContent(entry map[string]any) string
- func ExtractDiagramsFromEntries(entries []map[string]any) []string
- func ExtractEntryTimestamp(entry map[string]any) (time.Time, bool)
- func ExtractEntryType(entry map[string]any) string
- func ExtractMermaidBlocks(content string) []string
- func ExtractMermaidDiagrams(content string) []string
- func FindParentSessionPath(projectRoot string) string
- func FindParentSessionPathForAgent(projectRoot, agentID string) string
- func FormatGuidanceJSON(phase GuidancePhase, agentID string, guidance SessionGuidance, message string) ([]byte, error)
- func FormatGuidanceText(phase GuidancePhase, agentID string, guidance SessionGuidance) string
- func FormatHTMLGuidanceJSON(agentID string, guidance HTMLGuidance, generated bool, ...) ([]byte, error)
- func FormatHTMLGuidanceText(agentID string, guidance HTMLGuidance) string
- func FormatSummarizeGuidanceJSON(agentID string, guidance SummarizeGuidance, summary *SummarizeOutput) ([]byte, error)
- func FormatSummarizeGuidanceText(agentID string, guidance SummarizeGuidance) string
- func FormatSummaryJSON(agentID string, summary *SummarizeResponse, entryCount int, ...) ([]byte, error)
- func FormatSummaryText(agentID string, summary *SummarizeResponse, entryCount int) string
- func GenerateFilename(username, agentID string) string
- func GenerateSessionName(sessionID, username string) string
- func GetCacheDir() string
- func GetContextPath(repoID string) string
- func GetHistoryStoragePath(agentID string, activeRecording bool) string
- func GetRecordingDuration(projectRoot string) time.Duration
- func GetSessionName(sessionPath string) string
- func HasMermaidBlocks(content string) bool
- func HasSubstantiveEntries(rawPath string) bool
- func IsNoiseCommand(cmd string) bool
- func IsRecording(projectRoot string) bool
- func IsRecordingForAgent(projectRoot, agentID string) bool
- func IsRedactionSigned() bool
- func IsValidEntryType(entryType string) bool
- func LoadCustomPatterns(projectRoot string) ([]SecretPattern, []RedactParseError)
- func LocalSummary(entries []Entry) string
- func MapEntryType(raw string) string
- func MapRoleToType(role string) string
- func MarkExplicitStop(projectRoot, agentID string) error
- func MatchTasksToSubagents(taskCalls []TaskToolCallInfo, subagents []*SubagentSession) map[int]*SubagentReference
- func MergeHistoryWithRecording(sessionPath string, history *CapturedHistory) error
- func NewRedactorWithCustomRules(projectRoot string) (*Redactor, []RedactParseError)
- func ParseHistoryEntry(line []byte) (*HistoryMeta, *HistoryEntry, error)
- func ParseTimestamp(ts string) (time.Time, bool)
- func ProcessMermaidBlocks(content string) string
- func RawJSONLHasData(sessionPath string) bool
- func RecordingDurationString(state *RecordingState) string
- func RedactHistorySecrets(history *CapturedHistory) int
- func RenderMermaidToASCII(mermaidCode string) (string, error)
- func ReportSubagentComplete(opts SubagentCompleteOptions) error
- func RulesToPatterns(rules []RedactRule) ([]SecretPattern, []RedactParseError)
- func SaveRecordingState(projectRoot string, state *RecordingState) error
- func SessionHasHistory(sessionPath string) bool
- func ShortenPath(path string) string
- func StoreCapturedHistory(history *CapturedHistory, agentID string, activeRecording bool) (storagePath string, err error)
- func UpdateRecordingState(projectRoot string, updateFn func(*RecordingState)) error
- func UpdateRecordingStateForAgent(projectRoot, agentID string, updateFn func(*RecordingState)) error
- func ValidateHistoryEntry(entry *HistoryEntry) error
- func ValidateHistoryMeta(meta *HistoryMeta) error
- func VerifyRedactionSignature() *signing.VerificationResult
- func WriteHistoryJSONL(path string, history *CapturedHistory) error
- func WriteNeedsSummaryMarker(sessionCacheDir, rawPath, ledgerSessionDir string) error
- type AhaMoment
- type ArtifactPaths
- type CaptureOptions
- type CaptureOutput
- type CaptureResult
- type CaptureSubagentOptions
- type CaptureSubagentResult
- type CapturedHistory
- func LoadHistoryFromSession(sessionPath string) (*CapturedHistory, error)
- func ParseHistoryFile(path string) (*CapturedHistory, error)
- func ValidateAndRedact(reader io.Reader) (*CapturedHistory, int, error)
- func ValidateCapturePriorInput(reader io.Reader) (*CapturedHistory, error)
- func ValidateHistoryJSONLReader(reader io.Reader) (*CapturedHistory, error)
- func ValidateJSONL(reader io.Reader) (*CapturedHistory, error)
- func (h *CapturedHistory) ComputeTimeRange() *HistoryTimeRange
- func (h *CapturedHistory) Duration() time.Duration
- func (h *CapturedHistory) EntryCount() int
- func (h *CapturedHistory) GetEntriesByType(entryType string) []HistoryEntry
- func (h *CapturedHistory) GetPlanEntries() []HistoryEntry
- func (h *CapturedHistory) HasPlanningHistory() bool
- func (h *CapturedHistory) PlanningHistoryCount() int
- func (h *CapturedHistory) ToSessionEntries() []SessionEntry
- type ChapterSummary
- type DelegationHint
- type Entry
- type EntryType
- type FileModification
- type FileSummary
- type GhostCleanupResult
- type GuidanceOutput
- type GuidancePhase
- type HTMLGenerator
- type HTMLGuidance
- type HTMLGuidanceOutput
- type HealthStatus
- type HistoryEntry
- type HistoryMeta
- type HistoryTimeRange
- type HistoryValidationResult
- type MarkdownGenerator
- type MemoryStorage
- func (m *MemoryStorage) Clear()
- func (m *MemoryStorage) Count() int
- func (m *MemoryStorage) Delete(filename string) error
- func (m *MemoryStorage) Exists(filename string) bool
- func (m *MemoryStorage) GetLatest() (*SessionInfo, error)
- func (m *MemoryStorage) List() ([]SessionInfo, error)
- func (m *MemoryStorage) Load(filename string) (*StoredSession, error)
- func (m *MemoryStorage) Save(filename, sessionType string, meta *StoreMeta, entries []map[string]any) error
- type NeedsSummaryInfo
- type ParsedRedactFile
- type PatternManifestEntry
- type PlanEntry
- type PlanMarker
- type QualityDisposition
- type RecordingState
- func LoadAllRecordingStates(projectRoot string) ([]*RecordingState, error)
- func LoadRecordingState(projectRoot string) (*RecordingState, error)
- func LoadRecordingStateForAgent(projectRoot, agentID string) (*RecordingState, error)
- func StartRecording(projectRoot string, opts StartRecordingOptions) (*RecordingState, error)
- func StopRecording(projectRoot, agentID string) (*RecordingState, error)
- type RedactParseError
- type RedactRule
- type RedactRuleSource
- type RedactSourceInfo
- type RedactionManifest
- func (m *RedactionManifest) CanonicalJSON() ([]byte, error)
- func (m *RedactionManifest) FindPattern(name string) *PatternManifestEntry
- func (m *RedactionManifest) Hash() ([]byte, error)
- func (m *RedactionManifest) HashHex() (string, error)
- func (m *RedactionManifest) PatternCount() int
- func (m *RedactionManifest) PrettyJSON() ([]byte, error)
- type RedactionResult
- type Redactor
- func (r *Redactor) AddPattern(pattern SecretPattern)
- func (r *Redactor) ContainsSecrets(input string) bool
- func (r *Redactor) RedactCapturedHistory(history *CapturedHistory) (count int)
- func (r *Redactor) RedactEntries(entries []Entry) (count int)
- func (r *Redactor) RedactEntry(entry *Entry) (redacted bool)
- func (r *Redactor) RedactHistoryEntries(entries []HistoryEntry) (count int)
- func (r *Redactor) RedactMap(data map[string]any) bool
- func (r *Redactor) RedactSlice(data []any) bool
- func (r *Redactor) RedactString(input string) (output string, found []string)
- func (r *Redactor) RedactStringWithDetails(input string) (output string, results []RedactionResult)
- func (r *Redactor) RedactWithAllowlist(input string, allowlist []string) (output string, found []string)
- func (r *Redactor) ScanForSecrets(input string) []string
- type SageoxInsight
- type SecretPattern
- type Session
- func (s *Session) AddAssistantEntry(content string)
- func (s *Session) AddEntry(entry SessionEntry)
- func (s *Session) AddSystemEntry(content string)
- func (s *Session) AddToolEntry(toolName, toolInput, toolOutput string)
- func (s *Session) AddUserEntry(content string)
- func (s *Session) Close()
- func (s *Session) EntryCount() int
- func (s *Session) Footer() *SessionFooter
- type SessionEntry
- func NewAssistantEntry(content string) SessionEntry
- func NewAssistantSessionEntry(content string) SessionEntry
- func NewCoworkerLoadEntry(name, model string) SessionEntry
- func NewEntry(entryType SessionEntryType, content string) SessionEntry
- func NewSessionEntry(entryType SessionEntryType, content string) SessionEntry
- func NewSystemEntry(content string) SessionEntry
- func NewSystemSessionEntry(content string) SessionEntry
- func NewToolEntry(toolName, toolInput, toolOutput string) SessionEntry
- func NewToolSessionEntry(toolName, toolInput, toolOutput string) SessionEntry
- func NewUserEntry(content string) SessionEntry
- func NewUserSessionEntry(content string) SessionEntry
- type SessionEntryType
- type SessionError
- type SessionFilterMode
- type SessionFooter
- type SessionGuidance
- type SessionInfo
- type SessionMeta
- type SessionStatus
- type SessionWriter
- func (w *SessionWriter) Close() error
- func (w *SessionWriter) Count() int
- func (w *SessionWriter) FilePath() string
- func (w *SessionWriter) SessionName() string
- func (w *SessionWriter) WriteEntry(entry Writable) error
- func (w *SessionWriter) WriteHeader(meta *StoreMeta) error
- func (w *SessionWriter) WriteRaw(data map[string]any) error
- type StartGuidanceOptions
- type StartRecordingOptions
- type Storage
- type Store
- func (s *Store) BasePath() string
- func (s *Store) CheckNeedsDownload(name string) string
- func (s *Store) CreateRaw(sessionName string) (*SessionWriter, error)
- func (s *Store) Delete(name string) error
- func (s *Store) DeleteSession(sessionName string) error
- func (s *Store) Exists(filename string) bool
- func (s *Store) GetLatest() (*SessionInfo, error)
- func (s *Store) GetLatestRaw() (*SessionInfo, error)
- func (s *Store) GetSessionPath(sessionName string) string
- func (s *Store) IsSessionHydrated(sessionName string) bool
- func (s *Store) List() ([]SessionInfo, error)
- func (s *Store) ListAllSessions() ([]SessionInfo, error)
- func (s *Store) ListRawSessionsSince(since time.Time) ([]SessionInfo, error)
- func (s *Store) ListSessionNames() ([]string, error)
- func (s *Store) ListSessions() ([]SessionInfo, error)
- func (s *Store) ListSessionsSince(since time.Time) ([]SessionInfo, error)
- func (s *Store) Load(filename string) (*StoredSession, error)
- func (s *Store) Prune(olderThan time.Duration) (int, error)
- func (s *Store) ReadLFSSessionMeta(sessionName string) (*lfs.SessionMeta, error)
- func (s *Store) ReadRawSession(filename string) (*StoredSession, error)
- func (s *Store) ReadSession(name string) (*StoredSession, error)
- func (s *Store) ReadSessionRaw(sessionName string) (*StoredSession, error)
- func (s *Store) ResolveSessionName(name string) (string, error)
- func (s *Store) Save(filename, sessionType string, meta *StoreMeta, entries []map[string]any) error
- type StoreMeta
- type StoredSession
- type SubagentCompleteOptions
- type SubagentReference
- type SubagentRegistry
- type SubagentSession
- type SubagentSummary
- type SummarizeEntry
- type SummarizeGuidance
- type SummarizeGuidanceOutput
- type SummarizeOutput
- type SummarizeRequest
- type SummarizeResponse
- type SummaryMarkdownGenerator
- type SummaryView
- type TaskInput
- type TaskToolCallInfo
- type Writable
Constants ¶
const ( StopReasonStopped = "stopped" // user explicitly stopped via /ox-session-stop StopReasonCanceled = "canceled" // user explicitly canceled via /ox-session-abort StopReasonRecovered = "recovered" // recovered from orphan by daemon anti-entropy )
StopReason constants for how a session ended.
const ( ErrCodeNotRecording = "NOT_RECORDING" ErrCodeAlreadyRecording = "ALREADY_RECORDING" ErrCodeNoSession = "NO_SESSION" ErrCodeInvalidEntry = "INVALID_ENTRY" ErrCodeStorageError = "STORAGE_ERROR" ErrCodeAuthRequired = "AUTH_REQUIRED" )
Error codes for session operations
const ( EntryTypeUser = SessionEntryTypeUser EntryTypeAssistant = SessionEntryTypeAssistant EntryTypeSystem = SessionEntryTypeSystem EntryTypeTool = SessionEntryTypeTool )
EntryType constants for backward compatibility.
const ArtifactName = "redaction"
ArtifactName is the signing artifact name for the redaction manifest.
const DefaultListWindow = 7 * 24 * time.Hour
DefaultListWindow is the default time window for listing sessions. Only sessions within this window will have meta.json read for hydration status. Use time.Duration(0) to list all sessions.
const DefaultReminderInterval = 50
DefaultReminderInterval is the default number of entries between reminders.
const HistorySchemaVersion = "1"
HistorySchemaVersion is the current version of the history capture schema.
const HistorySourcePlanningHistory = "planning_history"
HistorySourcePlanningHistory is the source marker for planning history entries.
const ManifestSchemaVersion = "1"
ManifestSchemaVersion is incremented when the manifest structure changes. Signature verification requires matching schema versions.
const SessionSchemaVersion = "1"
SessionSchemaVersion is the current session schema version. Increment when making breaking changes to the session format.
const StaleRecordingThreshold = 12 * time.Hour
StaleRecordingThreshold defines how long a recording can run before it's considered potentially stale/abandoned (12 hours).
const SummaryPromptGuidelines = `` /* 4042-byte string literal not displayed */
SummaryPromptGuidelines contains the shared guidelines for session summarization. Used by both the resummary command and should match the server-side prompt.
Variables ¶
var ( // ErrSessionNotFound is returned when a session file cannot be located ErrSessionNotFound = errors.New("session not found") // ErrNoSessions is returned when no sessions exist in storage ErrNoSessions = errors.New("no sessions found") // ErrNoRawSessions is returned when no raw sessions exist ErrNoRawSessions = errors.New("no raw sessions found") // ErrEmptyPath is returned when a required path argument is empty ErrEmptyPath = errors.New("path cannot be empty") // ErrEmptyFilename is returned when a required filename argument is empty ErrEmptyFilename = errors.New("filename cannot be empty") // ErrNilEntry is returned when a nil entry is passed to a write operation ErrNilEntry = errors.New("entry cannot be nil") // ErrNilData is returned when nil data is passed to a write operation ErrNilData = errors.New("data cannot be nil") // ErrNilState is returned when a nil state is passed to a save operation ErrNilState = errors.New("recording state cannot be nil") // ErrSessionNotHydrated is returned when content files are not present locally. // The session's meta.json exists (from git pull) but content files need to be // downloaded from LFS blob storage via `ox session download`. ErrSessionNotHydrated = errors.New("session content not available locally: run 'ox session download' to fetch") )
sentinel errors for the session package
var ( // ErrHistoryMissingMeta is returned when the first line is not a valid _meta entry ErrHistoryMissingMeta = errors.New("history missing _meta line") // ErrHistoryInvalidMeta is returned when _meta is missing required fields ErrHistoryInvalidMeta = errors.New("history _meta missing required fields") // ErrHistoryInvalidEntryType is returned when entry type is not recognized ErrHistoryInvalidEntryType = errors.New("history entry has invalid type") // ErrHistoryNonMonotonicSeq is returned when seq numbers are not strictly increasing ErrHistoryNonMonotonicSeq = errors.New("history entry seq not monotonically increasing") // ErrHistoryDuplicateSeq is returned when two entries have the same seq number ErrHistoryDuplicateSeq = errors.New("history entry has duplicate seq") // ErrHistoryMissingSeq is returned when an entry is missing the seq field ErrHistoryMissingSeq = errors.New("history entry missing seq field") // ErrHistoryEmptyInput is returned when input reader is nil ErrHistoryEmptyInput = errors.New("history input is empty") )
History schema validation errors.
var ( // ErrHistoryNilHistory is returned when a nil history is passed to store ErrHistoryNilHistory = errors.New("captured history cannot be nil") // ErrHistoryEmptyEntries is returned when history has no entries to store ErrHistoryEmptyEntries = errors.New("captured history has no entries") // ErrHistoryStorageFailed is returned when storage operation fails ErrHistoryStorageFailed = errors.New("failed to store captured history") )
History storage errors.
var ( // ErrNotRecording is returned when stop is called but no recording is active ErrNotRecording = errors.New("not currently recording") // ErrAlreadyRecording is returned when start is called but already recording ErrAlreadyRecording = errors.New("already recording a session") // ErrNoLedger is returned when session recording is attempted but no ledger is configured ErrNoLedger = errors.New("no ledger configured for this project") )
var ValidEntryTypes = map[string]bool{ "user": true, "assistant": true, "system": true, "tool": true, }
ValidEntryTypes defines the allowed entry types for history entries.
Functions ¶
func BuildSummaryPrompt ¶
BuildSummaryPrompt builds a prompt for the calling agent to generate a session summary. The agent receives this prompt in the JSON output and produces the summary itself, avoiding a server-side API call. If ledgerSessionDir is non-empty, a step is added instructing the agent to push the summary to the ledger via `ox session push-summary`.
func ClearNeedsSummaryMarker ¶
ClearNeedsSummaryMarker removes the .needs-summary marker from a session cache directory.
func ClearRecordingState ¶
ClearRecordingState removes the recording state file from the session folder. Note: returns first-match state. Use ClearRecordingStateForAgent in agent-context code to avoid clearing another concurrent agent's recording.
func ClearRecordingStateForAgent ¶ added in v0.3.0
ClearRecordingStateForAgent removes recording state for a specific agent only. Safe for concurrent use: only touches this agent's .recording.json.
func ConsumeExplicitStop ¶ added in v0.3.0
ConsumeExplicitStop checks for and removes the per-agent explicit-stop marker. Returns true if the marker existed (meaning an auto-start should be skipped). Also cleans up any legacy global marker (without agent suffix) as a migration path.
func CountSubstantiveEntries ¶ added in v0.5.0
CountSubstantiveEntries counts lines in a raw.jsonl that are actual session entries, excluding the metadata header (first line). Returns 0 for header-only files or files that don't exist.
func EnrichEntriesWithSubagents ¶
func EnrichEntriesWithSubagents(entries []map[string]any, matches map[int]*SubagentReference)
EnrichEntriesWithSubagents adds subagent references to session entries. Modifies entries in place, adding "subagent" field to matched Task tool calls.
func ExtractAllMermaidFromEntries ¶
func ExtractAllMermaidFromEntries(entries []SessionEntry) []string
ExtractAllMermaidFromEntries finds all unique mermaid diagrams across entries. Returns deduplicated list of diagrams.
func ExtractContent ¶ added in v0.1.1
ExtractContent gets content from various field locations in an entry. Checks: content, data.content, data.message, message, text, result.
func ExtractDiagramsFromEntries ¶
ExtractDiagramsFromEntries scans all entries for mermaid diagrams. Returns deduplicated list of diagrams found.
func ExtractEntryTimestamp ¶ added in v0.1.1
ExtractEntryTimestamp gets the timestamp from an entry, checking both "timestamp" and "ts" field names.
func ExtractEntryType ¶ added in v0.1.1
ExtractEntryType gets the type field from an entry.
func ExtractMermaidBlocks ¶
ExtractMermaidBlocks finds all mermaid code blocks in content. Returns the raw mermaid code (without the ``` markers).
func ExtractMermaidDiagrams ¶
ExtractMermaidDiagrams finds all mermaid code blocks in content. Returns a slice of diagram contents (without the ```mermaid markers). Handles multiple diagrams and ignores malformed/unclosed blocks.
func FindParentSessionPath ¶
FindParentSessionPath looks up the active recording state and returns its session path. Used by subagents to discover where to report completion. Returns empty string if no recording is active. Note: returns first-match. Use FindParentSessionPathForAgent when agent ID is known.
func FindParentSessionPathForAgent ¶ added in v0.3.0
FindParentSessionPathForAgent looks up the recording state for a specific agent and returns its session path. Used by subagents to discover parent session.
func FormatGuidanceJSON ¶
func FormatGuidanceJSON(phase GuidancePhase, agentID string, guidance SessionGuidance, message string) ([]byte, error)
FormatGuidanceJSON formats guidance as JSON output.
func FormatGuidanceText ¶
func FormatGuidanceText(phase GuidancePhase, agentID string, guidance SessionGuidance) string
FormatGuidanceText formats guidance as human-readable text.
func FormatHTMLGuidanceJSON ¶
func FormatHTMLGuidanceJSON(agentID string, guidance HTMLGuidance, generated bool, htmlPath, message string) ([]byte, error)
FormatHTMLGuidanceJSON formats HTML generation guidance as JSON output.
func FormatHTMLGuidanceText ¶
func FormatHTMLGuidanceText(agentID string, guidance HTMLGuidance) string
FormatHTMLGuidanceText formats HTML generation guidance as human-readable text.
func FormatSummarizeGuidanceJSON ¶
func FormatSummarizeGuidanceJSON(agentID string, guidance SummarizeGuidance, summary *SummarizeOutput) ([]byte, error)
FormatSummarizeGuidanceJSON formats summarization guidance as JSON output.
func FormatSummarizeGuidanceText ¶
func FormatSummarizeGuidanceText(agentID string, guidance SummarizeGuidance) string
FormatSummarizeGuidanceText formats summarization guidance as human-readable text.
func FormatSummaryJSON ¶
func FormatSummaryJSON(agentID string, summary *SummarizeResponse, entryCount int, filePath, message string) ([]byte, error)
FormatSummaryJSON formats a summary as JSON output.
func FormatSummaryText ¶
func FormatSummaryText(agentID string, summary *SummarizeResponse, entryCount int) string
FormatSummaryText formats a summary as human-readable text.
func GenerateFilename ¶
GenerateFilename creates a unique filename for a session (legacy format). Format: 2026-01-05T10-30-<username>-<agentID>.jsonl The timestamp uses hour-minute precision with dashes for filesystem compatibility. Deprecated: Use GenerateSessionName for new session-folder structure.
func GenerateSessionName ¶
GenerateSessionName creates a unique session folder name. Format: YYYY-MM-DDTHH-MM-<username>-<sessionID> Example: 2026-01-06T14-32-ryan-Ox7f3a
func GetCacheDir ¶
func GetCacheDir() string
GetCacheDir returns the SageOx cache directory.
Path Resolution (via internal/paths package):
Default: ~/.sageox/cache/ With OX_XDG_ENABLE: $XDG_CACHE_HOME/sageox/
See internal/paths/doc.go for architecture rationale.
func GetContextPath ¶
GetContextPath returns the full path to a repo's session context directory.
Path Resolution (via internal/paths package):
Default: ~/.sageox/cache/sessions/<repo-id>/ With OX_XDG_ENABLE: $XDG_CACHE_HOME/sageox/sessions/<repo-id>/
See internal/paths/doc.go for architecture rationale.
func GetHistoryStoragePath ¶
GetHistoryStoragePath determines where to store captured history. If activeRecording is true, returns path to active session's raw.jsonl. Otherwise returns path for a new prior-history.jsonl in a new session folder.
Path resolution:
- Active recording: <session_path>/raw.jsonl
- New session: <sessions_base>/<new_session_name>/prior-history.jsonl
func GetRecordingDuration ¶
GetRecordingDuration returns how long the current recording has been running. Returns 0 if no recording is active.
func GetSessionName ¶
GetSessionName extracts the session name from a session path.
func HasMermaidBlocks ¶
HasMermaidBlocks checks if content contains any mermaid code blocks.
func HasSubstantiveEntries ¶ added in v0.5.0
HasSubstantiveEntries returns true if a raw.jsonl file has at least one entry beyond the metadata header line. A header-only file (1 line) has no real session content and should not be uploaded or finalized.
This is the canonical check — use it everywhere instead of inline line counting.
func IsNoiseCommand ¶
IsNoiseCommand checks if a command is noise (low-value unless it fails).
func IsRecording ¶
IsRecording checks if a recording is active for the given project root.
func IsRecordingForAgent ¶ added in v0.3.0
IsRecordingForAgent checks if a specific agent has an active recording.
func IsRedactionSigned ¶
func IsRedactionSigned() bool
IsRedactionSigned returns true if redaction signing is configured.
func IsValidEntryType ¶
IsValidEntryType returns true if the given type is valid.
func LoadCustomPatterns ¶ added in v0.3.0
func LoadCustomPatterns(projectRoot string) ([]SecretPattern, []RedactParseError)
LoadCustomPatterns discovers and loads REDACT.md files from all custom levels (team, repo, user), merges them in order, and returns compiled patterns. Returns patterns plus any parse errors encountered.
func LocalSummary ¶
LocalSummary generates a simple local summary without API call. Used as fallback when API is unavailable. Extracts the first substantive user message as a topic hint so the summary conveys what the session was about, not just stats.
func MapEntryType ¶ added in v0.1.1
MapEntryType normalizes raw entry type strings to canonical CSS/display types. Returns one of: "user", "assistant", "system", "tool", "tool_result", "info".
func MapRoleToType ¶ added in v0.1.1
MapRoleToType converts a message role (from data.role) to a display type.
func MarkExplicitStop ¶ added in v0.3.0
MarkExplicitStop writes a per-agent breadcrumb indicating the user explicitly stopped recording. This prevents the next auto-start cycle (e.g. from /clear hook re-prime) from silently restarting the session for this specific agent.
func MatchTasksToSubagents ¶
func MatchTasksToSubagents( taskCalls []TaskToolCallInfo, subagents []*SubagentSession, ) map[int]*SubagentReference
MatchTasksToSubagents attempts to match Task tool calls with subagent sessions. Returns a map from entry index to matched SubagentReference.
func MergeHistoryWithRecording ¶
func MergeHistoryWithRecording(sessionPath string, history *CapturedHistory) error
MergeHistoryWithRecording merges captured history into an active recording's raw.jsonl. History entries are prepended before existing recorded entries, with seq numbers adjusted.
The merge process:
- Read existing raw.jsonl entries
- Assign seq numbers to history entries (starting from 1)
- Adjust existing entry seq numbers to continue after history
- Write merged entries back to raw.jsonl
func NewRedactorWithCustomRules ¶ added in v0.3.0
func NewRedactorWithCustomRules(projectRoot string) (*Redactor, []RedactParseError)
NewRedactorWithCustomRules creates a Redactor with default patterns plus any user-defined patterns from REDACT.md files. Custom patterns are always additive -- built-in patterns cannot be removed. Parse errors are returned for logging/display but do not prevent redactor creation.
func ParseHistoryEntry ¶
func ParseHistoryEntry(line []byte) (*HistoryMeta, *HistoryEntry, error)
ParseHistoryEntry parses a JSONL line into a HistoryEntry or HistoryMeta.
func ParseTimestamp ¶ added in v0.1.1
ParseTimestamp parses a timestamp string in RFC3339 or RFC3339Nano format. Returns zero time and false if parsing fails.
func ProcessMermaidBlocks ¶
ProcessMermaidBlocks finds all ```mermaid blocks in content and renders them to ASCII. Returns the content with mermaid blocks replaced by their ASCII representations. If rendering fails for a block, it's left as-is with an error comment.
func RawJSONLHasData ¶ added in v0.5.0
RawJSONLHasData checks if a raw.jsonl file exists on disk and has content. This is a filesystem-level check (size > 0), not a line-level check.
func RecordingDurationString ¶
func RecordingDurationString(state *RecordingState) string
RecordingDurationString returns a human-readable duration string.
func RedactHistorySecrets ¶
func RedactHistorySecrets(history *CapturedHistory) int
RedactHistorySecrets applies secret redaction to all entries in captured history using the default redactor. This is a convenience function for one-off usage. Returns the count of entries that contained secrets.
func RenderMermaidToASCII ¶
RenderMermaidToASCII renders a mermaid diagram string to ASCII art. Returns the ASCII representation or an error if rendering fails. Uses the mermaid-ascii library compiled into the binary.
func ReportSubagentComplete ¶
func ReportSubagentComplete(opts SubagentCompleteOptions) error
ReportSubagentComplete registers a subagent's completion with the parent session. This should be called when a subagent finishes its work.
func RulesToPatterns ¶ added in v0.3.0
func RulesToPatterns(rules []RedactRule) ([]SecretPattern, []RedactParseError)
RulesToPatterns converts parsed RedactRules to SecretPatterns. For literal rules, the pattern is escaped via regexp.QuoteMeta. Invalid regex rules produce errors but don't stop conversion.
func SaveRecordingState ¶
func SaveRecordingState(projectRoot string, state *RecordingState) error
SaveRecordingState persists recording state to the session folder.
func SessionHasHistory ¶
SessionHasHistory checks if a session folder contains prior-history.jsonl.
func ShortenPath ¶
ShortenPath returns a shortened path for display. Replaces home directory with ~.
func StoreCapturedHistory ¶
func StoreCapturedHistory(history *CapturedHistory, agentID string, activeRecording bool) (storagePath string, err error)
StoreCapturedHistory stores validated history to the appropriate location. If activeRecording is true, merges history into the active session's raw.jsonl. Otherwise creates a new session folder with the history as prior-history.jsonl.
Returns the path where history was stored.
func UpdateRecordingState ¶
func UpdateRecordingState(projectRoot string, updateFn func(*RecordingState)) error
UpdateRecordingState updates and persists the recording state. Useful for updating entry count or last reminder sequence. Note: uses first-match state. Use UpdateRecordingStateForAgent in agent-context code.
func UpdateRecordingStateForAgent ¶ added in v0.3.0
func UpdateRecordingStateForAgent(projectRoot, agentID string, updateFn func(*RecordingState)) error
UpdateRecordingStateForAgent updates recording state for a specific agent. Safe for concurrent use: only touches this agent's .recording.json.
func ValidateHistoryEntry ¶
func ValidateHistoryEntry(entry *HistoryEntry) error
ValidateHistoryEntry checks if a history entry is valid.
func ValidateHistoryMeta ¶
func ValidateHistoryMeta(meta *HistoryMeta) error
ValidateHistoryMeta checks that required fields are present in the metadata.
func VerifyRedactionSignature ¶
func VerifyRedactionSignature() *signing.VerificationResult
VerifyRedactionSignature checks that the redaction manifest hasn't been tampered with.
func WriteHistoryJSONL ¶
func WriteHistoryJSONL(path string, history *CapturedHistory) error
WriteHistoryJSONL writes captured history to a JSONL file. Writes the _meta line first, then each entry on its own line.
func WriteNeedsSummaryMarker ¶
WriteNeedsSummaryMarker writes a .needs-summary marker to the session cache directory. This marker indicates that session stop completed but summary.json was not yet generated.
Types ¶
type AhaMoment ¶
type AhaMoment struct {
Seq int `json:"seq"` // message sequence number for navigation
Role string `json:"role"` // user, assistant, or system
Type string `json:"type"` // question, insight, decision, breakthrough, synthesis
Highlight string `json:"highlight"` // the key text/quote from this moment
Why string `json:"why"` // brief explanation of why this was important
}
AhaMoment captures a pivotal point in the conversation where key insight emerged. These moments document collaborative intelligence - the interplay between human intuition/direction and AI exploration/synthesis.
type ArtifactPaths ¶ added in v0.5.0
type ArtifactPaths struct {
SummaryMD string // summary.md — structured markdown summary
SummaryJSON string // summary.json — machine-readable summary
HTML string // session.html — interactive HTML viewer
SessionMD string // session.md — full session transcript in markdown
}
ArtifactPaths holds the output paths for generated session artifacts.
func WriteSessionArtifacts ¶ added in v0.5.0
func WriteSessionArtifacts(sessionDir string, stored *StoredSession, summaryResp *SummarizeResponse, htmlGen HTMLGenerator) (*ArtifactPaths, error)
WriteSessionArtifacts generates the standard set of session artifacts from a stored session and summary response. Both the CLI stop path and daemon anti-entropy finalization call this to ensure identical output.
The summaryResp may come from LocalSummary (stats-only) or LLM (rich). Either way, the same 4 files are produced.
type CaptureOptions ¶
type CaptureOptions struct {
// AgentID is the current agent's ID (used if not in history metadata)
AgentID string
// Title is an optional title for the captured session
Title string
// MergeWithActive if true, merges with any active recording
MergeWithActive bool
// SkipRedaction if true, skips secret redaction (for testing only)
SkipRedaction bool
}
CaptureOptions configures the capture-prior operation.
type CaptureOutput ¶
type CaptureOutput struct {
Success bool `json:"success"`
Type string `json:"type"` // "session_capture_prior"
AgentID string `json:"agent_id"`
Path string `json:"path"`
SessionName string `json:"session_name,omitempty"`
EntryCount int `json:"entry_count"`
SecretsRedacted int `json:"secrets_redacted,omitempty"`
TimeRange *HistoryTimeRange `json:"time_range,omitempty"`
Title string `json:"title,omitempty"`
Message string `json:"message,omitempty"`
}
CaptureOutput is the JSON output format for capture-prior command.
func NewCaptureOutput ¶
func NewCaptureOutput(result *CaptureResult) *CaptureOutput
NewCaptureOutput creates a CaptureOutput from a CaptureResult.
func (*CaptureOutput) ToJSON ¶
func (o *CaptureOutput) ToJSON() ([]byte, error)
ToJSON marshals the output to indented JSON.
type CaptureResult ¶
type CaptureResult struct {
// Path where the history was stored
Path string `json:"path"`
// SessionName is the generated session folder name
SessionName string `json:"session_name,omitempty"`
// EntryCount is the number of entries captured
EntryCount int `json:"entry_count"`
// SecretsRedacted is the count of secrets found and redacted
SecretsRedacted int `json:"secrets_redacted"`
// TimeRange contains the time span of the captured history
TimeRange *HistoryTimeRange `json:"time_range,omitempty"`
// Title is the session title from metadata
Title string `json:"title,omitempty"`
// AgentID from the captured metadata
AgentID string `json:"agent_id,omitempty"`
}
CaptureResult contains the outcome of a capture-prior operation.
func CapturePrior ¶
func CapturePrior(reader io.Reader, opts CaptureOptions) (*CaptureResult, error)
CapturePrior reads, validates, redacts, and stores captured history from JSONL input.
The input must be valid JSONL with:
- First line: {"_meta": {...}} with schema_version, source, agent_id
- Subsequent lines: entries with seq, type, content
Returns the capture result with the storage path and statistics.
func CapturePriorFromFile ¶
func CapturePriorFromFile(path string, opts CaptureOptions) (*CaptureResult, error)
CapturePriorFromFile reads captured history from a file.
type CaptureSubagentOptions ¶
type CaptureSubagentOptions struct {
// SessionPath is the parent session's folder path
SessionPath string
// SessionsBasePath is the base path where sessions are stored
SessionsBasePath string
// RecordingStartTime is when the parent recording started
RecordingStartTime time.Time
// RecordingEndTime is when the parent recording ended (optional, defaults to now)
RecordingEndTime time.Time
// TimeWindowBuffer is extra time to search for subagent sessions (default: 5 minutes)
TimeWindowBuffer time.Duration
}
CaptureSubagentOptions configures subagent session capture.
func GetSubagentCaptureOptions ¶
func GetSubagentCaptureOptions(state *RecordingState) CaptureSubagentOptions
GetSubagentCaptureOptions creates CaptureSubagentOptions from a RecordingState. This is a convenience function for the stop recording flow.
type CaptureSubagentResult ¶
type CaptureSubagentResult struct {
// TaskCallsFound is the number of Task tool calls detected
TaskCallsFound int
// SubagentsMatched is the number of subagents successfully matched
SubagentsMatched int
// EnrichedEntries contains entry indices that were enriched with subagent refs
EnrichedEntries []int
// UnmatchedTasks contains indices of Task calls that could not be matched
UnmatchedTasks []int
}
CaptureSubagentResult contains the results of subagent capture.
func CaptureSubagentSessions ¶
func CaptureSubagentSessions( entries []map[string]any, opts CaptureSubagentOptions, ) (*CaptureSubagentResult, error)
CaptureSubagentSessions is the main entry point for subagent capture. It detects Task tool calls in the given entries, finds matching subagent sessions, and enriches the entries with subagent references.
This should be called during the session stop flow, after reading entries but before writing the final session.
type CapturedHistory ¶
type CapturedHistory struct {
Meta *HistoryMeta
Entries []HistoryEntry
}
CapturedHistory holds the full parsed history.
func LoadHistoryFromSession ¶
func LoadHistoryFromSession(sessionPath string) (*CapturedHistory, error)
LoadHistoryFromSession loads captured history from a session folder. Looks for prior-history.jsonl in the session directory.
func ParseHistoryFile ¶
func ParseHistoryFile(path string) (*CapturedHistory, error)
ParseHistoryFile parses a JSONL history file from a file path.
func ValidateAndRedact ¶
func ValidateAndRedact(reader io.Reader) (*CapturedHistory, int, error)
ValidateAndRedact validates JSONL input and applies secret redaction. This combines validation and security processing in a single call.
Returns:
- Validated and redacted history
- Count of secrets redacted
- Error if validation fails
func ValidateCapturePriorInput ¶
func ValidateCapturePriorInput(reader io.Reader) (*CapturedHistory, error)
ValidateCapturePriorInput validates input specifically for capture-prior command. This adds additional validation beyond the schema:
- At least one entry required
- Updates time_range in metadata if not set
- Sets message_count in metadata
func ValidateHistoryJSONLReader ¶
func ValidateHistoryJSONLReader(reader io.Reader) (*CapturedHistory, error)
ValidateHistoryJSONLReader reads and validates a captured history JSONL stream.
func ValidateJSONL ¶
func ValidateJSONL(reader io.Reader) (*CapturedHistory, error)
ValidateJSONL validates JSONL input as a captured history. This is the primary entry point for validating agent-generated history.
Returns the parsed and validated history on success. Returns an error if:
- Input is nil or empty
- First line is not a valid _meta object
- _meta is missing required fields (schema_version, source, agent_id)
- Entry type is not one of: user, assistant, system, tool
- Entry seq numbers are not monotonically increasing
Example usage:
history, err := ValidateJSONL(reader)
if err != nil {
return fmt.Errorf("invalid history: %w", err)
}
func (*CapturedHistory) ComputeTimeRange ¶
func (h *CapturedHistory) ComputeTimeRange() *HistoryTimeRange
ComputeTimeRange returns the earliest and latest timestamps in the history.
func (*CapturedHistory) Duration ¶
func (h *CapturedHistory) Duration() time.Duration
Duration returns the duration of the captured history.
func (*CapturedHistory) EntryCount ¶
func (h *CapturedHistory) EntryCount() int
EntryCount returns the number of entries in the history.
func (*CapturedHistory) GetEntriesByType ¶
func (h *CapturedHistory) GetEntriesByType(entryType string) []HistoryEntry
GetEntriesByType returns all entries of a given type.
func (*CapturedHistory) GetPlanEntries ¶
func (h *CapturedHistory) GetPlanEntries() []HistoryEntry
GetPlanEntries returns all entries marked as plans.
func (*CapturedHistory) HasPlanningHistory ¶
func (h *CapturedHistory) HasPlanningHistory() bool
HasPlanningHistory returns true if any entries have planning_history source.
func (*CapturedHistory) PlanningHistoryCount ¶
func (h *CapturedHistory) PlanningHistoryCount() int
PlanningHistoryCount returns the number of entries with planning_history source.
func (*CapturedHistory) ToSessionEntries ¶
func (h *CapturedHistory) ToSessionEntries() []SessionEntry
ToSessionEntries converts all history entries to session entries.
type ChapterSummary ¶ added in v0.3.0
type ChapterSummary struct {
ID int `json:"id"` // 1-based chapter number
Title string `json:"title"` // LLM or heuristic title
StartSeq int `json:"start_seq"` // first message seq in this chapter
EndSeq int `json:"end_seq"` // last message seq in this chapter
ToolCounts map[string]int `json:"tool_counts,omitempty"` // aggregated tool usage {"Read": 5, "Edit": 3}
TotalTools int `json:"total_tools"` // total tool calls in chapter
HasEdits bool `json:"has_edits"` // true if chapter contains file modifications
}
ChapterSummary is a structured chapter for summary.json. Computed from the raw JSONL by the grouping algorithm, enriched with LLM-generated titles when available. Any tool can consume these without re-implementing the grouping logic.
type DelegationHint ¶
type DelegationHint struct {
Recommended bool `json:"recommended"`
SubagentType string `json:"subagent_type,omitempty"`
ModelTier string `json:"model_tier,omitempty"` // "fast" (haiku), "balanced" (sonnet), "reasoning" (opus)
RunInBackground bool `json:"run_in_background"`
Reason string `json:"reason"`
Command string `json:"cmd,omitempty"` // actionable command for agent to run
}
DelegationHint suggests how to delegate work to preserve context.
type Entry ¶
type Entry = SessionEntry
Entry is an alias for SessionEntry for backward compatibility and convenience.
func ConvertRawEntries ¶ added in v0.5.0
ConvertRawEntries converts adapter raw entries to session entries.
func FilterForSummarization ¶ added in v0.2.0
FilterForSummarization removes low-value tool entries from session data before sending to the LLM summarizer. Keeps raw.jsonl complete for auditability while reducing noise in the summarization input.
Filtered out (when successful):
- Read-only tools: Read, Glob, Grep, WebFetch, WebSearch
- Bash commands that are noise: ls, pwd, cat, head, tail, etc.
Always kept:
- All user and assistant messages (the human-AI dialog)
- System messages
- Write/Edit tool calls (actual changes)
- Failed tool calls (important for understanding debugging)
- Bash commands that modify state
type EntryType ¶
type EntryType = SessionEntryType
EntryType is an alias for SessionEntryType for backward compatibility.
func MapRoleToEntryType ¶ added in v0.5.0
MapRoleToEntryType converts an adapter role string to a session EntryType.
type FileModification ¶
type FileModification struct {
Path string // file path (relative or absolute)
Action string // Created, Modified, Deleted
}
FileModification represents a file change detected in the session.
type FileSummary ¶ added in v0.3.0
type FileSummary struct {
Path string `json:"path"` // shortened file path
Added int `json:"added"` // lines added
Removed int `json:"removed,omitempty"` // lines removed
}
FileSummary records a file modified during the session. Extracted from Edit/Write tool calls in the raw JSONL.
type GhostCleanupResult ¶ added in v0.5.0
type GhostCleanupResult struct {
Removed int // number of ghost sessions removed
Names []string // session folder names that were removed
}
GhostCleanupResult reports what was cleaned up.
func CleanupGhostSessions ¶ added in v0.5.0
func CleanupGhostSessions(projectRoot string) GhostCleanupResult
CleanupGhostSessions removes abandoned recording stubs where the parent process is dead and no meaningful data was captured. Uses PID liveness for instant detection — no time threshold needed.
Ghost = .recording.json exists + parent PID dead + no substantive raw.jsonl. Sessions with real data (raw.jsonl with entries) are NOT removed — those are orphans that need recovery, not cleanup.
Safe to call from daemon anti-entropy, doctor --fix, or session start. Uses projectRoot to find session directories via sessionsSearchPaths.
func CleanupGhostSessionsInDir ¶ added in v0.5.0
func CleanupGhostSessionsInDir(sessionsDir string) GhostCleanupResult
CleanupGhostSessionsInDir removes ghost sessions from a specific sessions directory. Used by the daemon which has a ledgerPath rather than a projectRoot.
type GuidanceOutput ¶
type GuidanceOutput struct {
Success bool `json:"success"`
Type string `json:"type"` // always "session_guidance"
Phase GuidancePhase `json:"phase"`
AgentID string `json:"agent_id"`
Guidance SessionGuidance `json:"guidance"`
Message string `json:"message,omitempty"`
}
GuidanceOutput is the JSON output format for session guidance.
type GuidancePhase ¶
type GuidancePhase string
GuidancePhase represents when guidance is being emitted.
const ( GuidancePhaseStart GuidancePhase = "start" GuidancePhaseStop GuidancePhase = "stop" GuidancePhaseRemind GuidancePhase = "remind" )
type HTMLGenerator ¶ added in v0.5.0
type HTMLGenerator interface {
GenerateToFile(stored *StoredSession, outputPath string) error
GenerateToFileWithSummary(stored *StoredSession, summary *SummarizeResponse, outputPath string) error
}
HTMLGenerator abstracts HTML generation to avoid import cycles (internal/session cannot import internal/session/html).
type HTMLGuidance ¶
type HTMLGuidance struct {
Instructions []string `json:"instructions"`
OutputPath string `json:"output_path"`
SourcePath string `json:"source_path"`
Features []string `json:"features"`
DelegationHint *DelegationHint `json:"delegation_hint,omitempty"`
}
HTMLGuidance contains instructions for generating HTML session viewer.
func GetHTMLGuidance ¶
func GetHTMLGuidance(agentID, rawPath, outputPath string) HTMLGuidance
GetHTMLGuidance returns detailed guidance for generating HTML session viewer.
type HTMLGuidanceOutput ¶
type HTMLGuidanceOutput struct {
Success bool `json:"success"`
Type string `json:"type"` // always "session_html_guidance"
AgentID string `json:"agent_id"`
Guidance HTMLGuidance `json:"guidance"`
Generated bool `json:"generated"`
HTMLPath string `json:"html_path,omitempty"`
Message string `json:"message,omitempty"`
}
HTMLGuidanceOutput is the JSON output format for HTML generation guidance.
type HealthStatus ¶
type HealthStatus struct {
// StorageWritable indicates if local storage is writable
StorageWritable bool
// StoragePath is the path to local session storage
StoragePath string
// StorageError contains error details if storage is not writable
StorageError string
// RepoCloned indicates if the ledger is cloned
RepoCloned bool
// RepoPath is the path to the ledger
RepoPath string
// RepoError contains error details if ledger has issues
RepoError string
// IsRecordingActive indicates if a recording is currently in progress
IsRecordingActive bool
// Recording contains the current recording state (if active)
Recording *RecordingState
// IsStaleRecording indicates the active recording may be abandoned
// (running for more than StaleRecordingThreshold)
IsStaleRecording bool
// StaleRecordingAge is how long the stale recording has been running
StaleRecordingAge time.Duration
// AllRecordings contains all active recording states found
AllRecordings []*RecordingState
// StaleRecordings contains recordings older than StaleRecordingThreshold
StaleRecordings []*RecordingState
// EmptyStaleCount is the number of stale recordings with no raw.jsonl (empty stubs)
EmptyStaleCount int
// ContentStaleCount is the number of stale recordings that have raw.jsonl content
ContentStaleCount int
// IsStopIncomplete indicates the recording was stopped but the session file was empty
IsStopIncomplete bool
// StopIncompleteAge is how long since the incomplete stop occurred
StopIncompleteAge time.Duration
// PendingCount is the number of sessions pending commit
PendingCount int
// SyncedWithRemote indicates if local repo is synced with remote
SyncedWithRemote bool
// SyncStatus describes the sync state (e.g., "ahead by 3", "behind by 1")
SyncStatus string
// Errors contains any errors encountered during health checks
Errors []string
}
HealthStatus contains session system health information.
func CheckHealth ¶
func CheckHealth(projectRoot string) *HealthStatus
CheckHealth performs a comprehensive health check of the session system. projectRoot is the current project's git root directory. If provided, ledger path is derived from it; if empty, ledger.DefaultPath() is used (cwd-based).
type HistoryEntry ¶
type HistoryEntry struct {
// Seq is the sequence number (monotonically increasing)
Seq int `json:"seq"`
// Type identifies the entry type (user, assistant, system, tool)
Type string `json:"type"`
// Content is the message or response content
Content string `json:"content"`
// Timestamp is when this entry occurred (if known)
Timestamp time.Time `json:"ts,omitempty"`
// Source identifies the origin of this entry
Source string `json:"source,omitempty"` // "planning_history"
// ToolName is the name of the tool called (for tool entries)
ToolName string `json:"tool_name,omitempty"`
// ToolInput is the input passed to the tool (for tool entries)
ToolInput string `json:"tool_input,omitempty"`
// ToolOutput is the output from the tool (for tool entries)
ToolOutput string `json:"tool_output,omitempty"`
// Summary is a brief summary of this entry (optional)
Summary string `json:"summary,omitempty"`
// IsPlan indicates this entry contains a plan or decision
IsPlan bool `json:"is_plan,omitempty"`
}
HistoryEntry is a single entry in captured history.
func HistoryEntryFromSessionEntry ¶
func HistoryEntryFromSessionEntry(e SessionEntry, seq int, source string) HistoryEntry
HistoryEntryFromSessionEntry creates a HistoryEntry from a SessionEntry.
func NewHistoryEntry ¶
func NewHistoryEntry(seq int, entryType, content string) *HistoryEntry
NewHistoryEntry creates a new history entry.
func (*HistoryEntry) ToSessionEntry ¶
func (e *HistoryEntry) ToSessionEntry() SessionEntry
ToSessionEntry converts a HistoryEntry to a SessionEntry.
type HistoryMeta ¶
type HistoryMeta struct {
// SchemaVersion identifies the history format version
SchemaVersion string `json:"schema_version"`
// CapturedAt is when this history was captured
CapturedAt time.Time `json:"captured_at"`
// StartedAt is when the original conversation began (if known)
StartedAt time.Time `json:"started_at,omitempty"`
// Source identifies how this history was generated
Source string `json:"source"` // "agent_reconstruction"
// AgentID is the short agent ID (e.g., "Oxa7b3")
AgentID string `json:"agent_id"`
// SessionID is an alias for AgentID for compatibility
SessionID string `json:"session_id,omitempty"`
// AgentType identifies the AI agent (e.g., "claude-code", "cursor")
AgentType string `json:"agent_type,omitempty"`
// SessionTitle is a human-readable title for this session
SessionTitle string `json:"session_title,omitempty"`
// Username is the authenticated user who created this session
Username string `json:"username,omitempty"`
// MessageCount is the total number of entries captured
MessageCount int `json:"message_count,omitempty"`
// TimeRange is the time span of captured history
TimeRange *HistoryTimeRange `json:"time_range,omitempty"`
}
HistoryMeta is the metadata header for captured history. This is the first line of a captured history JSONL file.
func CreateCapturedHistoryMeta ¶
func CreateCapturedHistoryMeta(agentID, agentType, source, title string) *HistoryMeta
CreateCapturedHistoryMeta creates metadata for captured history with given parameters.
func NewHistoryMeta ¶
func NewHistoryMeta(agentID, source string) *HistoryMeta
NewHistoryMeta creates metadata for captured history.
type HistoryTimeRange ¶
type HistoryTimeRange struct {
Earliest time.Time `json:"earliest"`
Latest time.Time `json:"latest"`
}
HistoryTimeRange represents the time span of captured history.
type HistoryValidationResult ¶
type HistoryValidationResult struct {
Valid bool `json:"valid"`
Errors []string `json:"errors,omitempty"`
EntryCount int `json:"entry_count"`
HasMeta bool `json:"has_meta"`
}
HistoryValidationResult contains the result of validating a history file.
func ValidateHistory ¶
func ValidateHistory(h *CapturedHistory) *HistoryValidationResult
ValidateHistory validates a CapturedHistory and returns detailed results.
func ValidateHistoryFile ¶
func ValidateHistoryFile(path string) (*HistoryValidationResult, error)
ValidateHistoryFile parses and validates a history file.
func ValidateHistoryJSONL ¶
func ValidateHistoryJSONL(jsonl string) (*HistoryValidationResult, error)
ValidateHistoryJSONL validates a JSONL string as a history.
type MarkdownGenerator ¶
type MarkdownGenerator struct {
// contains filtered or unexported fields
}
MarkdownGenerator creates markdown sessions from stored sessions.
func NewMarkdownGenerator ¶
func NewMarkdownGenerator() *MarkdownGenerator
NewMarkdownGenerator creates a new markdown generator.
func (*MarkdownGenerator) Generate ¶
func (g *MarkdownGenerator) Generate(t *StoredSession) ([]byte, error)
Generate creates markdown bytes from a StoredSession.
func (*MarkdownGenerator) GenerateToFile ¶
func (g *MarkdownGenerator) GenerateToFile(t *StoredSession, outputPath string) error
GenerateToFile writes the markdown session to a file. TODO(server-side): move to server-side for MVP+1; client should not write to ledger directly.
type MemoryStorage ¶
type MemoryStorage struct {
// contains filtered or unexported fields
}
MemoryStorage provides an in-memory implementation of Storage for testing. All data is stored in memory and lost when the instance is destroyed.
func NewMemoryStorage ¶
func NewMemoryStorage() *MemoryStorage
NewMemoryStorage creates a new in-memory storage for testing.
func (*MemoryStorage) Clear ¶
func (m *MemoryStorage) Clear()
Clear removes all sessions from memory (useful for test cleanup).
func (*MemoryStorage) Count ¶
func (m *MemoryStorage) Count() int
Count returns the number of sessions in memory.
func (*MemoryStorage) Delete ¶
func (m *MemoryStorage) Delete(filename string) error
Delete implements Storage.Delete for in-memory storage.
func (*MemoryStorage) Exists ¶
func (m *MemoryStorage) Exists(filename string) bool
Exists implements Storage.Exists for in-memory storage.
func (*MemoryStorage) GetLatest ¶
func (m *MemoryStorage) GetLatest() (*SessionInfo, error)
GetLatest implements Storage.GetLatest for in-memory storage.
func (*MemoryStorage) List ¶
func (m *MemoryStorage) List() ([]SessionInfo, error)
List implements Storage.List for in-memory storage.
func (*MemoryStorage) Load ¶
func (m *MemoryStorage) Load(filename string) (*StoredSession, error)
Load implements Storage.Load for in-memory storage.
type NeedsSummaryInfo ¶
type NeedsSummaryInfo struct {
CacheDir string `json:"cache_dir"`
RawPath string `json:"raw_path"`
LedgerSessionDir string `json:"ledger_session_dir"`
}
NeedsSummaryInfo describes a session that needs summary generation.
func FindSessionsNeedingSummary ¶
func FindSessionsNeedingSummary(contextPath string) ([]NeedsSummaryInfo, error)
FindSessionsNeedingSummary scans the sessions directory under contextPath for cache session directories containing a .needs-summary marker.
type ParsedRedactFile ¶ added in v0.3.0
type ParsedRedactFile struct {
Path string
Source RedactRuleSource
Rules []RedactRule
Errors []RedactParseError
}
ParsedRedactFile holds all rules from a single REDACT.md file.
func ParseRedactFile ¶ added in v0.3.0
func ParseRedactFile(path string, source RedactRuleSource) (*ParsedRedactFile, error)
ParseRedactFile reads and parses a REDACT.md file. Returns nil, nil if the file does not exist. The parser is lenient: it collects errors per-line and continues parsing.
type PatternManifestEntry ¶
type PatternManifestEntry struct {
Name string `json:"name"`
Regex string `json:"regex"`
Redact string `json:"redact"`
}
PatternManifestEntry represents a single pattern in the manifest. This is the canonical, signable representation of a SecretPattern.
type PlanEntry ¶
type PlanEntry struct {
// Entry is the original session entry
Entry SessionEntry
// Marker indicates which plan marker was detected
Marker PlanMarker
// IsPlanFlag indicates whether the entry had is_plan:true metadata
IsPlanFlag bool
}
PlanEntry represents an entry that contains plan content.
func ExtractPlan ¶
func ExtractPlan(entries []SessionEntry) *PlanEntry
ExtractPlan finds the plan from a slice of session entries. Priority order:
- Entry with is_plan:true metadata (highest priority)
- Entry with "## Final Plan" header
- Entry with "## Implementation Plan" header
- Entry with "## Plan" header
- Last assistant message (fallback)
If multiple entries match the same marker type, the last one is returned. Returns nil if entries is empty or no suitable content is found.
type PlanMarker ¶
type PlanMarker string
PlanMarker represents a type of plan marker found in content.
const ( // PlanMarkerNone indicates no plan markers were found PlanMarkerNone PlanMarker = "" // PlanMarkerPlan indicates a "## Plan" header was found PlanMarkerPlan PlanMarker = "plan" // PlanMarkerImplementationPlan indicates a "## Implementation Plan" header was found PlanMarkerImplementationPlan PlanMarker = "implementation_plan" // PlanMarkerFinalPlan indicates a "## Final Plan" header was found PlanMarkerFinalPlan PlanMarker = "final_plan" // PlanMarkerIsPlan indicates the entry has is_plan:true metadata PlanMarkerIsPlan PlanMarker = "is_plan" )
func DetectPlanMarkers ¶
func DetectPlanMarkers(content string) PlanMarker
DetectPlanMarkers scans content for plan header markers. Returns the marker type found, or PlanMarkerNone if no markers detected. Checks line by line to find headers at the start of lines.
type QualityDisposition ¶ added in v0.5.0
type QualityDisposition string
QualityDisposition is the action to take based on a session's quality score.
const ( // QualityUpload means the session should be pushed to the team ledger. QualityUpload QualityDisposition = "upload" // QualityLocalOnly means artifacts are kept locally but not pushed. QualityLocalOnly QualityDisposition = "local_only" // QualityDiscard means the session should be deleted entirely. QualityDiscard QualityDisposition = "discard" )
func EvaluateQuality ¶ added in v0.5.0
func EvaluateQuality(score, uploadThreshold, discardThreshold float64) QualityDisposition
EvaluateQuality determines what to do with a session based on its quality score. A score of 0 means the LLM didn't provide one — default to upload (backward compat).
type RecordingState ¶
type RecordingState struct {
AgentID string `json:"agent_id"`
StartedAt time.Time `json:"started_at"`
AdapterName string `json:"adapter_name"`
SessionFile string `json:"session_file"` // source file from adapter (Claude Code JSONL)
OutputFile string `json:"output_file"` // output file being recorded
SessionPath string `json:"session_path"` // path to session folder
Title string `json:"title,omitempty"`
EntryCount int `json:"entry_count"`
LastReminderSeq int `json:"last_reminder_seq"`
ReminderInterval int `json:"reminder_interval"`
FilterMode string `json:"filter_mode,omitempty"` // "infra" or "all" - controls event filtering
WorkspacePath string `json:"workspace_path,omitempty"` // git root / project directory
Branch string `json:"branch,omitempty"` // git branch at recording start
// Parent-child session tracking for subagent workflows
// When a parent spawns subagents, each subagent can report its session
// back to the parent session for aggregation.
ParentSessionPath string `json:"parent_session_path,omitempty"` // path to parent's session folder
ParentAgentID string `json:"parent_agent_id,omitempty"` // parent's agent ID (e.g., "Oxa7b3")
AgentType string `json:"agent_type,omitempty"` // original agent type for metadata: "codex", "amp", etc. Falls back to AdapterName if empty.
StopIncomplete bool `json:"stop_incomplete,omitempty"` // set when stop returned retry guidance (empty file)
Model string `json:"model,omitempty"` // LLM model for generic adapters where ReadMetadata returns nil
ParentPID int `json:"parent_pid,omitempty"` // parent agent process ID for liveness detection
SourceOffset int64 `json:"source_offset,omitempty"` // byte offset in source file for incremental reading
Origin string `json:"origin,omitempty"` // session origin: "human", "subagent", "agent" (from agentx.DetectOrigin)
}
RecordingState tracks an active recording session. Stored in sessions/<session-name>/.recording.json
func LoadAllRecordingStates ¶ added in v0.3.0
func LoadAllRecordingStates(projectRoot string) ([]*RecordingState, error)
LoadAllRecordingStates returns all active recording states by searching for .recording.json in session folders. Unlike LoadRecordingState which returns only the first match, this returns all concurrent recordings (e.g., from multiple worktrees or agents).
func LoadRecordingState ¶
func LoadRecordingState(projectRoot string) (*RecordingState, error)
LoadRecordingState loads active recording state by searching for .recording.json in session folders under the sessions directory. Returns nil, nil if no recording state exists.
func LoadRecordingStateForAgent ¶ added in v0.3.0
func LoadRecordingStateForAgent(projectRoot, agentID string) (*RecordingState, error)
LoadRecordingStateForAgent loads recording state for a specific agent. Returns nil, nil if no recording for that agent exists. Use this instead of LoadRecordingState when you have an agent ID to avoid accidentally operating on another concurrent agent's recording.
func StartRecording ¶
func StartRecording(projectRoot string, opts StartRecordingOptions) (*RecordingState, error)
StartRecording begins a new recording session. Returns ErrAlreadyRecording if a recording is already in progress.
func StopRecording ¶
func StopRecording(projectRoot, agentID string) (*RecordingState, error)
StopRecording ends an active recording session for a specific agent. Returns the final state and ErrNotRecording if no recording is active for this agent.
func (*RecordingState) Duration ¶
func (r *RecordingState) Duration() time.Duration
Duration returns how long the recording has been running.
func (*RecordingState) IsAgentAlive ¶ added in v0.5.0
func (r *RecordingState) IsAgentAlive() bool
IsAgentAlive checks if the recording agent's parent process is still running. Uses kill(pid, 0) for instant liveness detection. Returns true if no PID is recorded (assume alive for backward compat).
func (*RecordingState) IsSubagent ¶
func (r *RecordingState) IsSubagent() bool
IsSubagent returns true if this session was spawned by a parent agent. Checks both explicit parent tracking and environment-detected origin.
type RedactParseError ¶ added in v0.3.0
RedactParseError describes a parse error in a REDACT.md file.
func (RedactParseError) Error ¶ added in v0.3.0
func (e RedactParseError) Error() string
type RedactRule ¶ added in v0.3.0
type RedactRule struct {
Type string // "literal" or "regex"
RawPattern string // original text from the file
Replacement string // e.g. "[REDACTED_CODENAME]"
Source RedactRuleSource // team, repo, or user
SourcePath string // absolute path to the REDACT.md file
LineNumber int // line number in the source file
}
RedactRule is a single parsed rule from a REDACT.md file.
type RedactRuleSource ¶ added in v0.3.0
type RedactRuleSource string
RedactRuleSource identifies where a redaction rule originated.
const ( RuleSourceBuiltin RedactRuleSource = "builtin" RuleSourceTeam RedactRuleSource = "team" RuleSourceRepo RedactRuleSource = "repo" RuleSourceUser RedactRuleSource = "user" )
type RedactSourceInfo ¶ added in v0.3.0
type RedactSourceInfo struct {
Source RedactRuleSource
Path string // empty if file not found
Rules []RedactRule
Errors []RedactParseError
IOError error // non-nil if file could not be read (permission denied, etc.)
}
RedactSourceInfo describes a REDACT.md source with its resolved path and rules.
func DiscoverRedactSources ¶ added in v0.3.0
func DiscoverRedactSources(projectRoot string) []RedactSourceInfo
DiscoverRedactSources finds REDACT.md files at all levels and parses them. Returns source info for each level (even if the file doesn't exist, for reporting).
type RedactionManifest ¶
type RedactionManifest struct {
SchemaVersion string `json:"schema_version"`
Patterns []PatternManifestEntry `json:"patterns"`
}
RedactionManifest is the complete, signable manifest of all redaction patterns. The structure is designed for deterministic serialization.
func GenerateManifest ¶
func GenerateManifest() *RedactionManifest
GenerateManifest creates a deterministic manifest from the default patterns. Patterns are sorted by name for consistent ordering.
func (*RedactionManifest) CanonicalJSON ¶
func (m *RedactionManifest) CanonicalJSON() ([]byte, error)
CanonicalJSON returns the deterministic JSON encoding of the manifest. Uses sorted keys and no extra whitespace for consistent hashing.
func (*RedactionManifest) FindPattern ¶
func (m *RedactionManifest) FindPattern(name string) *PatternManifestEntry
FindPattern looks up a pattern by name.
func (*RedactionManifest) Hash ¶
func (m *RedactionManifest) Hash() ([]byte, error)
Hash returns the SHA-256 hash of the manifest's canonical JSON representation. This hash is what gets signed during release.
func (*RedactionManifest) HashHex ¶
func (m *RedactionManifest) HashHex() (string, error)
HashHex returns the hex-encoded SHA-256 hash of the manifest.
func (*RedactionManifest) PatternCount ¶
func (m *RedactionManifest) PatternCount() int
PatternCount returns the number of patterns in the manifest.
func (*RedactionManifest) PrettyJSON ¶
func (m *RedactionManifest) PrettyJSON() ([]byte, error)
PrettyJSON returns human-readable JSON for display purposes.
type RedactionResult ¶
type RedactionResult struct {
PatternName string // which pattern matched
Original string // the original matched text (for logging, be careful with this)
Position int // position in the string where match was found
}
RedactionResult contains details about a redaction
type Redactor ¶
type Redactor struct {
// contains filtered or unexported fields
}
Redactor handles secret detection and redaction
func NewRedactor ¶
func NewRedactor() *Redactor
NewRedactor creates a new Redactor with default patterns
func NewRedactorWithPatterns ¶
func NewRedactorWithPatterns(patterns []SecretPattern) *Redactor
NewRedactorWithPatterns creates a Redactor with custom patterns
func (*Redactor) AddPattern ¶
func (r *Redactor) AddPattern(pattern SecretPattern)
AddPattern adds an additional pattern to the redactor
func (*Redactor) ContainsSecrets ¶
ContainsSecrets checks if a string contains any secrets without modifying it
func (*Redactor) RedactCapturedHistory ¶
func (r *Redactor) RedactCapturedHistory(history *CapturedHistory) (count int)
RedactCapturedHistory applies secret redaction to all entries in captured history. Returns the count of entries that contained secrets.
func (*Redactor) RedactEntries ¶
RedactEntries redacts all entries in a slice. Returns the count of entries that contained secrets (in any field).
func (*Redactor) RedactEntry ¶
RedactEntry redacts secrets from an Entry's content. Returns true if any secrets were found and redacted.
func (*Redactor) RedactHistoryEntries ¶
func (r *Redactor) RedactHistoryEntries(entries []HistoryEntry) (count int)
RedactHistoryEntries redacts secrets from HistoryEntry slices. Returns the count of entries that contained secrets (in any field).
func (*Redactor) RedactMap ¶
RedactMap redacts secrets from string values in a map. Useful for redacting raw JSON entries before storage. Returns true if any secrets were found and redacted.
func (*Redactor) RedactSlice ¶
RedactSlice redacts secrets from string values in a slice. Returns true if any secrets were found and redacted.
func (*Redactor) RedactString ¶
RedactString scans and redacts secrets from a string. Returns the redacted output and a list of pattern names that matched.
func (*Redactor) RedactStringWithDetails ¶
func (r *Redactor) RedactStringWithDetails(input string) (output string, results []RedactionResult)
RedactStringWithDetails provides detailed redaction results
func (*Redactor) RedactWithAllowlist ¶
func (r *Redactor) RedactWithAllowlist(input string, allowlist []string) (output string, found []string)
RedactWithAllowlist redacts secrets but preserves strings in the allowlist. Useful for known-safe patterns that might trigger false positives.
func (*Redactor) ScanForSecrets ¶
ScanForSecrets returns pattern names of all secrets found without redacting
type SageoxInsight ¶
type SageoxInsight struct {
Seq int `json:"seq"` // message sequence number for navigation
Topic string `json:"topic"` // domain/topic area (e.g., "react-patterns", "api-design")
Insight string `json:"insight"` // what guidance was applied
Impact string `json:"impact"` // the outcome or value it provided
}
SageoxInsight captures moments where SageOx guidance provided unique value. These are explicitly attributed in the conversation using phrases like "Based on SageOx guidance..." and document the product's contribution.
type SecretPattern ¶
type SecretPattern struct {
Name string // identifier for the pattern
Pattern *regexp.Regexp // compiled regex
Redact string // replacement text, e.g., "[REDACTED_AWS_KEY]"
Source RedactRuleSource // origin: builtin, team, repo, or user (zero = builtin)
}
SecretPattern defines a pattern for detecting secrets
func DefaultPatterns ¶
func DefaultPatterns() []SecretPattern
DefaultPatterns returns built-in secret patterns covering common credential types. Patterns are ordered roughly by specificity (more specific patterns first).
type Session ¶
type Session struct {
// Meta is session context (first line in JSONL)
Meta *SessionMeta `json:"_meta"`
// Entries are conversation turns (stored as separate JSONL lines)
Entries []SessionEntry `json:"-"`
}
Session represents a complete recording session. The SessionMeta is stored as the first line of the JSONL file. Entries are stored as separate lines following the metadata.
func NewSession ¶
func NewSession(meta *SessionMeta) *Session
NewSession creates a new session with the given metadata.
func (*Session) AddAssistantEntry ¶
AddAssistantEntry appends an assistant entry to the session.
func (*Session) AddEntry ¶
func (s *Session) AddEntry(entry SessionEntry)
AddEntry appends an entry to the session.
func (*Session) AddSystemEntry ¶
AddSystemEntry appends a system entry to the session.
func (*Session) AddToolEntry ¶
AddToolEntry appends a tool entry to the session.
func (*Session) AddUserEntry ¶
AddUserEntry appends a user entry to the session.
func (*Session) Close ¶
func (s *Session) Close()
Close finalizes the session by closing the metadata.
func (*Session) EntryCount ¶
EntryCount returns the number of entries in the session.
func (*Session) Footer ¶
func (s *Session) Footer() *SessionFooter
Footer generates a footer for this session.
type SessionEntry ¶
type SessionEntry struct {
// Timestamp is when this entry was recorded
Timestamp time.Time `json:"ts"`
// Type identifies the entry type (user, assistant, system, tool)
Type SessionEntryType `json:"type"`
// Content is the message or response content
Content string `json:"content"`
// ToolName is the name of the tool called (for tool entries)
ToolName string `json:"tool_name,omitempty"`
// ToolInput is the input passed to the tool (for tool entries)
ToolInput string `json:"tool_input,omitempty"`
// ToolOutput is the output from the tool (for tool entries)
ToolOutput string `json:"tool_output,omitempty"`
// CoworkerName identifies the coworker or subagent that contributed to this entry.
// This includes both team coworkers (loaded via ox coworker load) and built-in
// Claude Code subagents (invoked via Task tool, e.g., code-reviewer, debugger).
CoworkerName string `json:"coworker_name,omitempty"`
// CoworkerModel is the model tier used by the coworker (e.g., sonnet, opus, haiku).
CoworkerModel string `json:"coworker_model,omitempty"`
}
SessionEntry represents a single conversation turn in the session.
func NewAssistantEntry ¶
func NewAssistantEntry(content string) SessionEntry
func NewAssistantSessionEntry ¶
func NewAssistantSessionEntry(content string) SessionEntry
NewAssistantSessionEntry creates an assistant entry.
func NewCoworkerLoadEntry ¶
func NewCoworkerLoadEntry(name, model string) SessionEntry
NewCoworkerLoadEntry creates a system entry for coworker/subagent load events. This enables metrics on which coworkers are being used in sessions.
func NewEntry ¶
func NewEntry(entryType SessionEntryType, content string) SessionEntry
Function aliases for backward compatibility
func NewSessionEntry ¶
func NewSessionEntry(entryType SessionEntryType, content string) SessionEntry
NewSessionEntry creates a new entry with the current timestamp.
func NewSystemEntry ¶
func NewSystemEntry(content string) SessionEntry
func NewSystemSessionEntry ¶
func NewSystemSessionEntry(content string) SessionEntry
NewSystemSessionEntry creates a system entry.
func NewToolEntry ¶
func NewToolEntry(toolName, toolInput, toolOutput string) SessionEntry
func NewToolSessionEntry ¶
func NewToolSessionEntry(toolName, toolInput, toolOutput string) SessionEntry
NewToolSessionEntry creates a new tool entry with the current timestamp.
func NewUserEntry ¶
func NewUserEntry(content string) SessionEntry
func NewUserSessionEntry ¶
func NewUserSessionEntry(content string) SessionEntry
NewUserSessionEntry creates a user entry.
type SessionEntryType ¶
type SessionEntryType string
SessionEntryType represents the type of conversation turn.
const ( // SessionEntryTypeUser is a user message or prompt SessionEntryTypeUser SessionEntryType = "user" // SessionEntryTypeAssistant is an assistant/AI response SessionEntryTypeAssistant SessionEntryType = "assistant" // SessionEntryTypeSystem is a system message (e.g., context injection) SessionEntryTypeSystem SessionEntryType = "system" // SessionEntryTypeTool is a tool call or result SessionEntryTypeTool SessionEntryType = "tool" )
func (SessionEntryType) IsValid ¶
func (e SessionEntryType) IsValid() bool
IsValid returns true if the entry type is recognized.
func (SessionEntryType) String ¶
func (e SessionEntryType) String() string
String returns the string representation of the entry type.
type SessionError ¶
type SessionError struct {
Code string `json:"code"` // machine-readable error code (e.g., NOT_RECORDING)
Message string `json:"msg"` // human-readable description
Retryable bool `json:"retry"` // whether the operation can be retried
Fix string `json:"fix,omitempty"` // suggested fix command
}
SessionError represents a structured error for JSON output. Provides machine-readable error information for coding agents.
func NewSessionError ¶
func NewSessionError(code, message string, retryable bool, fix string) *SessionError
NewSessionError creates a new SessionError.
func (*SessionError) Error ¶
func (e *SessionError) Error() string
Error implements the error interface.
type SessionFilterMode ¶
type SessionFilterMode string
SessionFilterMode represents the level of session recording. Values: "none", "all"
const ( SessionFilterModeNone SessionFilterMode = "none" // no automatic sessions SessionFilterModeAll SessionFilterMode = "all" // all coding agent sessions )
func (SessionFilterMode) IsValid ¶
func (m SessionFilterMode) IsValid() bool
IsValid returns true if the mode is a recognized value.
func (SessionFilterMode) ShouldRecord ¶
func (m SessionFilterMode) ShouldRecord() bool
ShouldRecord returns true if this mode enables any recording.
type SessionFooter ¶
type SessionFooter struct {
EndedAt time.Time `json:"ended_at"`
DurationMins int `json:"duration_minutes"`
EntryCount int `json:"entry_count"`
}
SessionFooter is the last line of each session JSONL (optional). It provides summary statistics for the recording session.
func NewSessionFooter ¶
func NewSessionFooter(startedAt time.Time, entryCount int) *SessionFooter
NewSessionFooter creates a footer with session statistics.
type SessionGuidance ¶
type SessionGuidance struct {
Include []string `json:"include"`
Exclude []string `json:"exclude"`
Tips []string `json:"tips,omitempty"`
ReminderInterval int `json:"reminder_interval,omitempty"`
// UserNotification is a message the agent should relay to the user.
// This is separate from agent instructions - it's for human awareness.
UserNotification string `json:"user_notification,omitempty"`
}
SessionGuidance contains structured guidance for session recording.
func RemindGuidance ¶
func RemindGuidance() SessionGuidance
RemindGuidance returns condensed guidance for periodic reminders.
func StartGuidance ¶
func StartGuidance() SessionGuidance
StartGuidance returns detailed guidance for beginning a session recording.
func StartGuidanceWithOptions ¶
func StartGuidanceWithOptions(opts StartGuidanceOptions) SessionGuidance
StartGuidanceWithOptions returns detailed guidance with configurable options.
func StopGuidance ¶
func StopGuidance() SessionGuidance
StopGuidance returns guidance for wrapping up a session recording.
type SessionInfo ¶
type SessionInfo struct {
SessionName string `json:"session_name,omitempty"` // session folder name (empty for legacy)
Filename string `json:"filename"` // file name only
FilePath string `json:"file_path"` // full path to file
Type string `json:"type"` // "raw" or "events"
Size int64 `json:"size"`
CreatedAt time.Time `json:"created_at"`
ModTime time.Time `json:"mod_time"`
HydrationStatus lfs.HydrationStatus `json:"hydration_status,omitempty"` // hydrated/dehydrated/partial
Username string `json:"username,omitempty"` // from meta.json
Summary string `json:"summary,omitempty"` // from meta.json
Recording bool `json:"recording,omitempty"` // true if session is actively being recorded
AgentID string `json:"agent_id,omitempty"` // from .recording.json when recording
EntryCount int `json:"entry_count,omitempty"` // from .recording.json or meta.json
IsSubagent bool `json:"is_subagent,omitempty"` // true if spawned by a parent session
ParentPID int `json:"parent_pid,omitempty"` // from .recording.json for liveness detection
Origin string `json:"origin,omitempty"` // session origin: "human", "subagent", "agent"
HasRawData bool `json:"has_raw_data,omitempty"` // true if raw.jsonl exists with content on disk
StopReason string `json:"stop_reason,omitempty"` // how session ended: "stopped", "aborted", "recovered"
}
SessionInfo contains metadata about a stored session.
type SessionMeta ¶
type SessionMeta struct {
// OxVersion is the version of ox that created this session
OxVersion string `json:"ox_version"`
// OxUsername is the authenticated SageOx username (if logged in)
OxUsername string `json:"ox_username,omitempty"`
// UserID is the unique user identifier from auth (if logged in)
UserID string `json:"user_id,omitempty"`
// SchemaVersion identifies the session format version
SchemaVersion string `json:"schema_version"`
// AgentType identifies the AI agent (e.g., "claude-code", "cursor", "copilot")
AgentType string `json:"agent_type"`
// AgentVersion is the version of the AI agent (if known)
AgentVersion string `json:"agent_version,omitempty"`
// Model is the LLM model used (e.g., "claude-sonnet-4-20250514")
Model string `json:"model,omitempty"`
// SessionID is the short agent ID (e.g., "Oxa7b3")
SessionID string `json:"session_id"`
// OxSID is the full session ID (e.g., "oxsid_01JEYQ9Z8X...")
OxSID string `json:"oxsid"`
// StartedAt is when the recording session began
StartedAt time.Time `json:"started_at"`
// EndedAt is when the recording session ended (set on close)
EndedAt time.Time `json:"ended_at,omitempty"`
// ProjectRemote is the git remote URL for provenance tracking
ProjectRemote string `json:"project_remote,omitempty"`
}
SessionMeta is the first line of each session JSONL file. It captures context about the recording session for provenance and replay.
func NewSessionMeta ¶
func NewSessionMeta(sessionID, oxsid, agentType, projectRemote, endpointURL string) *SessionMeta
NewSessionMeta creates metadata with current ox version and user. sessionID is the short agent ID (e.g., "Oxa7b3"). oxsid is the full session ID (e.g., "oxsid_01JEYQ9Z8X..."). agentType identifies the AI agent (e.g., "claude-code"). projectRemote is the git remote URL for provenance. endpointURL is the project endpoint for auth lookup (empty = default).
func NewSessionMetaWithVersion ¶
func NewSessionMetaWithVersion(sessionID, oxsid, agentType, agentVersion, projectRemote, endpointURL string) *SessionMeta
NewSessionMetaWithVersion creates metadata with a specific agent version.
func (*SessionMeta) Close ¶
func (m *SessionMeta) Close()
Close finalizes the metadata with end time.
func (*SessionMeta) Duration ¶
func (m *SessionMeta) Duration() time.Duration
Duration returns the session duration. Returns zero duration if EndedAt is not set.
type SessionStatus ¶ added in v0.5.0
type SessionStatus string
SessionStatus represents the lifecycle state of a session.
Lifecycle:
┌──────────┐
│ recording│
└────┬─────┘
┌──────────┼──────────┐
▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐
│ paused │ │ ghost │ │ orphan │
└───┬────┘ └───┬────┘ └───┬────┘
│ (cleanup) (finalize)
▼ │
┌────────┐ │
│ local │◄────────────────┘
└───┬────┘
▼
┌──────────┐
│ uploaded │
└──────────┘
┌──────────┐
│ canceled │ (terminal — data discarded)
└──────────┘
const ( StatusRecording SessionStatus = "recording" // actively being recorded, parent process alive StatusPaused SessionStatus = "paused" // user explicitly stopped recording (data preserved, not yet uploaded) StatusGhost SessionStatus = "ghost" // parent dead, no substantive data — safe to delete StatusOrphan SessionStatus = "orphan" // parent dead, has data — needs recovery/finalization StatusLocal SessionStatus = "local" // exists locally, not uploaded (may have been recovered from orphan) StatusUploaded SessionStatus = "uploaded" // committed to ledger StatusCanceled SessionStatus = "canceled" // user explicitly discarded session (terminal — data deleted) )
func ClassifySession ¶ added in v0.5.0
func ClassifySession(info SessionInfo, isUploaded bool) SessionStatus
ClassifySession determines the lifecycle status of a session based on its metadata and whether it exists in the ledger. This is the single source of truth for session status — all display and cleanup code should use this instead of inline logic.
type SessionWriter ¶
type SessionWriter struct {
// contains filtered or unexported fields
}
SessionWriter handles JSONL writing with proper header/footer semantics.
func (*SessionWriter) Close ¶
func (w *SessionWriter) Close() error
Close writes the footer and closes the file.
func (*SessionWriter) Count ¶
func (w *SessionWriter) Count() int
Count returns the number of entries written (excluding header/footer).
func (*SessionWriter) FilePath ¶
func (w *SessionWriter) FilePath() string
FilePath returns the path to the session file.
func (*SessionWriter) SessionName ¶
func (w *SessionWriter) SessionName() string
SessionName returns the session folder name (empty for legacy files).
func (*SessionWriter) WriteEntry ¶
func (w *SessionWriter) WriteEntry(entry Writable) error
WriteEntry writes a single entry to the session.
func (*SessionWriter) WriteHeader ¶
func (w *SessionWriter) WriteHeader(meta *StoreMeta) error
WriteHeader writes the session header with metadata. Should be called once at the start of recording.
type StartGuidanceOptions ¶
type StartGuidanceOptions struct {
AutoStarted bool // true if session was auto-started by ox agent prime
}
StartGuidanceOptions configures the guidance returned by StartGuidance.
type StartRecordingOptions ¶
type StartRecordingOptions struct {
AgentID string
AdapterName string
SessionFile string // source file from adapter (Claude Code JSONL)
OutputFile string // output file being recorded
Title string
Username string // username for session folder name
RepoContextPath string // path to repo context directory (for storing sessions)
ReminderInterval int // defaults to DefaultReminderInterval if 0
FilterMode string // "infra" or "all" - controls event filtering on stop
WorkspacePath string // git root / project directory
Branch string // git branch at recording start
// Parent session tracking for subagent workflows
ParentSessionPath string // path to parent's session folder (optional)
ParentAgentID string // parent's agent ID (optional)
AgentType string // original agent type for metadata (e.g., "codex", "amp")
Model string // LLM model for generic adapters
ParentPID int // parent agent process ID for liveness detection
Origin string // session origin: "human", "subagent", "agent" (from agentx.DetectOrigin)
}
StartRecordingOptions contains options for starting a recording.
type Storage ¶
type Storage interface {
// Save writes a complete session with metadata and entries.
// The filename should include the .jsonl extension.
// The sessionType should be "raw" or "events".
Save(filename, sessionType string, meta *StoreMeta, entries []map[string]any) error
// Load reads a session by filename.
// Searches both raw and events directories for file-based storage.
Load(filename string) (*StoredSession, error)
// List returns all session infos, sorted by date descending.
List() ([]SessionInfo, error)
// Delete removes a session by filename.
Delete(filename string) error
// Exists checks if a session with the given filename exists.
Exists(filename string) bool
// GetLatest returns the most recent session info.
GetLatest() (*SessionInfo, error)
}
Storage defines the interface for session persistence. Implementations include FileStorage (default), MemoryStorage (testing), and future CloudStorage (SageOx API sync).
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store manages session storage in the ledger. Path structure: {project}_sageox_ledger/sessions/ Uses session-folder structure for organized storage of multiple output formats.
func NewStore ¶
NewStore creates a store for the given ledger path. The repoContextPath should be the full path to the ledger directory (e.g., {project}_sageox_ledger/).
func (*Store) CheckNeedsDownload ¶
CheckNeedsDownload returns the session name if the session exists as a stub (meta.json present but content files not hydrated). Returns empty string if the session doesn't exist or is already hydrated.
func (*Store) CreateRaw ¶
func (s *Store) CreateRaw(sessionName string) (*SessionWriter, error)
CreateRaw creates a new raw session file and returns a writer. Uses session-folder structure: <session>/raw.jsonl The sessionName should be generated using GenerateSessionName().
func (*Store) DeleteSession ¶
DeleteSession removes a session folder and all its contents.
func (*Store) GetLatest ¶
func (s *Store) GetLatest() (*SessionInfo, error)
GetLatest returns the most recent session info (from any type). Searches all sessions regardless of age.
func (*Store) GetLatestRaw ¶
func (s *Store) GetLatestRaw() (*SessionInfo, error)
GetLatestRaw returns the most recent raw session info. Searches all sessions regardless of age.
func (*Store) GetSessionPath ¶
GetSessionPath returns the full path to a session folder.
func (*Store) IsSessionHydrated ¶
IsSessionHydrated checks if content files exist locally for a session. Returns true if content files are present (authored locally or hydrated from LFS).
func (*Store) List ¶
func (s *Store) List() ([]SessionInfo, error)
List implements Storage.List for file-based storage.
func (*Store) ListAllSessions ¶
func (s *Store) ListAllSessions() ([]SessionInfo, error)
ListAllSessions returns all session files regardless of age. This may be slow with many sessions due to meta.json reads.
func (*Store) ListRawSessionsSince ¶
func (s *Store) ListRawSessionsSince(since time.Time) ([]SessionInfo, error)
ListRawSessionsSince returns only raw session files created after the given time.
func (*Store) ListSessionNames ¶
ListSessionNames returns unique session folder names, sorted by date descending.
func (*Store) ListSessions ¶
func (s *Store) ListSessions() ([]SessionInfo, error)
ListSessions returns session files from the last 7 days, sorted by date descending. Use ListSessionsSince for custom time windows or ListAllSessions for all sessions.
func (*Store) ListSessionsSince ¶
func (s *Store) ListSessionsSince(since time.Time) ([]SessionInfo, error)
ListSessionsSince returns session files created after the given time. Pass zero time to list all sessions.
func (*Store) Load ¶
func (s *Store) Load(filename string) (*StoredSession, error)
Load implements Storage.Load for file-based storage.
func (*Store) Prune ¶
Prune removes sessions older than the specified duration. Returns the number of sessions removed.
func (*Store) ReadLFSSessionMeta ¶
func (s *Store) ReadLFSSessionMeta(sessionName string) (*lfs.SessionMeta, error)
ReadLFSSessionMeta reads the LFS meta.json for a session. Returns nil if the session has no meta.json (legacy or pre-LFS session).
func (*Store) ReadRawSession ¶
func (s *Store) ReadRawSession(filename string) (*StoredSession, error)
ReadRawSession reads the raw session file from a session folder.
func (*Store) ReadSession ¶
func (s *Store) ReadSession(name string) (*StoredSession, error)
ReadSession reads a session by session name or filename.
func (*Store) ReadSessionRaw ¶
func (s *Store) ReadSessionRaw(sessionName string) (*StoredSession, error)
ReadSessionRaw reads the raw session from a session folder.
func (*Store) ResolveSessionName ¶
ResolveSessionName resolves a partial session name (e.g. agent ID suffix like "OxKMZN") to the full session directory name (e.g. "2026-01-28T18-56-ajit-sageox-ai-OxKMZN"). Returns the input unchanged if it already matches exactly or no match is found. Returns an error if multiple sessions match the suffix.
type StoreMeta ¶
type StoreMeta struct {
Version string `json:"version"`
CreatedAt time.Time `json:"created_at"`
AgentID string `json:"agent_id,omitempty"`
AgentType string `json:"agent_type,omitempty"`
AgentVersion string `json:"agent_version,omitempty"` // version of the coding agent (e.g., "1.0.3")
Model string `json:"model,omitempty"` // LLM model used (e.g., "claude-sonnet-4-20250514")
Username string `json:"username,omitempty"`
RepoID string `json:"repo_id,omitempty"`
OxVersion string `json:"ox_version,omitempty"` // version of ox that created this session
}
StoreMeta contains session storage metadata written to the header.
func ParseStoreMeta ¶
ParseStoreMeta converts a map to StoreMeta struct. Supports both standard format (version, agent_id, created_at) and alternative format (schema_version, session_id, started_at).
type StoredSession ¶
type StoredSession struct {
Info SessionInfo `json:"info"`
Meta *StoreMeta `json:"metadata,omitempty"`
Entries []map[string]any `json:"entries"`
}
StoredSession represents a read session with its entries. This is distinct from Session in secrets.go which is for redaction.
func ReadSessionFromPath ¶
func ReadSessionFromPath(filePath string) (*StoredSession, error)
ReadSessionFromPath reads and parses a JSONL session from an arbitrary file path. This is useful for generating HTML from sessions outside the managed store location.
type SubagentCompleteOptions ¶
type SubagentCompleteOptions struct {
// SubagentID is the completing subagent's agent ID
SubagentID string
// ParentSessionPath is the path to the parent's session folder
ParentSessionPath string
// SessionPath is the path to the subagent's session (optional)
SessionPath string
// SessionName is the subagent's session folder name (optional)
SessionName string
// Summary describes what the subagent accomplished (optional)
Summary string
// DurationMs is how long the subagent ran (optional)
DurationMs int64
// EntryCount is the number of session entries (optional)
EntryCount int
// Model is the LLM model used (optional)
Model string
// AgentType is the coding agent type (optional)
AgentType string
}
SubagentCompleteOptions configures subagent completion reporting.
type SubagentReference ¶
type SubagentReference struct {
// SessionID is the subagent's agent ID (e.g., "Oxa7b3")
SessionID string `json:"session_id"`
// SessionPath is the relative path to the subagent's session folder
// Example: "sessions/2026-01-06T14-35-history-Oxdef/"
SessionPath string `json:"session_path"`
// EntryCount is the number of entries in the subagent's session
EntryCount int `json:"entry_count"`
// DurationMs is how long the subagent ran in milliseconds (optional)
DurationMs int64 `json:"duration_ms,omitempty"`
// Summary is a brief description of what the subagent did (optional)
Summary string `json:"summary,omitempty"`
// Model is the LLM model the subagent used (optional)
Model string `json:"model,omitempty"`
// AgentType is the coding agent type (optional)
AgentType string `json:"agent_type,omitempty"`
}
SubagentReference represents metadata about a subagent session embedded in a Task tool entry. This is the structure that gets added to parent session entries.
type SubagentRegistry ¶
type SubagentRegistry struct {
// contains filtered or unexported fields
}
SubagentRegistry tracks subagent completions for a parent session. Thread-safe for concurrent subagent reporting.
func NewSubagentRegistry ¶
func NewSubagentRegistry(sessionPath string) (*SubagentRegistry, error)
NewSubagentRegistry creates a registry for tracking subagent sessions. The sessionPath should be the parent session folder path.
func (*SubagentRegistry) Count ¶
func (r *SubagentRegistry) Count() (int, error)
Count returns the number of registered subagent sessions.
func (*SubagentRegistry) List ¶
func (r *SubagentRegistry) List() ([]*SubagentSession, error)
List returns all registered subagent sessions.
func (*SubagentRegistry) Register ¶
func (r *SubagentRegistry) Register(session *SubagentSession) error
Register adds a completed subagent session to the registry. Thread-safe: multiple subagents can register concurrently.
type SubagentSession ¶
type SubagentSession struct {
// SubagentID is the subagent's agent ID (e.g., "Oxa7b3")
SubagentID string `json:"subagent_id"`
// ParentSessionID is the parent's session ID
ParentSessionID string `json:"parent_session_id"`
// SessionPath is the path to the subagent's raw session
SessionPath string `json:"session_path,omitempty"`
// SessionName is the subagent's session folder name
SessionName string `json:"session_name,omitempty"`
// CompletedAt is when the subagent finished
CompletedAt time.Time `json:"completed_at"`
// EntryCount is the number of entries in the subagent session
EntryCount int `json:"entry_count,omitempty"`
// Summary is a brief description of what the subagent did
Summary string `json:"summary,omitempty"`
// DurationMs is how long the subagent ran in milliseconds
DurationMs int64 `json:"duration_ms,omitempty"`
// Model is the LLM model the subagent used
Model string `json:"model,omitempty"`
// AgentType is the coding agent type (claude-code, cursor, etc.)
AgentType string `json:"agent_type,omitempty"`
}
SubagentSession represents a completed subagent's session reference. These are stored in the parent session folder and aggregated on stop.
func FindSubagentSessions ¶
func FindSubagentSessions(opts CaptureSubagentOptions) ([]*SubagentSession, error)
FindSubagentSessions searches for subagent sessions that match the given time window. It looks for sessions registered via the subagent registry and also scans for session folders that fall within the time window.
func GetSubagentSessions ¶
func GetSubagentSessions(sessionPath string) ([]*SubagentSession, error)
GetSubagentSessions returns all subagent sessions for a session. The sessionPath should be the parent session folder path.
type SubagentSummary ¶
type SubagentSummary struct {
// Count is the number of subagents that completed
Count int `json:"count"`
// TotalEntries is the sum of all subagent session entries
TotalEntries int `json:"total_entries"`
// TotalDurationMs is the sum of all subagent durations
TotalDurationMs int64 `json:"total_duration_ms"`
// Subagents is the list of subagent references
Subagents []*SubagentSession `json:"subagents,omitempty"`
}
SubagentSummary provides aggregated statistics about subagent work.
func SummarizeSubagents ¶
func SummarizeSubagents(sessions []*SubagentSession) *SubagentSummary
SummarizeSubagents creates an aggregated summary of subagent work.
type SummarizeEntry ¶
type SummarizeEntry struct {
Type string `json:"type"`
Content string `json:"content"`
ToolName string `json:"tool_name,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
SummarizeEntry is a simplified entry for summarization.
type SummarizeGuidance ¶
type SummarizeGuidance struct {
Instructions []string `json:"instructions"`
Format string `json:"format"`
SavePath string `json:"save_path"`
LedgerPath string `json:"ledger_path"`
DelegationHint *DelegationHint `json:"delegation_hint,omitempty"`
}
SummarizeGuidance contains instructions for the coding agent on how to create and save session summaries for context recovery.
func GetSummarizeGuidance ¶
func GetSummarizeGuidance(agentID, contextPath string) SummarizeGuidance
GetSummarizeGuidance returns detailed guidance for creating session summaries.
type SummarizeGuidanceOutput ¶
type SummarizeGuidanceOutput struct {
Success bool `json:"success"`
Type string `json:"type"` // always "session_summarize_guidance"
AgentID string `json:"agent_id"`
Guidance SummarizeGuidance `json:"guidance"`
Summary *SummarizeOutput `json:"summary,omitempty"`
}
SummarizeGuidanceOutput is the JSON output format for summarize guidance.
type SummarizeOutput ¶
type SummarizeOutput struct {
Success bool `json:"success"`
Type string `json:"type"` // always "session_summary"
AgentID string `json:"agent_id"`
Summary string `json:"summary"`
KeyActions []string `json:"key_actions,omitempty"`
Outcome string `json:"outcome,omitempty"`
TopicsFound []string `json:"topics_found,omitempty"`
FinalPlan string `json:"final_plan,omitempty"` // final plan/architecture from session
Diagrams []string `json:"diagrams,omitempty"` // extracted mermaid diagrams
EntryCount int `json:"entry_count,omitempty"`
FilePath string `json:"file_path,omitempty"`
Message string `json:"message,omitempty"`
SummaryPrompt string `json:"summary_prompt,omitempty"` // prompt for calling agent to generate summary
}
SummarizeOutput is the JSON output format for session summarization.
type SummarizeRequest ¶
type SummarizeRequest struct {
AgentID string `json:"agent_id"`
AgentType string `json:"agent_type"`
Model string `json:"model,omitempty"`
Entries []SummarizeEntry `json:"entries"`
}
SummarizeRequest contains the session data to summarize.
type SummarizeResponse ¶
type SummarizeResponse struct {
Title string `json:"title"` // short descriptive title for the session
Summary string `json:"summary"` // one paragraph executive summary
KeyActions []string `json:"key_actions"` // bullet points of key actions taken
Outcome string `json:"outcome"` // success/partial/failed
TopicsFound []string `json:"topics_found"` // topics detected during session
FinalPlan string `json:"final_plan,omitempty"` // final plan/architecture from session
Diagrams []string `json:"diagrams,omitempty"` // extracted mermaid diagrams
ChapterTitles []string `json:"chapter_titles,omitempty"` // LLM-generated narrative chapter titles
Chapters []ChapterSummary `json:"chapters,omitempty"` // structured chapter data (computed from JSONL)
FilesChanged []FileSummary `json:"files_changed,omitempty"` // files modified during session (computed from JSONL)
AhaMoments []AhaMoment `json:"aha_moments,omitempty"` // pivotal moments of collaborative intelligence
SageoxInsights []SageoxInsight `json:"sageox_insights,omitempty"` // moments where SageOx guidance provided value
QualityScore float64 `json:"quality_score"` // 0.0-1.0 session value for team sharing
ScoreReason string `json:"score_reason,omitempty"` // brief explanation of the quality score
}
SummarizeResponse contains the LLM-generated summary plus computed metadata. The LLM produces: title, summary, key_actions, outcome, topics_found, chapter_titles, aha_moments, sageox_insights. The CLI computes and appends: chapters, files_changed.
func Summarize ¶
func Summarize(entries []Entry, agentID, agentType, model, endpointURL string) (*SummarizeResponse, error)
Summarize calls the SageOx API to generate an LLM summary of a session. If endpointURL is non-empty, uses that endpoint for auth and API calls; otherwise falls back to the default endpoint. Returns nil if summarization fails (non-critical feature).
type SummaryMarkdownGenerator ¶
type SummaryMarkdownGenerator struct{}
SummaryMarkdownGenerator generates markdown summaries from session data.
func NewSummaryMarkdownGenerator ¶
func NewSummaryMarkdownGenerator() *SummaryMarkdownGenerator
NewSummaryMarkdownGenerator creates a new markdown generator.
func (*SummaryMarkdownGenerator) Generate ¶
func (g *SummaryMarkdownGenerator) Generate(meta *StoreMeta, summary *SummaryView, entries []map[string]any) ([]byte, error)
Generate creates a summary markdown from metadata and summary view. The entries parameter is used to extract file modifications and diagrams.
type SummaryView ¶
type SummaryView struct {
Text string // one paragraph executive summary
KeyActions []string // bullet points of key actions taken
Outcome string // success/partial/failed
TopicsFound []string // topics detected during session
FinalPlan string // final plan/architecture from session
Diagrams []string // extracted mermaid diagrams
}
SummaryView contains the LLM-generated summary content.
func SummarizeResponseToSummaryView ¶ added in v0.5.0
func SummarizeResponseToSummaryView(resp *SummarizeResponse) *SummaryView
SummarizeResponseToSummaryView converts a SummarizeResponse to the SummaryView used by the markdown generator.
type TaskInput ¶
type TaskInput struct {
// Description is the task description/prompt
Description string `json:"description,omitempty"`
// Prompt is an alternative field name for description
Prompt string `json:"prompt,omitempty"`
// AgentType hints at what kind of subagent to spawn
AgentType string `json:"agent_type,omitempty"`
}
TaskInput represents the structured input to a Task tool call.
type TaskToolCallInfo ¶
type TaskToolCallInfo struct {
// EntryIndex is the index of this entry in the session
EntryIndex int
// Timestamp is when the Task tool was called
Timestamp time.Time
// ToolInput is the raw tool input (the task prompt)
ToolInput string
// ToolOutput is the raw tool output (the task result)
ToolOutput string
// ParsedInput contains structured task input if parseable
ParsedInput *TaskInput
}
TaskToolCallInfo represents information extracted from a Task tool call entry.
func DetectTaskToolCalls ¶
func DetectTaskToolCalls(entries []map[string]any) []TaskToolCallInfo
DetectTaskToolCalls scans session entries for Task tool calls. Returns a list of TaskToolCallInfo for each detected Task tool invocation.
Source Files
¶
- artifacts.go
- capture.go
- classify.go
- convert.go
- entry.go
- errors.go
- filter.go
- guidance.go
- health.go
- history_schema.go
- history_store.go
- manifest.go
- markdown.go
- mermaid.go
- metadata.go
- plan_extract.go
- quality.go
- recording.go
- redact_rules.go
- secrets.go
- session.go
- signing.go
- storage.go
- storage_memory.go
- store.go
- subagent.go
- subagent_capture.go
- summarize.go
- summary_marker.go
- summary_md.go
- validate.go