wsb 0.196.4203

Workspace - A tool suite for file operations, version management, and development workflow automation
Documentation
use crate::prelude::*;
use chrono::Utc;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DBSession {
    pub id: String,
    pub project: String,
    pub machine: String,
    pub agent: String,
    pub first_message: Option<String>,
    pub display_name: Option<String>,
    pub started_at: Option<String>,
    pub ended_at: Option<String>,
    pub message_count: i64,
    pub user_message_count: i64,
    pub file_path: Option<String>,
    pub file_size: Option<i64>,
    pub file_mtime: Option<i64>,
    pub file_hash: Option<String>,
    pub parent_session_id: Option<String>,
    pub relationship_type: String,
    pub total_output_tokens: i64,
    pub peak_context_tokens: i64,
    pub has_total_output_tokens: bool,
    pub has_peak_context_tokens: bool,
    pub is_automated: bool,
    pub cwd: String,
    pub git_branch: String,
    pub source_session_id: String,
    pub source_version: String,
    pub parser_malformed_lines: i64,
    pub is_truncated: bool,
    pub deleted_at: Option<String>,
    pub created_at: String,
}

impl DBSession {
    pub fn new(id: String, project: String, machine: String, agent: String) -> Self {
        Self {
            id,
            project,
            machine,
            agent,
            first_message: None,
            display_name: None,
            started_at: None,
            ended_at: None,
            message_count: 0,
            user_message_count: 0,
            file_path: None,
            file_size: None,
            file_mtime: None,
            file_hash: None,
            parent_session_id: None,
            relationship_type: String::new(),
            total_output_tokens: 0,
            peak_context_tokens: 0,
            has_total_output_tokens: false,
            has_peak_context_tokens: false,
            is_automated: false,
            cwd: String::new(),
            git_branch: String::new(),
            source_session_id: String::new(),
            source_version: String::new(),
            parser_malformed_lines: 0,
            is_truncated: false,
            deleted_at: None,
            created_at: Utc::now().to_rfc3339(),
        }
    }
}

#[derive(Debug, Clone)]
pub struct SessionInsert {
    pub id: String,
    pub project: String,
    pub machine: String,
    pub agent: String,
    pub first_message: Option<String>,
    pub started_at: Option<String>,
    pub ended_at: Option<String>,
    pub message_count: i64,
    pub user_message_count: i64,
    pub file_path: Option<String>,
    pub file_size: Option<i64>,
    pub file_mtime: Option<i64>,
    pub file_hash: Option<String>,
    pub parent_session_id: Option<String>,
    pub relationship_type: String,
    pub total_output_tokens: i64,
    pub peak_context_tokens: i64,
    pub has_total_output_tokens: bool,
    pub has_peak_context_tokens: bool,
    pub is_automated: bool,
    pub cwd: String,
    pub git_branch: String,
    pub source_session_id: String,
    pub source_version: String,
    pub parser_malformed_lines: i64,
    pub is_truncated: bool,
}

impl Default for SessionInsert {
    fn default() -> Self {
        Self {
            id: String::new(),
            project: "unknown".to_string(),
            machine: "local".to_string(),
            agent: "claude".to_string(),
            first_message: None,
            started_at: None,
            ended_at: None,
            message_count: 0,
            user_message_count: 0,
            file_path: None,
            file_size: None,
            file_mtime: None,
            file_hash: None,
            parent_session_id: None,
            relationship_type: String::new(),
            total_output_tokens: 0,
            peak_context_tokens: 0,
            has_total_output_tokens: false,
            has_peak_context_tokens: false,
            is_automated: false,
            cwd: String::new(),
            git_branch: String::new(),
            source_session_id: String::new(),
            source_version: String::new(),
            parser_malformed_lines: 0,
            is_truncated: false,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionFileInfo {
    pub file_path: Option<String>,
    pub file_size: Option<i64>,
    pub file_mtime: Option<i64>,
    pub file_hash: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchResult {
    pub session_id: String,
    pub project: String,
    pub agent: String,
    pub name: String,
    pub ordinal: i64,
    pub session_ended_at: Option<String>,
    pub snippet: String,
    pub rank: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pin {
    pub id: i64,
    pub session_id: String,
    pub message_id: i64,
    pub ordinal: i64,
    pub note: Option<String>,
    pub created_at: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub content: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub role: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session_project: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session_agent: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session_display_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub session_first_message: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Stats {
    pub session_count: i64,
    pub message_count: i64,
    pub project_count: i64,
    pub machine_count: i64,
    pub earliest_session: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProjectInfo {
    pub name: String,
    pub session_count: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentInfo {
    pub name: String,
    pub session_count: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UsageSummary {
    pub total_input_tokens: i64,
    pub total_output_tokens: i64,
    pub total_cache_creation_tokens: i64,
    pub total_cache_read_tokens: i64,
    pub estimated_cost_usd: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DailyUsage {
    pub date: String,
    pub session_count: i64,
    pub message_count: i64,
    pub input_tokens: i64,
    pub output_tokens: i64,
    pub cache_creation_tokens: i64,
    pub cache_read_tokens: i64,
    pub estimated_cost_usd: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelUsage {
    pub model: String,
    pub session_count: i64,
    pub input_tokens: i64,
    pub output_tokens: i64,
    pub cache_creation_tokens: i64,
    pub cache_read_tokens: i64,
    pub estimated_cost_usd: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProjectUsage {
    pub project: String,
    pub session_count: i64,
    pub message_count: i64,
    pub input_tokens: i64,
    pub output_tokens: i64,
    pub cache_creation_tokens: i64,
    pub cache_read_tokens: i64,
    pub estimated_cost_usd: f64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UsageFilter {
    pub date_from: Option<String>,
    pub date_to: Option<String>,
    pub project: Option<String>,
    pub agent: Option<String>,
    pub model: Option<String>,
}

#[derive(Debug, Default, Clone)]
pub struct SessionFilter {
    pub project: Option<String>,
    pub exclude_project: Option<String>,
    pub machine: Option<Vec<String>>,
    pub agent: Option<Vec<String>>,
    pub date: Option<String>,
    pub date_from: Option<String>,
    pub date_to: Option<String>,
    pub active_since: Option<String>,
    pub min_messages: Option<i64>,
    pub max_messages: Option<i64>,
    pub min_user_messages: Option<i64>,
    pub include_one_shot: bool,
    pub include_children: bool,
}