Skip to main content

claude_native/
multi_tool.rs

1use std::fs;
2use std::path::Path;
3
4use anyhow::Result;
5
6use crate::detection::ProjectType;
7use crate::init;
8use crate::scan::ProjectContext;
9
10/// Generate configs for multiple AI tools alongside CLAUDE.md.
11pub fn generate_all(ctx: &ProjectContext) -> Result<Vec<String>> {
12    let mut created = Vec::new();
13    let root = &ctx.root;
14    let pt = ctx.project_type.as_ref();
15
16    // Standard --init files
17    let init_files = init::init_project(ctx)?;
18    created.extend(init_files);
19
20    // .cursorrules (Cursor IDE)
21    if !root.join(".cursorrules").exists() {
22        fs::write(root.join(".cursorrules"), generate_cursorrules(ctx, pt))?;
23        created.push(".cursorrules".into());
24    }
25
26    // .github/copilot-instructions.md (GitHub Copilot)
27    let copilot_dir = root.join(".github");
28    let copilot_path = copilot_dir.join("copilot-instructions.md");
29    if !copilot_path.exists() {
30        fs::create_dir_all(&copilot_dir)?;
31        fs::write(&copilot_path, generate_copilot_instructions(ctx, pt))?;
32        created.push(".github/copilot-instructions.md".into());
33    }
34
35    Ok(created)
36}
37
38fn generate_cursorrules(ctx: &ProjectContext, pt: Option<&ProjectType>) -> String {
39    let name = project_name(ctx);
40    let (build, test) = init::detect_commands(ctx, pt);
41    format!(
42        "# {name} — Cursor Rules\n\
43         \n\
44         ## Build & Test\n\
45         - Build: `{build}`\n\
46         - Test: `{test}`\n\
47         \n\
48         ## Code Style\n\
49         - Follow existing patterns in the codebase\n\
50         - Write tests for new functionality\n\
51         - Keep functions focused and concise\n\
52         - Use descriptive variable and function names\n"
53    )
54}
55
56fn generate_copilot_instructions(ctx: &ProjectContext, pt: Option<&ProjectType>) -> String {
57    let name = project_name(ctx);
58    let (build, test) = init::detect_commands(ctx, pt);
59    format!(
60        "# {name} — Copilot Instructions\n\
61         \n\
62         ## Project\n\
63         Build: `{build}`\n\
64         Test: `{test}`\n\
65         \n\
66         ## Guidelines\n\
67         - Follow existing code patterns and conventions\n\
68         - Write tests for all new functionality\n\
69         - Keep functions under 80 lines\n\
70         - Prefer explicit types over inference where it aids readability\n"
71    )
72}
73
74fn project_name(ctx: &ProjectContext) -> String {
75    ctx.root.file_name()
76        .and_then(|n| n.to_str())
77        .unwrap_or("Project")
78        .to_string()
79}