db

package
v1.3.0 Latest Latest
Warning

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

Go to latest
Published: Feb 9, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

blocks.go implements 5-hour usage block analysis for rate limit tracking. Groups token usage entries into time-bounded blocks matching Claude's rate limit reset window, with per-block statistics and projections.

messages.go handles message-level CRUD operations. Each message belongs to a session and is stored with full metadata (role, content, tokens, cost). Provides both direct (InsertMessage) and transactional (TxInsertMessage) variants.

projects.go manages tracked development directories. Projects are auto-discovered from working_directory fields in indexed sessions and classified by recency (active/stale/archived). Users can enable/disable projects for selective indexing.

search.go implements full-text search using SQLite FTS5 with BM25 ranking. Provides both message-level search (Search) and session-grouped search (SearchGrouped) with composite scoring: BM25 * temporal_decay * density_bonus.

sessions.go handles session-level CRUD operations. A session aggregates all messages from a single AI coding conversation. Provides both direct and transactional (Tx) variants for atomic indexer operations.

Package db provides the SQLite persistence layer for mnemo.

All indexed sessions and messages are stored in ~/.mnemo/mnemo.db using pure-Go SQLite (modernc.org/sqlite, no CGO required). The schema includes:

  • messages table with FTS5 virtual table for full-text search
  • sessions table linking messages to projects and tools
  • token_usage table for per-request cost tracking
  • projects table for directory-based project management

FTS5 triggers automatically keep the search index in sync with inserts, updates, and deletes on the messages table.

token_usage.go tracks per-request token consumption and cost. Records are inserted per API call and the parent session's aggregate totals are updated atomically. Also provides stats aggregation by provider, tool, and model.

Index

Constants

View Source
const (
	ProjectStatusActive   = "active"
	ProjectStatusInactive = "inactive"
	ProjectStatusArchived = "archived"
)
View Source
const SessionDurationHours = 5

SessionDurationHours is Claude's rate limit reset window

Variables

This section is empty.

Functions

func AddProjectManually

func AddProjectManually(path string) error

AddProjectManually creates a project entry from a user-specified path.

func BeginTx added in v1.3.0

func BeginTx() (*sql.Tx, error)

BeginTx starts a new database transaction for atomic multi-step operations.

func ClassifyProjects

func ClassifyProjects() error

ClassifyProjects updates project status based on last_activity recency: active (<60 days), inactive (60-90 days), archived (>90 days).

func ClearIndex

func ClearIndex() error

ClearIndex drops all data from messages, sessions, and token_usage tables.

func CloseDB

func CloseDB()

CloseDB closes the global database connection.

func DeleteProject

func DeleteProject(path string) error

DeleteProject removes a project entry by its path.

func DeleteSessionMessages added in v1.3.0

func DeleteSessionMessages(sessionID string) error

DeleteSessionMessages removes all messages for a session. Must be called before re-indexing a session to prevent duplicates.

func GetAPICredentials

func GetAPICredentials() ([]string, error)

GetAPICredentials returns the list of providers with valid API keys.

func GetDB

func GetDB() *sql.DB

GetDB returns the package-level database connection. Must call InitDB first.

func GetIndexedSessions added in v1.3.0

func GetIndexedSessions() (map[string]time.Time, error)

GetIndexedSessions returns a map of session_id -> indexed_at for incremental indexing. Callers compare file mtime against indexed_at to skip unchanged sessions.

func GetMaxIndexedAtByTool added in v1.3.0

func GetMaxIndexedAtByTool() (map[string]time.Time, error)

GetMaxIndexedAtByTool returns the max(indexed_at) per tool for incremental DB-level checks.

func GetProjectsForOnboarding

func GetProjectsForOnboarding() (active []Project, inactive []Project, err error)

GetProjectsForOnboarding returns active and inactive projects for the first-run experience.

func GetStats

func GetStats() (int, int, error)

GetStats returns the total number of sessions and messages in the database.

func GetTokenStatsByProvider

func GetTokenStatsByProvider(days int) (map[string]TokenStats, error)

GetTokenStatsByProvider returns aggregate token usage grouped by provider, optionally filtered to the last N days (0 means all time).

func GetUsageByToolForActiveBlock

