1use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7pub struct SymbolFact {
8 pub path: String,
9 pub name: String,
10 pub kind: String,
11 pub complexity: u32,
12 pub calls: Vec<String>,
13 pub start_byte: usize,
14 pub end_byte: usize,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
18pub struct FileFact {
19 pub snapshot_id: String,
20 pub path: String,
21 pub language: String,
22 pub bytes: u64,
23 pub loc: u32,
24 pub sloc: u32,
25 pub complexity_total: u32,
26 pub max_fn_complexity: u32,
27 pub symbol_count: u32,
28 pub import_count: u32,
29 pub fan_in: u32,
30 pub fan_out: u32,
31 pub churn_30d: u32,
32 pub churn_90d: u32,
33 pub authors_90d: u32,
34 pub last_changed_ms: Option<u64>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
38pub struct RepoEdge {
39 pub from_path: String,
40 pub to_path: String,
41 pub kind: String,
42 pub weight: u32,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
46pub struct RepoSnapshotRecord {
47 pub id: String,
48 pub workspace: String,
49 pub head_commit: Option<String>,
50 pub dirty_fingerprint: String,
51 pub analyzer_version: String,
52 pub indexed_at_ms: u64,
53 pub dirty: bool,
54 pub graph_path: String,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
58pub struct ToolSpanView {
59 pub span_id: String,
60 pub tool: String,
61 pub status: String,
62 pub lead_time_ms: Option<u64>,
63 pub tokens_in: Option<u32>,
64 pub tokens_out: Option<u32>,
65 pub reasoning_tokens: Option<u32>,
66 pub cost_usd_e6: Option<i64>,
67 pub paths: Vec<String>,
68 pub parent_span_id: Option<String>,
69 pub depth: u32,
70 pub subtree_cost_usd_e6: Option<i64>,
71 pub subtree_token_count: Option<u32>,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
75pub struct RankedFile {
76 pub path: String,
77 pub value: u64,
78 pub complexity_total: u32,
79 pub churn_30d: u32,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
83pub struct RankedTool {
84 pub tool: String,
85 pub calls: u64,
86 pub p50_ms: Option<u64>,
87 pub p95_ms: Option<u64>,
88 pub total_tokens: u64,
89 pub total_reasoning_tokens: u64,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
93pub struct MetricsReport {
94 pub snapshot: Option<RepoSnapshotRecord>,
95 pub hottest_files: Vec<RankedFile>,
96 pub most_changed_files: Vec<RankedFile>,
97 pub most_complex_files: Vec<RankedFile>,
98 pub highest_risk_files: Vec<RankedFile>,
99 pub slowest_tools: Vec<RankedTool>,
100 pub highest_token_tools: Vec<RankedTool>,
101 pub highest_reasoning_tools: Vec<RankedTool>,
102 pub agent_pain_hotspots: Vec<RankedFile>,
103}
104
105#[derive(Debug, Clone, Default, PartialEq, Eq)]
106pub struct FileHistory {
107 pub churn_30d: u32,
108 pub churn_90d: u32,
109 pub authors_90d: u32,
110 pub last_changed_ms: Option<u64>,
111}
112
113#[derive(Debug, Clone, Default, PartialEq, Eq)]
114pub struct RepoAnalysis {
115 pub path: String,
116 pub language: String,
117 pub bytes: u64,
118 pub loc: u32,
119 pub sloc: u32,
120 pub complexity_total: u32,
121 pub max_fn_complexity: u32,
122 pub imports: Vec<String>,
123 pub symbols: Vec<SymbolFact>,
124}