(
range: String,
by_model: bool,
by_task: bool,
export: Option<String>,
)
| 4 | use tracedecay::global_db::GlobalDb; |
| 5 | |
| 6 | pub(crate) async fn handle_cost( |
| 7 | range: String, |
| 8 | by_model: bool, |
| 9 | by_task: bool, |
| 10 | export: Option<String>, |
| 11 | ) -> tracedecay::errors::Result<()> { |
| 12 | tracedecay::accounting::pricing::refresh_if_stale(); |
| 13 | |
| 14 | let gdb = match GlobalDb::open().await { |
| 15 | Some(db) => db, |
| 16 | None => { |
| 17 | eprintln!("Could not open global database."); |
| 18 | process::exit(1); |
| 19 | } |
| 20 | }; |
| 21 | |
| 22 | let ingest_stats = tracedecay::accounting::parser::ingest(&gdb).await; |
| 23 | if ingest_stats.turns_inserted > 0 { |
| 24 | eprintln!( |
| 25 | "Ingested {} new turns from Claude Code sessions.", |
| 26 | ingest_stats.turns_inserted |
| 27 | ); |
| 28 | } |
| 29 | |
| 30 | let since = tracedecay::accounting::metrics::parse_range(&range); |
| 31 | let tokens_saved = gdb.global_tokens_saved().await.unwrap_or(0); |
| 32 | let summary = tracedecay::accounting::metrics::cost_summary(&gdb, since, tokens_saved).await; |
| 33 | |
| 34 | let Some(summary) = summary else { |
| 35 | println!("No session data found. Use Claude Code and then run `tracedecay cost` to see spending."); |
| 36 | return Ok(()); |
| 37 | }; |
| 38 | |
| 39 | print_cost_summary(&gdb, &range, by_model, by_task, export.as_deref(), &summary).await; |
| 40 | Ok(()) |
| 41 | } |
| 42 | |
| 43 | async fn print_cost_summary( |
| 44 | gdb: &GlobalDb, |
no test coverage detected