use std::io::{self, Read};
use weave::lenses::{apply_stack, clarity::ClarityLens, narrow::NarrowLens, LensContext};
pub fn handle(budget: usize, file: Option<String>, json: bool) -> anyhow::Result<()> {
let mut text = String::new();
if let Some(ref path) = file {
text = std::fs::read_to_string(path)
.map_err(|e| anyhow::anyhow!("bctx compress: cannot read '{path}': {e}"))?;
} else {
io::stdin().read_to_string(&mut text)?;
}
if text.trim().is_empty() {
if json {
println!(
"{}",
serde_json::json!({
"compressed": "",
"tokens_before": 0,
"tokens_after": 0,
"savings_pct": 0.0,
})
);
}
return Ok(());
}
let ctx = LensContext::new(budget);
let stack: Vec<Box<dyn weave::lenses::Lens>> =
vec![Box::new(ClarityLens), Box::new(NarrowLens)];
let output = apply_stack(&stack, &text, &ctx);
if json {
println!(
"{}",
serde_json::json!({
"compressed": output.content,
"tokens_before": output.tokens_before,
"tokens_after": output.tokens_after,
"savings_pct": output.savings_pct(),
})
);
} else {
print!("{}", output.content);
eprintln!(
"[bctx: {} → {} tokens, {}% saved]",
output.tokens_before,
output.tokens_after,
output.savings_pct().round() as u64,
);
}
Ok(())
}