agent_rules_tool/
discover.rs1use crate::RuleFormat;
4use std::path::{Path, PathBuf};
5
6#[derive(Debug, Clone)]
8pub struct ToolRuleDir {
9 pub path: &'static str,
11 pub format: RuleFormat,
13 pub extensions: &'static [&'static str],
15 pub suffix: Option<&'static str>,
17}
18
19pub const TOOL_RULE_DIRS: &[ToolRuleDir] = &[
21 ToolRuleDir {
22 path: ".agents/rules",
23 format: RuleFormat::Agents,
24 extensions: &["md"],
25 suffix: None,
26 },
27 ToolRuleDir {
28 path: ".cursor/rules",
29 format: RuleFormat::Cursor,
30 extensions: &["mdc", "md"],
31 suffix: None,
32 },
33 ToolRuleDir {
34 path: ".windsurf/rules",
35 format: RuleFormat::Windsurf,
36 extensions: &["md"],
37 suffix: None,
38 },
39 ToolRuleDir {
40 path: ".github/instructions",
41 format: RuleFormat::Copilot,
42 extensions: &["md"],
43 suffix: Some(".instructions.md"),
44 },
45 ToolRuleDir {
46 path: ".clinerules",
47 format: RuleFormat::Cline,
48 extensions: &["md"],
49 suffix: None,
50 },
51 ToolRuleDir {
52 path: ".claude/rules",
53 format: RuleFormat::Claude,
54 extensions: &["md"],
55 suffix: None,
56 },
57 ToolRuleDir {
58 path: ".aiassistant/rules",
59 format: RuleFormat::Jetbrains,
60 extensions: &["md"],
61 suffix: None,
62 },
63 ToolRuleDir {
64 path: ".amazonq/rules",
65 format: RuleFormat::AmazonQ,
66 extensions: &["md"],
67 suffix: None,
68 },
69];
70
71pub fn infer_format_from_path(path: &Path) -> Option<RuleFormat> {
73 let path_str = path.to_string_lossy().replace('\\', "/");
74 for dir in TOOL_RULE_DIRS {
75 if path_str.contains(dir.path) {
76 return Some(dir.format);
77 }
78 }
79 None
80}
81
82pub fn find_tool_dir(path: &Path) -> Option<&'static ToolRuleDir> {
84 let path_str = path.to_string_lossy().replace('\\', "/");
85 TOOL_RULE_DIRS
86 .iter()
87 .find(|dir| path_str.contains(dir.path))
88}
89
90pub fn existing_tool_dirs(project_root: &Path) -> Vec<(PathBuf, &'static ToolRuleDir)> {
92 TOOL_RULE_DIRS
93 .iter()
94 .filter_map(|dir| {
95 let full = project_root.join(dir.path);
96 if full.exists() {
97 Some((full, dir))
98 } else {
99 None
100 }
101 })
102 .collect()
103}