claude-code-api 0.1.3

OpenAI-compatible API gateway for Claude Code CLI
use config::{Config, ConfigError, Environment, File};
use serde::{Deserialize, Serialize};
use std::env;

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Settings {
    pub server: ServerConfig,
    pub claude: ClaudeConfig,
    pub database: DatabaseConfig,
    pub auth: AuthConfig,
    #[serde(default)]
    pub file_access: FileAccessConfig,
    #[serde(default)]
    pub mcp: MCPConfig,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ServerConfig {
    pub host: String,
    pub port: u16,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ClaudeConfig {
    pub command: String,
    pub timeout_seconds: u64,
    pub max_concurrent_sessions: usize,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct DatabaseConfig {
    pub url: String,
    pub max_connections: u32,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct AuthConfig {
    pub enabled: bool,
    pub secret_key: String,
    pub token_expiry_hours: i64,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[derive(Default)]
pub struct FileAccessConfig {
    pub skip_permissions: bool,
    pub additional_dirs: Vec<String>,
}


#[derive(Debug, Deserialize, Serialize, Clone)]
#[derive(Default)]
pub struct MCPConfig {
    pub enabled: bool,
    pub config_file: Option<String>,
    pub config_json: Option<String>,
    pub strict: bool,
    pub debug: bool,
}


impl Settings {
    pub fn new() -> Result<Self, ConfigError> {
        let run_mode = env::var("RUN_MODE").unwrap_or_else(|_| "development".into());

        let s = Config::builder()
            .set_default("server.host", "0.0.0.0")?
            .set_default("server.port", 8080)?
            .set_default("claude.command", "claude")?
            .set_default("claude.timeout_seconds", 300)?
            .set_default("claude.max_concurrent_sessions", 10)?
            .set_default("database.url", "sqlite://./claude_code.db")?
            .set_default("database.max_connections", 5)?
            .set_default("auth.enabled", false)?
            .set_default("auth.secret_key", "change-me-in-production")?
            .set_default("auth.token_expiry_hours", 24)?
            .set_default("file_access.skip_permissions", false)?
            .set_default("file_access.additional_dirs", Vec::<String>::new())?
            .set_default("mcp.enabled", false)?
            .set_default("mcp.strict", false)?
            .set_default("mcp.debug", false)?
            .add_source(File::with_name(&format!("config/{run_mode}")).required(false))
            .add_source(File::with_name("config/local").required(false))
            .add_source(Environment::with_prefix("CLAUDE_CODE").separator("__"))
            .build()?;

        s.try_deserialize()
    }
}