vtcode_safety/command_safety/
command_db.rs1use super::safe_command_registry::CommandRule;
16use hashbrown::HashMap;
17
18#[derive(Clone)]
20pub struct CommandDatabase;
21
22impl CommandDatabase {
23 fn all_rules() -> HashMap<String, CommandRule> {
25 let mut rules = HashMap::new();
26
27 for cmd in Self::file_operations() {
29 rules.insert(cmd, CommandRule::safe_readonly());
30 }
31
32 for cmd in Self::source_control() {
34 rules.insert(
35 cmd,
36 CommandRule::with_allowed_subcommands(vec!["branch", "status", "log", "diff", "show", "rev-parse"]),
37 );
38 }
39
40 for cmd in Self::build_systems() {
42 rules.insert(cmd, CommandRule::safe_readonly());
43 }
44
45 for cmd in Self::version_managers() {
47 rules.insert(cmd, CommandRule::safe_readonly());
48 }
49
50 for cmd in Self::development_tools() {
52 rules.insert(cmd, CommandRule::safe_readonly());
53 }
54
55 for cmd in Self::text_processing() {
57 rules.insert(cmd, CommandRule::safe_readonly());
58 }
59
60 rules
61 }
62
63 fn file_operations() -> Vec<String> {
65 vec![
66 "cat", "head", "tail", "wc", "file", "stat", "ls", "find", "locate", "which", "whereis", "tree", "du", "df",
67 ]
68 .into_iter()
69 .map(|s| s.to_string())
70 .collect()
71 }
72
73 fn source_control() -> Vec<String> {
75 vec!["git", "hg", "svn", "bzr"].into_iter().map(|s| s.to_string()).collect()
76 }
77
78 fn build_systems() -> Vec<String> {
80 vec!["cargo", "make", "cmake", "ninja", "gradle", "mvn", "ant"]
81 .into_iter()
82 .map(|s| s.to_string())
83 .collect()
84 }
85
86 fn version_managers() -> Vec<String> {
88 vec!["rustup", "rbenv", "nvm", "pyenv", "jenv", "sdkman"]
89 .into_iter()
90 .map(|s| s.to_string())
91 .collect()
92 }
93
94 fn development_tools() -> Vec<String> {
96 vec![
97 "node", "python", "ruby", "go", "java", "javac", "gcc", "g++", "clang", "rustc",
98 ]
99 .into_iter()
100 .map(|s| s.to_string())
101 .collect()
102 }
103
104 fn text_processing() -> Vec<String> {
106 vec![
107 "grep", "sed", "awk", "cut", "paste", "sort", "uniq", "tr", "rev", "expand", "unexpand", "fmt", "pr",
108 ]
109 .into_iter()
110 .map(|s| s.to_string())
111 .collect()
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn database_loads_without_error() {
121 let rules = CommandDatabase::all_rules();
122 assert!(!rules.is_empty());
123 }
124
125 #[test]
126 fn database_includes_file_operations() {
127 let rules = CommandDatabase::all_rules();
128 assert!(rules.contains_key("cat"));
129 assert!(rules.contains_key("grep"));
130 }
131
132 #[test]
133 fn database_includes_source_control() {
134 let rules = CommandDatabase::all_rules();
135 assert!(rules.contains_key("git"));
136 assert!(rules.contains_key("svn"));
137 }
138
139 #[test]
140 fn database_includes_build_systems() {
141 let rules = CommandDatabase::all_rules();
142 assert!(rules.contains_key("cargo"));
143 assert!(rules.contains_key("make"));
144 }
145}