func GetUsageByToolForActiveBlock(provider string) ([]ToolUsageStats, *SessionBlock, error)

GetUsageByToolForActiveBlock returns per-tool usage for the current 5-hour block

func GetUsageStatsByModel

func GetUsageStatsByModel() (map[string]ModelUsageSummary, error)

GetUsageStatsByModel returns aggregate token usage grouped by model name.

func GetUsageStatsByTool

func GetUsageStatsByTool() (map[string]ToolUsageSummary, error)

GetUsageStatsByTool returns aggregate token usage grouped by AI tool (e.g. claude-code, opencode).

func InitDB

func InitDB() error

InitDB opens (or creates) the mnemo database at ~/.mnemo/mnemo.db and applies the schema and any pending migrations. Uses WAL mode for concurrent read access.

func InsertMessage

func InsertMessage(msg Message) error

InsertMessage inserts a single message record using the global DB connection.

func InsertSession

func InsertSession(sess Session) error

InsertSession upserts a session record with full metadata using the global DB connection.

func InsertSessionSimple

func InsertSessionSimple(id, project, firstQuery, filePath, tool string, msgCount int) error

InsertSessionSimple upserts a session record with minimal fields using the global DB connection.

func InsertTokenUsage

func InsertTokenUsage(usage TokenUsage) error

InsertTokenUsage records a single API request's token usage and updates the parent session's aggregate totals.

func MergeProjects

func MergeProjects(oldPath, newPath string) (int, int, error)

MergeProjects moves all session/message history from oldPath to newPath. Used when a project directory is relocated on the filesystem. All operations run in a single transaction for atomicity.

func OpenReadOnlySQLite

func OpenReadOnlySQLite(path string) (*sql.DB, error)

OpenReadOnlySQLite opens an external SQLite database in read-only mode for indexing tool-specific databases (e.g. Cursor's state.vscdb, Crush's crush.db).

func PruneStaleProjects

func PruneStaleProjects() (int, error)

PruneStaleProjects removes disabled projects with no activity in the last 180 days.

func SetAPICredential

func SetAPICredential(provider string) error

SetAPICredential records that a provider's API key is configured and valid.

func SetProjectUserEnabled

func SetProjectUserEnabled(path string, enabled bool) error

SetProjectUserEnabled toggles the user_enabled flag for a project path.

func TxDeleteSessionMessages added in v1.3.0

func TxDeleteSessionMessages(tx *sql.Tx, sessionID string) error

TxDeleteSessionMessages removes all messages for a session within a transaction.

func TxInsertMessage added in v1.3.0

func TxInsertMessage(tx *sql.Tx, msg Message) error

TxInsertMessage inserts a message within a transaction.

func TxInsertSession added in v1.3.0

func TxInsertSession(tx *sql.Tx, sess Session) error

TxInsertSession inserts a session record within a transaction.

func TxInsertSessionSimple added in v1.3.0

func TxInsertSessionSimple(tx *sql.Tx, id, project, firstQuery, filePath, tool string, msgCount int) error

TxInsertSessionSimple inserts a session record (minimal fields) within a transaction.

func UpdateSessionTokens

func UpdateSessionTokens(sessionID string, inputTokens, outputTokens, cacheRead, cacheWrite int, costUSD float64, model, provider string) error

UpdateSessionTokens increments a session's aggregate token counts and cost.

func UpsertProject

func UpsertProject(path string, lastActivity time.Time) error

UpsertProject creates or updates a project entry, setting last_activity.

Types

type Message

type Message struct {
	ID               int64
	SessionID        string
	Project          string
	Role             string
	Content          string
	Timestamp        time.Time
	Tool             string
	Model            string
	Provider         string
	InputTokens      int
	OutputTokens     int
	CacheReadTokens  int
	CacheWriteTokens int
	ReasoningTokens  int
	CostUSD          float64
	MessageUUID      string
	ParentUUID       string
	WorkingDirectory string
	Agent            string
	Date             string
}

Message represents a single message within an AI coding session.

type ModelUsageSummary added in v1.3.0

type ModelUsageSummary struct {
	Sessions     int
	InputTokens  int
	OutputTokens int
	TotalTokens  int
	CostUSD      float64
}

