claude_native/
multi_tool.rs1use std::fs;
2use std::path::Path;
3
4use anyhow::Result;
5
6use crate::detection::ProjectType;
7use crate::init;
8use crate::scan::ProjectContext;
9
10pub 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 let init_files = init::init_project(ctx)?;
18 created.extend(init_files);
19
20 if !root.join(".cursorrules").exists() {
22 fs::write(root.join(".cursorrules"), generate_cursorrules(ctx, pt))?;
23 created.push(".cursorrules".into());
24 }
25
26 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}