Skip to main content

vtcode_core/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    pub 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![
37                    "branch",
38                    "status",
39                    "log",
40                    "diff",
41                    "show",
42                    "rev-parse",
43                ]),
44            );
45        }
46
47        // Build systems
48        for cmd in Self::build_systems() {
49            rules.insert(cmd, CommandRule::safe_readonly());
50        }
51
52        // Version managers (read-only)
53        for cmd in Self::version_managers() {
54            rules.insert(cmd, CommandRule::safe_readonly());
55        }
56
57        // Development tools
58        for cmd in Self::development_tools() {
59            rules.insert(cmd, CommandRule::safe_readonly());
60        }
61
62        // Text processing
63        for cmd in Self::text_processing() {
64            rules.insert(cmd, CommandRule::safe_readonly());
65        }
66
67        rules
68    }
69
70    /// File operations (read-only commands)
71    fn file_operations() -> Vec<String> {
72        vec![
73            "cat", "head", "tail", "wc", "file", "stat", "ls", "find", "locate", "which",
74            "whereis", "tree", "du", "df",
75        ]
76        .into_iter()
77        .map(|s| s.to_string())
78        .collect()
79    }
80
81    /// Source control commands
82    fn source_control() -> Vec<String> {
83        vec!["git", "hg", "svn", "bzr"]
84            .into_iter()
85            .map(|s| s.to_string())
86            .collect()
87    }
88
89    /// Build system commands
90    fn build_systems() -> Vec<String> {
91        vec!["cargo", "make", "cmake", "ninja", "gradle", "mvn", "ant"]
92            .into_iter()
93            .map(|s| s.to_string())
94            .collect()
95    }
96
97    /// Version manager commands
98    fn version_managers() -> Vec<String> {
99        vec!["rustup", "rbenv", "nvm", "pyenv", "jenv", "sdkman"]
100            .into_iter()
101            .map(|s| s.to_string())
102            .collect()
103    }
104
105    /// Development tool commands
106    fn development_tools() -> Vec<String> {
107        vec![
108            "node", "python", "ruby", "go", "java", "javac", "gcc", "g++", "clang", "rustc",
109        ]
110        .into_iter()
111        .map(|s| s.to_string())
112        .collect()
113    }
114
115    /// Text processing commands
116    fn text_processing() -> Vec<String> {
117        vec![
118            "grep", "sed", "awk", "cut", "paste", "sort", "uniq", "tr", "rev", "expand",
119            "unexpand", "fmt", "pr",
120        ]
121        .into_iter()
122        .map(|s| s.to_string())
123        .collect()
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn database_loads_without_error() {
133        let rules = CommandDatabase::all_rules();
134        assert!(!rules.is_empty());
135    }
136
137    #[test]
138    fn database_includes_file_operations() {
139        let rules = CommandDatabase::all_rules();
140        assert!(rules.contains_key("cat"));
141        assert!(rules.contains_key("grep"));
142    }
143
144    #[test]
145    fn database_includes_source_control() {
146        let rules = CommandDatabase::all_rules();
147        assert!(rules.contains_key("git"));
148        assert!(rules.contains_key("svn"));
149    }
150
151    #[test]
152    fn database_includes_build_systems() {
153        let rules = CommandDatabase::all_rules();
154        assert!(rules.contains_key("cargo"));
155        assert!(rules.contains_key("make"));
156    }
157}