ModelUsageSummary holds aggregate token usage for a single model.

type Project

type Project struct {
	ID           int64
	Path         string
	Name         string
	LastActivity time.Time
	Status       string
	UserEnabled  bool
	CreatedAt    time.Time
}

Project represents a tracked development directory. Projects are auto-discovered from working_directory fields in indexed sessions and classified by recency: active (<60 days), inactive (60-90 days), or archived (>90 days).

func GetEnabledProjects

func GetEnabledProjects() ([]Project, error)

GetEnabledProjects returns only projects the user has explicitly enabled.

func GetProjectByPath

func GetProjectByPath(path string) (*Project, error)

GetProjectByPath looks up a single project by its filesystem path.

func GetProjects

func GetProjects() ([]Project, error)

GetProjects returns all tracked projects ordered by last activity.

func GetProjectsByStatus

func GetProjectsByStatus(status string) ([]Project, error)

GetProjectsByStatus returns projects filtered by classification (active/inactive/archived).

type RecentSession added in v1.3.0

type RecentSession struct {
	ID           string
	Project      string
	FirstQuery   string
	MessageCount int
	Tool         string
	IndexedAt    time.Time
	Model        string
	Provider     string
	InputTokens  int
	OutputTokens int
	CostUSD      float64
}

RecentSession holds a session returned by GetRecentSessions.

func GetRecentSessions

func GetRecentSessions(limit int) ([]RecentSession, error)

GetRecentSessions returns the most recent sessions ordered by indexed_at descending.

type SearchResult

type SearchResult struct {
	SessionID string
	Project   string
	Role      string
	Content   string
	Snippet   string
	Rank      float64
	Tool      string
	Model     string
	Provider  string
}

SearchResult holds a single FTS5 search match with BM25 ranking. Snippet contains the matched text with \u27ea and \u27eb delimiters for highlighting.

func Search(query string, limit int) ([]SearchResult, error)

Search performs a full-text search using FTS5 with BM25 ranking. Results include highlighted snippets with \u27ea \u27eb delimiters.

type Session

type Session struct {
	ID                   string
	Project              string
	FirstQuery           string
	MessageCount         int
	Tool                 string
	FilePath             string
	IndexedAt            time.Time
	Model                string
	Provider             string
	TotalInputTokens     int
	TotalOutputTokens    int
	TotalCacheRead       int
	TotalCacheWrite      int
	TotalReasoningTokens int
	TotalCostUSD         float64
	CLIVersion           string
	GitBranch            string
	WorkingDirectory     string
	StartTime            time.Time
	EndTime              time.Time
	Agent                string
	Date                 string
}

Session aggregates all messages from a single AI coding conversation. The ID is typically derived from the source tool's session identifier.

type SessionBlock

type SessionBlock struct {
	ID            string
	StartTime     time.Time
	EndTime       time.Time // StartTime + 5 hours
	ActualEndTime time.Time // Last activity within block
	IsActive      bool      // Currently within this block's time window
	IsGap         bool      // No activity during this period
	InputTokens   int
	OutputTokens  int
	CacheRead     int
	CacheWrite    int
	CostUSD       float64
	Models        []string
	Providers     []string
	SessionCount  int
	MessageCount  int
	ResetTime     *time.Time // From Claude error messages (if available)
}

