Skip to main content

lean_ctx/cli/
tee_cmd.rs

1pub fn cmd_tee(args: &[String]) {
2    let tee_dir = if let Some(h) = dirs::home_dir() {
3        h.join(".lean-ctx").join("tee")
4    } else {
5        eprintln!("Cannot determine home directory");
6        std::process::exit(1);
7    };
8
9    let action = args.first().map_or("list", std::string::String::as_str);
10    match action {
11        "list" | "ls" => {
12            if !tee_dir.exists() {
13                println!("No tee logs found (~/.lean-ctx/tee/ does not exist)");
14                return;
15            }
16            let mut entries: Vec<_> = std::fs::read_dir(&tee_dir)
17                .unwrap_or_else(|e| {
18                    eprintln!("Error: {e}");
19                    std::process::exit(1);
20                })
21                .filter_map(std::result::Result::ok)
22                .filter(|e| e.path().extension().and_then(|x| x.to_str()) == Some("log"))
23                .collect();
24            entries.sort_by_key(std::fs::DirEntry::file_name);
25
26            if entries.is_empty() {
27                println!("No tee logs found.");
28                return;
29            }
30
31            println!("Tee logs ({}):\n", entries.len());
32            for entry in &entries {
33                let size = entry.metadata().map_or(0, |m| m.len());
34                let name = entry.file_name();
35                let size_str = if size > 1024 {
36                    format!("{}K", size / 1024)
37                } else {
38                    format!("{size}B")
39                };
40                println!("  {:<60} {}", name.to_string_lossy(), size_str);
41            }
42            println!("\nUse 'lean-ctx tee clear' to delete all logs.");
43        }
44        "clear" | "purge" => {
45            if !tee_dir.exists() {
46                println!("No tee logs to clear.");
47                return;
48            }
49            let mut count = 0u32;
50            if let Ok(entries) = std::fs::read_dir(&tee_dir) {
51                for entry in entries.flatten() {
52                    if entry.path().extension().and_then(|x| x.to_str()) == Some("log")
53                        && std::fs::remove_file(entry.path()).is_ok()
54                    {
55                        count += 1;
56                    }
57                }
58            }
59            println!("Cleared {count} tee log(s) from {}", tee_dir.display());
60        }
61        "show" => {
62            let Some(filename) = args.get(1) else {
63                eprintln!("Usage: lean-ctx tee show <filename>");
64                std::process::exit(1);
65            };
66            let path = tee_dir.join(filename);
67            match crate::tools::ctx_read::read_file_lossy(&path.to_string_lossy()) {
68                Ok(content) => print!("{content}"),
69                Err(e) => {
70                    eprintln!("Error reading {}: {e}", path.display());
71                    std::process::exit(1);
72                }
73            }
74        }
75        "last" => {
76            if !tee_dir.exists() {
77                println!("No tee logs found.");
78                return;
79            }
80            let mut entries: Vec<_> = std::fs::read_dir(&tee_dir)
81                .ok()
82                .into_iter()
83                .flat_map(|d| d.filter_map(std::result::Result::ok))
84                .filter(|e| e.path().extension().and_then(|x| x.to_str()) == Some("log"))
85                .collect();
86            entries.sort_by_key(|e| {
87                e.metadata()
88                    .and_then(|m| m.modified())
89                    .unwrap_or(std::time::SystemTime::UNIX_EPOCH)
90            });
91            match entries.last() {
92                Some(entry) => {
93                    let path = entry.path();
94                    println!(
95                        "--- {} ---\n",
96                        path.file_name().unwrap_or_default().to_string_lossy()
97                    );
98                    match crate::tools::ctx_read::read_file_lossy(&path.to_string_lossy()) {
99                        Ok(content) => print!("{content}"),
100                        Err(e) => eprintln!("Error: {e}"),
101                    }
102                }
103                None => println!("No tee logs found."),
104            }
105        }
106        _ => {
107            eprintln!("Usage: lean-ctx tee [list|clear|show <file>|last]");
108            std::process::exit(1);
109        }
110    }
111}
112
113pub fn cmd_filter(args: &[String]) {
114    let action = args.first().map_or("list", std::string::String::as_str);
115    match action {
116        "list" | "ls" => {
117            if let Some(engine) = crate::core::filters::FilterEngine::load() {
118                let rules = engine.list_rules();
119                println!("Loaded {} filter rule(s):\n", rules.len());
120                for rule in &rules {
121                    println!("{rule}");
122                }
123            } else {
124                println!("No custom filters found.");
125                println!("Create one: lean-ctx filter init");
126            }
127        }
128        "validate" => {
129            let Some(path) = args.get(1) else {
130                eprintln!("Usage: lean-ctx filter validate <file.toml>");
131                std::process::exit(1);
132            };
133            match crate::core::filters::validate_filter_file(path) {
134                Ok(count) => println!("Valid: {count} rule(s) parsed successfully."),
135                Err(e) => {
136                    eprintln!("Validation failed: {e}");
137                    std::process::exit(1);
138                }
139            }
140        }
141        "init" => match crate::core::filters::create_example_filter() {
142            Ok(path) => {
143                println!("Created example filter: {path}");
144                println!("Edit it to add your custom compression rules.");
145            }
146            Err(e) => {
147                eprintln!("{e}");
148                std::process::exit(1);
149            }
150        },
151        _ => {
152            eprintln!("Usage: lean-ctx filter [list|validate <file>|init]");
153            std::process::exit(1);
154        }
155    }
156}
157
158pub fn cmd_slow_log(args: &[String]) {
159    use crate::core::slow_log;
160
161    let action = args.first().map_or("list", std::string::String::as_str);
162    match action {
163        "list" | "ls" | "" => println!("{}", slow_log::list()),
164        "clear" | "purge" => println!("{}", slow_log::clear()),
165        _ => {
166            eprintln!("Usage: lean-ctx slow-log [list|clear]");
167            std::process::exit(1);
168        }
169    }
170}