use std::path::{Path, PathBuf};
use crate::commands::persona;
use crate::config::Config;
use crate::memory::Summary;
use crate::session::home_dir;
use super::{HostAdapter, HostCaps};
pub struct ClaudeCodeAdapter;
impl HostAdapter for ClaudeCodeAdapter {
fn name(&self) -> &'static str {
"claude-code"
}
fn is_installed(&self) -> bool {
Path::new(&format!("{}/.claude", home_dir())).exists()
}
fn data_dir(&self) -> PathBuf {
std::env::var("SQUEEZ_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| PathBuf::from(format!("{}/.claude/squeez", home_dir())))
}
fn capabilities(&self) -> HostCaps {
HostCaps::BASH_WRAP | HostCaps::SESSION_MEM | HostCaps::BUDGET_HARD
}
fn install(&self, _bin_path: &Path) -> std::io::Result<()> {
Ok(())
}
fn uninstall(&self) -> std::io::Result<()> {
Ok(())
}
fn inject_memory(&self, cfg: &Config, _summaries: &[Summary]) -> std::io::Result<()> {
let home = home_dir();
let claude_dir = format!("{}/.claude", home);
let path = format!("{}/CLAUDE.md", claude_dir);
std::fs::create_dir_all(&claude_dir)?;
let persona_text = persona::text_with_lang(cfg.persona, &cfg.lang);
if persona_text.is_empty() {
return Ok(());
}
let mut block = String::from("<!-- squeez:start -->\n");
block.push_str("## squeez — always-on compression\n\n");
block.push_str(&format!(
"Persona: {} | Bash compression: ON | Memory: ON\n\n",
persona::as_str(cfg.persona)
));
block.push_str(persona_text);
if !persona_text.ends_with('\n') {
block.push('\n');
}
block.push_str("<!-- squeez:end -->\n");
let existing = std::fs::read_to_string(&path).unwrap_or_default();
let cleaned = if existing.contains("<!-- squeez:start -->") {
let start = existing.find("<!-- squeez:start -->").unwrap_or(0);
let end = existing
.find("<!-- squeez:end -->")
.map(|i| i + "<!-- squeez:end -->".len() + 1)
.unwrap_or(start);
format!(
"{}{}",
&existing[..start],
&existing[end.min(existing.len())..]
)
} else {
existing
};
let contents = format!("{}\n{}", block, cleaned.trim_start());
std::fs::write(&path, contents)
}
}