pub mod claude;
pub mod edits;
pub mod general;
pub mod hook;
use std::path::{Path, PathBuf};
pub struct Change {
pub path: PathBuf,
pub action: &'static str,
}
impl Change {
pub fn new(path: PathBuf, action: &'static str) -> Self {
Self { path, action }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum Scope {
Local,
User,
Project,
}
impl Scope {
pub fn as_str(self) -> &'static str {
match self {
Scope::Local => "local",
Scope::User => "user",
Scope::Project => "project",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum Harness {
Claude,
General,
}
pub fn run_use(harness: Harness, scope: Scope, root: &Path) -> anyhow::Result<i32> {
let changes = match harness {
Harness::Claude => {
claude::preflight(scope, root)?; claude::apply(scope, root)?
}
Harness::General => {
if !matches!(scope, Scope::Project) {
eprintln!(
"note: `general` supports project scope only; writing to the project root"
);
}
general::preflight(root)?;
general::apply(root)?
}
};
print_summary(harness, &changes);
Ok(0)
}
fn print_summary(harness: Harness, changes: &[Change]) {
eprintln!("✓ wired Rover into `{}`:", harness_name(harness));
for c in changes {
eprintln!(" - {} ({})", c.path.display(), c.action);
}
}
fn harness_name(harness: Harness) -> &'static str {
match harness {
Harness::Claude => "claude",
Harness::General => "general",
}
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[test]
fn run_use_general_writes_files_and_returns_zero() {
let tmp = tempdir().unwrap();
let code = run_use(Harness::General, Scope::Project, tmp.path()).unwrap();
assert_eq!(code, 0);
assert!(tmp.path().join("mcp.json").exists());
assert!(tmp.path().join("AGENTS.md").exists());
}
}