1pub mod claude;
6pub mod edits;
7pub mod general;
8pub mod hook;
9
10use std::path::{Path, PathBuf};
11
12pub struct Change {
14 pub path: PathBuf,
15 pub action: &'static str,
16}
17
18impl Change {
19 pub fn new(path: PathBuf, action: &'static str) -> Self {
20 Self { path, action }
21 }
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
26pub enum Scope {
27 Local,
28 User,
29 Project,
30}
31
32impl Scope {
33 pub fn as_str(self) -> &'static str {
34 match self {
35 Scope::Local => "local",
36 Scope::User => "user",
37 Scope::Project => "project",
38 }
39 }
40}
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
44pub enum Harness {
45 Claude,
46 General,
47}
48
49pub fn run_use(harness: Harness, scope: Scope, root: &Path) -> anyhow::Result<i32> {
51 let changes = match harness {
52 Harness::Claude => {
53 claude::preflight(scope, root)?; claude::apply(scope, root)?
55 }
56 Harness::General => {
57 if !matches!(scope, Scope::Project) {
58 eprintln!(
59 "note: `general` supports project scope only; writing to the project root"
60 );
61 }
62 general::preflight(root)?;
63 general::apply(root)?
64 }
65 };
66 print_summary(harness, &changes);
67 Ok(0)
68}
69
70fn print_summary(harness: Harness, changes: &[Change]) {
71 eprintln!("✓ wired Rover into `{}`:", harness_name(harness));
72 for c in changes {
73 eprintln!(" - {} ({})", c.path.display(), c.action);
74 }
75}
76
77fn harness_name(harness: Harness) -> &'static str {
78 match harness {
79 Harness::Claude => "claude",
80 Harness::General => "general",
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use tempfile::tempdir;
88
89 #[test]
90 fn run_use_general_writes_files_and_returns_zero() {
91 let tmp = tempdir().unwrap();
92 let code = run_use(Harness::General, Scope::Project, tmp.path()).unwrap();
93 assert_eq!(code, 0);
94 assert!(tmp.path().join("mcp.json").exists());
95 assert!(tmp.path().join("AGENTS.md").exists());
96 }
97}