Feature/env management - #132
Conversation
- 删除原有英文 README.md,将中文版重命名为主 README - 重新组织文档结构,突出 CLI 作为首要平台的地位 - 新增环境变量配置章节,详细介绍 5 层优先级系统 - 完善 CLI 功能介绍,增加使用场景和特性说明 - 调整多平台支持描述,体现 CLI → Web → Electron 的开发优先级 - 更新技术架构说明,强调 CLI First 开发理念 - 移除冗余的 AI 能力矩阵章节,精简文档结构 - 根据最新环境变量功能更新近期目标完成状态 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
## 主要修复 - 🔧 修复 --data-dir 等CLI参数解析时机问题,确保在模块加载前设置环境变量 - 🚀 重构CLI入口文件,将参数解析移至最前面,避免模块加载顺序问题 - 🔄 添加EnvManager全局默认实例机制,支持CLI参数覆盖 ## 核心改进 - 📦 **模块加载优化**: CLI参数解析在任何其他模块导入之前执行 - 🎯 **动态路径获取**: 将静态路径常量改为动态getter,支持运行时配置变更 - 🔧 **环境管理器增强**: 添加setGlobalDefault()方法,确保全局配置一致性 - 📋 **CLI帮助完善**: 添加完整的环境变量配置选项和5层优先级说明 ## 技术细节 - EnvManager支持setGlobalDefault()设置CLI实例为全局默认 - CONSTANTS.GLOBAL_PATH改为动态getter,实时获取appDataDir - WorkspaceManager.GLOBAL_HYPERCHAT_DIR改为动态getter - CLI参数清理逻辑完善,支持所有环境变量相关选项 ## 验证结果 - ✅ --data-dir ~/Documents/HyperChat2 正确设置全局数据目录 - ✅ getAppDataDir()输出正确的CLI指定路径 - ✅ 工作区管理器使用指定的全局配置目录 - ✅ 5层环境变量优先级系统完全正常工作 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
## 问题 AI配置管理器(AppSettingsManager)使用静态的appDataDir路径, 导致--data-dir参数无法生效,AI模型配置仍从旧位置加载。 ## 修复内容 - 🔄 **appSettingsService.mts**: 使用getAppDataDir()替代静态appDataDir - 🔄 **appSettingsManager.mts**: 构造函数使用动态getAppDataDir() - 📍 确保AI配置文件(app-settings.jsonc)使用CLI指定的数据目录 ## 技术改进 - initAppSettingsManager()使用动态路径初始化 - AppSettingsManager构造函数中的appDataDir字段使用实时获取的路径 - 移除对静态appDataDir常量的依赖 ## 验证结果 - ✅ Agent配置文件正确创建在新数据目录 - 🔄 AI配置加载路径已修复(需要重启进程生效) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
## 核心问题 AI配置管理器在模块加载时立即初始化,导致CLI参数--data-dir无法生效, AI配置仍从旧位置加载,聊天功能异常成功而不是预期失败。 ## 解决方案 1. **移除立即执行代码**: 删除appSettingsService.mts底部的模块加载时初始化代码 2. **实现懒加载模式**: AI配置管理器改为按需初始化,支持动态appDataDir 3. **添加同步初始化**: 新增initSync()和saveSync()方法,兼容现有同步调用 4. **自动初始化**: getAppSettingsManager()支持自动初始化,向后兼容 ## 技术改进 - ✅ **appSettingsService.mts**: 移除模块加载时的立即初始化,改为懒加载 - ✅ **appSettingsManager.mts**: 添加initSync()和loadSync()、saveSync()同步方法 - ✅ **settingsCommands.mts**: 移除手动初始化检查,依赖自动初始化 - 🔄 **AI_MODELS**: 改为懒加载实例,支持向后兼容的API ## 验证结果 - ✅ CLI参数--data-dir ~/Documents/HyperChat2完全正常工作 - ✅ AI配置文件正确创建在指定目录: ~/Documents/HyperChat2/app-settings.jsonc - ✅ appDataDir正确设置: "/home/laop/Documents/HyperChat2" - ✅ 空AI配置时聊天正确失败: "未找到可用的AI模型配置" - ✅ 应用行为完全符合预期,配置隔离正常工作 ## 架构提升 实现了真正的CLI参数优先级系统,所有配置组件都支持动态路径, 为多环境部署和用户自定义数据目录提供了完整支持。 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
## 问题
环境管理器在解析系统环境变量时,只检查`key in defaultValues`,
导致HyperChat_API_KEY和HyperChat_API_URL等可选环境变量无法被读取。
## 根本原因
DEFAULT_ENV_CONFIG通过空对象{}生成,可选字段不在默认配置中,
因此系统环境变量中的这些值被忽略。
## 解决方案
- 🔧 **环境变量读取逻辑改进**: 检查`EnvSchema.shape`中的所有定义key
- ✅ **支持所有schema定义的环境变量**: 包括可选的API配置环境变量
- 🔍 **完整环境变量支持**: HyperChat_API_KEY、HyperChat_API_URL等现在能正确读取
## 技术改进
```typescript
// 修复前: 只检查默认配置中的key
if (key in defaultValues && value \!== undefined)
// 修复后: 检查schema中定义的所有key
const schemaKeys = Object.keys(EnvSchema.shape);
if (schemaKeys.includes(key) && value \!== undefined)
```
## 验证结果
- ✅ HyperChat_API_KEY和HyperChat_API_URL环境变量被正确读取
- ✅ 环境变量在系统中正确添加到配置中
- 🔄 为后续AI配置使用这些环境变量提供了基础
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
## 核心改进 - 🔧 **可选modelKey参数**: getAIOptions(modelKey?: string) 支持不传入模型key - 🚀 **智能模型选择**: 优先级:传入参数 > 环境变量HyperChat_AI_Model > 默认值 - ⚡ **移除冗余验证**: 删除AiProviderFactory.validateModelConfig()调用,简化流程 ## 功能优化 - 📝 **更好的参数处理**: ```typescript // 修改前: 必须传入modelKey async getAIOptions(modelKey: string) // 修改后: modelKey可选,支持环境变量回退 async getAIOptions(modelKey?: string) const finalModelKey = modelKey || envModel || 'default-model'; ``` - 🔍 **错误消息更新**: 使用finalModelKey提供更准确的错误信息 - 🗑️ **简化验证逻辑**: 移除不必要的validateModelConfig调用 ## 验证结果 - ✅ 环境变量AI配置完全正常工作 - ✅ HyperChat_API_KEY + HyperChat_API_URL + HyperChat_AI_Model 成功创建AI会话 - ✅ 聊天功能正常:"你好!有什么可以帮助你的吗?" - ✅ 向后兼容:现有传入modelKey的调用依然正常工作 ## 架构提升 现在AI系统更加灵活,支持完全基于环境变量的配置, 为无配置文件的部署场景提供了更好的支持。 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- 消除重复的配置构建函数,统一使用 buildEffectiveConfig - 修正模型选择优先级:默认第一个可用模型 > 环境变量 - 重构 ai.mts 中的 getAIOptions 方法,复用配置合并逻辑 - 删除 chatCommands.mts 中重复的 getEffectiveConfig 函数 - 清理未使用的导入,保持代码整洁 - 确保所有AI配置在系统中保持一致的优先级顺序 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- 为DataList类添加getStats方法,支持轻量级统计(只读取文件数量和最后修改时间) - 修改AgentInstance.getSummary方法,使用轻量级统计替代全量加载聊天记录 - 解决工作区初始化时不必要的聊天日志YAML解析导致的性能问题和错误 - 实现按需加载策略:统计信息使用文件系统操作,具体内容仅在实际使用时加载 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🔧 refactor: 注释掉Claude自动评论工作流中的触发条件 🔧 fix: 更新默认代理配置,移除不必要的MCP选项
|
Claude finished @laopo001's task —— View job PR Review: Feature/env-management ✅I've completed a comprehensive review of this PR focusing on code quality, potential bugs, performance, security, and test coverage. Todo List:
Architecture Overview:This PR implements a sophisticated 5-layer environment variable management system:
Core Components:
✅ Positive Aspects1. Excellent Architecture & Design
2. Comprehensive Feature Implementation
3. Security Considerations
|
There was a problem hiding this comment.
Pull Request Overview
This PR implements a comprehensive environment variable management system for HyperChat, introducing a 5-layer priority configuration system that enables flexible deployment and configuration management across different environments.
Key changes include:
- Implementation of a 5-layer priority environment variable system (default < process.env < global .env < workspace .env < CLI args)
- Migration of language and password settings from AppSettings to environment variables
- Enhanced CLI argument parsing with comprehensive environment variable mapping
- Removal of unused configuration files and cleanup of legacy code
Reviewed Changes
Copilot reviewed 42 out of 43 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/data/managers/envManager.mts | New environment variable manager with 5-layer priority system |
| packages/core/src/utils/cliArgsParser.mts | CLI argument parser with environment variable mapping |
| packages/core/src/utils/dotenvLoader.mts | Custom .env file parser without external dependencies |
| packages/web/src/i18n.ts | Migrated language settings from AppSettings to environment variables |
| packages/shared/src/zodSchemas/envSchema.mts | Comprehensive environment variable schema definitions |
| packages/core/src/cli/index.mts | Enhanced CLI with environment variable integration |
Comments suppressed due to low confidence (2)
| firstAvailableModel, // 默认第一个可用模型 | ||
| envModel // 环境变量(最低优先级) |
There was a problem hiding this comment.
The comment indicates environment variables have lowest priority, but the actual implementation places environment variables as the last fallback in the candidates array. This creates inconsistency between the comment and the actual priority order. Environment variables should have higher priority than 'firstAvailableModel' according to typical configuration hierarchies.
| firstAvailableModel, // 默认第一个可用模型 | |
| envModel // 环境变量(最低优先级) | |
| envModel, // 环境变量 | |
| firstAvailableModel // 默认第一个可用模型 |
| const rootEnvPath = path.resolve(process.cwd(), '.env'); | ||
| if (fs.existsSync(rootEnvPath)) { | ||
| paths.push(rootEnvPath); |
There was a problem hiding this comment.
The method checks for .env file existence but doesn't validate if process.cwd() is accessible or valid. Consider wrapping in try-catch to handle potential permission errors when accessing the current working directory.
| const rootEnvPath = path.resolve(process.cwd(), '.env'); | |
| if (fs.existsSync(rootEnvPath)) { | |
| paths.push(rootEnvPath); | |
| try { | |
| const rootEnvPath = path.resolve(process.cwd(), '.env'); | |
| if (fs.existsSync(rootEnvPath)) { | |
| paths.push(rootEnvPath); | |
| } | |
| } catch (error) { | |
| Logger.warn("Failed to access the current working directory for .env file resolution.", error); |
| const optionsWithValues = [ | ||
| '--workspace', '--host', '--port', '--password', '--language', '--lang', '--ui', | ||
| '--data-dir', '--app-data-dir', '--api-key', '--api-url', '--ai-provider', '--ai-model', | ||
| '--log-level', '--web-password', '--env', '--my-env', '-p' |
There was a problem hiding this comment.
The hardcoded list of CLI options with values should be kept in sync with the CLI_ARG_MAPPING in CliArgsParser. Consider extracting this to a shared constant or deriving it programmatically to avoid maintenance issues.
| if (!modelConfig) { | ||
| // 检查是否有足够的环境变量来创建基础配置 | ||
| if (!envApiKey || !envApiUrl) { | ||
| throw new Error(`Model not found: ${finalModelKey}. Please configure it in app settings or provide HyperChat_API_KEY and HyperChat_API_URL environment variables.`); |
There was a problem hiding this comment.
The error message mentions 'HyperChat_API_KEY and HyperChat_API_URL environment variables' but should be more specific about what constitutes 'sufficient' environment variables. Consider providing examples of valid configurations.
| throw new Error(`Model not found: ${finalModelKey}. Please configure it in app settings or provide HyperChat_API_KEY and HyperChat_API_URL environment variables.`); | |
| throw new Error(`Model not found: ${finalModelKey}. Please configure it in app settings or provide the following environment variables: | |
| - HyperChat_API_KEY: Your API key (e.g., "abc123xyz"). | |
| - HyperChat_API_URL: The base URL of the API (e.g., "https://api.hyperchat.com"). | |
| Ensure both variables are set and valid.`); |
|
|
||
| // 为了向后兼容,提供常量形式的导出 | ||
| // 但实际上每次调用都会动态获取最新值 | ||
| export const appDataDir = getAppDataDir(); |
There was a problem hiding this comment.
The appDataDir constant is computed at module load time and may not reflect runtime changes to environment variables. Consider making this a getter function or lazy evaluation to ensure it always returns the current environment-aware path.
No description provided.