config.js
3.51 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
130
131
132
133
134
135
136
137
138
139
140
141
/**
* 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)',
icon: '🔐',
description: 'Feishu / API Key / CORS 等环境变量',
filePath: path.join(ROOT, '.env'),
format: 'env',
},
{
key: 'claude-settings',
label: 'Claude Code Settings',
icon: '🧠',
description: 'Claude CLI 全局配置(模型、API、权限)',
filePath: path.join(os.homedir(), '.claude', 'settings.json'),
format: 'json',
},
{
key: 'feishu-bot',
label: 'Feishu Bot',
icon: '🐦',
description: '飞书机器人配置脚本',
filePath: path.join(ROOT, 'skills', 'feishu-bot', 'bot.py'),
format: 'text',
},
{
key: 'whatsapp-bot',
label: 'WhatsApp Bot',
icon: '💬',
description: 'WhatsApp Bot 配置脚本',
filePath: path.join(ROOT, 'skills', 'whatsapp-bot', 'bot.js'),
format: 'text',
},
{
key: 'start-script',
label: '启动脚本',
icon: '🚀',
description: 'start.sh 一键启动配置',
filePath: path.join(ROOT, 'start.sh'),
format: 'text',
},
];
/**
* 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;