/** * Config API 路由 * 读取 / 写入系统配置文件 */ const express = require('express'); const router = express.Router(); const fs = require('fs'); const path = require('path'); const os = require('os'); const ROOT = path.resolve(__dirname, '../..'); /** * 配置项定义 */ const CONFIG_ITEMS = [ { key: 'env', label: '环境变量 (.env)', description: 'API Key / CORS 等环境变量', filePath: path.join(ROOT, '.env'), format: 'env', }, { key: 'claude-settings', label: 'Claude Code Settings', description: 'Claude CLI 全局配置(模型、API、权限)', filePath: path.join(os.homedir(), '.claude', 'settings.json'), format: 'json', }, { key: 'backends', label: 'Backends', description: 'ACP 后端 / Launcher 配置', filePath: path.join(ROOT, 'server', 'config', 'backends.json'), format: 'json', }, { key: 'agents', label: 'Agents', description: 'Agent 定义配置', filePath: path.join(ROOT, 'server', 'config', 'agents.json'), format: 'json', }, ]; /** * GET /api/config/items * 返回所有配置项列表 */ router.get('/items', (req, res) => { const items = CONFIG_ITEMS.map(item => ({ key: item.key, label: item.label, icon: item.icon, description: item.description, format: item.format, exists: fs.existsSync(item.filePath), })); res.json({ items }); }); /** * GET /api/config/items/:key * 读取配置项内容 */ router.get('/items/:key', (req, res) => { const item = CONFIG_ITEMS.find(i => i.key === req.params.key); if (!item) return res.status(404).json({ error: 'Config item not found' }); if (!fs.existsSync(item.filePath)) { return res.json({ key: item.key, content: '', exists: false, ...item }); } try { let content = fs.readFileSync(item.filePath, 'utf-8'); // 如果指定了 jsonPath,只返回该字段 if (item.jsonPath) { const json = JSON.parse(content); content = JSON.stringify(json[item.jsonPath] || {}, null, 2); } res.json({ key: item.key, label: item.label, icon: item.icon, description: item.description, format: item.format, content, exists: true, }); } catch (err) { res.status(500).json({ error: err.message }); } }); /** * PUT /api/config/items/:key * 保存配置项内容 */ router.put('/items/:key', express.json({ limit: '1mb' }), (req, res) => { const item = CONFIG_ITEMS.find(i => i.key === req.params.key); if (!item) return res.status(404).json({ error: 'Config item not found' }); const { content } = req.body; if (content === undefined) return res.status(400).json({ error: 'Missing content' }); try { // 如果指定了 jsonPath,只更新该字段 if (item.jsonPath) { let json = {}; if (fs.existsSync(item.filePath)) { json = JSON.parse(fs.readFileSync(item.filePath, 'utf-8')); } json[item.jsonPath] = JSON.parse(content); fs.writeFileSync(item.filePath, JSON.stringify(json, null, 2) + '\n'); } else { fs.writeFileSync(item.filePath, content); } res.json({ success: true, message: 'Config saved' }); } catch (err) { res.status(500).json({ error: err.message }); } }); module.exports = router;