use spool::bootstrap::{self, SpoolLayout};
use std::path::PathBuf;
fn main() -> anyhow::Result<()> {
let sandbox = std::env::temp_dir().join("spool-bootstrap-smoke");
let _ = std::fs::remove_dir_all(&sandbox);
let layout = SpoolLayout::from_root(sandbox.clone());
let workspace_root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let bundled_dir = workspace_root.join("target/release");
if !bundled_dir.exists() {
eprintln!(
"โ Build the release binaries first:\n cargo build --release --bin spool --bin spool-mcp --bin spool-daemon"
);
std::process::exit(1);
}
println!("๐งช spool bootstrap smoke test");
println!(" sandbox: {}", sandbox.display());
println!(" bundled: {}", bundled_dir.display());
println!();
let report = bootstrap::run_bootstrap_with_layout(&layout, &bundled_dir)?;
println!("๐ Bootstrap messages:");
for msg in &report.messages {
println!(" โข {msg}");
}
println!();
println!("๐ฆ Layout created:");
for (label, path) in [
("root ", layout.root().to_path_buf()),
("bin ", layout.bin_dir()),
("data ", layout.data_dir()),
("plugins ", layout.plugins_dir()),
("version ", layout.version_file()),
] {
let mark = if path.exists() { "โ
" } else { "โ" };
println!(" {mark} {label}{}", path.display());
}
println!();
println!("๐ Files in ~/.spool/bin/:");
if let Ok(entries) = std::fs::read_dir(layout.bin_dir()) {
for entry in entries.flatten() {
let size = entry.metadata().map(|m| m.len()).unwrap_or(0);
println!(
" โข {} ({} bytes)",
entry.file_name().to_string_lossy(),
size
);
}
}
println!();
if let Some(release) = &report.release {
println!("๐ Release report:");
println!(" โข copied: {}", release.copied.len());
println!(" โข skipped: {}", release.skipped.len());
println!();
}
if let Some(cfg) = &report.auto_configure {
println!("๐ AI client configuration:");
for client in &cfg.clients {
let icon = if client.installed {
"โ
"
} else if client.detected {
"โ ๏ธ "
} else {
"โญ๏ธ "
};
println!(
" {icon} {} โ detected={} installed={} status={}",
client.client, client.detected, client.installed, client.status
);
for note in &client.notes {
println!(" โณ {note}");
}
}
println!();
}
if let Some(path) = &report.path_config {
println!("๐ฃ๏ธ PATH configuration:");
println!(" โข configured: {}", path.configured);
println!(" โข files modified: {}", path.modified_files.len());
for f in &path.modified_files {
println!(" โณ {}", f.display());
}
println!();
}
println!("๐ Final state:");
let s = &report.state_after;
println!(
" โข service version: {:?}",
s.service.as_ref().map(|s| &s.version)
);
println!(" โข gui version: {:?}", s.gui_version);
println!(" โข mcp_registered: {}", s.mcp_registered);
println!(" โข hooks_installed: {}", s.hooks_installed);
println!(" โข path_configured: {}", s.path_configured);
println!();
println!("๐ Bootstrap smoke test completed successfully");
println!(" To inspect: ls -la {}", sandbox.display());
Ok(())
}