Documentation
¶
Index ¶
- Constants
- Variables
- func IsAutomatedSession(firstMessage string) bool
- func SnapInterval(durationSec int64) int64
- func SystemPrefixSQL(contentCol, roleCol string) string
- type ActivityEntry
- type ActivityResponse
- type AgentBreakdown
- type AgentInfo
- type AgentSummary
- type AnalyticsFilter
- type AnalyticsSummary
- type DB
- func (db *DB) BulkStarSessions(sessionIDs []string) error
- func (db *DB) Close() error
- func (db *DB) CloseConnections() error
- func (d *DB) CopyExcludedSessionsFrom(sourcePath string) error
- func (db *DB) CopyInsightsFrom(sourcePath string) error
- func (d *DB) CopyOrphanedDataFrom(sourcePath string) (int, error)
- func (d *DB) CopySessionMetadataFrom(sourcePath string) error
- func (db *DB) DecodeCursor(s string) (SessionCursor, error)
- func (db *DB) DeleteInsight(id int64) error
- func (db *DB) DeleteSession(id string) error
- func (db *DB) DeleteSessionIfTrashed(id string) (int64, error)
- func (db *DB) DeleteSessions(ids []string) (int, error)
- func (db *DB) DeleteSkippedFile(path string) error
- func (db *DB) DropFTS() error
- func (db *DB) EmptyTrash() (int, error)
- func (db *DB) EncodeCursor(endedAt, id string, total ...int) string
- func (db *DB) FileBackedSessionCount(ctx context.Context) (int, error)
- func (db *DB) FindPruneCandidates(f PruneFilter) ([]Session, error)
- func (db *DB) GetAgents(ctx context.Context, excludeOneShot, excludeAutomated bool) ([]AgentInfo, error)
- func (db *DB) GetAllMessages(ctx context.Context, sessionID string) ([]Message, error)
- func (db *DB) GetAnalyticsActivity(ctx context.Context, f AnalyticsFilter, granularity string) (ActivityResponse, error)
- func (db *DB) GetAnalyticsHeatmap(ctx context.Context, f AnalyticsFilter, metric string) (HeatmapResponse, error)
- func (db *DB) GetAnalyticsHourOfWeek(ctx context.Context, f AnalyticsFilter) (HourOfWeekResponse, error)
- func (db *DB) GetAnalyticsProjects(ctx context.Context, f AnalyticsFilter) (ProjectsAnalyticsResponse, error)
- func (db *DB) GetAnalyticsSessionShape(ctx context.Context, f AnalyticsFilter) (SessionShapeResponse, error)
- func (db *DB) GetAnalyticsSummary(ctx context.Context, f AnalyticsFilter) (AnalyticsSummary, error)
- func (db *DB) GetAnalyticsTools(ctx context.Context, f AnalyticsFilter) (ToolsAnalyticsResponse, error)
- func (db *DB) GetAnalyticsTopSessions(ctx context.Context, f AnalyticsFilter, metric string) (TopSessionsResponse, error)
- func (db *DB) GetAnalyticsVelocity(ctx context.Context, f AnalyticsFilter) (VelocityResponse, error)
- func (db *DB) GetChildSessions(ctx context.Context, parentID string) ([]Session, error)
- func (db *DB) GetDailyUsage(ctx context.Context, f UsageFilter) (DailyUsageResult, error)
- func (db *DB) GetFileInfoByPath(path string) (size int64, mtime int64, ok bool)
- func (db *DB) GetInsight(ctx context.Context, id int64) (*Insight, error)
- func (db *DB) GetMachines(ctx context.Context, excludeOneShot, excludeAutomated bool) ([]string, error)
- func (db *DB) GetMessageByOrdinal(sessionID string, ordinal int) (*Message, error)
- func (db *DB) GetMessages(ctx context.Context, sessionID string, from, limit int, asc bool) ([]Message, error)
- func (db *DB) GetModelPricing(model string) (*ModelPricing, error)
- func (db *DB) GetPinnedMessageIDs(ctx context.Context, sessionID string) (map[int64]bool, error)
- func (db *DB) GetPricingMeta(key string) (string, error)
- func (db *DB) GetProjects(ctx context.Context, excludeOneShot, excludeAutomated bool) ([]ProjectInfo, error)
- func (db *DB) GetSession(ctx context.Context, id string) (*Session, error)
- func (d *DB) GetSessionActivity(ctx context.Context, sessionID string) (*SessionActivityResponse, error)
- func (db *DB) GetSessionFileInfo(id string) (size int64, mtime int64, ok bool)
- func (db *DB) GetSessionFilePath(id string) string
- func (db *DB) GetSessionForIncremental(path string) (*IncrementalInfo, bool)
- func (db *DB) GetSessionFull(ctx context.Context, id string) (*Session, error)
- func (db *DB) GetSessionMessageCount(id string) (count int, ok bool)
- func (db *DB) GetSessionVersion(id string) (count int, fileMtime int64, ok bool)
- func (db *DB) GetStats(ctx context.Context, excludeOneShot, excludeAutomated bool) (Stats, error)
- func (db *DB) GetSyncState(key string) (string, error)
- func (db *DB) GetTopSessionsByCost(ctx context.Context, f UsageFilter, limit int) ([]TopSessionEntry, error)
- func (db *DB) GetUsageSessionCounts(ctx context.Context, f UsageFilter) (UsageSessionCounts, error)
- func (db *DB) HasFTS() bool
- func (db *DB) InsertInsight(s Insight) (int64, error)
- func (db *DB) InsertMessages(msgs []Message) error
- func (db *DB) IsSessionExcluded(id string) bool
- func (db *DB) LinkSubagentSessions() error
- func (db *DB) ListInsights(ctx context.Context, f InsightFilter) ([]Insight, error)
- func (db *DB) ListPinnedMessages(ctx context.Context, sessionID string, project string) ([]PinnedMessage, error)
- func (db *DB) ListSessions(ctx context.Context, f SessionFilter) (SessionPage, error)
- func (db *DB) ListSessionsModifiedBetween(ctx context.Context, since, until string, projects, excludeProjects []string) ([]Session, error)
- func (db *DB) ListStarredSessionIDs(ctx context.Context) ([]string, error)
- func (db *DB) ListTrashedSessions(ctx context.Context) ([]Session, error)
- func (db *DB) LoadSkippedFiles() (map[string]int64, error)
- func (db *DB) MaxOrdinal(sessionID string) int
- func (db *DB) MessageContentFingerprint(sessionID string) (sum, max, min int64, err error)
- func (db *DB) MessageCount(sessionID string) (int, error)
- func (db *DB) MessageTokenFingerprint(sessionID string) (string, error)
- func (db *DB) NeedsResync() bool
- func (db *DB) Path() string
- func (db *DB) PinMessage(sessionID string, messageID int64, note *string) (int64, error)
- func (db *DB) PurgeExcludedSessions() error
- func (db *DB) ReadOnly() bool
- func (db *DB) Reader() *sql.DB
- func (db *DB) RebuildFTS() error
- func (db *DB) RenameSession(id string, displayName *string) error
- func (db *DB) Reopen() error
- func (db *DB) ReplaceSessionMessages(sessionID string, msgs []Message) error
- func (db *DB) ReplaceSkippedFiles(entries map[string]int64) error
- func (db *DB) ResetAllMtimes() error
- func (db *DB) RestoreSession(id string) (int64, error)
- func (db *DB) Search(ctx context.Context, f SearchFilter) (SearchPage, error)
- func (db *DB) SearchSession(ctx context.Context, sessionID, query string) ([]int, error)
- func (db *DB) SetCursorSecret(secret []byte)
- func (db *DB) SetPricingMeta(key, value string) error
- func (db *DB) SetSyncState(key, value string) error
- func (db *DB) SoftDeleteSession(id string) error
- func (db *DB) StarSession(sessionID string) (bool, error)
- func (db *DB) SystemMessageFingerprint(sessionID string) (string, error)
- func (db *DB) ToolCallContentFingerprint(sessionID string) (int64, error)
- func (db *DB) ToolCallCount(sessionID string) (int, error)
- func (db *DB) UnpinMessage(sessionID string, messageID int64) error
- func (db *DB) UnstarSession(sessionID string) error
- func (db *DB) Update(fn func(tx *sql.Tx) error) error
- func (db *DB) UpdateSessionIncremental(id string, endedAt *string, msgCount, userMsgCount int, ...) error
- func (db *DB) UpsertModelPricing(prices []ModelPricing) error
- func (db *DB) UpsertSession(s Session) error
- type DailyUsageEntry
- type DailyUsageResult
- type DistributionBucket
- type HeatmapEntry
- type HeatmapLevels
- type HeatmapResponse
- type HourOfWeekCell
- type HourOfWeekResponse
- type IncrementalInfo
- type Insight
- type InsightFilter
- type Message
- type ModelBreakdown
- type ModelPricing
- type Percentiles
- type PinnedMessage
- type ProjectAnalytics
- type ProjectBreakdown
- type ProjectInfo
- type ProjectsAnalyticsResponse
- type PruneFilter
- type SearchFilter
- type SearchPage
- type SearchResult
- type Session
- type SessionActivityBucket
- type SessionActivityResponse
- type SessionCoverageCandidate
- type SessionCoverageUpdate
- type SessionCursor
- type SessionFilter
- type SessionPage
- type SessionShapeResponse
- type Stats
- type Store
- type ToolAgentBreakdown
- type ToolCall
- type ToolCategoryCount
- type ToolResult
- type ToolResultEvent
- type ToolTrendEntry
- type ToolsAnalyticsResponse
- type TopSession
- type TopSessionEntry
- type TopSessionsResponse
- type UsageFilter
- type UsageSessionCounts
- type UsageTotals
- type VelocityBreakdown
- type VelocityOverview
- type VelocityResponse
Constants ¶
const ( // DefaultMessageLimit is the default number of messages returned. DefaultMessageLimit = 100 // MaxMessageLimit is the maximum number of messages returned. MaxMessageLimit = 1000 )
const ( DefaultSearchLimit = 50 MaxSearchLimit = 500 )
const ( // DefaultSessionLimit is the default number of sessions returned. DefaultSessionLimit = 200 // MaxSessionLimit is the maximum number of sessions returned. MaxSessionLimit = 500 )
const MaxHeatmapDays = 366
MaxHeatmapDays is the maximum number of day entries the heatmap will return. Ranges exceeding this are clamped to the most recent MaxHeatmapDays from the end date.
Variables ¶
var ErrInvalidCursor = errors.New("invalid cursor")
ErrInvalidCursor is returned when a cursor cannot be decoded or verified.
var ErrReadOnly = errReadOnly{}
ErrReadOnly is returned by write methods on read-only store implementations (e.g. the PostgreSQL reader).
var ErrSessionExcluded = errors.New("session excluded")
ErrSessionExcluded is returned by UpsertSession when the session was permanently deleted by the user. Callers should skip any follow-up writes (messages, tool_calls) for this session.
var SystemMsgPrefixes = []string{
"This session is being continued",
"[Request interrupted",
"<task-notification>",
"<command-message>",
"<command-name>",
"<local-command-",
"Stop hook feedback:",
}
SystemMsgPrefixes lists content prefixes that identify system-injected user messages. These are excluded from search results even when the is_system column has not been backfilled (e.g. Claude sessions parsed before schema version 2). Keep in sync with the frontend list in frontend/src/lib/utils/messages.ts.
Functions ¶
func IsAutomatedSession ¶ added in v0.18.0
IsAutomatedSession returns true if the first message matches a known automated review/fix prompt pattern.
func SnapInterval ¶ added in v0.17.0
SnapInterval picks a bucket interval targeting ~30 buckets. For very long sessions the interval scales beyond the fixed step list so the total bucket count never exceeds maxBuckets.
func SystemPrefixSQL ¶ added in v0.16.0
SystemPrefixSQL returns a SQL clause that excludes user messages matching any system prefix. The column alias for content must be passed (e.g. "m.content" or "m2.content"). Uses case-sensitive substr comparison, which behaves identically on SQLite and PostgreSQL (unlike LIKE, which is case-insensitive on SQLite).
Types ¶
type ActivityEntry ¶
type ActivityEntry struct {
Date string `json:"date"`
Sessions int `json:"sessions"`
Messages int `json:"messages"`
UserMessages int `json:"user_messages"`
AssistantMessages int `json:"assistant_messages"`
ToolCalls int `json:"tool_calls"`
ThinkingMessages int `json:"thinking_messages"`
ByAgent map[string]int `json:"by_agent"`
}
ActivityEntry is one time bucket in the activity timeline.
type ActivityResponse ¶
type ActivityResponse struct {
Granularity string `json:"granularity"`
Series []ActivityEntry `json:"series"`
}
ActivityResponse wraps the activity series.
type AgentBreakdown ¶ added in v0.21.0
type AgentBreakdown struct {
Agent string `json:"agent"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
Cost float64 `json:"cost"`
}
AgentBreakdown is the per-agent slice of a day's usage.
type AgentSummary ¶
AgentSummary holds per-agent counts for the summary.
type AnalyticsFilter ¶
type AnalyticsFilter struct {
From string // ISO date YYYY-MM-DD, inclusive
To string // ISO date YYYY-MM-DD, inclusive
Machine string // optional machine filter
Project string // optional project filter
Agent string // optional agent filter
Timezone string // IANA timezone for day bucketing
DayOfWeek *int // nil = all, 0=Mon, 6=Sun (ISO)
Hour *int // nil = all, 0-23
MinUserMessages int // user_message_count >= N
ExcludeOneShot bool // exclude sessions with user_message_count <= 1
ExcludeAutomated bool // exclude automated (roborev) sessions
ActiveSince string // ISO timestamp cutoff
}
AnalyticsFilter is the shared filter for all analytics queries.
func (AnalyticsFilter) HasTimeFilter ¶
func (f AnalyticsFilter) HasTimeFilter() bool
HasTimeFilter returns true when hour-of-day or day-of-week filtering is active.
type AnalyticsSummary ¶
type AnalyticsSummary struct {
TotalSessions int `json:"total_sessions"`
TotalMessages int `json:"total_messages"`
TotalOutputTokens int `json:"total_output_tokens"`
TokenReportingSessions int `json:"token_reporting_sessions"`
ActiveProjects int `json:"active_projects"`
ActiveDays int `json:"active_days"`
AvgMessages float64 `json:"avg_messages"`
MedianMessages int `json:"median_messages"`
P90Messages int `json:"p90_messages"`
MostActive string `json:"most_active_project"`
Concentration float64 `json:"concentration"`
Agents map[string]*AgentSummary `json:"agents"`
}
AnalyticsSummary is the response for the summary endpoint.
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB manages a write connection and a read-only pool. The reader and writer fields use atomic.Pointer so that concurrent HTTP handler goroutines can safely read while Reopen/CloseConnections swap the underlying *sql.DB.
func Open ¶
Open creates or opens a SQLite database at the given path. It configures WAL mode, mmap, and returns a DB with separate writer and reader connections.
If an existing database has an outdated schema (missing columns), it is deleted and recreated from scratch. If the schema is current but the data version is stale, the database is preserved and file mtimes are reset to trigger a re-sync on the next cycle.
func (*DB) BulkStarSessions ¶ added in v0.11.0
BulkStarSessions stars multiple sessions in a single transaction. Used for migrating localStorage stars to the database.
func (*DB) Close ¶
Close closes both writer and reader connections, plus any retired pools left over from previous Reopen calls.
func (*DB) CloseConnections ¶ added in v0.8.0
CloseConnections closes both connections without reopening, releasing file locks so the database file can be renamed. Also drains any retired pools from previous Reopen calls. Callers must call Reopen afterwards to restore service.
func (*DB) CopyExcludedSessionsFrom ¶ added in v0.11.0
CopyExcludedSessionsFrom copies the excluded_sessions table from the source DB so permanently deleted sessions survive full DB rebuilds. The source must not have active connections.
func (*DB) CopyInsightsFrom ¶ added in v0.8.0
CopyInsightsFrom copies all insights from the database at sourcePath into this database using ATTACH/DETACH.
func (*DB) CopyOrphanedDataFrom ¶ added in v0.10.0
CopyOrphanedDataFrom copies sessions (and their messages and tool_calls) that exist in the source database but not in this database. This preserves archived sessions whose source files no longer exist on disk.
Orphaned sessions are identified by ID-diff: any session present in the source but absent from the target after a full file sync. This correctly captures sessions whose source files were deleted, moved, or otherwise lost — exactly the set that would be dropped by a naive DB swap.
The source database must not have active connections (call CloseConnections on its DB handle first). Uses ATTACH DATABASE on a pinned connection for atomicity.
func (*DB) CopySessionMetadataFrom ¶ added in v0.11.0
CopySessionMetadataFrom merges user-managed data from the source DB into sessions that were re-synced into this DB. This preserves display_name, deleted_at, starred_sessions, and pinned_messages across full DB rebuilds.
func (*DB) DecodeCursor ¶
func (db *DB) DecodeCursor(s string) (SessionCursor, error)
DecodeCursor parses a base64-encoded cursor string.
func (*DB) DeleteInsight ¶ added in v0.4.0
DeleteInsight removes an insight by ID.
func (*DB) DeleteSession ¶
DeleteSession removes a session and its messages (cascading). The session ID is recorded in excluded_sessions so the sync engine does not re-import it from disk. Both operations run in a single transaction. The exclusion is only written when a session row was actually deleted, preventing ghost entries for non-existent IDs.
func (*DB) DeleteSessionIfTrashed ¶ added in v0.11.0
DeleteSessionIfTrashed atomically deletes a session only if it is currently in the trash (deleted_at IS NOT NULL). Returns the number of rows affected. This avoids a TOCTOU race between checking deleted_at and performing the delete.
func (*DB) DeleteSessions ¶
DeleteSessions removes multiple sessions by ID in a single transaction. Batches operations in groups of 500 to stay under SQLite variable limits. Deleted IDs are recorded in excluded_sessions so the sync engine does not re-import them. Returns count of deleted rows.
func (*DB) DeleteSkippedFile ¶ added in v0.5.0
DeleteSkippedFile removes a single skip cache entry.
func (*DB) DropFTS ¶ added in v0.8.0
DropFTS drops the FTS table and its triggers. This makes bulk message delete+reinsert fast by avoiding per-row FTS index updates. Call RebuildFTS after to restore search.
func (*DB) EmptyTrash ¶ added in v0.11.0
EmptyTrash permanently deletes all soft-deleted sessions. Session IDs are recorded in excluded_sessions so the sync engine does not re-import them. Both operations run in a single transaction to prevent ghost exclusions when the delete fails. Returns the count of deleted rows.
func (*DB) EncodeCursor ¶
EncodeCursor returns a base64-encoded cursor string.
func (*DB) FileBackedSessionCount ¶ added in v0.8.0
FileBackedSessionCount returns the number of root sessions synced from files (excludes non-file-backed agents like OpenCode and Claude.ai). Used by ResyncAll to decide whether empty file discovery should abort the swap.
func (*DB) FindPruneCandidates ¶
func (db *DB) FindPruneCandidates( f PruneFilter, ) ([]Session, error)
FindPruneCandidates returns sessions matching all filter criteria. Returns full Session rows including file metadata.
func (*DB) GetAgents ¶ added in v0.9.0
func (db *DB) GetAgents( ctx context.Context, excludeOneShot, excludeAutomated bool, ) ([]AgentInfo, error)
GetAgents returns distinct agent names with session counts.
func (*DB) GetAllMessages ¶
GetAllMessages returns all messages for a session ordered by ordinal.
func (*DB) GetAnalyticsActivity ¶
func (db *DB) GetAnalyticsActivity( ctx context.Context, f AnalyticsFilter, granularity string, ) (ActivityResponse, error)
GetAnalyticsActivity returns session/message counts grouped by time bucket.
func (*DB) GetAnalyticsHeatmap ¶
func (db *DB) GetAnalyticsHeatmap( ctx context.Context, f AnalyticsFilter, metric string, ) (HeatmapResponse, error)
GetAnalyticsHeatmap returns daily counts with intensity levels.
func (*DB) GetAnalyticsHourOfWeek ¶
func (db *DB) GetAnalyticsHourOfWeek( ctx context.Context, f AnalyticsFilter, ) (HourOfWeekResponse, error)
GetAnalyticsHourOfWeek returns message counts bucketed by day-of-week and hour-of-day in the user's timezone.
func (*DB) GetAnalyticsProjects ¶
func (db *DB) GetAnalyticsProjects( ctx context.Context, f AnalyticsFilter, ) (ProjectsAnalyticsResponse, error)
GetAnalyticsProjects returns per-project analytics.
func (*DB) GetAnalyticsSessionShape ¶
func (db *DB) GetAnalyticsSessionShape( ctx context.Context, f AnalyticsFilter, ) (SessionShapeResponse, error)
GetAnalyticsSessionShape returns distribution histograms for session length, duration, and autonomy ratio.
func (*DB) GetAnalyticsSummary ¶
func (db *DB) GetAnalyticsSummary( ctx context.Context, f AnalyticsFilter, ) (AnalyticsSummary, error)
GetAnalyticsSummary returns aggregate statistics.
func (*DB) GetAnalyticsTools ¶
func (db *DB) GetAnalyticsTools( ctx context.Context, f AnalyticsFilter, ) (ToolsAnalyticsResponse, error)
GetAnalyticsTools returns tool usage analytics aggregated from the tool_calls table.
func (*DB) GetAnalyticsTopSessions ¶
func (db *DB) GetAnalyticsTopSessions( ctx context.Context, f AnalyticsFilter, metric string, ) (TopSessionsResponse, error)
GetAnalyticsTopSessions returns the top 10 sessions by the given metric ("messages", "duration", or "output_tokens") within the filter.
func (*DB) GetAnalyticsVelocity ¶
func (db *DB) GetAnalyticsVelocity( ctx context.Context, f AnalyticsFilter, ) (VelocityResponse, error)
GetAnalyticsVelocity computes turn cycle, first response, and throughput metrics with breakdowns by agent and complexity.
func (*DB) GetChildSessions ¶ added in v0.7.0
GetChildSessions returns sessions whose parent_session_id matches the given parentID, ordered by started_at ascending.
func (*DB) GetDailyUsage ¶ added in v0.20.0
func (db *DB) GetDailyUsage( ctx context.Context, f UsageFilter, ) (DailyUsageResult, error)
GetDailyUsage returns token usage and cost aggregated by day. It scans messages with non-empty token_usage JSON blobs, parses them in Go (faster than SQLite's json_extract per row), joins against an in-memory pricing map, and buckets by local date.
func (*DB) GetFileInfoByPath ¶ added in v0.4.1
GetFileInfoByPath returns file_size and file_mtime for a session identified by file_path. Used for codex/gemini files where the session ID requires parsing.
func (*DB) GetInsight ¶ added in v0.4.0
GetInsight returns a single insight by ID. Returns nil, nil if not found.
func (*DB) GetMachines ¶
func (db *DB) GetMachines( ctx context.Context, excludeOneShot, excludeAutomated bool, ) ([]string, error)
GetMachines returns distinct machine names.
func (*DB) GetMessageByOrdinal ¶
GetMessageByOrdinal returns a single message by session ID and ordinal.
func (*DB) GetMessages ¶
func (db *DB) GetMessages( ctx context.Context, sessionID string, from, limit int, asc bool, ) ([]Message, error)
GetMessages returns paginated messages for a session. from: starting ordinal (inclusive) limit: max messages to return asc: true for ascending ordinal order, false for descending
func (*DB) GetModelPricing ¶ added in v0.20.0
func (db *DB) GetModelPricing( model string, ) (*ModelPricing, error)
GetModelPricing returns pricing for an exact model match. Returns nil, nil if not found.
func (*DB) GetPinnedMessageIDs ¶ added in v0.11.0
GetPinnedMessageIDs returns message IDs that are pinned for a session.
func (*DB) GetPricingMeta ¶ added in v0.22.2
GetPricingMeta reads a metadata value stored as a sentinel row in model_pricing. Returns "" if not found.
func (*DB) GetProjects ¶
func (db *DB) GetProjects( ctx context.Context, excludeOneShot, excludeAutomated bool, ) ([]ProjectInfo, error)
GetProjects returns project names with session counts.
func (*DB) GetSession ¶
GetSession returns a single session by ID, excluding soft-deleted (trashed) sessions.
func (*DB) GetSessionActivity ¶ added in v0.17.0
func (d *DB) GetSessionActivity( ctx context.Context, sessionID string, ) (*SessionActivityResponse, error)
GetSessionActivity returns time-bucketed message counts for a session. Only visible messages are counted (system and prefix-detected injected messages excluded).
func (*DB) GetSessionFileInfo ¶
GetSessionFileInfo returns file_size and file_mtime for a session. Used for fast skip checks during sync.
func (*DB) GetSessionFilePath ¶ added in v0.14.0
GetSessionFilePath returns the stored file_path for a session, or empty string if not found or NULL.
func (*DB) GetSessionForIncremental ¶ added in v0.13.0
func (db *DB) GetSessionForIncremental( path string, ) (*IncrementalInfo, bool)
GetSessionForIncremental returns session state needed for incremental parsing, looked up by file_path. Returns false when the path is unknown or maps to multiple sessions (e.g. Claude DAG forks), since incremental parsing cannot update multiple sessions from a single append.
func (*DB) GetSessionFull ¶
GetSessionFull returns a single session by ID with all file metadata.
func (*DB) GetSessionMessageCount ¶ added in v0.13.0
GetSessionMessageCount returns the message_count for a session. Returns (0, false) when the session does not exist.
func (*DB) GetSessionVersion ¶ added in v0.13.0
GetSessionVersion returns the message count and file mtime for change detection in SSE watchers.
func (*DB) GetStats ¶
func (db *DB) GetStats( ctx context.Context, excludeOneShot, excludeAutomated bool, ) (Stats, error)
GetStats returns database statistics, counting only root sessions with messages (matching the session list filter).
func (*DB) GetSyncState ¶ added in v0.16.0
GetSyncState reads a value from the pg_sync_state table.
func (*DB) GetTopSessionsByCost ¶ added in v0.21.0
func (db *DB) GetTopSessionsByCost( ctx context.Context, f UsageFilter, limit int, ) ([]TopSessionEntry, error)
GetTopSessionsByCost returns sessions ranked by total cost over the filter range. Default limit 20, max 100.
func (*DB) GetUsageSessionCounts ¶ added in v0.21.0
func (db *DB) GetUsageSessionCounts( ctx context.Context, f UsageFilter, ) (UsageSessionCounts, error)
GetUsageSessionCounts returns distinct session counts grouped by project and agent. Sessions spanning multiple days count once. Soft-deleted sessions are excluded via usageMessageEligibility.
Like GetDailyUsage and GetTopSessionsByCost, this query pads the UTC bounds by +/-14h and applies a post-query localDate filter so timezone-boundary messages are counted correctly.
func (*DB) InsertInsight ¶ added in v0.4.0
InsertInsight inserts an insight and returns its ID.
func (*DB) InsertMessages ¶
InsertMessages batch-inserts messages for a session.
func (*DB) IsSessionExcluded ¶ added in v0.11.0
IsSessionExcluded returns true if the session ID was permanently deleted by the user.
func (*DB) LinkSubagentSessions ¶ added in v0.14.0
LinkSubagentSessions sets parent_session_id and relationship_type on sessions that are referenced by tool_calls.subagent_session_id. Updates sessions that either have no parent yet or have a non-subagent relationship (e.g. a Zencoder session classified as "continuation" from header parentId that is actually a spawned subagent).
func (*DB) ListInsights ¶ added in v0.4.0
ListInsights returns insights matching the filter, ordered by created_at DESC, capped at 500 rows.
func (*DB) ListPinnedMessages ¶ added in v0.11.0
func (db *DB) ListPinnedMessages( ctx context.Context, sessionID string, project string, ) ([]PinnedMessage, error)
ListPinnedMessages returns all pins, optionally filtered by session or project. Pass empty sessionID for all pins across all sessions. When listing all pins, message content and role are included. project is only applied when sessionID is empty.
func (*DB) ListSessions ¶
func (db *DB) ListSessions( ctx context.Context, f SessionFilter, ) (SessionPage, error)
ListSessions returns a cursor-paginated list of sessions.
func (*DB) ListSessionsModifiedBetween ¶ added in v0.16.0
func (db *DB) ListSessionsModifiedBetween( ctx context.Context, since, until string, projects, excludeProjects []string, ) ([]Session, error)
ListSessionsModifiedBetween returns all sessions created or modified after since and at or before until.
Uses file_mtime (nanoseconds since epoch from the source file) as the primary modification signal so that active sessions with new messages are detected even when ended_at has not changed. Falls back to session timestamps for rows without file_mtime.
Precision note: file_mtime is compared as nanosecond integers, while text timestamps are normalized to millisecond precision (strftime '%f' -> 3 decimal places). Sub-millisecond differences in text timestamp fields are therefore truncated.
func (*DB) ListStarredSessionIDs ¶ added in v0.11.0
ListStarredSessionIDs returns all starred session IDs.
func (*DB) ListTrashedSessions ¶ added in v0.11.0
ListTrashedSessions returns sessions that have been soft-deleted.
func (*DB) LoadSkippedFiles ¶ added in v0.5.0
LoadSkippedFiles returns all persisted skip cache entries as a map from file_path to file_mtime.
func (*DB) MaxOrdinal ¶ added in v0.5.0
MaxOrdinal returns the highest ordinal for a session, or -1 if the session has no messages.
func (*DB) MessageContentFingerprint ¶ added in v0.16.0
MessageContentFingerprint returns a lightweight fingerprint of all messages for a session, computed as the sum, max, and min of content_length values.
func (*DB) MessageCount ¶
MessageCount returns the number of messages for a session.
func (*DB) MessageTokenFingerprint ¶ added in v0.18.0
MessageTokenFingerprint returns an exact ordered fingerprint of stored token metadata for a session's messages. Used by PG push fast-paths to detect token metadata changes without rewriting unchanged sessions.
func (*DB) NeedsResync ¶ added in v0.10.0
NeedsResync reports whether the database was opened with a stale data version, indicating the caller should trigger a full resync (build fresh DB, copy orphaned data, swap) rather than an incremental sync.
func (*DB) PinMessage ¶ added in v0.11.0
PinMessage creates a pin for a message. If the message is already pinned, the note is updated. The message must belong to the specified session (enforced via INSERT ... SELECT).
func (*DB) PurgeExcludedSessions ¶ added in v0.11.0
PurgeExcludedSessions removes any session rows whose IDs appear in excluded_sessions. Used after a resync to clean up sessions that were synced before their exclusion was recorded.
func (*DB) RebuildFTS ¶ added in v0.8.0
RebuildFTS recreates the FTS table, triggers, and repopulates the index from the messages table.
func (*DB) RenameSession ¶ added in v0.11.0
RenameSession sets or clears the display_name for a session. Pass nil to clear a custom name (reverts to first_message).
func (*DB) Reopen ¶ added in v0.8.0
Reopen closes and reopens both connections to the same path. Used after an atomic file swap to pick up the new database contents. Preserves cursorSecret.
func (*DB) ReplaceSessionMessages ¶
ReplaceSessionMessages deletes existing and inserts new messages in a single transaction. Any existing pins are preserved by re-attaching them to the new message rows that share the same ordinal (pins for ordinals that no longer exist are dropped).
func (*DB) ReplaceSkippedFiles ¶ added in v0.5.0
ReplaceSkippedFiles replaces all skip cache entries in a single transaction. This is called after each sync cycle to persist the in-memory skip cache.
func (*DB) ResetAllMtimes ¶ added in v0.6.0
ResetAllMtimes zeroes file_mtime for every session, forcing the next sync to re-process all files regardless of whether their size+mtime matches what was previously stored.
func (*DB) RestoreSession ¶ added in v0.11.0
RestoreSession clears deleted_at, making the session visible again. Returns the number of rows affected (0 if session doesn't exist or is not in trash).
func (*DB) Search ¶
func (db *DB) Search( ctx context.Context, f SearchFilter, ) (SearchPage, error)
Search performs FTS5 full-text search across messages, grouped by session, plus a LIKE-based search on session display names and first messages.
Results come from two branches joined with UNION ALL:
FTS branch — message content matches. ROW_NUMBER() picks the single best-ranked message per session (rank ASC, ordinal ASC, rowid ASC). The outer JOIN messages_fts includes a MATCH clause to prevent segment duplicates. Ordinal is the matched message's ordinal (≥ 0).
Name branch — display_name / first_message LIKE matches that are NOT already covered by the FTS branch. Ordinal is -1 (no specific message to navigate to).
func (*DB) SearchSession ¶ added in v0.14.0
SearchSession performs a case-insensitive substring search within a single session's messages, returning matching ordinals in document order. This is used by the in-session find bar (analogous to browser Cmd+F). Both message content and tool-call result_content are searched so that matches inside tool output blocks are reachable. Only fields that the frontend renders and highlights are included to avoid phantom matches.
func (*DB) SetCursorSecret ¶
SetCursorSecret updates the secret key used for cursor signing.
func (*DB) SetPricingMeta ¶ added in v0.22.2
SetPricingMeta stores a metadata value as a sentinel row in model_pricing with zero pricing fields.
func (*DB) SetSyncState ¶ added in v0.16.0
SetSyncState writes a value to the pg_sync_state table.
func (*DB) SoftDeleteSession ¶ added in v0.11.0
SoftDeleteSession marks a session as deleted by setting deleted_at.
func (*DB) StarSession ¶ added in v0.11.0
StarSession marks a session as starred. Uses INSERT...SELECT with an EXISTS check so the operation is atomic and avoids FK errors if the session is concurrently deleted. Returns false if the session does not exist (idempotent for already-starred).
func (*DB) SystemMessageFingerprint ¶ added in v0.16.0
SystemMessageFingerprint returns the ordered, comma-separated list of ordinals for system messages in a session (e.g. "0,2,5"). This is an exact fingerprint of the system-message ordinal set: any reclassification of which messages are system — even when counts, sums, or sums-of-squares remain equal — produces a different string. Used by the PG push fast-path.
func (*DB) ToolCallContentFingerprint ¶ added in v0.16.0
ToolCallContentFingerprint returns the sum of result_content_length values for a session's tool calls, used as a lightweight content change detector.
func (*DB) ToolCallCount ¶ added in v0.16.0
ToolCallCount returns the number of tool_calls rows for a session.
func (*DB) UnpinMessage ¶ added in v0.11.0
UnpinMessage removes a pin.
func (*DB) UnstarSession ¶ added in v0.11.0
UnstarSession removes a session's star.
func (*DB) Update ¶
Update executes fn within a write lock and transaction. The transaction is committed if fn returns nil, rolled back otherwise.
func (*DB) UpdateSessionIncremental ¶ added in v0.13.0
func (db *DB) UpdateSessionIncremental( id string, endedAt *string, msgCount, userMsgCount int, fileSize, fileMtime int64, totalOutputTokens, peakContextTokens int, hasTotalOutputTokens, hasPeakContextTokens bool, ) error
UpdateSessionIncremental updates only the fields that change during an incremental append: ended_at, message_count, user_message_count, file_size, file_mtime, and token aggregates. All values are absolute (not deltas) so the update is idempotent on retry.
func (*DB) UpsertModelPricing ¶ added in v0.20.0
func (db *DB) UpsertModelPricing( prices []ModelPricing, ) error
UpsertModelPricing inserts or replaces pricing rows in a single transaction.
func (*DB) UpsertSession ¶
UpsertSession inserts or updates a session. Sessions that were permanently deleted (in excluded_sessions) are silently skipped.
type DailyUsageEntry ¶ added in v0.20.0
type DailyUsageEntry struct {
Date string `json:"date"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
TotalCost float64 `json:"totalCost"`
ModelsUsed []string `json:"modelsUsed"`
ModelBreakdowns []ModelBreakdown `json:"modelBreakdowns,omitempty"`
ProjectBreakdowns []ProjectBreakdown `json:"projectBreakdowns,omitempty"`
AgentBreakdowns []AgentBreakdown `json:"agentBreakdowns,omitempty"`
}
DailyUsageEntry holds token counts and cost for one day.
type DailyUsageResult ¶ added in v0.20.0
type DailyUsageResult struct {
Daily []DailyUsageEntry `json:"daily"`
Totals UsageTotals `json:"totals"`
}
DailyUsageResult wraps the daily entries and totals.
type DistributionBucket ¶
DistributionBucket is a labeled count for histogram display.
type HeatmapEntry ¶
type HeatmapEntry struct {
Date string `json:"date"`
Value int `json:"value"`
Level int `json:"level"`
}
HeatmapEntry is one day in the heatmap calendar.
type HeatmapLevels ¶
type HeatmapLevels struct {
L1 int `json:"l1"`
L2 int `json:"l2"`
L3 int `json:"l3"`
L4 int `json:"l4"`
}
HeatmapLevels defines the quartile thresholds for levels 1-4.
type HeatmapResponse ¶
type HeatmapResponse struct {
Metric string `json:"metric"`
Entries []HeatmapEntry `json:"entries"`
Levels HeatmapLevels `json:"levels"`
EntriesFrom string `json:"entries_from"`
}
HeatmapResponse wraps the heatmap data.
type HourOfWeekCell ¶
type HourOfWeekCell struct {
DayOfWeek int `json:"day_of_week"` // 0=Mon, 6=Sun
Hour int `json:"hour"` // 0-23
Messages int `json:"messages"`
}
HourOfWeekCell is one cell in the 7x24 hour-of-week grid.
type HourOfWeekResponse ¶
type HourOfWeekResponse struct {
Cells []HourOfWeekCell `json:"cells"`
}
HourOfWeekResponse wraps the hour-of-week heatmap data.
type IncrementalInfo ¶ added in v0.13.0
type IncrementalInfo struct {
ID string
FileSize int64
MsgCount int
UserMsgCount int
TotalOutputTokens int
PeakContextTokens int
HasTotalOutputTokens bool
HasPeakContextTokens bool
}
IncrementalInfo holds the data needed for incremental re-parsing of an append-only session file.
type Insight ¶ added in v0.4.0
type Insight struct {
ID int64 `json:"id"`
Type string `json:"type"`
DateFrom string `json:"date_from"`
DateTo string `json:"date_to"`
Project *string `json:"project"`
Agent string `json:"agent"`
Model *string `json:"model"`
Prompt *string `json:"prompt"`
Content string `json:"content"`
CreatedAt string `json:"created_at"`
}
Insight represents a row in the insights table.
type InsightFilter ¶ added in v0.4.0
type InsightFilter struct {
Type string // "daily_activity" or "agent_analysis"
Project string // "" = no filter
GlobalOnly bool // true = project IS NULL only
}
InsightFilter specifies how to query insights.
type Message ¶
type Message struct {
ID int64 `json:"id"`
SessionID string `json:"session_id"`
Ordinal int `json:"ordinal"`
Role string `json:"role"`
Content string `json:"content"`
Timestamp string `json:"timestamp"`
HasThinking bool `json:"has_thinking"`
HasToolUse bool `json:"has_tool_use"`
ContentLength int `json:"content_length"`
Model string `json:"model"`
TokenUsage json.RawMessage `json:"token_usage,omitempty"`
ContextTokens int `json:"context_tokens"`
OutputTokens int `json:"output_tokens"`
HasContextTokens bool `json:"has_context_tokens"`
HasOutputTokens bool `json:"has_output_tokens"`
ClaudeMessageID string `json:"claude_message_id,omitempty"`
ClaudeRequestID string `json:"claude_request_id,omitempty"`
ToolCalls []ToolCall `json:"tool_calls,omitempty"`
ToolResults []ToolResult `json:"-"` // transient, for pairing
IsSystem bool `json:"is_system"` // persisted, filters search/analytics
}
Message represents a row in the messages table.
func (Message) TokenPresence ¶ added in v0.18.0
TokenPresence reports whether context/output token fields were present in stored message metadata. It preserves explicit flags, falls back to non-zero numeric values for legacy rows, and inspects raw token_usage payload keys to preserve zero-valued coverage.
type ModelBreakdown ¶ added in v0.20.0
type ModelBreakdown struct {
ModelName string `json:"modelName"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
Cost float64 `json:"cost"`
}
ModelBreakdown holds per-model token and cost breakdown.
type ModelPricing ¶ added in v0.20.0
type ModelPricing struct {
ModelPattern string `json:"model_pattern"`
InputPerMTok float64 `json:"input_per_mtok"`
OutputPerMTok float64 `json:"output_per_mtok"`
CacheCreationPerMTok float64 `json:"cache_creation_per_mtok"`
CacheReadPerMTok float64 `json:"cache_read_per_mtok"`
UpdatedAt string `json:"updated_at"`
}
ModelPricing holds per-model token pricing (per million tokens).
type Percentiles ¶
Percentiles holds p50 and p90 values.
type PinnedMessage ¶ added in v0.11.0
type PinnedMessage struct {
ID int64 `json:"id"`
SessionID string `json:"session_id"`
MessageID int64 `json:"message_id"`
Ordinal int `json:"ordinal"`
Note *string `json:"note,omitempty"`
Content *string `json:"content,omitempty"`
Role *string `json:"role,omitempty"`
CreatedAt string `json:"created_at"`
// Session metadata — populated only for the "all pins" query.
SessionProject *string `json:"session_project,omitempty"`
SessionAgent *string `json:"session_agent,omitempty"`
SessionDisplayName *string `json:"session_display_name,omitempty"`
SessionFirstMessage *string `json:"session_first_message,omitempty"`
}
PinnedMessage represents a row in the pinned_messages table.
type ProjectAnalytics ¶
type ProjectAnalytics struct {
Name string `json:"name"`
Sessions int `json:"sessions"`
Messages int `json:"messages"`
FirstSession string `json:"first_session"`
LastSession string `json:"last_session"`
AvgMessages float64 `json:"avg_messages"`
MedianMessages int `json:"median_messages"`
Agents map[string]int `json:"agents"`
DailyTrend float64 `json:"daily_trend"`
}
ProjectAnalytics holds analytics for a single project.
type ProjectBreakdown ¶ added in v0.21.0
type ProjectBreakdown struct {
Project string `json:"project"`
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
Cost float64 `json:"cost"`
}
ProjectBreakdown is the per-project slice of a day's usage.
type ProjectInfo ¶
ProjectInfo holds a project name and its session count.
type ProjectsAnalyticsResponse ¶
type ProjectsAnalyticsResponse struct {
Projects []ProjectAnalytics `json:"projects"`
}
ProjectsAnalyticsResponse wraps the projects list.
type PruneFilter ¶
type PruneFilter struct {
Project string // substring match (LIKE '%x%')
MaxMessages *int // user messages <= N (nil = no filter)
Before string // ended_at < date (YYYY-MM-DD)
FirstMessage string // first_message LIKE 'prefix%'
}
PruneFilter defines criteria for finding sessions to prune. Filters combine with AND. At least one must be set.
func (PruneFilter) HasFilters ¶
func (f PruneFilter) HasFilters() bool
HasFilters reports whether at least one filter is set.
type SearchFilter ¶
type SearchFilter struct {
Query string
Project string
Sort string // "relevance" (default) or "recency"
Cursor int // offset for pagination
Limit int
}
SearchFilter specifies search parameters.
type SearchPage ¶
type SearchPage struct {
Results []SearchResult `json:"results"`
NextCursor int `json:"next_cursor,omitempty"`
}
SearchPage holds paginated search results.
type SearchResult ¶
type SearchResult struct {
SessionID string `json:"session_id"`
Project string `json:"project"`
Agent string `json:"agent"`
Name string `json:"name"`
Ordinal int `json:"ordinal"`
SessionEndedAt string `json:"session_ended_at"`
Snippet string `json:"snippet"`
Rank float64 `json:"rank"`
}
SearchResult holds a session-level match with the best-ranked snippet.
type Session ¶
type Session struct {
ID string `json:"id"`
Project string `json:"project"`
Machine string `json:"machine"`
Agent string `json:"agent"`
FirstMessage *string `json:"first_message"`
DisplayName *string `json:"display_name,omitempty"`
StartedAt *string `json:"started_at"`
EndedAt *string `json:"ended_at"`
MessageCount int `json:"message_count"`
UserMessageCount int `json:"user_message_count"`
ParentSessionID *string `json:"parent_session_id,omitempty"`
RelationshipType string `json:"relationship_type,omitempty"`
TotalOutputTokens int `json:"total_output_tokens"`
PeakContextTokens int `json:"peak_context_tokens"`
HasTotalOutputTokens bool `json:"has_total_output_tokens"`
HasPeakContextTokens bool `json:"has_peak_context_tokens"`
IsAutomated bool `json:"is_automated"`
DeletedAt *string `json:"deleted_at,omitempty"`
FilePath *string `json:"file_path,omitempty"`
FileSize *int64 `json:"file_size,omitempty"`
FileMtime *int64 `json:"file_mtime,omitempty"`
FileHash *string `json:"file_hash,omitempty"`
LocalModifiedAt *string `json:"local_modified_at,omitempty"`
CreatedAt string `json:"created_at"`
}
Session represents a row in the sessions table.
type SessionActivityBucket ¶ added in v0.17.0
type SessionActivityBucket struct {
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
UserCount int `json:"user_count"`
AssistantCount int `json:"assistant_count"`
FirstOrdinal *int `json:"first_ordinal"` // nil for empty buckets
}
SessionActivityBucket holds message counts for one time interval.
type SessionActivityResponse ¶ added in v0.17.0
type SessionActivityResponse struct {
Buckets []SessionActivityBucket `json:"buckets"`
IntervalSeconds int64 `json:"interval_seconds"`
TotalMessages int `json:"total_messages"`
}
SessionActivityResponse is the response for the activity endpoint.
type SessionCoverageCandidate ¶ added in v0.18.0
type SessionCoverageCandidate struct {
ID string
TotalOutputTokens int
PeakContextTokens int
HasTotal bool
HasPeak bool
}
SessionCoverageCandidate holds the current state of a session's token coverage flags, used as input to ComputeSessionCoverageUpdates.
type SessionCoverageUpdate ¶ added in v0.18.0
SessionCoverageUpdate holds the computed coverage flags for a session that needs updating.
func ComputeSessionCoverageUpdates ¶ added in v0.18.0
func ComputeSessionCoverageUpdates( candidates []SessionCoverageCandidate, msgCoverage map[string][2]bool, ) []SessionCoverageUpdate
ComputeSessionCoverageUpdates computes which sessions need their coverage flags updated based on their current state and message-level coverage. msgCoverage maps session ID to [hasContext, hasOutput]. Returns only sessions whose flags would change.
type SessionCursor ¶
type SessionCursor struct {
EndedAt string `json:"e"`
ID string `json:"i"`
Total int `json:"t,omitempty"`
}
SessionCursor is the opaque pagination token.
type SessionFilter ¶
type SessionFilter struct {
Project string
ExcludeProject string // exclude sessions with this project name
Machine string
Agent string
Date string // exact date YYYY-MM-DD
DateFrom string // range start (inclusive)
DateTo string // range end (inclusive)
ActiveSince string // ISO-8601 timestamp; filters on most recent activity
MinMessages int // message_count >= N (0 = no filter)
MaxMessages int // message_count <= N (0 = no filter)
MinUserMessages int // user_message_count >= N (0 = no filter)
ExcludeOneShot bool // exclude sessions with user_message_count <= 1
ExcludeAutomated bool // exclude sessions where is_automated = 1
IncludeChildren bool // include subagent sessions (for sidebar grouping)
Cursor string // opaque cursor from previous page
Limit int
}
SessionFilter specifies how to query sessions.
type SessionPage ¶
type SessionPage struct {
Sessions []Session `json:"sessions"`
NextCursor string `json:"next_cursor,omitempty"`
Total int `json:"total"`
}
SessionPage is a page of session results.
type SessionShapeResponse ¶
type SessionShapeResponse struct {
Count int `json:"count"`
LengthDistribution []DistributionBucket `json:"length_distribution"`
DurationDistribution []DistributionBucket `json:"duration_distribution"`
AutonomyDistribution []DistributionBucket `json:"autonomy_distribution"`
}
SessionShapeResponse holds distribution histograms for session characteristics.
type Stats ¶
type Stats struct {
SessionCount int `json:"session_count"`
MessageCount int `json:"message_count"`
ProjectCount int `json:"project_count"`
MachineCount int `json:"machine_count"`
EarliestSession *string `json:"earliest_session"`
}
Stats holds database-wide statistics.
type Store ¶ added in v0.16.0
type Store interface {
// Cursor pagination.
SetCursorSecret(secret []byte)
EncodeCursor(endedAt, id string, total ...int) string
DecodeCursor(s string) (SessionCursor, error)
// Sessions.
ListSessions(ctx context.Context, f SessionFilter) (SessionPage, error)
GetSession(ctx context.Context, id string) (*Session, error)
GetSessionFull(ctx context.Context, id string) (*Session, error)
GetChildSessions(ctx context.Context, parentID string) ([]Session, error)
// Messages.
GetMessages(ctx context.Context, sessionID string, from, limit int, asc bool) ([]Message, error)
GetAllMessages(ctx context.Context, sessionID string) ([]Message, error)
GetSessionActivity(ctx context.Context, sessionID string) (*SessionActivityResponse, error)
// Search.
HasFTS() bool
Search(ctx context.Context, f SearchFilter) (SearchPage, error)
SearchSession(ctx context.Context, sessionID, query string) ([]int, error)
// SSE change detection.
GetSessionVersion(id string) (count int, fileMtime int64, ok bool)
// Metadata.
GetStats(ctx context.Context, excludeOneShot, excludeAutomated bool) (Stats, error)
GetProjects(ctx context.Context, excludeOneShot, excludeAutomated bool) ([]ProjectInfo, error)
GetAgents(ctx context.Context, excludeOneShot, excludeAutomated bool) ([]AgentInfo, error)
GetMachines(ctx context.Context, excludeOneShot, excludeAutomated bool) ([]string, error)
// Analytics.
GetAnalyticsSummary(ctx context.Context, f AnalyticsFilter) (AnalyticsSummary, error)
GetAnalyticsActivity(ctx context.Context, f AnalyticsFilter, granularity string) (ActivityResponse, error)
GetAnalyticsHeatmap(ctx context.Context, f AnalyticsFilter, metric string) (HeatmapResponse, error)
GetAnalyticsProjects(ctx context.Context, f AnalyticsFilter) (ProjectsAnalyticsResponse, error)
GetAnalyticsHourOfWeek(ctx context.Context, f AnalyticsFilter) (HourOfWeekResponse, error)
GetAnalyticsSessionShape(ctx context.Context, f AnalyticsFilter) (SessionShapeResponse, error)
GetAnalyticsTools(ctx context.Context, f AnalyticsFilter) (ToolsAnalyticsResponse, error)
GetAnalyticsVelocity(ctx context.Context, f AnalyticsFilter) (VelocityResponse, error)
GetAnalyticsTopSessions(ctx context.Context, f AnalyticsFilter, metric string) (TopSessionsResponse, error)
// Usage (token cost).
GetDailyUsage(ctx context.Context, f UsageFilter) (DailyUsageResult, error)
GetTopSessionsByCost(ctx context.Context, f UsageFilter, limit int) ([]TopSessionEntry, error)
GetUsageSessionCounts(ctx context.Context, f UsageFilter) (UsageSessionCounts, error)
// Stars (local-only; PG returns ErrReadOnly).
StarSession(sessionID string) (bool, error)
UnstarSession(sessionID string) error
ListStarredSessionIDs(ctx context.Context) ([]string, error)
BulkStarSessions(sessionIDs []string) error
// Pins (local-only; PG returns ErrReadOnly).
PinMessage(sessionID string, messageID int64, note *string) (int64, error)
UnpinMessage(sessionID string, messageID int64) error
ListPinnedMessages(ctx context.Context, sessionID string, project string) ([]PinnedMessage, error)
// Insights (local-only; PG returns ErrReadOnly).
ListInsights(ctx context.Context, f InsightFilter) ([]Insight, error)
GetInsight(ctx context.Context, id int64) (*Insight, error)
InsertInsight(s Insight) (int64, error)
DeleteInsight(id int64) error
// Session management (local-only; PG returns ErrReadOnly).
RenameSession(id string, displayName *string) error
SoftDeleteSession(id string) error
RestoreSession(id string) (int64, error)
DeleteSessionIfTrashed(id string) (int64, error)
ListTrashedSessions(ctx context.Context) ([]Session, error)
EmptyTrash() (int, error)
// Upload (local-only; PG returns ErrReadOnly).
UpsertSession(s Session) error
ReplaceSessionMessages(sessionID string, msgs []Message) error
// ReadOnly returns true for remote/PG-backed stores.
ReadOnly() bool
}
Store is the interface the HTTP server uses for all data access. The concrete *DB (SQLite) satisfies it implicitly. The pgdb package provides a read-only PostgreSQL implementation.
type ToolAgentBreakdown ¶
type ToolAgentBreakdown struct {
Agent string `json:"agent"`
Total int `json:"total"`
Categories []ToolCategoryCount `json:"categories"`
}
ToolAgentBreakdown holds tool usage breakdown for one agent.
type ToolCall ¶
type ToolCall struct {
MessageID int64 `json:"-"`
SessionID string `json:"-"`
ToolName string `json:"tool_name"`
Category string `json:"category"`
ToolUseID string `json:"tool_use_id,omitempty"`
InputJSON string `json:"input_json,omitempty"`
SkillName string `json:"skill_name,omitempty"`
ResultContentLength int `json:"result_content_length,omitempty"`
ResultContent string `json:"result_content,omitempty"`
SubagentSessionID string `json:"subagent_session_id,omitempty"`
ResultEvents []ToolResultEvent `json:"result_events,omitempty"`
}
ToolCall represents a single tool invocation stored in the tool_calls table.
type ToolCategoryCount ¶
type ToolCategoryCount struct {
Category string `json:"category"`
Count int `json:"count"`
Pct float64 `json:"pct"`
}
ToolCategoryCount holds a count and percentage for one tool category.
type ToolResult ¶ added in v0.4.0
type ToolResult struct {
ToolUseID string
ContentLength int
ContentRaw string // raw JSON of the content field; decode lazily
}
ToolResult holds a tool_result content block for pairing.
type ToolResultEvent ¶ added in v0.17.0
type ToolResultEvent struct {
ToolUseID string `json:"tool_use_id,omitempty"`
AgentID string `json:"agent_id,omitempty"`
SubagentSessionID string `json:"subagent_session_id,omitempty"`
Source string `json:"source"`
Status string `json:"status"`
Content string `json:"content"`
ContentLength int `json:"content_length"`
Timestamp string `json:"timestamp,omitempty"`
EventIndex int `json:"event_index"`
}
ToolResultEvent represents a canonical chronological result update.
type ToolTrendEntry ¶
ToolTrendEntry holds tool call counts for one time bucket.
type ToolsAnalyticsResponse ¶
type ToolsAnalyticsResponse struct {
TotalCalls int `json:"total_calls"`
ByCategory []ToolCategoryCount `json:"by_category"`
ByAgent []ToolAgentBreakdown `json:"by_agent"`
Trend []ToolTrendEntry `json:"trend"`
}
ToolsAnalyticsResponse wraps tool usage analytics.
type TopSession ¶
type TopSession struct {
ID string `json:"id"`
Project string `json:"project"`
FirstMessage *string `json:"first_message"`
MessageCount int `json:"message_count"`
OutputTokens int `json:"output_tokens"`
DurationMin float64 `json:"duration_min"`
}
TopSession holds summary info for a ranked session.
type TopSessionEntry ¶ added in v0.21.0
type TopSessionEntry struct {
SessionID string `json:"sessionId"`
DisplayName string `json:"displayName"`
Agent string `json:"agent"`
Project string `json:"project"`
StartedAt string `json:"startedAt"`
TotalTokens int `json:"totalTokens"`
Cost float64 `json:"cost"`
}
TopSessionEntry is one row in the "top sessions by cost" result.
type TopSessionsResponse ¶
type TopSessionsResponse struct {
Metric string `json:"metric"`
Sessions []TopSession `json:"sessions"`
}
TopSessionsResponse wraps the top sessions list.
type UsageFilter ¶ added in v0.20.0
type UsageFilter struct {
From string // YYYY-MM-DD, inclusive
To string // YYYY-MM-DD, inclusive
Agent string // "" for all; supports comma-separated
Project string // "" for all; supports comma-separated
Model string // "" for all; supports comma-separated
ExcludeProject string // comma-separated projects to exclude
ExcludeAgent string // comma-separated agents to exclude
ExcludeModel string // comma-separated models to exclude
Timezone string // IANA timezone, "" for UTC
Breakdowns bool // populate Project/AgentBreakdowns per day
}
UsageFilter controls the date range, agent, and timezone for daily usage aggregation queries.
type UsageSessionCounts ¶ added in v0.21.0
type UsageSessionCounts struct {
Total int `json:"total"`
ByProject map[string]int `json:"byProject"`
ByAgent map[string]int `json:"byAgent"`
}
UsageSessionCounts holds distinct session counts grouped by project and agent over a filter range.
type UsageTotals ¶ added in v0.20.0
type UsageTotals struct {
InputTokens int `json:"inputTokens"`
OutputTokens int `json:"outputTokens"`
CacheCreationTokens int `json:"cacheCreationTokens"`
CacheReadTokens int `json:"cacheReadTokens"`
TotalCost float64 `json:"totalCost"`
// CacheSavings is the net dollar delta vs an uncached run:
// cache reads save (input_rate - cache_read_rate) per token,
// cache creations cost (input_rate - cache_creation_rate)
// per token (usually negative because creation is billed
// above the input rate). Computed from per-model rates so
// mixed-model workloads get the right number, not a fixed
// Sonnet proxy.
CacheSavings float64 `json:"cacheSavings"`
}
UsageTotals holds aggregate token and cost totals.
type VelocityBreakdown ¶
type VelocityBreakdown struct {
Label string `json:"label"`
Sessions int `json:"sessions"`
Overview VelocityOverview `json:"overview"`
}
VelocityBreakdown is velocity metrics for a subgroup.
type VelocityOverview ¶
type VelocityOverview struct {
TurnCycleSec Percentiles `json:"turn_cycle_sec"`
FirstResponseSec Percentiles `json:"first_response_sec"`
MsgsPerActiveMin float64 `json:"msgs_per_active_min"`
CharsPerActiveMin float64 `json:"chars_per_active_min"`
ToolCallsPerActiveMin float64 `json:"tool_calls_per_active_min"`
}
VelocityOverview holds aggregate velocity metrics.
type VelocityResponse ¶
type VelocityResponse struct {
Overall VelocityOverview `json:"overall"`
ByAgent []VelocityBreakdown `json:"by_agent"`
ByComplexity []VelocityBreakdown `json:"by_complexity"`
}
VelocityResponse wraps overall and grouped velocity metrics.