lean_ctx/cli/
ledger_cmd.rs1use crate::core::context_ledger::ContextLedger;
2
3pub fn cmd_ledger(args: &[String]) {
4 let action = args.first().map_or("status", String::as_str);
5
6 match action {
7 "status" => {
8 #[cfg(unix)]
9 if let Some(out) = crate::daemon_client::try_daemon_tool_call_blocking_text(
10 "ctx_ledger",
11 Some(serde_json::json!({ "action": "status" })),
12 ) {
13 println!("{out}");
14 return;
15 }
16 let ledger = ContextLedger::load();
17 let pressure = ledger.pressure();
18 println!(
19 "Context pressure: {:.0}% ({}/{} tokens)",
20 pressure.utilization * 100.0,
21 ledger.total_tokens_sent,
22 ledger.window_size,
23 );
24 println!("Entries: {}", ledger.entries.len());
25 println!("Recommendation: {:?}", pressure.recommendation);
26 let top = ledger.files_by_token_cost();
27 if !top.is_empty() {
28 println!("Top files by cost:");
29 for (path, tokens) in top.iter().take(5) {
30 println!(" {path} ({tokens} tok)");
31 }
32 }
33 }
34
35 "reset" => {
36 #[cfg(unix)]
37 if let Some(out) = crate::daemon_client::try_daemon_tool_call_blocking_text(
38 "ctx_ledger",
39 Some(serde_json::json!({ "action": "reset" })),
40 ) {
41 println!("{out}");
42 return;
43 }
44 let mut ledger = ContextLedger::load();
45 let prev_entries = ledger.entries.len();
46 let prev_tokens = ledger.total_tokens_sent;
47 ledger.reset();
48 ledger.save();
49 println!(
50 "Ledger reset. Removed {prev_entries} entries, freed {prev_tokens} tracked tokens. Pressure: 0%."
51 );
52 }
53
54 "evict" => {
55 let targets: Vec<&str> = args[1..].iter().map(String::as_str).collect();
56 if targets.is_empty() {
57 eprintln!("Usage: lean-ctx ledger evict <file1> [file2...]");
58 std::process::exit(1);
59 }
60
61 #[cfg(unix)]
62 {
63 let targets_joined = targets.join(", ");
64 if let Some(out) = crate::daemon_client::try_daemon_tool_call_blocking_text(
65 "ctx_ledger",
66 Some(serde_json::json!({ "action": "evict", "targets": targets_joined })),
67 ) {
68 println!("{out}");
69 return;
70 }
71 }
72
73 let mut ledger = ContextLedger::load();
74 let removed = ledger.evict_paths(&targets);
75 ledger.save();
76 let pressure = ledger.pressure();
77 println!(
78 "Evicted {removed}/{} target(s). Pressure now: {:.0}%.",
79 targets.len(),
80 pressure.utilization * 100.0,
81 );
82 }
83
84 "prune" => {
85 let mut ledger = ContextLedger::load();
86 let pruned = ledger.prune();
87 ledger.save();
88 let pressure = ledger.pressure();
89 println!(
90 "Pruned {pruned} entries. Remaining: {}. Pressure: {:.0}%.",
91 ledger.entries.len(),
92 pressure.utilization * 100.0,
93 );
94 }
95
96 _ => {
97 eprintln!("Usage: lean-ctx ledger <status|reset|evict|prune> [args...]");
98 std::process::exit(1);
99 }
100 }
101}