SessionBlock represents a 5-hour usage window (matching Claude's rate limit reset)

func GetActiveBlock

func GetActiveBlock() (*SessionBlock, error)

GetActiveBlock returns the current 5-hour block (if any activity exists)

func GetRecentBlocks

func GetRecentBlocks(count int) ([]SessionBlock, error)

GetRecentBlocks returns the last N blocks

func GetSessionBlocks

func GetSessionBlocks(days int) ([]SessionBlock, error)

GetSessionBlocks returns identified 5-hour blocks for a time range

func IdentifySessionBlocks

func IdentifySessionBlocks(entries []UsageEntry) []SessionBlock

IdentifySessionBlocks groups usage entries into 5-hour windows This mirrors ccusage's _session-blocks.ts logic

func (SessionBlock) CostPerHour

func (b SessionBlock) CostPerHour() float64

CostPerHour calculates hourly burn rate

func (SessionBlock) DurationMinutes

func (b SessionBlock) DurationMinutes() float64

DurationMinutes returns minutes of actual activity

func (SessionBlock) ProjectedCost

func (b SessionBlock) ProjectedCost() float64

ProjectedCost estimates cost at end of 5-hour window

func (SessionBlock) ProjectedTokens

func (b SessionBlock) ProjectedTokens() int

ProjectedTokens estimates tokens at end of 5-hour window

func (SessionBlock) RemainingTime

func (b SessionBlock) RemainingTime() time.Duration

RemainingTime returns time left in block

func (SessionBlock) TokensPerMinute

func (b SessionBlock) TokensPerMinute() float64

TokensPerMinute calculates burn rate

func (SessionBlock) TotalTokens

func (b SessionBlock) TotalTokens() int

TotalTokens returns sum of all token types

type SessionMatch

type SessionMatch struct {
	SessionID    string
	Project      string
	FirstQuery   string
	MessageCount int
	Tool         string
	StartTime    time.Time
	MatchCount   int
	BestRank     float64
	FinalScore   float64
	Snippet      string
	SnippetRole  string
}

SessionMatch holds a session-level search result with aggregated scoring. This is the primary return type for the redesigned search system.

func SearchGrouped

func SearchGrouped(query string, limit int) ([]SessionMatch, error)

SearchGrouped performs a session-level search with intelligent ranking. Fetches message-level FTS5 results, groups by session in Go, then enriches with session metadata. Ranked by BM25 * temporal_decay * density_bonus.

type TokenStats

type TokenStats struct {
	TotalInputTokens  int
	TotalOutputTokens int
	TotalCacheRead    int
	TotalCacheWrite   int
	TotalTokens       int
	TotalCostUSD      float64
	SessionCount      int
}

TokenStats holds aggregate token usage across multiple API requests.

func GetTokenStats

func GetTokenStats(days int) (TokenStats, error)

GetTokenStats returns aggregate token usage across all providers, optionally filtered to the last N days (0 means all time).

type TokenUsage

type TokenUsage struct {
	SessionID        string
	Model            string
	InputTokens      int
	OutputTokens     int
	CacheReadTokens  int
	CacheWriteTokens int
	TotalTokens      int
	CostUSD          float64
	Provider         string
	Timestamp        time.Time
}

TokenUsage represents a single API request's token consumption and cost.

type ToolUsageStats

type ToolUsageStats struct {
	Tool         string
	Provider     string
	InputTokens  int
	OutputTokens int
	CacheRead    int
	CacheWrite   int
	TotalTokens  int
	SessionCount int
}

ToolUsageStats represents token usage from a specific tool

func GetUsageByToolInWindow

func GetUsageByToolInWindow(provider string, windowStart, windowEnd time.Time) ([]ToolUsageStats, error)

GetUsageByToolInWindow returns token usage grouped by tool for a provider within a specific time window (e.g., current 5-hour block)

type ToolUsageSummary added in v1.3.0

type ToolUsageSummary struct {
	Sessions     int
	InputTokens  int
	OutputTokens int
	TotalTokens  int
	CostUSD      float64
}

ToolUsageSummary holds aggregate token usage for a single tool.

type UsageEntry

type UsageEntry struct {
	SessionID        string
	Timestamp        time.Time
	Model            string
	Provider         string
	InputTokens      int
	OutputTokens     int
	CacheReadTokens  int
	CacheWriteTokens int
	CostUSD          float64
}

UsageEntry represents a single token usage record for block identification

func GetUsageEntries

func GetUsageEntries(days int) ([]UsageEntry, error)

GetUsageEntries fetches token usage records for block identification. Falls back to the sessions table if the token_usage table is empty, which happens when data was indexed from session history rather than live-tracked via the proxy.

type UsageStats added in v1.3.0

type UsageStats struct {
	TotalInputTokens  int
	TotalOutputTokens int
	TotalCacheRead    int
	TotalCacheWrite   int
	TotalTokens       int
	TotalCostUSD      float64
	SessionCount      int
}

UsageStats holds aggregate token usage across all sessions.

func GetUsageStats

func GetUsageStats() (UsageStats, error)

GetUsageStats returns aggregate token usage computed from the sessions table.

Jump to

Keyboard shortcuts

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