refactor: 统一项目名称从OpenFang到ZCLAW
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

重构所有代码和文档中的项目名称,将OpenFang统一更新为ZCLAW。包括:
- 配置文件中的项目名称
- 代码注释和文档引用
- 环境变量和路径
- 类型定义和接口名称
- 测试用例和模拟数据

同时优化部分代码结构,移除未使用的模块,并更新相关依赖项。
This commit is contained in:
iven
2026-03-27 07:36:03 +08:00
parent 4b08804aa9
commit 0d4fa96b82
226 changed files with 7288 additions and 5788 deletions

View File

@@ -252,10 +252,78 @@ fn default_skills_dir() -> Option<std::path::PathBuf> {
}
impl KernelConfig {
/// Load configuration from file
/// Load configuration from file.
///
/// Search order:
/// 1. Path from `ZCLAW_CONFIG` environment variable
/// 2. `~/.zclaw/config.toml`
/// 3. Fallback to `Self::default()`
///
/// Supports `${VAR_NAME}` environment variable interpolation in string values.
pub async fn load() -> Result<Self> {
// TODO: Load from ~/.zclaw/config.toml
Ok(Self::default())
let config_path = Self::find_config_path();
match config_path {
Some(path) => {
if !path.exists() {
tracing::debug!(target: "kernel_config", "Config file not found: {:?}, using defaults", path);
return Ok(Self::default());
}
tracing::info!(target: "kernel_config", "Loading config from: {:?}", path);
let content = std::fs::read_to_string(&path).map_err(|e| {
zclaw_types::ZclawError::Internal(format!("Failed to read config {}: {}", path.display(), e))
})?;
let interpolated = interpolate_env_vars(&content);
let mut config: KernelConfig = toml::from_str(&interpolated).map_err(|e| {
zclaw_types::ZclawError::Internal(format!("Failed to parse config {}: {}", path.display(), e))
})?;
// Resolve skills_dir if not explicitly set
if config.skills_dir.is_none() {
config.skills_dir = default_skills_dir();
}
tracing::info!(
target: "kernel_config",
model = %config.llm.model,
base_url = %config.llm.base_url,
has_api_key = !config.llm.api_key.is_empty(),
"Config loaded successfully"
);
Ok(config)
}
None => Ok(Self::default()),
}
}
/// Find the config file path.
fn find_config_path() -> Option<PathBuf> {
// 1. Environment variable override
if let Ok(path) = std::env::var("ZCLAW_CONFIG") {
return Some(PathBuf::from(path));
}
// 2. ~/.zclaw/config.toml
if let Some(home) = dirs::home_dir() {
let path = home.join(".zclaw").join("config.toml");
if path.exists() {
return Some(path);
}
}
// 3. Project root config/config.toml (for development)
let project_config = std::env::current_dir()
.ok()
.map(|cwd| cwd.join("config").join("config.toml"))?;
if project_config.exists() {
return Some(project_config);
}
None
}
/// Create the LLM driver
@@ -439,3 +507,81 @@ impl LlmConfig {
self
}
}
// === Environment variable interpolation ===
/// Replace `${VAR_NAME}` patterns in a string with environment variable values.
/// If the variable is not set, the pattern is left as-is.
fn interpolate_env_vars(content: &str) -> String {
let mut result = String::with_capacity(content.len());
let mut chars = content.char_indices().peekable();
while let Some((_, ch)) = chars.next() {
if ch == '$' && chars.peek().map(|(_, c)| *c == '{').unwrap_or(false) {
chars.next(); // consume '{'
let mut var_name = String::new();
while let Some((_, c)) = chars.peek() {
match c {
'}' => {
chars.next(); // consume '}'
if let Ok(value) = std::env::var(&var_name) {
result.push_str(&value);
} else {
result.push_str("${");
result.push_str(&var_name);
result.push('}');
}
break;
}
_ => {
var_name.push(*c);
chars.next();
}
}
}
// Handle unclosed ${... at end of string
if !content[result.len()..].contains('}') && var_name.is_empty() {
// Already consumed, nothing to do
}
} else {
result.push(ch);
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_interpolate_env_vars_basic() {
std::env::set_var("ZCLAW_TEST_VAR", "hello");
let result = interpolate_env_vars("prefix ${ZCLAW_TEST_VAR} suffix");
assert_eq!(result, "prefix hello suffix");
}
#[test]
fn test_interpolate_env_vars_missing() {
let result = interpolate_env_vars("${ZCLAW_NONEXISTENT_VAR_12345}");
assert_eq!(result, "${ZCLAW_NONEXISTENT_VAR_12345}");
}
#[test]
fn test_interpolate_env_vars_no_vars() {
let result = interpolate_env_vars("no variables here");
assert_eq!(result, "no variables here");
}
#[test]
fn test_interpolate_env_vars_multiple() {
std::env::set_var("ZCLAW_TEST_A", "alpha");
std::env::set_var("ZCLAW_TEST_B", "beta");
let result = interpolate_env_vars("${ZCLAW_TEST_A}-${ZCLAW_TEST_B}");
assert_eq!(result, "alpha-beta");
}
}