kaizen-cli 0.1.15

Distributable agent observability: real-time-tailable sessions, agile-style retros, and repo-level improvement (Cursor, Claude Code, Codex). SQLite, redact before any sync you enable.
Documentation
// SPDX-License-Identifier: AGPL-3.0-or-later
//! Smart metric data. Pure structs only.

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SymbolFact {
    pub path: String,
    pub name: String,
    pub kind: String,
    pub complexity: u32,
    pub calls: Vec<String>,
    pub start_byte: usize,
    pub end_byte: usize,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct FileFact {
    pub snapshot_id: String,
    pub path: String,
    pub language: String,
    pub bytes: u64,
    pub loc: u32,
    pub sloc: u32,
    pub complexity_total: u32,
    pub max_fn_complexity: u32,
    pub symbol_count: u32,
    pub import_count: u32,
    pub fan_in: u32,
    pub fan_out: u32,
    pub churn_30d: u32,
    pub churn_90d: u32,
    pub authors_90d: u32,
    pub last_changed_ms: Option<u64>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RepoEdge {
    pub from_path: String,
    pub to_path: String,
    pub kind: String,
    pub weight: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RepoSnapshotRecord {
    pub id: String,
    pub workspace: String,
    pub head_commit: Option<String>,
    pub dirty_fingerprint: String,
    pub analyzer_version: String,
    pub indexed_at_ms: u64,
    pub dirty: bool,
    pub graph_path: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ToolSpanView {
    pub span_id: String,
    pub tool: String,
    pub status: String,
    pub lead_time_ms: Option<u64>,
    pub tokens_in: Option<u32>,
    pub tokens_out: Option<u32>,
    pub reasoning_tokens: Option<u32>,
    pub cost_usd_e6: Option<i64>,
    pub paths: Vec<String>,
    pub parent_span_id: Option<String>,
    pub depth: u32,
    pub subtree_cost_usd_e6: Option<i64>,
    pub subtree_token_count: Option<u32>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RankedFile {
    pub path: String,
    pub value: u64,
    pub complexity_total: u32,
    pub churn_30d: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RankedTool {
    pub tool: String,
    pub calls: u64,
    pub p50_ms: Option<u64>,
    pub p95_ms: Option<u64>,
    pub total_tokens: u64,
    pub total_reasoning_tokens: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct MetricsReport {
    pub snapshot: Option<RepoSnapshotRecord>,
    pub hottest_files: Vec<RankedFile>,
    pub most_changed_files: Vec<RankedFile>,
    pub most_complex_files: Vec<RankedFile>,
    pub highest_risk_files: Vec<RankedFile>,
    pub slowest_tools: Vec<RankedTool>,
    pub highest_token_tools: Vec<RankedTool>,
    pub highest_reasoning_tools: Vec<RankedTool>,
    pub agent_pain_hotspots: Vec<RankedFile>,
}

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct FileHistory {
    pub churn_30d: u32,
    pub churn_90d: u32,
    pub authors_90d: u32,
    pub last_changed_ms: Option<u64>,
}

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct RepoAnalysis {
    pub path: String,
    pub language: String,
    pub bytes: u64,
    pub loc: u32,
    pub sloc: u32,
    pub complexity_total: u32,
    pub max_fn_complexity: u32,
    pub imports: Vec<String>,
    pub symbols: Vec<SymbolFact>,
}