1use crate::colors::SectionColors;
2use crate::utils::visible_len;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, PartialEq, Debug)]
6pub enum SectionKind {
7 Generic,
8 QuotaCompact(String),
9 QuotaDetailed(String),
10 ContextCompact,
11 ContextDetailed,
12}
13
14#[derive(Clone)]
15pub struct Section {
16 pub kind: SectionKind,
17 pub content: String,
18 pub priority: u16, pub colors: SectionColors, pub width: usize, }
22
23impl Section {
24 pub fn with_kind(
25 kind: SectionKind,
26 content: String,
27 priority: u16,
28 colors: SectionColors,
29 ) -> Self {
30 let width = visible_len(&content);
31 Section {
32 kind,
33 content,
34 priority,
35 colors,
36 width,
37 }
38 }
39
40 pub fn new(content: String, priority: u16, colors: SectionColors) -> Self {
41 Self::with_kind(SectionKind::Generic, content, priority, colors)
42 }
43
44 pub fn new_quota_compact(
45 label: &str,
46 content: String,
47 priority: u16,
48 colors: SectionColors,
49 ) -> Self {
50 Self::with_kind(
51 SectionKind::QuotaCompact(label.to_string()),
52 content,
53 priority,
54 colors,
55 )
56 }
57
58 pub fn new_quota_detailed(
59 label: &str,
60 content: String,
61 priority: u16,
62 colors: SectionColors,
63 ) -> Self {
64 Self::with_kind(
65 SectionKind::QuotaDetailed(label.to_string()),
66 content,
67 priority,
68 colors,
69 )
70 }
71
72 pub fn new_context_compact(content: String, priority: u16, colors: SectionColors) -> Self {
73 Self::with_kind(SectionKind::ContextCompact, content, priority, colors)
74 }
75
76 pub fn new_context_detailed(content: String, priority: u16, colors: SectionColors) -> Self {
77 Self::with_kind(SectionKind::ContextDetailed, content, priority, colors)
78 }
79}
80
81#[derive(Clone, Copy, Debug, PartialEq, Eq)]
82pub enum ContextAccuracy {
83 Exact,
84 Estimated,
85}
86
87pub struct ContextUsageInfo {
89 pub percentage: f64,
90 pub current_usage_tokens: u64,
91 pub context_window_size: Option<u64>,
92 pub accuracy: ContextAccuracy,
93}
94
95#[derive(Debug, Deserialize, Clone)]
96pub struct ClaudeInput {
97 pub cwd: Option<String>,
98 pub workspace: Option<Workspace>,
99 pub model: Option<Model>,
100 pub context_window: Option<ContextWindow>,
101 pub cost: Option<Cost>,
102 pub output_style: Option<OutputStyle>,
103 pub worktree: Option<Worktree>,
104 pub version: Option<String>,
105}
106
107#[derive(Debug, Deserialize, Clone)]
108pub struct Workspace {
109 pub current_dir: Option<String>,
110 pub project_dir: Option<String>,
111 pub added_dirs: Option<Vec<String>>,
112}
113
114#[derive(Debug, Deserialize, Clone)]
115pub struct Model {
116 pub id: Option<String>,
117 pub display_name: Option<String>,
118}
119
120#[derive(Debug, Deserialize, Clone)]
121pub struct OutputStyle {
122 pub name: Option<String>,
123}
124
125#[derive(Debug, Deserialize, Clone)]
126pub struct ContextWindow {
127 pub context_window_size: Option<u64>,
128 pub total_input_tokens: Option<u64>,
129 pub total_output_tokens: Option<u64>,
130 pub current_usage: Option<CurrentUsage>,
131 pub used_percentage: Option<f64>,
132 pub remaining_percentage: Option<f64>,
133}
134
135#[derive(Debug, Deserialize, Clone)]
136pub struct CurrentUsage {
137 pub input_tokens: Option<u64>,
138 #[serde(alias = "_output_tokens")]
139 pub output_tokens: Option<u64>,
140 pub cache_creation_input_tokens: Option<u64>,
141 pub cache_read_input_tokens: Option<u64>,
142}
143
144#[derive(Debug, Deserialize, Clone)]
145pub struct Cost {
146 pub total_cost_usd: Option<f64>,
147 pub total_duration_ms: Option<u64>,
148 pub total_api_duration_ms: Option<u64>,
149 pub total_lines_added: Option<u64>,
150 pub total_lines_removed: Option<u64>,
151}
152
153#[derive(Debug, Deserialize, Clone)]
154pub struct Worktree {
155 pub name: Option<String>,
156 pub path: Option<String>,
157 pub branch: Option<String>,
158 pub original_cwd: Option<String>,
159 pub original_branch: Option<String>,
160}
161
162#[derive(Debug, Deserialize)]
163pub struct QuotaResponse {
164 pub five_hour: Option<QuotaLimit>,
165 pub seven_day: Option<QuotaLimit>,
166}
167
168#[derive(Debug, Deserialize)]
169pub struct ApiErrorResponse {
170 pub error: ApiErrorBody,
171}
172
173#[derive(Debug, Deserialize)]
174pub struct ApiErrorBody {
175 #[serde(rename = "type")]
176 pub error_type: Option<String>,
177 pub message: Option<String>,
178}
179
180#[derive(Debug, Deserialize)]
181pub struct QuotaLimit {
182 pub utilization: f64,
183 pub resets_at: Option<String>,
184}
185
186#[derive(Debug, Deserialize)]
187pub struct KeychainCredentials {
188 #[serde(rename = "claudeAiOauth")]
189 pub claude_ai_oauth: Option<OAuthCredentials>,
190}
191
192#[derive(Debug, Deserialize)]
193pub struct OAuthCredentials {
194 #[serde(rename = "accessToken")]
195 pub access_token: String,
196}
197
198#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
200pub struct QuotaData {
201 pub five_hour_pct: Option<f64>,
202 pub five_hour_resets_at: Option<String>,
203 pub seven_day_pct: Option<f64>,
204 pub seven_day_resets_at: Option<String>,
205}
206
207#[derive(Debug, Serialize, Deserialize, Clone)]
208pub struct CachedQuota {
209 pub timestamp: u64,
210 pub data: QuotaData,
211}
212
213#[derive(Debug, Default, Serialize, Deserialize, Clone)]
214pub struct QuotaCacheState {
215 pub last_success_at: Option<u64>,
216 pub last_success_data: Option<QuotaData>,
217 pub next_retry_at: Option<u64>,
218 pub last_error_kind: Option<String>,
219 pub retry_after_secs: Option<u64>,
220 pub refresh_in_progress_until: Option<u64>,
221}
222
223#[derive(Debug, PartialEq)]
224pub struct GitInfo {
225 pub branch: String,
226 pub is_dirty: bool,
227 pub repo_name: Option<String>,
228 pub lines_added: usize,
229 pub lines_removed: usize,
230}