Skip to main content

vtcode_safety/command_safety/
command_db.rs

1//! Command database: comprehensive safe command rules organized by category.
2//!
3//! This module organizes commands into semantic categories and provides
4//! helper functions for building command rules at scale.
5//!
6//! Categories:
7//! - File operations (read-only)
8//! - Source control (read-only)
9//! - Build systems
10//! - Version managers
11//! - Development tools
12//! - Text processing
13//! - System utilities (read-only)
14
15use super::safe_command_registry::CommandRule;
16use hashbrown::HashMap;
17
18/// Database of command rules by category
19#[derive(Clone)]
20pub struct CommandDatabase;
21
22impl CommandDatabase {
23    /// Returns all built-in command rules
24    fn all_rules() -> HashMap<String, CommandRule> {
25        let mut rules = HashMap::new();
26
27        // File operations (read-only)
28        for cmd in Self::file_operations() {
29            rules.insert(cmd, CommandRule::safe_readonly());
30        }
31
32        // Source control (read-only safe + dangerous operations)
33        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        // Build systems
41        for cmd in Self::build_systems() {
42            rules.insert(cmd, CommandRule::safe_readonly());
43        }
44
45        // Version managers (read-only)
46        for cmd in Self::version_managers() {
47            rules.insert(cmd, CommandRule::safe_readonly());
48        }
49
50        // Development tools
51        for cmd in Self::development_tools() {
52            rules.insert(cmd, CommandRule::safe_readonly());
53        }
54
55        // Text processing
56        for cmd in Self::text_processing() {
57            rules.insert(cmd, CommandRule::safe_readonly());
58        }
59
60        rules
61    }
62
63    /// File operations (read-only commands)
64    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    /// Source control commands
74    fn source_control() -> Vec<String> {
75        vec!["git", "hg", "svn", "bzr"].into_iter().map(|s| s.to_string()).collect()
76    }
77
78    /// Build system commands
79    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    /// Version manager commands
87    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    /// Development tool commands
95    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    /// Text processing commands
105    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}