terminal_jarvis/
installation_arguments.rs

1// src/installation_arguments.rs
2//
3// Tool installation command management and validation
4//
5// This module provides a centralized system for managing installation commands
6// across all supported AI coding tools, with NPM availability validation.
7//
8// Configuration is now loaded from the modular config system for better maintainability
9// and future database integration capabilities.
10
11use crate::tools::tools_command_mapping::{get_install_command, get_update_command};
12use crate::tools::tools_config::get_tool_config_loader;
13use std::collections::HashMap;
14
15/// Installation command structure for compatibility with existing code
16#[derive(Debug, Clone)]
17pub struct InstallCommand {
18    pub command: String,
19    pub args: Vec<String>,
20    pub pipe_to: Option<String>, // For curl-based installations that pipe to bash
21    pub description: String,
22    pub requires_npm: bool,
23    #[allow(dead_code)] // Used for installation privilege management
24    pub requires_sudo: bool,
25}
26
27/// Manages installation commands and dependency validation for AI coding tools
28///
29/// Provides a centralized interface for:
30/// - Checking system dependencies (NPM availability)
31/// - Retrieving installation commands for specific tools
32/// - Validating installation prerequisites
33///
34/// All installation commands are loaded from ai-tools-registry.toml to ensure consistency
35/// and enable easy maintenance without code changes.
36pub struct InstallationManager;
37
38impl InstallationManager {
39    /// Checks if NPM is available on the system
40    ///
41    /// Executes `npm --version` to verify NPM installation and accessibility.
42    /// Used to validate prerequisites before attempting NPM-based tool installations.
43    ///
44    /// # Returns
45    ///
46    /// * `true` - NPM is installed and accessible
47    /// * `false` - NPM is not available or execution failed
48    ///
49    /// # Example
50    ///
51    /// ```rust,ignore
52    /// if InstallationManager::check_npm_available() {
53    ///     println!("NPM is available for tool installation");
54    /// } else {
55    ///     println!("NPM is required but not found");
56    /// }
57    /// ```
58    pub fn check_npm_available() -> bool {
59        std::process::Command::new("npm")
60            .arg("--version")
61            .output()
62            .map(|output| output.status.success())
63            .unwrap_or(false)
64    }
65
66    /// Checks if curl is available on the system
67    ///
68    /// Executes `curl --version` to verify curl installation and accessibility.
69    /// Used to validate prerequisites before attempting curl-based tool installations.
70    ///
71    /// # Returns
72    ///
73    /// * `true` - curl is installed and accessible
74    /// * `false` - curl is not available or execution failed
75    pub fn check_curl_available() -> bool {
76        std::process::Command::new("curl")
77            .arg("--version")
78            .output()
79            .map(|output| output.status.success())
80            .unwrap_or(false)
81    }
82
83    /// Checks if uv is available on the system
84    ///
85    /// Executes `uv --version` to verify uv installation and accessibility.
86    /// Used to validate prerequisites before attempting uv-based tool installations.
87    ///
88    /// # Returns
89    ///
90    /// * `true` - uv is installed and accessible
91    /// * `false` - uv is not available or execution failed
92    pub fn check_uv_available() -> bool {
93        std::process::Command::new("uv")
94            .arg("--version")
95            .output()
96            .map(|output| output.status.success())
97            .unwrap_or(false)
98    }
99
100    /// Returns a list of all supported tool names
101    ///
102    /// Provides the canonical list of tool names that can be used with
103    /// [`get_install_command`](Self::get_install_command).
104    ///
105    /// # Returns
106    ///
107    /// A vector of tool name strings (e.g., ["claude", "gemini", "qwen"])
108    ///
109    /// # Example
110    ///
111    /// ```rust,ignore
112    /// let tools = InstallationManager::get_tool_names();
113    /// for tool in tools {
114    ///     println!("Supported tool: {}", tool);
115    /// }
116    /// ```
117    pub fn get_tool_names() -> Vec<String> {
118        let config_loader = get_tool_config_loader();
119        config_loader.get_tool_names()
120    }
121
122    /// Retrieves installation command for a specific tool
123    ///
124    /// # Arguments
125    ///
126    /// * `tool` - The name of the tool (e.g., "claude", "gemini")
127    ///
128    /// # Returns
129    ///
130    /// * `Some(InstallCommand)` - Installation command metadata if tool is supported
131    /// * `None` - If the tool name is not recognized
132    ///
133    /// # Example
134    ///
135    /// ```rust,ignore
136    /// if let Some(cmd) = InstallationManager::get_install_command("claude") {
137    ///     println!("Install command: {} {}", cmd.command, cmd.args.join(" "));
138    /// } else {
139    ///     println!("Tool not found");
140    /// }
141    /// ```
142    pub fn get_install_command(tool: &str) -> Option<InstallCommand> {
143        get_install_command(tool).map(|cmd| InstallCommand {
144            command: cmd.command,
145            args: cmd.args,
146            pipe_to: cmd.pipe_to,
147            description: cmd.description,
148            requires_npm: cmd.requires_npm,
149            requires_sudo: cmd.requires_sudo,
150        })
151    }
152
153    /// Retrieves update command for a specific tool
154    ///
155    /// # Arguments
156    ///
157    /// * `tool` - The name of the tool (e.g., "claude", "gemini")
158    ///
159    /// # Returns
160    ///
161    /// * `Some(InstallCommand)` - Update command metadata if tool is supported
162    /// * `None` - If the tool name is not recognized
163    ///
164    /// # Example
165    ///
166    /// ```rust,ignore
167    /// if let Some(cmd) = InstallationManager::get_update_command("claude") {
168    ///     println!("Update command: {} {}", cmd.command, cmd.args.join(" "));
169    /// } else {
170    ///     println!("Tool not found");
171    /// }
172    /// ```
173    #[allow(dead_code)] // Used by update functionality
174    pub fn get_update_command(tool: &str) -> Option<InstallCommand> {
175        get_update_command(tool).map(|cmd| InstallCommand {
176            command: cmd.command,
177            args: cmd.args,
178            pipe_to: cmd.pipe_to,
179            description: cmd.description,
180            requires_npm: cmd.requires_npm,
181            requires_sudo: cmd.requires_sudo,
182        })
183    }
184
185    /// Returns all available installation commands
186    ///
187    /// Provides the complete mapping of tool names to their installation commands.
188    /// This is the authoritative source for all supported tools and their metadata.
189    ///
190    /// # Returns
191    ///
192    /// A HashMap mapping tool names to their InstallCommand structures
193    ///
194    /// # Note
195    ///
196    /// This method loads from the modular TOML configuration files in `config/tools/` on each call.
197    /// For single-tool lookups, prefer [`get_install_command`](Self::get_install_command).
198    pub fn get_install_commands() -> HashMap<String, InstallCommand> {
199        let config_loader = get_tool_config_loader();
200        let tool_names = config_loader.get_tool_names();
201        let mut commands = HashMap::new();
202
203        for tool in tool_names {
204            if let Some(cmd) = get_install_command(&tool) {
205                commands.insert(
206                    tool,
207                    InstallCommand {
208                        command: cmd.command,
209                        args: cmd.args,
210                        pipe_to: cmd.pipe_to,
211                        description: cmd.description,
212                        requires_npm: cmd.requires_npm,
213                        requires_sudo: cmd.requires_sudo,
214                    },
215                );
216            }
217        }
218
219        commands
220    }
221}