diff --git a/src/config.rs b/src/config.rs index 7ffea86d..02cc77f5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -26,6 +26,11 @@ pub struct HooksConfig { /// Survives `rtk init -g` re-runs since config.toml is user-owned. #[serde(default)] pub exclude_commands: Vec, + /// Suppress "No hook installed" and "Hook outdated" warnings. + /// Useful when running rtk via CLAUDE.md instructions instead of hooks, + /// or with tools like OpenCode that don't use Claude Code hooks. + #[serde(default)] + pub suppress_hook_warning: bool, } #[derive(Debug, Serialize, Deserialize)] @@ -127,6 +132,19 @@ pub fn limits() -> LimitsConfig { Config::load().map(|c| c.limits).unwrap_or_default() } +/// Check if hook warnings are suppressed via config or env var. +pub fn hook_warning_suppressed() -> bool { + if std::env::var("RTK_SUPPRESS_HOOK_WARNING") + .map(|v| v == "1" || v.eq_ignore_ascii_case("true")) + .unwrap_or(false) + { + return true; + } + Config::load() + .map(|c| c.hooks.suppress_hook_warning) + .unwrap_or(false) +} + /// Check if telemetry is enabled in config. Returns None if config can't be loaded. pub fn telemetry_enabled() -> Option { Config::load().ok().map(|c| c.telemetry.enabled) @@ -205,6 +223,7 @@ exclude_commands = ["curl", "gh"] fn test_hooks_config_default_empty() { let config = Config::default(); assert!(config.hooks.exclude_commands.is_empty()); + assert!(!config.hooks.suppress_hook_warning); } #[test] @@ -216,5 +235,26 @@ history_days = 90 "#; let config: Config = toml::from_str(toml).expect("valid toml"); assert!(config.hooks.exclude_commands.is_empty()); + assert!(!config.hooks.suppress_hook_warning); + } + + #[test] + fn test_suppress_hook_warning_deserialize() { + let toml = r#" +[hooks] +suppress_hook_warning = true +"#; + let config: Config = toml::from_str(toml).expect("valid toml"); + assert!(config.hooks.suppress_hook_warning); + } + + #[test] + fn test_suppress_hook_warning_default_false() { + let toml = r#" +[hooks] +exclude_commands = ["curl"] +"#; + let config: Config = toml::from_str(toml).expect("valid toml"); + assert!(!config.hooks.suppress_hook_warning); } } diff --git a/src/hook_check.rs b/src/hook_check.rs index 2716ec15..6c6cb7ae 100644 --- a/src/hook_check.rs +++ b/src/hook_check.rs @@ -55,6 +55,11 @@ fn check_and_warn() -> Option<()> { HookStatus::Outdated => "[rtk] /!\\ Hook outdated — run `rtk init -g` to update", }; + // Suppress if configured via config.toml or RTK_SUPPRESS_HOOK_WARNING env var + if crate::config::hook_warning_suppressed() { + return Some(()); + } + // Rate limit: warn once per day let marker = warn_marker_path()?; if let Ok(meta) = std::fs::metadata(&marker) {