pub struct DataStore { /* private fields */ }Expand description
Central data store for ccboard
Thread-safe access to all Claude Code data. Uses DashMap for sessions (high contention) and RwLock for stats/settings (low contention).
Implementations§
Source§impl DataStore
impl DataStore
Sourcepub fn new(
claude_home: PathBuf,
project_path: Option<PathBuf>,
config: DataStoreConfig,
) -> Self
pub fn new( claude_home: PathBuf, project_path: Option<PathBuf>, config: DataStoreConfig, ) -> Self
Create a new data store
Sourcepub fn with_defaults(
claude_home: PathBuf,
project_path: Option<PathBuf>,
) -> Self
pub fn with_defaults( claude_home: PathBuf, project_path: Option<PathBuf>, ) -> Self
Create with default configuration
Sourcepub fn degraded_state(&self) -> DegradedState
pub fn degraded_state(&self) -> DegradedState
Get current degraded state
Sourcepub async fn initial_load(&self) -> LoadReport
pub async fn initial_load(&self) -> LoadReport
Initial load of all data with LoadReport for graceful degradation
Sourcepub fn stats(&self) -> Option<StatsCache>
pub fn stats(&self) -> Option<StatsCache>
Get a clone of stats
Sourcepub fn context_window_stats(&self) -> ContextWindowStats
pub fn context_window_stats(&self) -> ContextWindowStats
Calculate context window saturation from current sessions
Sourcepub fn settings(&self) -> MergedConfig
pub fn settings(&self) -> MergedConfig
Get merged settings
Sourcepub fn mcp_config(&self) -> Option<McpConfig>
pub fn mcp_config(&self) -> Option<McpConfig>
Get MCP server configuration
Sourcepub fn invocation_stats(&self) -> InvocationStats
pub fn invocation_stats(&self) -> InvocationStats
Get invocation statistics
Sourcepub fn quota_status(&self) -> Option<QuotaStatus>
pub fn quota_status(&self) -> Option<QuotaStatus>
Calculate current quota status from stats and budget config
Returns None if stats are not loaded or budget is not configured.
Sourcepub fn live_sessions(&self) -> Vec<LiveSession>
pub fn live_sessions(&self) -> Vec<LiveSession>
Get live Claude Code sessions (running processes, ps-based)
Detects active Claude processes on the system and returns metadata. Returns empty vector if detection fails or no processes are running.
Sourcepub fn merged_live_sessions(&self) -> Vec<MergedLiveSession>
pub fn merged_live_sessions(&self) -> Vec<MergedLiveSession>
Get merged live sessions: hook data + ps-based fallback
Hook sessions are prioritized; unmatched ps sessions appear as ProcessOnly.
Sourcepub async fn reload_live_hook_sessions(&self, path: &Path)
pub async fn reload_live_hook_sessions(&self, path: &Path)
Reload hook-based live session state from a file path
Sourcepub fn claude_global_stats(&self) -> Option<ClaudeGlobalStats>
pub fn claude_global_stats(&self) -> Option<ClaudeGlobalStats>
Get per-project last session stats from ~/.claude.json
Sourcepub fn session_count(&self) -> usize
pub fn session_count(&self) -> usize
Get session count
Sourcepub fn get_session(&self, id: &str) -> Option<Arc<SessionMetadata>>
pub fn get_session(&self, id: &str) -> Option<Arc<SessionMetadata>>
Get session by ID
Returns Arc
Sourcepub async fn load_session_content(
&self,
session_id: &str,
) -> Result<Vec<ConversationMessage>, CoreError>
pub async fn load_session_content( &self, session_id: &str, ) -> Result<Vec<ConversationMessage>, CoreError>
Load full session content with lazy caching
Returns conversation messages parsed from session JSONL file. Uses Moka cache (LRU with 5min TTL) for repeated access.
§Performance
- First call: Parse JSONL (~50-500ms for 1000-message session)
- Cached calls: <1ms (memory lookup)
- Cache eviction: LRU + 5min idle timeout
§Errors
Returns CoreError if session not found or file cannot be read.
Sourcepub fn analytics(&self) -> Option<AnalyticsData>
pub fn analytics(&self) -> Option<AnalyticsData>
Get analytics data for a period (cached)
Returns cached analytics if available, otherwise None.
Call compute_analytics() to compute and cache.
Sourcepub async fn compute_analytics(&self, period: Period)
pub async fn compute_analytics(&self, period: Period)
Compute and cache analytics data for a period
This is a CPU-intensive operation (trends, forecasting, patterns). For 1000+ sessions, this may take 100-300ms, so it’s offloaded to a blocking task.
Cache is invalidated on stats reload or session updates (EventBus pattern).
Sourcepub fn discover(&self) -> Option<Vec<DiscoverSuggestion>>
pub fn discover(&self) -> Option<Vec<DiscoverSuggestion>>
Get cached discover suggestions (None if not yet computed)
Sourcepub async fn compute_discover(
&self,
max_sessions: usize,
min_count: usize,
top: usize,
)
pub async fn compute_discover( &self, max_sessions: usize, min_count: usize, top: usize, )
Extract user messages from recent sessions and run pattern discovery.
Loads JSONL content for up to max_sessions most recent sessions,
extracts user message text, and stores results in discover_cache.
Publishes DataEvent::AnalyticsUpdated on completion so the TUI re-renders.
Sourcepub fn session_ids(&self) -> Vec<SessionId>
pub fn session_ids(&self) -> Vec<SessionId>
Get all session IDs
Sourcepub fn clear_session_content_cache(&self)
pub fn clear_session_content_cache(&self)
Clear session content cache (for memory optimization on F5)
Sourcepub fn sessions_by_project(&self) -> HashMap<String, Vec<Arc<SessionMetadata>>>
pub fn sessions_by_project(&self) -> HashMap<String, Vec<Arc<SessionMetadata>>>
Get sessions grouped by project
Returns Arc
Sourcepub fn all_sessions(&self) -> Vec<Arc<SessionMetadata>>
pub fn all_sessions(&self) -> Vec<Arc<SessionMetadata>>
Get all sessions (unsorted)
Returns Arc
Sourcepub fn recent_sessions(&self, limit: usize) -> Vec<Arc<SessionMetadata>>
pub fn recent_sessions(&self, limit: usize) -> Vec<Arc<SessionMetadata>>
Get recent sessions (sorted by last timestamp, newest first)
Returns Arc
Sourcepub fn search_sessions(&self, query: &str, limit: usize) -> Vec<SearchResult>
pub fn search_sessions(&self, query: &str, limit: usize) -> Vec<SearchResult>
Search sessions using FTS5 full-text search.
Returns relevance-ranked results. Returns empty vec if FTS5 not initialized.
Sourcepub async fn analyze_session(&self, session_id: &str) -> Result<ActivitySummary>
pub async fn analyze_session(&self, session_id: &str) -> Result<ActivitySummary>
Analyze a session’s tool calls and generate activity summary + alerts.
Results are stored in the in-memory DashMap and the SQLite cache. Publishes DataEvent::AnalyticsUpdated on completion so the TUI re-renders.
Sourcepub fn get_session_activity(&self, session_id: &str) -> Option<ActivitySummary>
pub fn get_session_activity(&self, session_id: &str) -> Option<ActivitySummary>
Get the cached activity summary for a session (returns None if not yet analyzed).
Sourcepub fn get_all_stored_alerts(
&self,
min_severity: Option<&str>,
) -> Vec<StoredAlert>
pub fn get_all_stored_alerts( &self, min_severity: Option<&str>, ) -> Vec<StoredAlert>
Get all stored security alerts from the SQLite cache.
min_severity: optional filter — “Warning” or “Critical”
Sourcepub fn mcp_call_stats(&self) -> Vec<McpCallStat>
pub fn mcp_call_stats(&self) -> Vec<McpCallStat>
Aggregate MCP call stats from all analyzed sessions.
Returns one entry per server that has been called, sorted by call_count descending. Servers with 0 calls are omitted.
Sourcepub fn all_violations(&self) -> Vec<Alert>
pub fn all_violations(&self) -> Vec<Alert>
Consolidated violations feed: merges in-memory DashMap results (freshest) with SQLite-persisted alerts. DashMap takes priority for sessions analyzed this run.
Returns alerts sorted Critical → Warning → Info, then by timestamp descending.
Sourcepub fn top_sessions_by_tokens(&self, limit: usize) -> Vec<Arc<SessionMetadata>>
pub fn top_sessions_by_tokens(&self, limit: usize) -> Vec<Arc<SessionMetadata>>
Get top sessions by total tokens (sorted descending)
Returns Arc
Sourcepub fn top_models_by_tokens(&self) -> Vec<(String, u64)>
pub fn top_models_by_tokens(&self) -> Vec<(String, u64)>
Get top models by total tokens (aggregated, sorted descending) Returns (model_name, total_tokens) pairs
Sourcepub fn top_days_by_tokens(&self) -> Vec<(String, u64)>
pub fn top_days_by_tokens(&self) -> Vec<(String, u64)>
Get top days by total tokens (aggregated, sorted descending) Returns (date_string, total_tokens) pairs
Sourcepub fn projects_leaderboard(&self) -> Vec<ProjectLeaderboardEntry>
pub fn projects_leaderboard(&self) -> Vec<ProjectLeaderboardEntry>
Get project leaderboard with aggregated metrics
Returns all projects with session count, total tokens, total cost, and average session cost. Cost is calculated using accurate model-based pricing from the pricing module.
Sourcepub async fn reload_stats(&self)
pub async fn reload_stats(&self)
Reload stats (called on file change)
Sourcepub async fn reload_settings(&self)
pub async fn reload_settings(&self)
Reload settings from files (called when settings change)
Sourcepub async fn update_session(&self, path: &Path)
pub async fn update_session(&self, path: &Path)
Add or update a session (called when session file changes)
Sourcepub async fn compute_invocations(&self)
pub async fn compute_invocations(&self)
Compute invocation statistics from all sessions
This scans all session files to count agent/command/skill invocations. Should be called after initial load or when sessions are updated.
Sourcepub async fn compute_billing_blocks(&self)
pub async fn compute_billing_blocks(&self)
Compute billing blocks from all sessions
This scans all sessions with timestamps and aggregates usage into 5-hour billing blocks. Uses real model pricing based on token breakdown for accurate cost calculation.
Sourcepub fn billing_blocks(&self) -> RwLockReadGuard<'_, BillingBlockManager>
pub fn billing_blocks(&self) -> RwLockReadGuard<'_, BillingBlockManager>
Get billing blocks (read-only access)
Sourcepub fn usage_estimate(&self) -> UsageEstimate
pub fn usage_estimate(&self) -> UsageEstimate
Calculate usage estimate based on billing blocks and subscription plan
Sourcepub fn load_preferences(&self) -> CcboardPreferences
pub fn load_preferences(&self) -> CcboardPreferences
Load ccboard user preferences from the cache directory.
Sourcepub fn save_preferences(&self, prefs: &CcboardPreferences) -> Result<()>
pub fn save_preferences(&self, prefs: &CcboardPreferences) -> Result<()>
Save ccboard user preferences to the cache directory.
Sourcepub fn is_bookmarked(&self, session_id: &str) -> bool
pub fn is_bookmarked(&self, session_id: &str) -> bool
Returns true if the session is bookmarked
Sourcepub fn bookmark_entry(&self, session_id: &str) -> Option<BookmarkEntry>
pub fn bookmark_entry(&self, session_id: &str) -> Option<BookmarkEntry>
Returns the bookmark entry for a session, if any. Cloned to avoid holding the lock across an await point.
Sourcepub fn toggle_bookmark(&self, session_id: &str) -> Result<bool>
pub fn toggle_bookmark(&self, session_id: &str) -> Result<bool>
Toggle bookmark (add with default tag “bookmarked”, or remove).
Returns true if the session is now bookmarked.
Sourcepub fn upsert_bookmark(
&self,
session_id: &str,
tag: impl Into<String>,
note: Option<String>,
) -> Result<()>
pub fn upsert_bookmark( &self, session_id: &str, tag: impl Into<String>, note: Option<String>, ) -> Result<()>
Add or update a bookmark with a custom tag and optional note.
Sourcepub fn remove_bookmark(&self, session_id: &str) -> Result<bool>
pub fn remove_bookmark(&self, session_id: &str) -> Result<bool>
Remove a bookmark explicitly.
Sourcepub fn bookmark_count(&self) -> usize
pub fn bookmark_count(&self) -> usize
Number of bookmarked sessions
Sourcepub fn has_summary(&self, session_id: &str) -> bool
pub fn has_summary(&self, session_id: &str) -> bool
True if a cached LLM summary exists for this session
Sourcepub fn load_summary(&self, session_id: &str) -> Option<String>
pub fn load_summary(&self, session_id: &str) -> Option<String>
Load cached summary text, or None if not yet generated
Sourcepub fn subagent_children(&self, parent_id: &str) -> Vec<Arc<SessionMetadata>>
pub fn subagent_children(&self, parent_id: &str) -> Vec<Arc<SessionMetadata>>
Returns all direct subagent sessions of the given parent session ID.
A session is a subagent if its parent_session_id == parent_id.
Sourcepub fn compute_has_subagents(&self)
pub fn compute_has_subagents(&self)
Backfills has_subagents on all sessions based on cross-references.
A session has subagents if any other session has parent_session_id == this_id.
Called once after initial_load() completes.