config.js
3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* 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;