use crate::utils::env_utils;
use std::collections::HashSet;
pub const TASK_OUTPUT_TOOL_NAME: &str = "TaskOutput";
pub const EXIT_PLAN_MODE_V2_TOOL_NAME: &str = "ExitPlanModeV2";
pub const ENTER_PLAN_MODE_TOOL_NAME: &str = "EnterPlanMode";
pub const AGENT_TOOL_NAME: &str = "Agent";
pub const ASK_USER_QUESTION_TOOL_NAME: &str = "AskUserQuestion";
pub const TASK_STOP_TOOL_NAME: &str = "TaskStop";
pub const FILE_READ_TOOL_NAME: &str = "Read";
pub const WEB_SEARCH_TOOL_NAME: &str = "WebSearch";
pub const TODO_WRITE_TOOL_NAME: &str = "TodoWrite";
pub const GREP_TOOL_NAME: &str = "Grep";
pub const WEB_FETCH_TOOL_NAME: &str = "WebFetch";
pub const GLOB_TOOL_NAME: &str = "Glob";
pub const FILE_EDIT_TOOL_NAME: &str = "FileEdit";
pub const FILE_WRITE_TOOL_NAME: &str = "Write";
pub const NOTEBOOK_EDIT_TOOL_NAME: &str = "NotebookEdit";
pub const SKILL_TOOL_NAME: &str = "Skill";
pub const SEND_MESSAGE_TOOL_NAME: &str = "SendMessage";
pub const TASK_CREATE_TOOL_NAME: &str = "TaskCreate";
pub const TASK_GET_TOOL_NAME: &str = "TaskGet";
pub const TASK_LIST_TOOL_NAME: &str = "TaskList";
pub const TASK_UPDATE_TOOL_NAME: &str = "TaskUpdate";
pub const TOOL_SEARCH_TOOL_NAME: &str = "ToolSearch";
pub const SYNTHETIC_OUTPUT_TOOL_NAME: &str = "SyntheticOutput";
pub const ENTER_WORKTREE_TOOL_NAME: &str = "EnterWorktree";
pub const EXIT_WORKTREE_TOOL_NAME: &str = "ExitWorktree";
pub const WORKFLOW_TOOL_NAME: &str = "workflow";
pub const CRON_CREATE_TOOL_NAME: &str = "CronCreate";
pub const CRON_DELETE_TOOL_NAME: &str = "CronDelete";
pub const CRON_LIST_TOOL_NAME: &str = "CronList";
pub const REPL_TOOL_NAME: &str = "REPL";
pub const TUNGSTEN_TOOL_NAME: &str = "tungsten";
pub const CONFIG_TOOL_NAME: &str = "Config";
pub const LSP_TOOL_NAME: &str = "LSP";
pub const LIST_MCP_RESOURCES_TOOL_NAME: &str = "ListMcpResourcesTool";
pub const READ_MCP_RESOURCE_TOOL_NAME: &str = "ReadMcpResourceTool";
pub const BASH_TOOL_NAME: &str = "Bash";
pub const POWERSHELL_TOOL_NAME: &str = "PowerShell";
pub const MONITOR_TOOL_NAME: &str = "Monitor";
pub const SEND_USER_FILE_TOOL_NAME: &str = "send_user_file";
pub const WEB_BROWSER_TOOL_NAME: &str = "WebBrowser";
pub const SLEEP_TOOL_NAME: &str = "Sleep";
pub const REMOTE_TRIGGER_TOOL_NAME: &str = "RemoteTrigger";
pub const PUSH_NOTIFICATION_TOOL_NAME: &str = "PushNotification";
pub const SUBSCRIBE_PR_TOOL_NAME: &str = "SubscribePR";
pub const SUGGEST_BACKGROUND_PR_TOOL_NAME: &str = "SuggestBackgroundPR";
pub const OVERFLOW_TEST_TOOL_NAME: &str = "OverflowTestTool";
pub const CTX_INSPECT_TOOL_NAME: &str = "CtxInspect";
pub const TERMINAL_CAPTURE_TOOL_NAME: &str = "terminal_capture";
pub const SNIP_TOOL_NAME: &str = "snip";
pub const VERIFY_PLAN_EXECUTION_TOOL_NAME: &str = "verify_plan_execution";
pub const LIST_PEERS_TOOL_NAME: &str = "ListPeers";
pub fn all_agent_disallowed_tools() -> HashSet<&'static str> {
let mut set = HashSet::new();
set.insert(TASK_OUTPUT_TOOL_NAME);
set.insert(EXIT_PLAN_MODE_V2_TOOL_NAME);
set.insert(ENTER_PLAN_MODE_TOOL_NAME);
if !env_utils::is_ant_user() {
set.insert(AGENT_TOOL_NAME);
}
set.insert(ASK_USER_QUESTION_TOOL_NAME);
set.insert(TASK_STOP_TOOL_NAME);
set.insert(WORKFLOW_TOOL_NAME);
set
}
pub fn custom_agent_disallowed_tools() -> HashSet<&'static str> {
all_agent_disallowed_tools()
}
pub fn async_agent_allowed_tools() -> HashSet<&'static str> {
let mut set = HashSet::new();
set.insert(FILE_READ_TOOL_NAME);
set.insert(WEB_SEARCH_TOOL_NAME);
set.insert(TODO_WRITE_TOOL_NAME);
set.insert(GREP_TOOL_NAME);
set.insert(WEB_FETCH_TOOL_NAME);
set.insert(GLOB_TOOL_NAME);
set.insert(BASH_TOOL_NAME);
set.insert(POWERSHELL_TOOL_NAME);
set.insert(FILE_EDIT_TOOL_NAME);
set.insert(FILE_WRITE_TOOL_NAME);
set.insert(NOTEBOOK_EDIT_TOOL_NAME);
set.insert(SKILL_TOOL_NAME);
set.insert(SYNTHETIC_OUTPUT_TOOL_NAME);
set.insert(TOOL_SEARCH_TOOL_NAME);
set.insert(ENTER_WORKTREE_TOOL_NAME);
set.insert(EXIT_WORKTREE_TOOL_NAME);
set
}
pub fn coordinator_mode_allowed_tools() -> HashSet<&'static str> {
let mut set = HashSet::new();
set.insert(AGENT_TOOL_NAME);
set.insert(TASK_STOP_TOOL_NAME);
set.insert(SEND_MESSAGE_TOOL_NAME);
set.insert(SYNTHETIC_OUTPUT_TOOL_NAME);
set
}
pub fn in_process_teammate_allowed_tools() -> HashSet<&'static str> {
let mut set = HashSet::new();
set.insert(TASK_CREATE_TOOL_NAME);
set.insert(TASK_GET_TOOL_NAME);
set.insert(TASK_LIST_TOOL_NAME);
set.insert(TASK_UPDATE_TOOL_NAME);
set.insert(SEND_MESSAGE_TOOL_NAME);
set.insert(CRON_CREATE_TOOL_NAME);
set.insert(CRON_DELETE_TOOL_NAME);
set.insert(CRON_LIST_TOOL_NAME);
set
}
pub fn repl_only_tools() -> HashSet<&'static str> {
let mut set = HashSet::new();
set.insert(FILE_READ_TOOL_NAME);
set.insert(FILE_WRITE_TOOL_NAME);
set.insert(FILE_EDIT_TOOL_NAME);
set.insert(GLOB_TOOL_NAME);
set.insert(GREP_TOOL_NAME);
set.insert(BASH_TOOL_NAME);
set.insert(NOTEBOOK_EDIT_TOOL_NAME);
set.insert(AGENT_TOOL_NAME);
set
}
pub fn is_repl_mode_enabled() -> bool {
if env_utils::is_env_defined_falsy(std::env::var("CLAUDE_CODE_REPL").ok().as_deref()) {
return false;
}
if env_utils::is_env_truthy(std::env::var("CLAUDE_REPL_MODE").ok().as_deref()) {
return true;
}
env_utils::is_ant_user()
&& std::env::var("CLAUDE_CODE_ENTRYPOINT")
.map(|v| v == "cli")
.unwrap_or(false)
}
pub fn is_tool_search_enabled_optimistic() -> bool {
let mode = get_tool_search_mode();
if mode == "standard" {
return false;
}
if std::env::var("ENABLE_TOOL_SEARCH").is_err() {
if let Ok(base_url) = std::env::var("ANTHROPIC_BASE_URL") {
let first_party_hosts = ["api.anthropic.com", "api.anthropic.ai"];
if !first_party_hosts.iter().any(|h| base_url.contains(h)) {
return false;
}
}
}
true
}
pub fn get_tool_search_mode() -> &'static str {
if env_utils::is_env_truthy(
std::env::var("CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS")
.ok()
.as_deref(),
) {
return "standard";
}
let value = std::env::var("ENABLE_TOOL_SEARCH").ok();
if let Some(ref v) = value {
if let Some(percent) = parse_auto_percentage(v) {
if percent == 0 {
return "tst";
}
if percent == 100 {
return "standard";
}
return "tst-auto";
}
}
if env_utils::is_env_truthy(value.as_deref()) {
return "tst";
}
if env_utils::is_env_defined_falsy(value.as_deref()) {
return "standard";
}
"tst"
}
fn parse_auto_percentage(value: &str) -> Option<i32> {
if !value.starts_with("auto:") {
return None;
}
let percent_str = &value[5..];
percent_str.parse::<i32>().ok().map(|p| p.max(0).min(100))
}
pub fn is_worktree_mode_enabled() -> bool {
true
}
pub fn is_agent_swarms_enabled() -> bool {
if env_utils::is_ant_user() {
return true;
}
if !env_utils::is_env_truthy(
std::env::var("CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS")
.ok()
.as_deref(),
) && !std::env::args().any(|a| a == "--agent-teams")
{
return false;
}
true
}
pub fn is_powershell_tool_enabled() -> bool {
if env_utils::get_platform() != "windows" {
return false;
}
if env_utils::is_ant_user() {
return !env_utils::is_env_defined_falsy(
std::env::var("CLAUDE_CODE_USE_POWERSHELL_TOOL")
.ok()
.as_deref(),
);
}
env_utils::is_env_truthy(
std::env::var("CLAUDE_CODE_USE_POWERSHELL_TOOL")
.ok()
.as_deref(),
)
}
pub fn shell_tool_names() -> Vec<&'static str> {
let mut names = vec![BASH_TOOL_NAME];
if is_powershell_tool_enabled() {
names.push(POWERSHELL_TOOL_NAME);
}
names
}
pub fn has_embedded_search_tools() -> bool {
if !env_utils::is_env_truthy(std::env::var("EMBEDDED_SEARCH_TOOLS").ok().as_deref()) {
return false;
}
let entrypoint = std::env::var("CLAUDE_CODE_ENTRYPOINT").unwrap_or_default();
!["sdk-ts", "sdk-py", "sdk-cli", "local-agent"].contains(&entrypoint.as_str())
}
pub fn is_todo_v2_enabled() -> bool {
if env_utils::is_env_truthy(std::env::var("CLAUDE_CODE_ENABLE_TASKS").ok().as_deref()) {
return true;
}
true
}