Skip to main content

vtcode_core/config/
mod.rs

1//! Configuration facade for vtcode-core.
2//!
3//! This module re-exports the extracted `vtcode-config` crate so existing
4//! call sites continue to access configuration types and helpers through
5//! `vtcode_core::config`.
6
7pub mod acp;
8pub mod api;
9pub mod api_keys;
10pub mod constants;
11pub mod context;
12pub mod core;
13pub mod defaults;
14pub mod hooks;
15pub mod loader;
16pub mod mcp;
17pub mod models;
18pub mod telemetry;
19pub mod types;
20pub mod validation;
21pub mod validator;
22
23pub use acp::{
24    AgentClientProtocolConfig, AgentClientProtocolTransport, AgentClientProtocolZedConfig,
25    AgentClientProtocolZedToolsConfig, AgentClientProtocolZedWorkspaceTrustMode, WorkspaceTrustLevel,
26};
27pub use api::{
28    ConfigLayerView, ConfigReadRequest, ConfigReadResponse, ConfigResetRequest, ConfigResetResponse, ConfigService,
29    ConfigWriteRequest, ConfigWriteResponse, ConfigWriteStrategy, ConfigWriteTarget, OverrideMetadata,
30};
31pub use api_keys::ApiKeySources;
32pub use context::{ContextFeaturesConfig, LedgerConfig};
33pub use core::{
34    AgentConfig, AgentOnboardingConfig, AgentPromptSuggestionsConfig, AutoPermissionConfig,
35    AutoPermissionEnvironmentConfig, AutomationConfig, CommandsConfig, EditorToolConfig, FullAutoConfig,
36    GatekeeperConfig, ModelConfig, OpenAIPromptCacheKeyMode, PermissionsConfig, PersistentMemoryConfig,
37    PromptCachingConfig, ProviderPromptCachingConfig, ScheduledTasksConfig, SecurityConfig, ToolPolicy, ToolProfile,
38    ToolsConfig, build_openai_prompt_cache_key, build_session_affinity_prompt_cache_key,
39    map_prompt_cache_key_for_provider, session_affinity_key_enabled, session_affinity_provider,
40    tool_call_delay_for_rate, tool_loop_limit_reached,
41};
42pub use core::{PluginRuntimeConfig, PluginTrustLevel};
43pub use defaults::{
44    ConfigDefaultsProvider, ContextStoreDefaults, PerformanceDefaults, ScenarioDefaults, SyntaxHighlightingDefaults,
45    WorkspacePathsDefaults, current_config_defaults, get_config_dir, get_data_dir, install_config_defaults_provider,
46    reset_to_default_config_defaults, with_config_defaults,
47};
48pub use hooks::{
49    HookCommandConfig, HookCommandKind, HookGroupConfig, HooksConfig, LifecycleHooksConfig, WorkspaceHookCommand,
50    WorkspaceLifecycleHooks,
51};
52pub use loader::{ConfigManager, SyntaxHighlightingConfig, VTCodeConfig};
53pub use mcp::{
54    McpAllowListConfig, McpAllowListRules, McpClientConfig, McpHttpServerConfig, McpProviderConfig,
55    McpStdioServerConfig, McpTransportConfig, McpUiConfig, McpUiMode,
56};
57pub use models::{ModelId, OpenRouterMetadata};
58pub use telemetry::TelemetryConfig;
59pub use types::{ReasoningEffortLevel, SystemPromptMode, ToolDocumentationMode, UiSurfacePreference, VerbosityLevel};
60pub use validation::{ValidationResult, validate_config, validate_model_exists};
61pub use validator::ConfigValidator;
62pub use vtcode_config::WebmcpConfig;
63pub use vtcode_config::root::{
64    KeyboardProtocolConfig, KeyboardProtocolMode, LayoutModeOverride, PtyConfig, ReasoningDisplayMode, ToolDisplayMode,
65    ToolOutputMode, UiConfig, UiDisplayMode, UiTranscriptReviewConfig,
66};
67pub use vtcode_config::status_line::{StatusLineConfig, StatusLineMode};
68pub use vtcode_config::terminal_title::{DEFAULT_TERMINAL_TITLE_ITEMS, TerminalTitleConfig};
69pub use vtcode_config::{
70    FileOpener, HistoryConfig, HistoryPersistence, NotificationCondition, TerminalNotificationMethod,
71    TuiAlternateScreen, TuiConfig, TuiNotificationEvent, TuiNotificationsConfig,
72};
73pub use vtcode_config::{TimeoutsConfig, resolve_timeout};
74
75#[cfg(all(test, feature = "tui"))]
76fn keyboard_protocol_to_flags_for_terminal(
77    config: &KeyboardProtocolConfig,
78    is_macos: bool,
79    term_program: Option<&str>,
80    term: Option<&str>,
81) -> crossterm::event::KeyboardEnhancementFlags {
82    use ratatui::crossterm::event::KeyboardEnhancementFlags;
83
84    if !config.enabled {
85        return KeyboardEnhancementFlags::empty();
86    }
87
88    let mut flags = match config.mode {
89        KeyboardProtocolMode::Default => {
90            KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
91                | KeyboardEnhancementFlags::REPORT_EVENT_TYPES
92                | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS
93        }
94        KeyboardProtocolMode::Full => {
95            KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
96                | KeyboardEnhancementFlags::REPORT_EVENT_TYPES
97                | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS
98                | KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES
99        }
100        KeyboardProtocolMode::Minimal => KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES,
101        KeyboardProtocolMode::Custom => {
102            let mut flags = KeyboardEnhancementFlags::empty();
103            if config.disambiguate_escape_codes {
104                flags |= KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES;
105            }
106            if config.report_event_types {
107                flags |= KeyboardEnhancementFlags::REPORT_EVENT_TYPES;
108            }
109            if config.report_alternate_keys {
110                flags |= KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS;
111            }
112            if config.report_all_keys {
113                flags |= KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES;
114            }
115            flags
116        }
117    };
118
119    if should_force_report_all_keys(config.mode, is_macos, term_program, term) {
120        flags |= KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES;
121    }
122
123    flags
124}
125
126#[cfg(all(test, feature = "tui"))]
127fn should_force_report_all_keys(
128    mode: KeyboardProtocolMode,
129    is_macos: bool,
130    term_program: Option<&str>,
131    term: Option<&str>,
132) -> bool {
133    if !is_macos || mode != KeyboardProtocolMode::Default {
134        return false;
135    }
136
137    // Ghostty on macOS needs "report all keys" enabled so bare Command presses
138    // surface as modifier-key events that transcript link clicks can merge in.
139    vtcode_commons::terminal_detection::is_ghostty_terminal(term_program, term)
140}
141
142#[cfg(all(test, feature = "tui"))]
143mod keyboard_protocol_tests {
144    use super::*;
145    use ratatui::crossterm::event::KeyboardEnhancementFlags;
146
147    fn default_keyboard_protocol_config() -> KeyboardProtocolConfig {
148        KeyboardProtocolConfig {
149            enabled: true,
150            mode: KeyboardProtocolMode::Default,
151            disambiguate_escape_codes: true,
152            report_event_types: true,
153            report_alternate_keys: true,
154            report_all_keys: false,
155        }
156    }
157
158    #[test]
159    fn test_keyboard_protocol_defaults() {
160        let flags = keyboard_protocol_to_flags_for_terminal(
161            &default_keyboard_protocol_config(),
162            false,
163            Some("Ghostty"),
164            Some("xterm-ghostty"),
165        );
166
167        assert!(flags.contains(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES));
168        assert!(flags.contains(KeyboardEnhancementFlags::REPORT_EVENT_TYPES));
169        assert!(flags.contains(KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS));
170        assert!(!flags.contains(KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES));
171    }
172
173    #[test]
174    fn test_keyboard_protocol_defaults_enable_all_keys_for_ghostty_on_macos() {
175        let flags = keyboard_protocol_to_flags_for_terminal(
176            &default_keyboard_protocol_config(),
177            true,
178            Some("Ghostty"),
179            Some("xterm-ghostty"),
180        );
181
182        assert!(flags.contains(KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES));
183    }
184
185    #[test]
186    fn test_keyboard_protocol_minimal_mode() {
187        let config = KeyboardProtocolConfig {
188            enabled: true,
189            mode: KeyboardProtocolMode::Minimal,
190            disambiguate_escape_codes: true,
191            report_event_types: true,
192            report_alternate_keys: true,
193            report_all_keys: false,
194        };
195
196        let flags = keyboard_protocol_to_flags_for_terminal(&config, true, Some("Ghostty"), Some("xterm-ghostty"));
197
198        assert!(flags.contains(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES));
199        assert!(!flags.contains(KeyboardEnhancementFlags::REPORT_EVENT_TYPES));
200        assert!(!flags.contains(KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS));
201        assert!(!flags.contains(KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES));
202    }
203
204    #[test]
205    fn test_keyboard_protocol_disabled() {
206        let config = KeyboardProtocolConfig {
207            enabled: false,
208            mode: KeyboardProtocolMode::Default,
209            disambiguate_escape_codes: true,
210            report_event_types: true,
211            report_alternate_keys: true,
212            report_all_keys: false,
213        };
214
215        let flags = keyboard_protocol_to_flags_for_terminal(&config, true, Some("Ghostty"), Some("xterm-ghostty"));
216        assert!(flags.is_empty());
217    }
218
219    #[test]
220    fn test_keyboard_protocol_custom_mode() {
221        let config = KeyboardProtocolConfig {
222            enabled: true,
223            mode: KeyboardProtocolMode::Custom,
224            disambiguate_escape_codes: true,
225            report_event_types: false,
226            report_alternate_keys: true,
227            report_all_keys: false,
228        };
229
230        let flags = keyboard_protocol_to_flags_for_terminal(&config, true, Some("Ghostty"), Some("xterm-ghostty"));
231
232        assert!(flags.contains(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES));
233        assert!(!flags.contains(KeyboardEnhancementFlags::REPORT_EVENT_TYPES));
234        assert!(flags.contains(KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS));
235        assert!(!flags.contains(KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES));
236    }
237
238    #[test]
239    fn test_keyboard_protocol_validation() {
240        let config = KeyboardProtocolConfig {
241            enabled: true,
242            mode: KeyboardProtocolMode::Default,
243            disambiguate_escape_codes: true,
244            report_event_types: true,
245            report_alternate_keys: true,
246            report_all_keys: false,
247        };
248
249        // All enum variants are valid; validation always succeeds.
250        config.validate().unwrap();
251    }
252}