juglans 0.1.0

Compiler and runtime for Juglans Workflow Language (JWL)
Documentation
// src/services/config.rs
use serde::Deserialize;
use std::fs;
use std::path::Path;
use anyhow::{Result, Context};
use tracing::info;

#[derive(Debug, Deserialize, Clone)]
pub struct AccountConfig {
    pub id: String,
    pub name: String,
    pub role: Option<String>,
    // 【新增】API Key 用于访问 Jug0
    pub api_key: Option<String>,
}

#[derive(Debug, Deserialize, Clone)]
pub struct WorkspaceConfig {
    pub id: String,
    pub name: String,
    pub members: Option<Vec<String>>,
}

#[derive(Debug, Deserialize, Clone)]
pub struct McpServerConfig {
    pub name: String,
    pub base_url: String,
    pub alias: Option<String>,
    pub token: Option<String>,
}

// 【新增】Jug0 后端配置
#[derive(Debug, Deserialize, Clone)]
pub struct Jug0Config {
    pub base_url: String,
}

#[derive(Debug, Deserialize, Clone)]
pub struct JuglansConfig {
    pub account: AccountConfig,
    pub workspace: Option<WorkspaceConfig>,
    
    // 【新增】
    #[serde(default = "default_jug0_config")]
    pub jug0: Jug0Config,

    #[serde(default)]
    pub mcp_servers: Vec<McpServerConfig>,

    #[serde(default)]
    pub env: std::collections::HashMap<String, String>,
}

fn default_jug0_config() -> Jug0Config {
    Jug0Config {
        base_url: "https://api.jug0.com".to_string(),
    }
}

impl JuglansConfig {
    pub fn load() -> Result<Self> {
        let path = Path::new("juglans.toml");
        
        if !path.exists() {
            info!("⚠️ 'juglans.toml' not found. Using default dev configuration.");
            return Ok(JuglansConfig {
                account: AccountConfig {
                    id: "dev_user".to_string(),
                    name: "Developer".to_string(),
                    role: Some("admin".to_string()),
                    api_key: None,
                },
                workspace: Some(WorkspaceConfig {
                    id: "default_ws".to_string(),
                    name: "Default Workspace".to_string(),
                    members: Some(vec!["dev_user".to_string()]),
                }),
                jug0: default_jug0_config(),
                mcp_servers: vec![],
                env: Default::default(),
            });
        }

        let content = fs::read_to_string(path)
            .context("Failed to read juglans.toml")?;
            
        let config: JuglansConfig = toml::from_str(&content)
            .context("Failed to parse juglans.toml")?;
            
        info!("🔧 Loaded configuration for user: {}", config.account.name);
        Ok(config)
    }
}