From 02ea499d38d8fd2535c9d4735ae831f535f17777 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Sat, 21 Mar 2026 13:57:00 -0700 Subject: [PATCH] feat(config): add suppress_hook_warning option Add hooks.suppress_hook_warning config option and RTK_SUPPRESS_HOOK_WARNING env var to disable "No hook installed" and "Hook outdated" warnings. Users running rtk via CLAUDE.md instructions instead of hooks, or with tools like OpenCode, get these warnings on every command. The warnings waste tokens and confuse AI agents since rtk is working correctly. The env var is checked first (useful for CI and tools without config files), then the config file. Both default to false so existing behavior is unchanged. Fixes #682 Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> --- src/config.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/hook_check.rs | 5 +++++ 2 files changed, 45 insertions(+) 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) {