use std::fs::OpenOptions;
use std::io::Write;
use std::path::{Path, PathBuf};
pub struct DebugLogger {
enabled: bool,
log_file: PathBuf,
}
impl DebugLogger {
pub fn new(enabled: bool) -> Self {
let enabled = enabled || std::env::var("CCS_DEBUG").unwrap_or_default() == "1";
let log_file = std::env::temp_dir().join("claude-code-statusline.log");
Self { enabled, log_file }
}
pub fn log(&self, message: &str) {
if !self.enabled {
tracing::debug!(target: "claude-code-statusline", "{message}");
return;
}
if let Some(parent) = Path::new(&self.log_file).parent() {
std::fs::create_dir_all(parent).ok();
}
if let Ok(mut file) = OpenOptions::new()
.create(true)
.append(true)
.open(&self.log_file)
{
writeln!(file, "{message}").ok();
}
}
pub fn log_stderr(&self, message: &str) {
tracing::debug!(target: "claude-code-statusline", "{message}");
if self.enabled {
eprintln!("[DEBUG] {message}");
}
}
pub fn log_execution_start(&self) {
self.log("--- New execution ---");
}
pub fn log_config(&self, debug: bool, command_timeout: u64) {
self.log(&format!(
"Config loaded: debug={debug}, command_timeout={command_timeout}"
));
}
pub fn log_input(&self, buffer: &str) {
self.log(&format!("Input length: {} bytes", buffer.len()));
if !buffer.is_empty() {
self.log(&format!(
"First 500 chars: {}",
&buffer[..buffer.len().min(500)]
));
}
}
pub fn log_success(&self, model: &str, cwd: &str) {
self.log(&format!("SUCCESS: Model={model}, CWD={cwd}"));
}
pub fn log_prompt(&self, prompt: &str) {
self.log(&format!("Generated: {prompt}"));
}
pub fn log_error(&self, error: &str) {
tracing::error!(target: "claude-code-statusline", "{error}");
self.log(&format!("ERROR: {error}"));
}
#[allow(dead_code)]
pub fn is_enabled(&self) -> bool {
self.enabled
}
}