@adversity/coding-tool-x 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +8 -0
- package/dist/web/assets/{index-dhun1bYQ.js → index-Bu1oPcKu.js} +1172 -718
- package/dist/web/assets/{index-hHb7DAda.css → index-XSok7-mN.css} +3 -3
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/src/config/default.js +1 -1
- package/src/server/api/config-export.js +122 -0
- package/src/server/api/config-templates.js +12 -6
- package/src/server/api/health-check.js +1 -89
- package/src/server/api/permissions.js +92 -69
- package/src/server/index.js +4 -11
- package/src/server/services/config-export-service.js +209 -0
- package/src/server/services/config-templates-service.js +61 -38
- package/src/server/services/health-check.js +1 -315
- package/src/server/services/permission-templates-service.js +339 -0
- package/src/server/services/workspace-service.js +8 -66
package/dist/web/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" href="/favicon.ico">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
7
|
<title>CC-TOOL - ClaudeCode增强工作助手</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-Bu1oPcKu.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-XSok7-mN.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="app"></div>
|
package/package.json
CHANGED
package/src/config/default.js
CHANGED
|
@@ -3,7 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const os = require('os');
|
|
4
4
|
|
|
5
5
|
const DEFAULT_CONFIG = {
|
|
6
|
-
projectsDir: path.join(os.homedir(), '.claude', '
|
|
6
|
+
projectsDir: path.join(os.homedir(), '.claude', 'projects'),
|
|
7
7
|
defaultProject: null,
|
|
8
8
|
maxDisplaySessions: 100,
|
|
9
9
|
pageSize: 15,
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置导出/导入 API 路由
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const express = require('express');
|
|
6
|
+
const configExportService = require('../services/config-export-service');
|
|
7
|
+
|
|
8
|
+
const router = express.Router();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 导出所有配置
|
|
12
|
+
* GET /api/config-export
|
|
13
|
+
*/
|
|
14
|
+
router.get('/', (req, res) => {
|
|
15
|
+
try {
|
|
16
|
+
const result = configExportService.exportAllConfigs();
|
|
17
|
+
|
|
18
|
+
if (result.success) {
|
|
19
|
+
// 设置响应头,触发文件下载
|
|
20
|
+
const filename = `ctx-config-${new Date().toISOString().split('T')[0]}.json`;
|
|
21
|
+
res.setHeader('Content-Disposition', `attachment; filename="${filename}"`);
|
|
22
|
+
res.setHeader('Content-Type', 'application/json');
|
|
23
|
+
res.json(result.data);
|
|
24
|
+
} else {
|
|
25
|
+
res.status(500).json({
|
|
26
|
+
success: false,
|
|
27
|
+
message: result.message
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error('[ConfigExport API] 导出失败:', err);
|
|
32
|
+
res.status(500).json({
|
|
33
|
+
success: false,
|
|
34
|
+
message: err.message
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 导入配置
|
|
41
|
+
* POST /api/config-export/import
|
|
42
|
+
* Body: { data: {...}, overwrite: boolean }
|
|
43
|
+
*/
|
|
44
|
+
router.post('/import', (req, res) => {
|
|
45
|
+
try {
|
|
46
|
+
const { data, overwrite = false } = req.body;
|
|
47
|
+
|
|
48
|
+
if (!data) {
|
|
49
|
+
return res.status(400).json({
|
|
50
|
+
success: false,
|
|
51
|
+
message: '缺少导入数据'
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const result = configExportService.importConfigs(data, { overwrite });
|
|
56
|
+
|
|
57
|
+
res.json(result);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.error('[ConfigExport API] 导入失败:', err);
|
|
60
|
+
res.status(500).json({
|
|
61
|
+
success: false,
|
|
62
|
+
message: err.message
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 预览导入配置(不实际导入)
|
|
69
|
+
* POST /api/config-export/preview
|
|
70
|
+
*/
|
|
71
|
+
router.post('/preview', (req, res) => {
|
|
72
|
+
try {
|
|
73
|
+
const { data } = req.body;
|
|
74
|
+
|
|
75
|
+
if (!data || !data.data) {
|
|
76
|
+
return res.status(400).json({
|
|
77
|
+
success: false,
|
|
78
|
+
message: '无效的导入数据格式'
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const summary = {
|
|
83
|
+
version: data.version,
|
|
84
|
+
exportedAt: data.exportedAt,
|
|
85
|
+
counts: {
|
|
86
|
+
permissionTemplates: (data.data.permissionTemplates || []).length,
|
|
87
|
+
configTemplates: (data.data.configTemplates || []).length,
|
|
88
|
+
channels: (data.data.channels || []).length
|
|
89
|
+
},
|
|
90
|
+
items: {
|
|
91
|
+
permissionTemplates: (data.data.permissionTemplates || []).map(t => ({
|
|
92
|
+
id: t.id,
|
|
93
|
+
name: t.name,
|
|
94
|
+
description: t.description
|
|
95
|
+
})),
|
|
96
|
+
configTemplates: (data.data.configTemplates || []).map(t => ({
|
|
97
|
+
id: t.id,
|
|
98
|
+
name: t.name,
|
|
99
|
+
description: t.description
|
|
100
|
+
})),
|
|
101
|
+
channels: (data.data.channels || []).map(c => ({
|
|
102
|
+
id: c.id,
|
|
103
|
+
name: c.name,
|
|
104
|
+
type: c.type
|
|
105
|
+
}))
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
res.json({
|
|
110
|
+
success: true,
|
|
111
|
+
data: summary
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error('[ConfigExport API] 预览失败:', err);
|
|
115
|
+
res.status(500).json({
|
|
116
|
+
success: false,
|
|
117
|
+
message: err.message
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
module.exports = router;
|
|
@@ -139,7 +139,7 @@ router.delete('/:id', (req, res) => {
|
|
|
139
139
|
*/
|
|
140
140
|
router.post('/:id/apply', (req, res) => {
|
|
141
141
|
try {
|
|
142
|
-
const { targetPath, aiConfigType } = req.body;
|
|
142
|
+
const { targetPath, aiConfigType, aiConfigTypes } = req.body;
|
|
143
143
|
if (!targetPath) {
|
|
144
144
|
return res.status(400).json({
|
|
145
145
|
success: false,
|
|
@@ -147,8 +147,11 @@ router.post('/:id/apply', (req, res) => {
|
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
const options = {};
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
// 优先使用新的数组参数,兼容旧的单值参数
|
|
151
|
+
if (aiConfigTypes) {
|
|
152
|
+
options.aiConfigTypes = aiConfigTypes;
|
|
153
|
+
} else if (aiConfigType) {
|
|
154
|
+
options.aiConfigTypes = [aiConfigType];
|
|
152
155
|
}
|
|
153
156
|
const result = templatesService.applyTemplateToProject(targetPath, req.params.id, options);
|
|
154
157
|
res.json({
|
|
@@ -170,7 +173,7 @@ router.post('/:id/apply', (req, res) => {
|
|
|
170
173
|
*/
|
|
171
174
|
router.post('/:id/preview', (req, res) => {
|
|
172
175
|
try {
|
|
173
|
-
const { targetPath, aiConfigType } = req.body;
|
|
176
|
+
const { targetPath, aiConfigType, aiConfigTypes } = req.body;
|
|
174
177
|
if (!targetPath) {
|
|
175
178
|
return res.status(400).json({
|
|
176
179
|
success: false,
|
|
@@ -178,8 +181,11 @@ router.post('/:id/preview', (req, res) => {
|
|
|
178
181
|
});
|
|
179
182
|
}
|
|
180
183
|
const options = {};
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
// 优先使用新的数组参数,兼容旧的单值参数
|
|
185
|
+
if (aiConfigTypes) {
|
|
186
|
+
options.aiConfigTypes = aiConfigTypes;
|
|
187
|
+
} else if (aiConfigType) {
|
|
188
|
+
options.aiConfigTypes = [aiConfigType];
|
|
183
189
|
}
|
|
184
190
|
const preview = templatesService.previewTemplateApplication(targetPath, req.params.id, options);
|
|
185
191
|
res.json({
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const router = express.Router();
|
|
3
|
-
const {
|
|
4
|
-
healthCheckAllProjects,
|
|
5
|
-
scanLegacySessionFiles,
|
|
6
|
-
migrateSessionFiles,
|
|
7
|
-
cleanLegacySessionFiles
|
|
8
|
-
} = require('../services/health-check');
|
|
3
|
+
const { healthCheckAllProjects } = require('../services/health-check');
|
|
9
4
|
const { getProjects } = require('../services/sessions');
|
|
10
5
|
|
|
11
6
|
module.exports = (config) => {
|
|
@@ -31,88 +26,5 @@ module.exports = (config) => {
|
|
|
31
26
|
}
|
|
32
27
|
});
|
|
33
28
|
|
|
34
|
-
/**
|
|
35
|
-
* GET /api/health-check/scan-legacy - 扫描旧文件
|
|
36
|
-
*/
|
|
37
|
-
router.get('/scan-legacy', (req, res) => {
|
|
38
|
-
try {
|
|
39
|
-
const result = scanLegacySessionFiles();
|
|
40
|
-
|
|
41
|
-
res.json({
|
|
42
|
-
success: true,
|
|
43
|
-
timestamp: new Date().toISOString(),
|
|
44
|
-
...result
|
|
45
|
-
});
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error('Legacy scan failed:', error);
|
|
48
|
-
res.status(500).json({
|
|
49
|
-
success: false,
|
|
50
|
-
error: error.message
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* POST /api/health-check/migrate-legacy - 迁移旧文件到正确位置
|
|
57
|
-
* Body:
|
|
58
|
-
* {
|
|
59
|
-
* "dryRun": boolean, // 是否只是预演
|
|
60
|
-
* "projectNames": string[] // 可选:指定要迁移的项目
|
|
61
|
-
* }
|
|
62
|
-
*/
|
|
63
|
-
router.post('/migrate-legacy', (req, res) => {
|
|
64
|
-
try {
|
|
65
|
-
const { dryRun = false, projectNames = null } = req.body;
|
|
66
|
-
|
|
67
|
-
const result = migrateSessionFiles({
|
|
68
|
-
dryRun,
|
|
69
|
-
projectNames
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
res.json({
|
|
73
|
-
success: true,
|
|
74
|
-
timestamp: new Date().toISOString(),
|
|
75
|
-
...result
|
|
76
|
-
});
|
|
77
|
-
} catch (error) {
|
|
78
|
-
console.error('Legacy migration failed:', error);
|
|
79
|
-
res.status(500).json({
|
|
80
|
-
success: false,
|
|
81
|
-
error: error.message
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* POST /api/health-check/clean-legacy - 清理旧文件
|
|
88
|
-
* Body:
|
|
89
|
-
* {
|
|
90
|
-
* "dryRun": boolean, // 是否只是预演
|
|
91
|
-
* "projectNames": string[] // 可选:指定要清理的项目
|
|
92
|
-
* }
|
|
93
|
-
*/
|
|
94
|
-
router.post('/clean-legacy', (req, res) => {
|
|
95
|
-
try {
|
|
96
|
-
const { dryRun = false, projectNames = null } = req.body;
|
|
97
|
-
|
|
98
|
-
const result = cleanLegacySessionFiles({
|
|
99
|
-
dryRun,
|
|
100
|
-
projectNames
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
res.json({
|
|
104
|
-
success: true,
|
|
105
|
-
timestamp: new Date().toISOString(),
|
|
106
|
-
...result
|
|
107
|
-
});
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error('Legacy cleanup failed:', error);
|
|
110
|
-
res.status(500).json({
|
|
111
|
-
success: false,
|
|
112
|
-
error: error.message
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
29
|
return router;
|
|
118
30
|
};
|
|
@@ -25,6 +25,7 @@ const express = require('express');
|
|
|
25
25
|
const fs = require('fs');
|
|
26
26
|
const path = require('path');
|
|
27
27
|
const os = require('os');
|
|
28
|
+
const permissionTemplatesService = require('../services/permission-templates-service');
|
|
28
29
|
|
|
29
30
|
const router = express.Router();
|
|
30
31
|
|
|
@@ -207,81 +208,15 @@ router.post('/all-allow', (req, res) => {
|
|
|
207
208
|
});
|
|
208
209
|
|
|
209
210
|
/**
|
|
210
|
-
*
|
|
211
|
+
* 获取所有权限模版(内置 + 自定义)
|
|
211
212
|
* GET /api/permissions/templates
|
|
212
213
|
*/
|
|
213
214
|
router.get('/templates', (req, res) => {
|
|
214
215
|
try {
|
|
215
|
-
const templates =
|
|
216
|
-
safe: {
|
|
217
|
-
name: '安全模式',
|
|
218
|
-
description: '仅允许只读命令,危险操作需要确认',
|
|
219
|
-
allow: [
|
|
220
|
-
'Bash(cat:*)',
|
|
221
|
-
'Bash(ls:*)',
|
|
222
|
-
'Bash(pwd)',
|
|
223
|
-
'Bash(echo:*)',
|
|
224
|
-
'Bash(head:*)',
|
|
225
|
-
'Bash(tail:*)',
|
|
226
|
-
'Bash(grep:*)',
|
|
227
|
-
'Read(*)'
|
|
228
|
-
],
|
|
229
|
-
deny: [
|
|
230
|
-
'Bash(rm:*)',
|
|
231
|
-
'Bash(sudo:*)',
|
|
232
|
-
'Bash(git push:*)',
|
|
233
|
-
'Bash(git reset --hard:*)',
|
|
234
|
-
'Bash(chmod:*)',
|
|
235
|
-
'Bash(chown:*)',
|
|
236
|
-
'Edit(*)'
|
|
237
|
-
]
|
|
238
|
-
},
|
|
239
|
-
balanced: {
|
|
240
|
-
name: '平衡模式',
|
|
241
|
-
description: '允许常用开发命令,危险操作需要确认',
|
|
242
|
-
allow: [
|
|
243
|
-
'Bash(cat:*)',
|
|
244
|
-
'Bash(ls:*)',
|
|
245
|
-
'Bash(pwd)',
|
|
246
|
-
'Bash(echo:*)',
|
|
247
|
-
'Bash(head:*)',
|
|
248
|
-
'Bash(tail:*)',
|
|
249
|
-
'Bash(grep:*)',
|
|
250
|
-
'Bash(find:*)',
|
|
251
|
-
'Bash(git status)',
|
|
252
|
-
'Bash(git diff:*)',
|
|
253
|
-
'Bash(git log:*)',
|
|
254
|
-
'Bash(npm run:*)',
|
|
255
|
-
'Bash(pnpm:*)',
|
|
256
|
-
'Bash(yarn:*)',
|
|
257
|
-
'Read(*)',
|
|
258
|
-
'Edit(*)'
|
|
259
|
-
],
|
|
260
|
-
deny: [
|
|
261
|
-
'Bash(rm -rf:*)',
|
|
262
|
-
'Bash(sudo:*)',
|
|
263
|
-
'Bash(git push --force:*)',
|
|
264
|
-
'Bash(git reset --hard:*)'
|
|
265
|
-
]
|
|
266
|
-
},
|
|
267
|
-
permissive: {
|
|
268
|
-
name: '宽松模式',
|
|
269
|
-
description: '允许大多数命令,仅阻止极度危险的操作',
|
|
270
|
-
allow: [
|
|
271
|
-
'Bash(*)',
|
|
272
|
-
'Read(*)',
|
|
273
|
-
'Edit(*)'
|
|
274
|
-
],
|
|
275
|
-
deny: [
|
|
276
|
-
'Bash(rm -rf /*)',
|
|
277
|
-
'Bash(sudo rm -rf:*)'
|
|
278
|
-
]
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
|
|
216
|
+
const templates = permissionTemplatesService.getAllTemplates();
|
|
282
217
|
res.json({
|
|
283
218
|
success: true,
|
|
284
|
-
templates
|
|
219
|
+
data: templates
|
|
285
220
|
});
|
|
286
221
|
} catch (err) {
|
|
287
222
|
console.error('[Permissions API] Get templates error:', err);
|
|
@@ -292,6 +227,94 @@ router.get('/templates', (req, res) => {
|
|
|
292
227
|
}
|
|
293
228
|
});
|
|
294
229
|
|
|
230
|
+
/**
|
|
231
|
+
* 获取单个权限模版
|
|
232
|
+
* GET /api/permissions/templates/:id
|
|
233
|
+
*/
|
|
234
|
+
router.get('/templates/:id', (req, res) => {
|
|
235
|
+
try {
|
|
236
|
+
const template = permissionTemplatesService.getTemplateById(req.params.id);
|
|
237
|
+
if (!template) {
|
|
238
|
+
return res.status(404).json({
|
|
239
|
+
success: false,
|
|
240
|
+
message: '模版不存在'
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
res.json({
|
|
244
|
+
success: true,
|
|
245
|
+
data: template
|
|
246
|
+
});
|
|
247
|
+
} catch (err) {
|
|
248
|
+
console.error('[Permissions API] Get template error:', err);
|
|
249
|
+
res.status(500).json({
|
|
250
|
+
success: false,
|
|
251
|
+
message: err.message
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* 创建自定义权限模版
|
|
258
|
+
* POST /api/permissions/templates
|
|
259
|
+
*/
|
|
260
|
+
router.post('/templates', (req, res) => {
|
|
261
|
+
try {
|
|
262
|
+
const template = permissionTemplatesService.createTemplate(req.body);
|
|
263
|
+
res.json({
|
|
264
|
+
success: true,
|
|
265
|
+
data: template,
|
|
266
|
+
message: '模版创建成功'
|
|
267
|
+
});
|
|
268
|
+
} catch (err) {
|
|
269
|
+
console.error('[Permissions API] Create template error:', err);
|
|
270
|
+
res.status(400).json({
|
|
271
|
+
success: false,
|
|
272
|
+
message: err.message
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* 更新自定义权限模版
|
|
279
|
+
* PUT /api/permissions/templates/:id
|
|
280
|
+
*/
|
|
281
|
+
router.put('/templates/:id', (req, res) => {
|
|
282
|
+
try {
|
|
283
|
+
const template = permissionTemplatesService.updateTemplate(req.params.id, req.body);
|
|
284
|
+
res.json({
|
|
285
|
+
success: true,
|
|
286
|
+
data: template,
|
|
287
|
+
message: '模版更新成功'
|
|
288
|
+
});
|
|
289
|
+
} catch (err) {
|
|
290
|
+
console.error('[Permissions API] Update template error:', err);
|
|
291
|
+
res.status(400).json({
|
|
292
|
+
success: false,
|
|
293
|
+
message: err.message
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* 删除自定义权限模版
|
|
300
|
+
* DELETE /api/permissions/templates/:id
|
|
301
|
+
*/
|
|
302
|
+
router.delete('/templates/:id', (req, res) => {
|
|
303
|
+
try {
|
|
304
|
+
permissionTemplatesService.deleteTemplate(req.params.id);
|
|
305
|
+
res.json({
|
|
306
|
+
success: true,
|
|
307
|
+
message: '模版删除成功'
|
|
308
|
+
});
|
|
309
|
+
} catch (err) {
|
|
310
|
+
console.error('[Permissions API] Delete template error:', err);
|
|
311
|
+
res.status(400).json({
|
|
312
|
+
success: false,
|
|
313
|
+
message: err.message
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
|
|
295
318
|
/**
|
|
296
319
|
* 获取各 CLI 工具的启动参数配置说明
|
|
297
320
|
* GET /api/permissions/cli-config
|
package/src/server/index.js
CHANGED
|
@@ -146,6 +146,9 @@ async function startServer(port) {
|
|
|
146
146
|
// 命令执行权限 API
|
|
147
147
|
app.use('/api/permissions', require('./api/permissions'));
|
|
148
148
|
|
|
149
|
+
// 配置导出/导入 API
|
|
150
|
+
app.use('/api/config-export', require('./api/config-export'));
|
|
151
|
+
|
|
149
152
|
// 健康检查 API
|
|
150
153
|
app.use('/api/health-check', require('./api/health-check')(config));
|
|
151
154
|
|
|
@@ -259,7 +262,7 @@ function autoRestoreProxies() {
|
|
|
259
262
|
|
|
260
263
|
// 启动时执行健康检查
|
|
261
264
|
function performStartupHealthCheck() {
|
|
262
|
-
const { healthCheckAllProjects
|
|
265
|
+
const { healthCheckAllProjects } = require('./services/health-check');
|
|
263
266
|
const { getProjects } = require('./services/sessions');
|
|
264
267
|
|
|
265
268
|
try {
|
|
@@ -289,16 +292,6 @@ function performStartupHealthCheck() {
|
|
|
289
292
|
console.log(chalk.green(` ✓ 所有 ${healthResult.summary.healthy} 个项目状态正常`));
|
|
290
293
|
}
|
|
291
294
|
|
|
292
|
-
// 扫描旧文件
|
|
293
|
-
const legacyResult = scanLegacySessionFiles();
|
|
294
|
-
|
|
295
|
-
if (legacyResult.found && legacyResult.projectCount > 0) {
|
|
296
|
-
console.log(chalk.yellow(`\n ⚠ 发现 ${legacyResult.projectCount} 个项目的旧会话文件在全局目录`));
|
|
297
|
-
console.log(chalk.gray(' 💡 提示: 可通过 Web UI 或 API 清理这些文件'));
|
|
298
|
-
console.log(chalk.gray(` - Web UI: 设置 -> 系统维护 -> 清理旧文件`));
|
|
299
|
-
console.log(chalk.gray(` - API: POST /api/health-check/clean-legacy`));
|
|
300
|
-
}
|
|
301
|
-
|
|
302
295
|
console.log('');
|
|
303
296
|
} catch (err) {
|
|
304
297
|
console.error(chalk.red(' ✗ 健康检查失败:'), err.message);
|