Skip to main content

vtcode_core/cli/
tool_policy_commands.rs

1//! CLI commands for managing tool policies
2
3use crate::tool_policy::{ToolPolicy, ToolPolicyManager};
4use crate::tools::ToolRegistry;
5use crate::utils::colors::style;
6use anyhow::Result;
7use clap::Subcommand;
8
9/// Tool policy management commands
10#[derive(Debug, Clone, Subcommand)]
11pub enum ToolPolicyCommands {
12    /// Show current tool policy status
13    Status,
14    /// Allow a specific tool
15    Allow {
16        /// Tool name to allow
17        tool: String,
18    },
19    /// Deny a specific tool
20    Deny {
21        /// Tool name to deny
22        tool: String,
23    },
24    /// Set a tool to prompt for confirmation
25    Prompt {
26        /// Tool name to set to prompt
27        tool: String,
28    },
29    /// Allow all tools
30    AllowAll,
31    /// Deny all tools
32    DenyAll,
33    /// Reset all tools to prompt
34    ResetAll,
35}
36
37/// Handle tool policy commands
38pub async fn handle_tool_policy_command(command: ToolPolicyCommands) -> Result<()> {
39    let mut policy_manager = ToolPolicyManager::new().await?;
40
41    match command {
42        ToolPolicyCommands::Status => {
43            policy_manager.print_status();
44        }
45        ToolPolicyCommands::Allow { tool } => {
46            let normalized_tool = normalize_cli_tool_name(&tool).await;
47            policy_manager.set_policy(&normalized_tool, ToolPolicy::Allow).await?;
48            println!(
49                "{}",
50                style(format!("✓ Tool '{}' is now allowed", display_tool_name(&tool, &normalized_tool))).green()
51            );
52        }
53        ToolPolicyCommands::Deny { tool } => {
54            let normalized_tool = normalize_cli_tool_name(&tool).await;
55            policy_manager.set_policy(&normalized_tool, ToolPolicy::Deny).await?;
56            println!(
57                "{}",
58                style(format!("✗ Tool '{}' is now denied", display_tool_name(&tool, &normalized_tool))).red()
59            );
60        }
61        ToolPolicyCommands::Prompt { tool } => {
62            let normalized_tool = normalize_cli_tool_name(&tool).await;
63            policy_manager.set_policy(&normalized_tool, ToolPolicy::Prompt).await?;
64            println!(
65                "{}",
66                style(format!(
67                    "? Tool '{}' will now prompt for confirmation",
68                    display_tool_name(&tool, &normalized_tool)
69                ))
70                .cyan()
71            );
72        }
73        ToolPolicyCommands::AllowAll => {
74            policy_manager.allow_all_tools().await?;
75            println!("{}", style("✓ All tools are now allowed").green());
76        }
77        ToolPolicyCommands::DenyAll => {
78            policy_manager.deny_all_tools().await?;
79            println!("{}", style("✗ All tools are now denied").red());
80        }
81        ToolPolicyCommands::ResetAll => {
82            policy_manager.reset_all_to_prompt().await?;
83            println!("{}", style("? All tools reset to prompt for confirmation").cyan());
84        }
85    }
86
87    Ok(())
88}
89
90async fn normalize_cli_tool_name(tool: &str) -> String {
91    let Ok(workspace_root) = std::env::current_dir() else {
92        return tool.to_string();
93    };
94
95    let registry = ToolRegistry::new(workspace_root).await;
96    registry
97        .resolve_public_tool_name_sync(tool)
98        .unwrap_or_else(|_| tool.to_string())
99}
100
101fn display_tool_name(requested_tool: &str, normalized_tool: &str) -> String {
102    if requested_tool == normalized_tool {
103        requested_tool.to_string()
104    } else {
105        format!("{requested_tool} -> {normalized_tool}")
106    }
107}