mod cli_proxy;
mod shell_hook;
mod tests;
use clap::{Parser, Subcommand};
use sqz_engine::SqzEngine;
use sqz_engine::{EntropyAnalyzer, InfoLevel};
use sqz_engine::{TeeManager, TeeMode};
use sqz_engine::{DashboardConfig, DashboardMetrics, DashboardServer};
use cli_proxy::CliProxy;
use shell_hook::ShellHook;
const SQZ_BANNER: &str = r#"
███████╗ ██████╗ ███████╗
██╔════╝██╔═══██╗╚══███╔╝
███████╗██║ ██║ ███╔╝
╚════██║██║▄▄ ██║ ███╔╝
███████║╚██████╔╝███████╗
╚══════╝ ╚══▀▀═╝ ╚══════╝
The Context Intelligence Layer
"#;
#[derive(Parser)]
#[command(
name = "sqz",
version,
about = "sqz — universal context intelligence layer",
before_help = SQZ_BANNER,
)]
struct Cli {
#[command(subcommand)]
command: Option<Command>,
}
#[derive(Subcommand)]
enum Command {
Init {
#[arg(long, short)]
yes: bool,
#[arg(long, short, alias = "g")]
global: bool,
#[arg(long, value_name = "TOOLS", conflicts_with = "skip")]
only: Option<String>,
#[arg(long, value_name = "TOOLS")]
skip: Option<String>,
},
Compress {
text: Option<String>,
#[arg(long, default_value = "auto")]
mode: String,
#[arg(long)]
verify: bool,
#[arg(long)]
no_cache: bool,
#[arg(long, value_name = "NAME")]
cmd: Option<String>,
},
Expand {
#[arg(required = true)]
prefix: String,
},
Export {
session_id: String,
},
Import {
file: String,
},
Status,
Cost {
session_id: String,
},
Analyze {
file: Option<String>,
#[arg(long, default_value_t = 60.0)]
high: f64,
#[arg(long, default_value_t = 25.0)]
low: f64,
},
Tee {
#[command(subcommand)]
action: Option<TeeAction>,
},
Dashboard {
#[arg(long, default_value_t = 3001)]
port: u16,
},
Proxy {
#[arg(long, default_value_t = 8080)]
port: u16,
},
Uninstall {
#[arg(long, short)]
yes: bool,
},
Stats {
session_id: Option<String>,
#[arg(long, short)]
project: Option<String>,
},
Gain {
#[arg(long, default_value_t = 7)]
days: u32,
#[arg(long, short)]
project: Option<String>,
},
Discover {
#[arg(long, default_value_t = 7)]
days: u32,
},
Resume {
session_id: Option<String>,
},
Hook {
tool: String,
},
Compact,
#[command(name = "print-opencode-plugin")]
PrintOpencodePlugin,
}
#[derive(Subcommand)]
enum TeeAction {
List,
Get {
id: String,
},
}
fn main() {
let cli = Cli::parse();
match cli.command {
None => {
let proxy = match CliProxy::new() {
Ok(p) => p,
Err(e) => {
eprintln!("[sqz] failed to initialise engine: {e}");
std::process::exit(1);
}
};
if let Err(e) = proxy.run_proxy() {
eprintln!("[sqz] proxy error: {e}");
std::process::exit(1);
}
}
Some(Command::Init { yes, global, only, skip }) => cmd_init(yes, global, only, skip),
Some(Command::Compress { text, mode, verify, no_cache, cmd }) => {
cmd_compress(text, &mode, verify, no_cache, cmd)
}
Some(Command::Expand { prefix }) => cmd_expand(&prefix),
Some(Command::Export { session_id }) => cmd_export(&session_id),
Some(Command::Import { file }) => cmd_import(&file),
Some(Command::Status) => cmd_status(),
Some(Command::Cost { session_id }) => cmd_cost(&session_id),
Some(Command::Analyze { file, high, low }) => cmd_analyze(file, high, low),
Some(Command::Tee { action }) => cmd_tee(action),
Some(Command::Dashboard { port }) => cmd_dashboard(port),
Some(Command::Proxy { port }) => cmd_proxy(port),
Some(Command::Uninstall { yes }) => cmd_uninstall(yes),
Some(Command::Stats { session_id, project }) => cmd_stats(session_id, project),
Some(Command::Gain { days, project }) => cmd_gain(days, project),
Some(Command::Discover { days }) => cmd_discover(days),
Some(Command::Resume { session_id }) => cmd_resume(session_id),
Some(Command::Hook { tool }) => cmd_hook(&tool),
Some(Command::Compact) => cmd_compact(),
Some(Command::PrintOpencodePlugin) => cmd_print_opencode_plugin(),
}
}
fn cmd_init(skip_confirm: bool, global: bool, only: Option<String>, skip: Option<String>) {
use std::io::Write;
let filter = match (only.as_deref(), skip.as_deref()) {
(None, None) => sqz_engine::ToolFilter::All,
(Some(raw), None) => match sqz_engine::parse_tool_list(raw) {
Ok(names) if names.is_empty() => {
sqz_engine::ToolFilter::Only(names)
}
Ok(names) => sqz_engine::ToolFilter::Only(names),
Err(e) => {
eprintln!("[sqz] init: {e}");
std::process::exit(1);
}
},
(None, Some(raw)) => match sqz_engine::parse_tool_list(raw) {
Ok(names) => sqz_engine::ToolFilter::Skip(names),
Err(e) => {
eprintln!("[sqz] init: {e}");
std::process::exit(1);
}
},
(Some(_), Some(_)) => {
eprintln!("[sqz] init: --only and --skip are mutually exclusive");
std::process::exit(1);
}
};
let hook = ShellHook::detect();
let rc_path = hook.rc_path();
let preset_dir = default_preset_dir();
let preset_path = preset_dir.join("default.toml");
let sqz_path = std::env::current_exe()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|_| "sqz".to_string());
let project_dir = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
let scope = if global {
sqz_engine::InstallScope::Global
} else {
sqz_engine::InstallScope::Project
};
let mut plan: Vec<(String, String, bool)> = Vec::new();
let rc_exists = rc_path.exists();
let rc_has_hook = rc_exists && std::fs::read_to_string(&rc_path)
.map(|s| s.contains(hook.sentinel()))
.unwrap_or(false);
if !rc_has_hook {
plan.push((
rc_path.display().to_string(),
if rc_exists { "append shell hook".to_string() } else { "create with shell hook".to_string() },
!rc_exists,
));
}
if !preset_path.exists() {
plan.push((
preset_path.display().to_string(),
"create default preset".to_string(),
true,
));
}
let tool_configs = sqz_engine::generate_hook_configs(&sqz_path);
let opencode_existing = sqz_engine::find_opencode_config(&project_dir);
let opencode_jsonc_has_comments =
sqz_engine::opencode_config_has_comments(&project_dir);
for config in &tool_configs {
if !filter.includes(&config.tool_name) {
continue;
}
if config.tool_name == "OpenCode" {
match sqz_engine::plan_opencode_config_change(&project_dir) {
Ok(planned) if planned.will_change => {
let is_existing = opencode_existing.is_some();
let note = if is_existing && opencode_jsonc_has_comments {
format!(
"{} hook config (merge sqz entries — comments in .jsonc \
will be dropped)",
config.tool_name
)
} else if is_existing {
format!("{} hook config (merge sqz entries)", config.tool_name)
} else {
format!("{} hook config", config.tool_name)
};
plan.push((
planned.target_path.display().to_string(),
note,
!is_existing,
));
}
Ok(_) => {
}
Err(_) => {
if let Some(path) = &opencode_existing {
plan.push((
path.display().to_string(),
format!("{} hook config (merge sqz entries)", config.tool_name),
false,
));
} else {
let full_path = project_dir.join(&config.config_path);
plan.push((
full_path.display().to_string(),
format!("{} hook config", config.tool_name),
true,
));
}
}
}
continue;
}
if config.tool_name == "Codex" {
let agents_path = sqz_engine::agents_md_path(&project_dir);
let agents_exists = agents_path.exists();
plan.push((
agents_path.display().to_string(),
if agents_exists {
"Codex guidance (append to existing AGENTS.md)".to_string()
} else {
"Codex guidance (create AGENTS.md)".to_string()
},
!agents_exists,
));
let codex_toml = sqz_engine::codex_config_path();
let codex_toml_exists = codex_toml.exists();
plan.push((
codex_toml.display().to_string(),
if codex_toml_exists {
"Codex MCP registration (merge [mcp_servers.sqz] into existing config)".to_string()
} else {
"Codex MCP registration (create user-level config.toml)".to_string()
},
!codex_toml_exists,
));
continue;
}
if config.tool_name == "Claude Code" && scope == sqz_engine::InstallScope::Global {
if let Some(target) = sqz_engine::claude_user_settings_path() {
let target_exists = target.exists();
plan.push((
target.display().to_string(),
if target_exists {
"Claude Code hooks (merge sqz entries into user settings)".to_string()
} else {
"Claude Code hooks (create user settings.json)".to_string()
},
!target_exists,
));
}
continue;
}
let full_path = project_dir.join(&config.config_path);
if !full_path.exists() {
plan.push((
full_path.display().to_string(),
format!("{} hook config", config.tool_name),
true,
));
}
}
if plan.is_empty() {
println!("[sqz] everything is already set up. Nothing to do.");
return;
}
println!("[sqz] detected shell: {:?}", hook);
println!();
println!("The following files will be modified:");
println!();
for (path, action, is_new) in &plan {
let tag = if *is_new { "create" } else { "modify" };
println!(" [{tag}] {path}");
println!(" {action}");
}
println!();
if !skip_confirm {
print!("Do you want to continue? [Y/n] ");
let _ = std::io::stdout().flush();
let mut answer = String::new();
if std::io::stdin().read_line(&mut answer).is_err() {
eprintln!("[sqz] could not read input, aborting.");
std::process::exit(1);
}
let answer = answer.trim().to_lowercase();
if !answer.is_empty() && answer != "y" && answer != "yes" {
println!("[sqz] aborted.");
return;
}
}
if !rc_has_hook {
match hook.install() {
Ok(true) => println!("[sqz] ✓ hook installed to {}", rc_path.display()),
Ok(false) => println!("[sqz] ✓ hook already present in {}", rc_path.display()),
Err(e) => {
eprintln!("[sqz] ✗ warning: {e}");
eprintln!(" shell hook installation failed; output will pass uncompressed.");
}
}
} else {
println!("[sqz] ✓ shell hook already present in {}", rc_path.display());
}
install_completions(&hook);
if let Err(e) = std::fs::create_dir_all(&preset_dir) {
eprintln!("[sqz] ✗ warning: could not create preset dir {}: {e}", preset_dir.display());
} else if !preset_path.exists() {
match std::fs::write(&preset_path, DEFAULT_PRESET_TOML) {
Ok(()) => println!("[sqz] ✓ default preset written to {}", preset_path.display()),
Err(e) => eprintln!("[sqz] ✗ warning: could not write preset: {e}"),
}
} else {
println!("[sqz] ✓ default preset already exists at {}", preset_path.display());
}
let installed_tools =
sqz_engine::install_tool_hooks_scoped_filtered(&project_dir, &sqz_path, scope, &filter);
for tool in &installed_tools {
println!("[sqz] ✓ {} hook installed", tool);
}
println!();
println!("[sqz] init complete. Restart your shell or source the RC file.");
if !global && installed_tools.iter().any(|t| t == "Claude Code") {
println!();
println!("[sqz] note: Claude Code hook installed at project scope.");
println!(" To enable sqz in every project on this machine, re-run:");
println!(" sqz init --global");
println!(" (writes ~/.claude/settings.json, merges with existing user settings)");
}
}
fn cmd_compress(text: Option<String>, mode: &str, show_verify: bool, no_cache: bool, cmd: Option<String>) {
let is_stdin = text.is_none();
let input = match text {
Some(t) => t,
None => {
use std::io::Read;
let mut buf = String::new();
if let Err(e) = std::io::stdin().read_to_string(&mut buf) {
eprintln!("[sqz] stdin read error: {e}");
std::process::exit(1);
}
buf
}
};
let env_opts = cli_proxy::InterceptOptions::from_env();
let opts = cli_proxy::InterceptOptions {
no_cache: no_cache || env_opts.no_cache,
};
if mode == "auto" && is_stdin {
let label = cmd
.or_else(|| std::env::var("SQZ_CMD").ok())
.unwrap_or_else(|| "stdin".to_string());
let proxy = match CliProxy::new() {
Ok(p) => p,
Err(e) => {
eprintln!("[sqz] proxy init error: {e}");
print!("{input}");
return;
}
};
let compressed = proxy.intercept_output_with_options(&label, &input, opts);
print!("{}", compressed);
return;
}
let engine = require_engine();
let result = match mode {
"safe" => {
eprintln!("[sqz] mode: safe (preserving all content)");
engine.compress_with_mode(&input, sqz_engine::CompressionMode::Safe)
}
"aggressive" => {
eprintln!("[sqz] mode: aggressive (maximum reduction)");
engine.compress_with_mode(&input, sqz_engine::CompressionMode::Aggressive)
}
"default" => {
engine.compress_with_mode(&input, sqz_engine::CompressionMode::Default)
}
_ => engine.compress(&input), }; match result {
Ok(c) => {
print!("{}", c.data);
let reduction = (1.0 - c.compression_ratio) * 100.0;
let project = std::env::current_dir().ok();
let project_str = project.as_ref().map(|p| p.to_string_lossy().to_string());
let _ = engine.session_store().log_compression_with_project(
c.tokens_original,
c.tokens_compressed,
&c.stages_applied,
mode,
project_str.as_deref(),
);
if show_verify {
let confidence = c.verify.as_ref().map(|v| v.confidence).unwrap_or(1.0);
let passed = c.verify.as_ref().map(|v| v.passed).unwrap_or(true);
let status = if passed { "✓" } else { "⚠" };
eprintln!(
"[sqz] {}/{} tokens ({:.0}% reduction) | confidence {:.0}% {}",
c.tokens_compressed,
c.tokens_original,
reduction,
confidence * 100.0,
status,
);
} else {
eprintln!(
"[sqz] {}/{} tokens ({:.0}% reduction)",
c.tokens_compressed,
c.tokens_original,
reduction,
);
}
}
Err(e) => {
eprintln!("[sqz] fallback: compression error: {e}");
print!("{input}");
}
}
}
fn cmd_export(session_id: &str) {
let engine = require_engine();
match engine.export_ctx(session_id) {
Ok(ctx) => println!("{ctx}"),
Err(e) => {
eprintln!("[sqz] export error: {e}");
std::process::exit(1);
}
}
}
fn cmd_expand(raw: &str) {
let trimmed = raw.trim();
let prefix = trimmed
.strip_prefix('§')
.unwrap_or(trimmed)
.strip_prefix("ref:")
.unwrap_or(trimmed.strip_prefix('§').unwrap_or(trimmed))
.trim_end_matches('§')
.trim()
.to_string();
let engine = match sqz_engine::SqzEngine::new() {
Ok(e) => e,
Err(e) => {
eprintln!("[sqz] expand: engine init error: {e}");
std::process::exit(3);
}
};
match engine.cache_manager().expand_prefix(&prefix) {
Ok(Some(sqz_engine::ExpandResult::Original { hash, bytes })) => {
use std::io::Write;
let mut out = std::io::stdout().lock();
if let Err(e) = out.write_all(&bytes) {
eprintln!("[sqz] expand: stdout write error: {e}");
std::process::exit(3);
}
eprintln!("[sqz] expanded ref prefix '{prefix}' → {} bytes (full hash {hash})", bytes.len());
}
Ok(Some(sqz_engine::ExpandResult::CompressedOnly { hash, compressed })) => {
println!("{compressed}");
eprintln!(
"[sqz] expanded ref prefix '{prefix}' (compressed form only; full hash {hash})"
);
eprintln!(
"[sqz] note: this cache entry predates the original-capture migration."
);
eprintln!(
"[sqz] to capture the true original bytes, re-run the command that produced"
);
eprintln!(
"[sqz] this ref with 'SQZ_NO_DEDUP=1' or '--no-cache'."
);
}
Ok(None) => {
eprintln!(
"[sqz] expand: no cache entry matches prefix '{prefix}'."
);
eprintln!("[sqz] hint: the ref may be from a different machine or a wiped ~/.sqz/sessions.db.");
std::process::exit(1);
}
Err(e) => {
eprintln!("[sqz] expand: {e}");
std::process::exit(2);
}
}
}
fn cmd_import(file: &str) {
let ctx = match std::fs::read_to_string(file) {
Ok(s) => s,
Err(e) => {
eprintln!("[sqz] could not read file '{file}': {e}");
std::process::exit(1);
}
};
let engine = require_engine();
match engine.import_ctx(&ctx) {
Ok(id) => println!("[sqz] imported session: {id}"),
Err(e) => {
eprintln!("[sqz] import error: {e}");
std::process::exit(1);
}
}
}
fn cmd_status() {
let engine = require_engine();
let report = engine.usage_report("default");
println!("agent: {}", report.agent_id);
println!("consumed: {} tokens ({:.1}%)", report.consumed, report.consumed_pct * 100.0);
println!("pinned: {} tokens", report.pinned);
println!("available: {} tokens", report.available);
println!("allocated: {} tokens", report.allocated);
}
fn cmd_cost(session_id: &str) {
let engine = require_engine();
match engine.cost_summary(session_id) {
Ok(s) => {
println!("session: {session_id}");
println!("total tokens: {}", s.total_tokens);
println!("total cost: ${:.6}", s.total_usd);
println!("cache savings: ${:.6}", s.cache_savings_usd);
println!("compression savings: ${:.6}", s.compression_savings_usd);
}
Err(e) => {
eprintln!("[sqz] cost error: {e}");
std::process::exit(1);
}
}
}
fn cmd_analyze(file: Option<String>, high_pct: f64, low_pct: f64) {
let source = match file {
Some(path) => match std::fs::read_to_string(&path) {
Ok(s) => s,
Err(e) => {
eprintln!("[sqz] could not read file '{path}': {e}");
std::process::exit(1);
}
},
None => {
use std::io::Read;
let mut buf = String::new();
if let Err(e) = std::io::stdin().read_to_string(&mut buf) {
eprintln!("[sqz] stdin read error: {e}");
std::process::exit(1);
}
buf
}
};
let analyzer = EntropyAnalyzer::with_thresholds(high_pct, low_pct);
let blocks = analyzer.analyze(&source);
if blocks.is_empty() {
println!("[sqz] no blocks found in input");
return;
}
for (i, block) in blocks.iter().enumerate() {
let level_tag = match block.info_level {
InfoLevel::HighInfo => "HighInfo",
InfoLevel::MediumInfo => "MediumInfo",
InfoLevel::LowInfo => "LowInfo",
};
println!(
"block {}: lines {}-{} | entropy {:.4} | {}",
i + 1,
block.line_range.start + 1,
block.line_range.end,
block.entropy,
level_tag,
);
}
let high_count = blocks.iter().filter(|b| b.info_level == InfoLevel::HighInfo).count();
let med_count = blocks.iter().filter(|b| b.info_level == InfoLevel::MediumInfo).count();
let low_count = blocks.iter().filter(|b| b.info_level == InfoLevel::LowInfo).count();
println!(
"\n[sqz] {} blocks total: {} HighInfo, {} MediumInfo, {} LowInfo",
blocks.len(),
high_count,
med_count,
low_count,
);
}
fn cmd_tee(action: Option<TeeAction>) {
let mgr = TeeManager::with_default_dir(TeeMode::Never);
match action {
None | Some(TeeAction::List) => {
match mgr.list() {
Ok(entries) if entries.is_empty() => {
println!("[sqz] no saved tee entries");
}
Ok(entries) => {
for e in &entries {
println!(
"{} | {} | exit {} | {} bytes",
e.id, e.command, e.exit_code, e.size_bytes
);
}
println!("\n[sqz] {} entries", entries.len());
}
Err(e) => {
eprintln!("[sqz] tee list error: {e}");
std::process::exit(1);
}
}
}
Some(TeeAction::Get { id }) => {
match mgr.get(&id) {
Ok(content) => print!("{content}"),
Err(e) => {
eprintln!("[sqz] tee get error: {e}");
std::process::exit(1);
}
}
}
}
}
fn cmd_dashboard(port: u16) {
let config = DashboardConfig { port };
let metrics = std::sync::Arc::new(std::sync::Mutex::new(DashboardMetrics::default()));
let server = DashboardServer::new(config, metrics);
println!("[sqz] starting dashboard on http://127.0.0.1:{port}");
if let Err(e) = server.run() {
eprintln!("[sqz] dashboard error: {e}");
std::process::exit(1);
}
}
fn cmd_proxy(port: u16) {
use std::io::{Read, Write};
use std::net::TcpListener;
let engine = require_engine();
let config = sqz_engine::ProxyConfig {
port,
..Default::default()
};
let addr = format!("127.0.0.1:{port}");
let listener = match TcpListener::bind(&addr) {
Ok(l) => l,
Err(e) => {
eprintln!("[sqz] proxy: failed to bind to {addr}: {e}");
std::process::exit(1);
}
};
eprintln!("[sqz] proxy listening on http://{addr}");
eprintln!("[sqz] configure your API client to use http://{addr} as the base URL");
eprintln!("[sqz] example: OPENAI_BASE_URL=http://{addr}/v1");
eprintln!("[sqz] example: ANTHROPIC_BASE_URL=http://{addr}");
eprintln!();
for stream in listener.incoming() {
match stream {
Ok(mut client) => {
let mut buf = vec![0u8; 1024 * 1024]; let n = match client.read(&mut buf) {
Ok(n) if n > 0 => n,
_ => continue,
};
buf.truncate(n);
let (method, path, _headers, body) = match sqz_engine::parse_http_request(&buf) {
Ok(r) => r,
Err(e) => {
let resp = sqz_engine::build_http_response(
400, "Bad Request",
&[("content-type", "text/plain")],
&format!("sqz proxy: {e}"),
);
let _ = client.write_all(&resp);
continue;
}
};
if path == "/health" || path == "/" {
let resp = sqz_engine::build_http_response(
200, "OK",
&[("content-type", "application/json")],
r#"{"status":"ok","service":"sqz-proxy"}"#,
);
let _ = client.write_all(&resp);
continue;
}
if method != "POST" {
let resp = sqz_engine::build_http_response(
405, "Method Not Allowed",
&[("content-type", "text/plain")],
"sqz proxy: only POST is supported",
);
let _ = client.write_all(&resp);
continue;
}
let format = match sqz_engine::ApiFormat::from_path(&path) {
Some(f) => f,
None => {
let resp = sqz_engine::build_http_response(
404, "Not Found",
&[("content-type", "text/plain")],
&format!("sqz proxy: unknown API path: {path}"),
);
let _ = client.write_all(&resp);
continue;
}
};
let (compressed_body, stats) = match sqz_engine::compress_request(
&body, format, &config, &engine,
) {
Ok(r) => r,
Err(e) => {
eprintln!("[sqz] proxy: compression error: {e}, forwarding uncompressed");
(body.clone(), sqz_engine::ProxyStats::default())
}
};
if stats.tokens_saved() > 0 {
eprintln!(
"[sqz] proxy: {}/{} tokens ({:.0}% reduction) | {} msgs compressed, {} summarized",
stats.tokens_compressed, stats.tokens_original,
stats.reduction_pct(),
stats.messages_compressed, stats.messages_summarized,
);
}
let project = std::env::current_dir().ok();
let project_str = project.as_ref().map(|p| p.to_string_lossy().to_string());
let _ = engine.session_store().log_compression_with_project(
stats.tokens_original,
stats.tokens_compressed,
&["proxy".to_string()],
&format!("proxy:{:?}", format),
project_str.as_deref(),
);
let response_json = serde_json::json!({
"sqz_proxy": true,
"original_tokens": stats.tokens_original,
"compressed_tokens": stats.tokens_compressed,
"reduction_pct": format!("{:.1}%", stats.reduction_pct()),
"messages_compressed": stats.messages_compressed,
"messages_summarized": stats.messages_summarized,
"compressed_body": serde_json::from_str::<serde_json::Value>(&compressed_body)
.unwrap_or(serde_json::Value::String(compressed_body)),
});
let resp_body = serde_json::to_string_pretty(&response_json).unwrap_or_default();
let resp = sqz_engine::build_http_response(
200, "OK",
&[("content-type", "application/json"), ("x-sqz-tokens-saved", &stats.tokens_saved().to_string())],
&resp_body,
);
let _ = client.write_all(&resp);
}
Err(e) => {
eprintln!("[sqz] proxy: connection error: {e}");
}
}
}
}
fn cmd_uninstall(skip_confirm: bool) {
use std::io::Write;
let hook = ShellHook::detect();
println!("[sqz] detected shell: {:?}", hook);
let mut files_to_remove: Vec<(String, bool)> = Vec::new();
let rc_path = hook.rc_path();
let rc_has_hook = rc_path.exists() && std::fs::read_to_string(&rc_path)
.map(|s| s.contains(hook.sentinel()))
.unwrap_or(false);
if rc_has_hook {
files_to_remove.push((rc_path.display().to_string(), true));
}
let project_dir = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."));
let sqz_path_str = std::env::current_exe()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|_| "sqz".to_string());
let tool_configs = sqz_engine::generate_hook_configs(&sqz_path_str);
for config in &tool_configs {
if config.tool_name == "OpenCode" {
continue;
}
if config.tool_name == "Codex" {
continue;
}
let full = project_dir.join(&config.config_path);
if full.exists() {
files_to_remove.push((full.display().to_string(), true));
}
}
let opencode_config = sqz_engine::find_opencode_config(&project_dir);
let opencode_config_display = opencode_config
.as_ref()
.map(|p| p.display().to_string());
if let Some(path) = &opencode_config_display {
files_to_remove.push((format!("{path} (sqz entries only)"), true));
}
let agents_md = sqz_engine::agents_md_path(&project_dir);
let agents_md_exists = agents_md.exists();
if agents_md_exists {
files_to_remove.push((
format!("{} (sqz guidance block only)", agents_md.display()),
true,
));
}
let codex_toml = sqz_engine::codex_config_path();
let codex_toml_exists = codex_toml.exists();
if codex_toml_exists {
files_to_remove.push((
format!("{} ([mcp_servers.sqz] only)", codex_toml.display()),
true,
));
}
let claude_user_settings = sqz_engine::claude_user_settings_path();
let claude_user_settings_exists = claude_user_settings
.as_ref()
.map(|p| p.exists())
.unwrap_or(false);
if let (Some(path), true) = (&claude_user_settings, claude_user_settings_exists) {
files_to_remove.push((
format!("{} (sqz hook entries only)", path.display()),
true,
));
}
let opencode_plugin = sqz_engine::opencode_plugin_path();
let opencode_plugin_exists = opencode_plugin.exists();
if opencode_plugin_exists {
files_to_remove.push((opencode_plugin.display().to_string(), true));
}
if files_to_remove.is_empty() {
println!("[sqz] nothing to uninstall — no sqz files found.");
return;
}
println!("\nThe following files will be modified or removed:\n");
for (path, _) in &files_to_remove {
println!(" [remove] {path}");
}
println!();
if !skip_confirm {
print!("Do you want to continue? [Y/n] ");
let _ = std::io::stdout().flush();
let mut answer = String::new();
if std::io::stdin().read_line(&mut answer).is_err() {
eprintln!("[sqz] could not read input, aborting.");
std::process::exit(1);
}
let answer = answer.trim().to_lowercase();
if !answer.is_empty() && answer != "y" && answer != "yes" {
println!("[sqz] aborted.");
return;
}
}
if rc_has_hook {
match hook.uninstall() {
Ok(true) => println!("[sqz] ✓ hook removed from {}", rc_path.display()),
Ok(false) => println!("[sqz] ✓ hook not found in {}", rc_path.display()),
Err(e) => eprintln!("[sqz] ✗ warning: {e}"),
}
}
for config in &tool_configs {
if config.tool_name == "OpenCode" {
continue;
}
if config.tool_name == "Codex" {
continue;
}
let full = project_dir.join(&config.config_path);
if full.exists() {
match std::fs::remove_file(&full) {
Ok(()) => println!("[sqz] ✓ removed {}", full.display()),
Err(e) => eprintln!("[sqz] ✗ could not remove {}: {e}", full.display()),
}
}
}
if opencode_config.is_some() {
match sqz_engine::remove_sqz_from_opencode_config(&project_dir) {
Ok(Some((path, true))) => {
if path.exists() {
println!(
"[sqz] ✓ removed sqz entries from {}",
path.display()
);
} else {
println!("[sqz] ✓ removed {}", path.display());
}
}
Ok(Some((path, false))) => {
println!(
"[sqz] ✓ no sqz entries found in {}",
path.display()
);
}
Ok(None) => {
}
Err(e) => {
if let Some(path) = &opencode_config_display {
eprintln!("[sqz] ✗ could not clean up {path}: {e}");
} else {
eprintln!("[sqz] ✗ could not clean up OpenCode config: {e}");
}
}
}
}
if opencode_plugin_exists {
match std::fs::remove_file(&opencode_plugin) {
Ok(()) => println!("[sqz] ✓ removed {}", opencode_plugin.display()),
Err(e) => eprintln!(
"[sqz] ✗ could not remove {}: {e}",
opencode_plugin.display()
),
}
}
if agents_md_exists {
match sqz_engine::remove_agents_md_guidance(&project_dir) {
Ok(Some((path, true))) => {
if path.exists() {
println!("[sqz] ✓ removed sqz block from {}", path.display());
} else {
println!("[sqz] ✓ removed {}", path.display());
}
}
Ok(Some((path, false))) => {
println!("[sqz] ✓ no sqz block found in {}", path.display());
}
Ok(None) => { }
Err(e) => {
eprintln!(
"[sqz] ✗ could not clean up {}: {e}",
agents_md.display()
);
}
}
}
if codex_toml_exists {
match sqz_engine::remove_codex_mcp_config() {
Ok(Some((path, true))) => {
if path.exists() {
println!(
"[sqz] ✓ removed [mcp_servers.sqz] from {}",
path.display()
);
} else {
println!("[sqz] ✓ removed {}", path.display());
}
}
Ok(Some((path, false))) => {
println!(
"[sqz] ✓ no [mcp_servers.sqz] entry found in {}",
path.display()
);
}
Ok(None) => { }
Err(e) => {
eprintln!(
"[sqz] ✗ could not clean up {}: {e}",
codex_toml.display()
);
}
}
}
if claude_user_settings_exists {
match sqz_engine::remove_claude_global_hook() {
Ok(Some((path, true))) => {
if path.exists() {
println!(
"[sqz] ✓ removed sqz hook entries from {}",
path.display()
);
} else {
println!("[sqz] ✓ removed {}", path.display());
}
}
Ok(Some((path, false))) => {
println!(
"[sqz] ✓ no sqz hook entries found in {}",
path.display()
);
}
Ok(None) => { }
Err(e) => {
if let Some(path) = &claude_user_settings {
eprintln!(
"[sqz] ✗ could not clean up {}: {e}",
path.display()
);
} else {
eprintln!("[sqz] ✗ could not resolve ~/.claude/settings.json: {e}");
}
}
}
}
println!("\n[sqz] uninstall complete.");
}
fn resolve_project_filter(raw: &str) -> String {
if raw == "list" {
return raw.to_string();
}
let path = if raw == "." {
std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from("."))
} else {
let p = std::path::PathBuf::from(raw);
if p.is_absolute() {
p
} else {
std::env::current_dir()
.unwrap_or_else(|_| std::path::PathBuf::from("."))
.join(p)
}
};
path.to_string_lossy().to_string()
}
fn cmd_stats(session_id: Option<String>, project: Option<String>) {
let engine = require_engine();
if project.as_deref() == Some("list") {
let projects = engine.session_store().list_projects().unwrap_or_default();
if projects.is_empty() {
println!("[sqz] No per-project data yet. Compression events from older sqz versions don't have project info.");
println!("[sqz] New compressions will be tagged automatically.");
return;
}
println!();
println!(" Tracked projects:");
println!(" {}", "─".repeat(60));
for (dir, count, saved) in &projects {
println!(" {:>6} compressions {:>8} saved {}", count, saved, dir);
}
println!(" {}", "─".repeat(60));
println!();
println!(" Use: sqz stats --project <path>");
println!(" sqz gain --project <path>");
println!();
return;
}
let project_dir = project.as_deref().map(resolve_project_filter);
let bar = "├─────────────────────────┼──────────────────┤";
let top = "┌─────────────────────────┬──────────────────┐";
let bot = "└─────────────────────────┴──────────────────┘";
let row = |label: &str, val: &str| {
println!("│ {:<23} │ {:>16} │", label, val);
};
let title = if let Some(ref dir) = project_dir {
let short = std::path::Path::new(dir)
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_else(|| dir.clone());
format!("sqz stats — {}", short)
} else {
"sqz compression stats".to_string()
};
println!();
println!("{top}");
println!("│ {:^42} │", title);
println!("{bar}");
let cs = if let Some(ref dir) = project_dir {
engine.session_store().compression_stats_for_project(dir).unwrap_or_default()
} else {
engine.session_store().compression_stats().unwrap_or_default()
};
row("Total compressions", &format!("{}", cs.total_compressions));
row("Tokens in (total)", &format!("{}", cs.total_tokens_in));
row("Tokens out (total)", &format!("{}", cs.total_tokens_out));
row("Tokens saved", &format!("{}", cs.tokens_saved()));
row("Avg reduction", &format!("{:.1}%", cs.reduction_pct()));
if let Some(ref dir) = project_dir {
println!("{bar}");
row("Project", dir);
}
if let Some(ref sid) = session_id {
match engine.cost_summary(sid) {
Ok(cost) => {
println!("{bar}");
row("Session", sid);
row("Total tokens", &format!("{}", cost.total_tokens));
row("Total cost", &format!("${:.6}", cost.total_usd));
row("Cache savings", &format!("${:.6}", cost.cache_savings_usd));
row("Compression savings", &format!("${:.6}", cost.compression_savings_usd));
if cost.total_usd > 0.0 {
let pct = (cost.compression_savings_usd / (cost.total_usd + cost.compression_savings_usd)) * 100.0;
row("Effective reduction", &format!("{:.1}%", pct));
}
}
Err(e) => {
println!("{bar}");
row("Session", sid);
row("Error", &format!("{e}"));
}
}
}
if project_dir.is_none() {
let cache_entries = engine.session_store()
.list_cache_entries_lru()
.unwrap_or_default();
let cache_size: u64 = cache_entries.iter().map(|(_, sz)| sz).sum();
println!("{bar}");
row("Cache entries", &format!("{}", cache_entries.len()));
row("Cache size", &format_bytes(cache_size));
}
println!("{bot}");
println!();
}
fn cmd_gain(days: u32, project: Option<String>) {
let engine = require_engine();
let project_dir = project.as_deref().map(resolve_project_filter);
let gains = if let Some(ref dir) = project_dir {
engine.session_store().daily_gains_for_project(days, dir).unwrap_or_default()
} else {
engine.session_store().daily_gains(days).unwrap_or_default()
};
let stats = if let Some(ref dir) = project_dir {
engine.session_store().compression_stats_for_project(dir).unwrap_or_default()
} else {
engine.session_store().compression_stats().unwrap_or_default()
};
if gains.is_empty() {
if project_dir.is_some() {
println!("[sqz] No compression data for this project yet.");
} else {
println!("[sqz] No compression data yet. Run `sqz compress` to start tracking.");
}
return;
}
let max_saved = gains.iter().map(|g| g.tokens_saved).max().unwrap_or(1).max(1);
let bar_width: u64 = 30;
let header = if let Some(ref dir) = project_dir {
let short = std::path::Path::new(dir)
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_else(|| dir.clone());
format!("sqz token savings — {} (last {} days)", short, days)
} else {
format!("sqz token savings (last {} days)", days)
};
println!();
println!(" {}", header);
println!(" {}", "─".repeat(50));
for g in &gains {
let bar_len = (g.tokens_saved * bar_width / max_saved) as usize;
let bar: String = "█".repeat(bar_len);
let pad: String = " ".repeat(bar_width as usize - bar_len);
println!(
" {} │{}{}│ {} saved",
&g.date[5..], bar,
pad,
g.tokens_saved,
);
}
println!(" {}", "─".repeat(50));
println!(
" Total: {} compressions, {} tokens saved ({:.1}% avg reduction)",
stats.total_compressions,
stats.tokens_saved(),
stats.reduction_pct(),
);
println!();
}
fn format_bytes(bytes: u64) -> String {
if bytes < 1024 {
format!("{} B", bytes)
} else if bytes < 1024 * 1024 {
format!("{:.1} KB", bytes as f64 / 1024.0)
} else {
format!("{:.1} MB", bytes as f64 / (1024.0 * 1024.0))
}
}
fn cmd_discover(days: u32) {
let engine = require_engine();
let store = engine.session_store();
let stats = match store.compression_stats() {
Ok(s) => s,
Err(e) => {
eprintln!("[sqz] failed to read stats: {e}");
return;
}
};
let gains = match store.daily_gains(days) {
Ok(g) => g,
Err(e) => {
eprintln!("[sqz] failed to read daily gains: {e}");
return;
}
};
println!("sqz discover — missed savings analysis (last {} days)", days);
println!("{}", "─".repeat(50));
if stats.total_compressions == 0 {
println!();
println!(" No compression data found.");
println!(" sqz hasn't intercepted any commands yet.");
println!();
println!(" To start saving tokens:");
println!(" sqz init # install shell hooks");
println!(" # then restart your AI tool");
println!();
return;
}
let total_original = stats.total_tokens_in;
let total_compressed = stats.total_tokens_out;
let total_saved = stats.tokens_saved();
let avg_reduction = stats.reduction_pct();
println!();
println!(" Compressions: {}", stats.total_compressions);
println!(" Tokens original: {}", total_original);
println!(" Tokens after: {}", total_compressed);
println!(" Tokens saved: {} ({:.1}% avg reduction)", total_saved, avg_reduction);
println!();
let days_with_data = gains.iter().filter(|g| g.tokens_saved > 0).count();
let days_without = (days as usize).saturating_sub(days_with_data);
if days_without > 0 && days_with_data > 0 {
let avg_daily_savings = total_saved / days_with_data.max(1) as u64;
let missed = avg_daily_savings * days_without as u64;
println!(" {} days with no sqz activity.", days_without);
println!(" Estimated missed savings: ~{} tokens", missed);
println!();
}
println!(" High-value commands to route through sqz:");
println!(" git status/diff/log → 70-80% reduction");
println!(" cargo test/build → 80-90% reduction (failures only)");
println!(" docker ps/images → 70-80% reduction");
println!(" npm test/install → 60-90% reduction");
println!(" kubectl get → 60-70% reduction");
println!();
}
fn cmd_resume(session_id: Option<String>) {
let engine = require_engine();
let store = engine.session_store();
let sid = match session_id {
Some(id) => id,
None => {
match store.latest_session() {
Ok(Some(summary)) => summary.id,
Ok(None) => {
eprintln!("[sqz] no sessions found. Start a session first.");
return;
}
Err(e) => {
eprintln!("[sqz] failed to query sessions: {e}");
return;
}
}
}
};
let session = match store.load_session(sid.clone()) {
Ok(s) => s,
Err(e) => {
eprintln!("[sqz] failed to load session '{}': {e}", sid);
return;
}
};
use sqz_engine::SessionContinuityManager;
let continuity = SessionContinuityManager::new(store);
use sqz_engine::{Snapshot, SnapshotEvent, SnapshotEventType};
let mut events = Vec::new();
if !session.compressed_summary.is_empty() {
events.push(SnapshotEvent::new(
SnapshotEventType::Summary,
session.compressed_summary.clone(),
));
}
for (i, turn) in session.conversation.iter().rev().take(5).enumerate() {
let event_type = if i == 0 && turn.role == sqz_engine::Role::User {
SnapshotEventType::LastPrompt
} else {
SnapshotEventType::Context
};
let content = if turn.content.len() > 200 {
format!("{}...", &turn.content[..200])
} else {
turn.content.clone()
};
events.push(SnapshotEvent::new(event_type, content));
}
for learning in &session.learnings {
events.push(SnapshotEvent::new(
SnapshotEventType::Learning,
format!("{}: {}", learning.key, learning.value),
));
}
for correction in &session.corrections.entries {
events.push(SnapshotEvent::new(
SnapshotEventType::Decision,
format!("{} → {}", correction.original, correction.correction),
));
}
let snapshot = Snapshot {
events,
};
let guide = continuity.generate_guide(&snapshot);
println!("{}", guide.text);
eprintln!("[sqz] session guide: {} tokens from session '{}'", guide.token_count, sid);
}
fn cmd_compact() {
let engine = require_engine();
let store = engine.session_store();
let known_files = store.known_files().unwrap_or_default();
let cache_entries = store.list_cache_entries_lru().unwrap_or_default();
let current_turn = engine.cache_manager().current_turn();
if known_files.is_empty() && cache_entries.is_empty() {
println!("[sqz] nothing to compact — no cached content");
return;
}
let items: Vec<sqz_engine::ContextItem> = cache_entries
.iter()
.enumerate()
.map(|(i, (hash, size))| sqz_engine::ContextItem {
id: format!("cache:{}", &hash[..hash.len().min(12)]),
content: format!("[cached content, {} bytes]", size),
last_accessed_turn: current_turn.saturating_sub(cache_entries.len() as u64 - i as u64),
access_count: 1,
tokens: (*size as u32 + 3) / 4,
pinned: false,
})
.collect();
let config = sqz_engine::EvictionConfig::default();
match sqz_engine::evict(&items, current_turn, &config) {
Ok(result) => {
if result.evicted.is_empty() {
println!("[sqz] compact: nothing to evict (all items are recent)");
} else {
engine.cache_manager().notify_compaction();
println!("{}", result.eviction_summary);
println!(
"[sqz] compact: {} → {} tokens ({} freed)",
result.tokens_before,
result.tokens_after,
result.tokens_before - result.tokens_after,
);
}
}
Err(e) => {
eprintln!("[sqz] compact error: {e}");
}
}
}
fn cmd_print_opencode_plugin() {
let sqz_path = std::env::current_exe()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_else(|_| "sqz".to_string());
print!("{}", sqz_engine::generate_opencode_plugin(&sqz_path));
}
fn cmd_hook(tool: &str) {
use std::io::Read;
let mut input = String::new();
if let Err(e) = std::io::stdin().read_to_string(&mut input) {
eprintln!("[sqz] hook: stdin read error: {e}");
println!("{{}}");
return;
}
if tool == "precompact" {
match SqzEngine::new() {
Ok(engine) => {
engine.cache_manager().notify_compaction();
eprintln!("[sqz] precompact: marked cached refs stale");
}
Err(e) => {
eprintln!("[sqz] precompact: engine init failed: {e}");
}
}
println!("{{}}");
return;
}
let result = match tool {
"opencode" => sqz_engine::process_opencode_hook(&input),
"cursor" => sqz_engine::process_hook_cursor(&input),
"gemini" => sqz_engine::process_hook_gemini(&input),
"windsurf" => sqz_engine::process_hook_windsurf(&input),
_ => sqz_engine::process_hook(&input),
};
match result {
Ok(output) => print!("{output}"),
Err(e) => {
eprintln!("[sqz] hook: processing error: {e}");
print!("{input}");
}
}
}
fn require_engine() -> SqzEngine {
SqzEngine::new().unwrap_or_else(|e| {
eprintln!("[sqz] failed to initialise engine: {e}");
std::process::exit(1);
})
}
fn default_preset_dir() -> std::path::PathBuf {
let home = std::env::var("HOME")
.or_else(|_| std::env::var("USERPROFILE"))
.map(std::path::PathBuf::from)
.unwrap_or_else(|_| std::path::PathBuf::from("."));
home.join(".sqz").join("presets")
}
fn install_completions(hook: &ShellHook) {
let home = std::env::var("HOME")
.or_else(|_| std::env::var("USERPROFILE"))
.map(std::path::PathBuf::from)
.unwrap_or_else(|_| std::path::PathBuf::from("."));
let (dest, content): (std::path::PathBuf, &str) = match hook {
ShellHook::Fish => (
home.join(".config").join("fish").join("completions").join("sqz.fish"),
include_str!("../completions/sqz.fish"),
),
ShellHook::Zsh => (
home.join(".zsh").join("completions").join("_sqz"),
include_str!("../completions/sqz.zsh"),
),
ShellHook::Bash => (
home.join(".local").join("share").join("bash-completion").join("completions").join("sqz"),
include_str!("../completions/sqz.bash"),
),
ShellHook::Nushell => (
home.join(".config").join("nushell").join("completions").join("sqz.nu"),
include_str!("../completions/sqz.nu"),
),
ShellHook::PowerShell => {
let profile = std::env::var("PROFILE")
.map(std::path::PathBuf::from)
.unwrap_or_else(|_| {
home.join("Documents")
.join("PowerShell")
.join("Microsoft.PowerShell_profile.ps1")
});
(profile, include_str!("../completions/sqz.ps1"))
}
};
if let Some(parent) = dest.parent() {
if std::fs::create_dir_all(parent).is_err() {
return; }
}
let write_result = if matches!(hook, ShellHook::PowerShell) {
let existing = std::fs::read_to_string(&dest).unwrap_or_default();
if existing.contains("Register-ArgumentCompleter -Native -CommandName sqz") {
return; }
use std::io::Write;
std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&dest)
.and_then(|mut f| writeln!(f, "\n{content}"))
} else {
std::fs::write(&dest, content)
};
match write_result {
Ok(()) => println!("[sqz] completions installed to {}", dest.display()),
Err(_) => {} }
}
const DEFAULT_PRESET_TOML: &str = r#"[meta]
name = "default"
version = "1"
description = "Default sqz preset"
[compression]
keep_fields.enabled = false
strip_fields.enabled = false
condense.enabled = true
strip_nulls.enabled = true
flatten.enabled = false
truncate_strings.enabled = false
collapse_arrays.enabled = false
custom_transforms.enabled = false
[budget]
window_size = 200000
warning_threshold = 0.70
ceiling_threshold = 0.85
default_agent_budget = 50000
[terse_mode]
enabled = false
level = "moderate"
"#;