use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct ClaudeStartOptions { #[serde(default)] pub working_dir: String, #[serde(default)] pub model: Option, #[serde(default)] pub api_key: Option, #[serde(default)] pub custom_instructions: Option, #[serde(default)] pub mcp_servers_json: Option, #[serde(default)] pub allowed_tools: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct HikariConfig { #[serde(default)] pub model: Option, #[serde(default)] pub api_key: Option, #[serde(default)] pub custom_instructions: Option, #[serde(default)] pub mcp_servers_json: Option, #[serde(default)] pub auto_granted_tools: Vec, #[serde(default)] pub theme: Theme, #[serde(default = "default_greeting_enabled")] pub greeting_enabled: bool, #[serde(default)] pub greeting_custom_prompt: Option, #[serde(default = "default_notifications_enabled")] pub notifications_enabled: bool, #[serde(default = "default_notification_volume")] pub notification_volume: f32, } impl Default for HikariConfig { fn default() -> Self { Self { model: None, api_key: None, custom_instructions: None, mcp_servers_json: None, auto_granted_tools: Vec::new(), theme: Theme::default(), greeting_enabled: true, greeting_custom_prompt: None, notifications_enabled: true, notification_volume: 0.7, } } } fn default_greeting_enabled() -> bool { true } fn default_notifications_enabled() -> bool { true } fn default_notification_volume() -> f32 { 0.7 } #[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)] #[serde(rename_all = "lowercase")] pub enum Theme { #[default] Dark, Light, } #[cfg(test)] mod tests { use super::*; #[test] fn test_default_config() { let config = HikariConfig::default(); assert!(config.model.is_none()); assert!(config.api_key.is_none()); assert!(config.custom_instructions.is_none()); assert!(config.mcp_servers_json.is_none()); assert!(config.auto_granted_tools.is_empty()); assert_eq!(config.theme, Theme::Dark); assert!(config.greeting_enabled); assert!(config.greeting_custom_prompt.is_none()); } #[test] fn test_config_serialization() { let config = HikariConfig { model: Some("claude-sonnet-4-20250514".to_string()), api_key: None, custom_instructions: Some("Be helpful".to_string()), mcp_servers_json: None, auto_granted_tools: vec!["Read".to_string(), "Glob".to_string()], theme: Theme::Light, greeting_enabled: true, greeting_custom_prompt: Some("Hello!".to_string()), notifications_enabled: true, notification_volume: 0.7, }; let json = serde_json::to_string(&config).unwrap(); let deserialized: HikariConfig = serde_json::from_str(&json).unwrap(); assert_eq!(deserialized.model, config.model); assert_eq!(deserialized.custom_instructions, config.custom_instructions); assert_eq!(deserialized.auto_granted_tools, config.auto_granted_tools); assert_eq!(deserialized.theme, Theme::Light); assert!(deserialized.greeting_enabled); assert_eq!(deserialized.greeting_custom_prompt, Some("Hello!".to_string())); } #[test] fn test_theme_serialization() { let dark = Theme::Dark; let light = Theme::Light; assert_eq!(serde_json::to_string(&dark).unwrap(), "\"dark\""); assert_eq!(serde_json::to_string(&light).unwrap(), "\"light\""); } }