Skip to main content

lean_ctx/cli/
discover_cmd.rs

1use super::common::load_shell_history;
2
3pub fn cmd_discover(_args: &[String]) {
4    let history = load_shell_history();
5    if history.is_empty() {
6        println!("No shell history found.");
7        return;
8    }
9
10    let result = crate::tools::ctx_discover::analyze_history(&history, 20);
11    println!("{}", crate::tools::ctx_discover::format_cli_output(&result));
12}
13
14pub fn cmd_ghost(args: &[String]) {
15    let json = args.iter().any(|a| a == "--json");
16
17    let history = load_shell_history();
18    let discover = crate::tools::ctx_discover::analyze_history(&history, 20);
19
20    let session = crate::core::session::SessionState::load_latest();
21    let store = crate::core::stats::load();
22
23    let unoptimized_tokens = discover.potential_tokens;
24    let _unoptimized_usd = discover.potential_usd;
25
26    let redundant_reads = store.cep.total_cache_hits as usize;
27    let redundant_tokens = redundant_reads * 200;
28
29    let wasted_original = store
30        .cep
31        .total_tokens_original
32        .saturating_sub(store.cep.total_tokens_compressed) as usize;
33    let truncated_tokens = wasted_original / 3;
34
35    let total_ghost = unoptimized_tokens + redundant_tokens + truncated_tokens;
36    let total_usd =
37        total_ghost as f64 * crate::core::stats::DEFAULT_INPUT_PRICE_PER_M / 1_000_000.0;
38    let monthly_usd = total_usd * 30.0;
39
40    if json {
41        let obj = serde_json::json!({
42            "ghost_tokens": total_ghost,
43            "breakdown": {
44                "unoptimized_shells": unoptimized_tokens,
45                "redundant_reads": redundant_tokens,
46                "truncated_contexts": truncated_tokens,
47            },
48            "estimated_usd": total_usd,
49            "monthly_usd": monthly_usd,
50            "session_active": session.is_some(),
51            "history_commands": discover.total_commands,
52            "already_optimized": discover.already_optimized,
53        });
54        println!("{}", serde_json::to_string_pretty(&obj).unwrap_or_default());
55        return;
56    }
57
58    let bold = "\x1b[1m";
59    let green = "\x1b[32m";
60    let yellow = "\x1b[33m";
61    let red = "\x1b[31m";
62    let dim = "\x1b[2m";
63    let rst = "\x1b[0m";
64    let white = "\x1b[97m";
65
66    println!();
67    println!("  {bold}{white}lean-ctx ghost report{rst}");
68    println!("  {dim}{}{rst}", "=".repeat(40));
69    println!();
70
71    if total_ghost == 0 {
72        println!("  {green}No ghost tokens detected!{rst}");
73        println!(
74            "  {dim}All {} commands optimized.{rst}",
75            discover.total_commands
76        );
77        println!();
78        return;
79    }
80
81    let severity = if total_ghost > 10000 {
82        red
83    } else if total_ghost > 3000 {
84        yellow
85    } else {
86        green
87    };
88
89    println!(
90        "  {bold}Ghost Tokens found:{rst}     {severity}{total_ghost:>8}{rst} tokens {dim}(~${total_usd:.2}){rst}"
91    );
92    println!();
93
94    if unoptimized_tokens > 0 {
95        let missed_count: u32 = discover.missed_commands.iter().map(|m| m.count).sum();
96        println!(
97            "  {dim}  Unoptimized shells:{rst}  {white}{unoptimized_tokens:>8}{rst} {dim}({missed_count} cmds without lean-ctx){rst}"
98        );
99    }
100    if redundant_tokens > 0 {
101        println!(
102            "  {dim}  Redundant reads:{rst}     {white}{redundant_tokens:>8}{rst} {dim}({redundant_reads} cache hits = wasted re-reads){rst}"
103        );
104    }
105    if truncated_tokens > 0 {
106        println!(
107            "  {dim}  Oversized contexts:{rst}  {white}{truncated_tokens:>8}{rst} {dim}(uncompressed portion of tool results){rst}"
108        );
109    }
110
111    println!();
112    println!("  {bold}Monthly savings potential:{rst} {green}${monthly_usd:.2}{rst}");
113
114    if !discover.missed_commands.is_empty() {
115        println!();
116        println!("  {bold}Top unoptimized commands:{rst}");
117        for m in discover.missed_commands.iter().take(5) {
118            println!(
119                "    {dim}{:>4}x{rst}  {white}{:<12}{rst} {dim}{}{rst}",
120                m.count, m.prefix, m.description
121            );
122        }
123    }
124
125    println!();
126    if discover.already_optimized == 0 {
127        println!(
128            "  {yellow}Run '{bold}lean-ctx setup{rst}{yellow}' to eliminate ghost tokens.{rst}"
129        );
130    } else {
131        println!(
132            "  {dim}Already optimized: {}/{} commands{rst}",
133            discover.already_optimized, discover.total_commands
134        );
135    }
136    println!();
137}