@winspan/claude-forge 3.6.39 → 3.6.44
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/dist/convention/types.d.ts +15 -5
- package/dist/convention/types.d.ts.map +1 -1
- package/dist/daemon/engine-registry.d.ts.map +1 -1
- package/dist/daemon/engine-registry.js +6 -0
- package/dist/daemon/engine-registry.js.map +1 -1
- package/dist/daemon/handler-context.d.ts +5 -1
- package/dist/daemon/handler-context.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use-handler.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use-handler.js +59 -2
- package/dist/daemon/handlers/post-tool-use-handler.js.map +1 -1
- package/dist/daemon/handlers/pre-tool-use-handler.d.ts.map +1 -1
- package/dist/daemon/handlers/pre-tool-use-handler.js +25 -2
- package/dist/daemon/handlers/pre-tool-use-handler.js.map +1 -1
- package/dist/daemon/handlers/session-cleanup.d.ts +2 -0
- package/dist/daemon/handlers/session-cleanup.d.ts.map +1 -1
- package/dist/daemon/handlers/session-cleanup.js +20 -0
- package/dist/daemon/handlers/session-cleanup.js.map +1 -1
- package/dist/daemon/handlers/stop-handler.d.ts.map +1 -1
- package/dist/daemon/handlers/stop-handler.js +1 -0
- package/dist/daemon/handlers/stop-handler.js.map +1 -1
- package/dist/pipeline/completion-gate.d.ts +1 -0
- package/dist/pipeline/completion-gate.d.ts.map +1 -1
- package/dist/pipeline/completion-gate.js +43 -3
- package/dist/pipeline/completion-gate.js.map +1 -1
- package/dist/pipeline/completion-verifier.d.ts +75 -0
- package/dist/pipeline/completion-verifier.d.ts.map +1 -0
- package/dist/pipeline/completion-verifier.js +217 -0
- package/dist/pipeline/completion-verifier.js.map +1 -0
- package/dist/pipeline/diagnosis-service.d.ts +43 -0
- package/dist/pipeline/diagnosis-service.d.ts.map +1 -0
- package/dist/pipeline/diagnosis-service.js +136 -0
- package/dist/pipeline/diagnosis-service.js.map +1 -0
- package/dist/pipeline/execution-engine.d.ts +79 -0
- package/dist/pipeline/execution-engine.d.ts.map +1 -0
- package/dist/pipeline/execution-engine.js +227 -0
- package/dist/pipeline/execution-engine.js.map +1 -0
- package/dist/pipeline/node-type-sync.d.ts.map +1 -1
- package/dist/pipeline/node-type-sync.js +25 -22
- package/dist/pipeline/node-type-sync.js.map +1 -1
- package/dist/pipeline/plan-service.d.ts +58 -0
- package/dist/pipeline/plan-service.d.ts.map +1 -0
- package/dist/pipeline/plan-service.js +382 -0
- package/dist/pipeline/plan-service.js.map +1 -0
- package/dist/pipeline/strategy-selector.d.ts +41 -0
- package/dist/pipeline/strategy-selector.d.ts.map +1 -0
- package/dist/pipeline/strategy-selector.js +112 -0
- package/dist/pipeline/strategy-selector.js.map +1 -0
- package/dist/pipeline/template-evolver.d.ts +45 -0
- package/dist/pipeline/template-evolver.d.ts.map +1 -0
- package/dist/pipeline/template-evolver.js +223 -0
- package/dist/pipeline/template-evolver.js.map +1 -0
- package/dist/storage/repositories/node-attempt-repository.d.ts +29 -0
- package/dist/storage/repositories/node-attempt-repository.d.ts.map +1 -0
- package/dist/storage/repositories/node-attempt-repository.js +57 -0
- package/dist/storage/repositories/node-attempt-repository.js.map +1 -0
- package/dist/storage/repositories/pipeline-plan-repository.d.ts +75 -0
- package/dist/storage/repositories/pipeline-plan-repository.d.ts.map +1 -0
- package/dist/storage/repositories/pipeline-plan-repository.js +123 -0
- package/dist/storage/repositories/pipeline-plan-repository.js.map +1 -0
- package/dist/storage/repositories/template-evolution-repository.d.ts +39 -0
- package/dist/storage/repositories/template-evolution-repository.d.ts.map +1 -0
- package/dist/storage/repositories/template-evolution-repository.js +83 -0
- package/dist/storage/repositories/template-evolution-repository.js.map +1 -0
- package/dist/storage/schema/migration-manager.d.ts +1 -1
- package/dist/storage/schema/migration-manager.d.ts.map +1 -1
- package/dist/storage/schema/migration-manager.js +63 -1
- package/dist/storage/schema/migration-manager.js.map +1 -1
- package/dist/storage/sqlite.d.ts +8 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +13 -0
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/web/routes/evolution.d.ts +4 -0
- package/dist/web/routes/evolution.d.ts.map +1 -0
- package/dist/web/routes/evolution.js +61 -0
- package/dist/web/routes/evolution.js.map +1 -0
- package/dist/web/routes/plans.d.ts +5 -0
- package/dist/web/routes/plans.d.ts.map +1 -0
- package/dist/web/routes/plans.js +163 -0
- package/dist/web/routes/plans.js.map +1 -0
- package/dist/web/routes/templates.d.ts +4 -0
- package/dist/web/routes/templates.d.ts.map +1 -0
- package/dist/web/routes/templates.js +117 -0
- package/dist/web/routes/templates.js.map +1 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +6 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web-static/assets/Analytics-Bo74j97W.js +1 -0
- package/dist/web-static/assets/BatchProgress-BQ533tSf.js +1 -0
- package/dist/web-static/assets/{Breadcrumb-DbDeWYcH.js → Breadcrumb-DtfwnOx6.js} +1 -1
- package/dist/web-static/assets/{Config-yTRFpmlP.js → Config-DhfQsbT1.js} +1 -1
- package/dist/web-static/assets/{ConfirmDialog-CH1HyRaY.js → ConfirmDialog-CVzB7X5y.js} +1 -1
- package/dist/web-static/assets/{Conventions-DaqIk41m.js → Conventions-BobuQiOk.js} +1 -1
- package/dist/web-static/assets/Dashboard-Bj28rnDe.js +1 -0
- package/dist/web-static/assets/{ErrorState-HW0OjEYK.js → ErrorState-DXHA8lr8.js} +1 -1
- package/dist/web-static/assets/Events-C0y7WcDP.js +1 -0
- package/dist/web-static/assets/Evolution-DimZAXFS.js +1 -0
- package/dist/web-static/assets/Knowledge-Y1lX6vor.js +2 -0
- package/dist/web-static/assets/{NodeTypes-B5E6NYKn.js → NodeTypes-DyrDqhBp.js} +1 -1
- package/dist/web-static/assets/{Pagination-ooTI9JPa.js → Pagination-lp8b_3NR.js} +1 -1
- package/dist/web-static/assets/{PipelineDetail-DCnqD5lr.js → PipelineDetail-DGKz18zu.js} +3 -3
- package/dist/web-static/assets/{PipelineTemplates-CxGoLw6Q.js → PipelineTemplates-D4zvL6I1.js} +1 -1
- package/dist/web-static/assets/Pipelines-CR9oD3Xy.js +2 -0
- package/dist/web-static/assets/ProjectDetail-RfdtEvTT.js +1 -0
- package/dist/web-static/assets/Projects-RGIPdiJn.js +1 -0
- package/dist/web-static/assets/Quality-BdvL1VQn.js +3 -0
- package/dist/web-static/assets/{SessionDetail-DleCNmQH.js → SessionDetail-BNDIfmmq.js} +1 -1
- package/dist/web-static/assets/{Sessions-Dz6xFq_4.js → Sessions-CorfQV78.js} +2 -2
- package/dist/web-static/assets/{BatchProgress-CIrC9RcC.js → Skeleton-B7PVDJJ_.js} +1 -1
- package/dist/web-static/assets/Skills-BJt0OrKj.js +1 -0
- package/dist/web-static/assets/TemplateDetail-DOfBYdQ3.js +1 -0
- package/dist/web-static/assets/Templates-Cp3yC5tv.js +1 -0
- package/dist/web-static/assets/{client-B_-7qCOP.js → client-BhcjNvkG.js} +1 -1
- package/dist/web-static/assets/index-CfBMQvSa.js +2 -0
- package/dist/web-static/assets/index-CqwJts5v.css +2 -0
- package/dist/web-static/assets/{ui-B2gvOcFY.js → ui-CDL3BZ13.js} +1 -1
- package/dist/web-static/assets/useDebounce-DNfPs3Tv.js +1 -0
- package/dist/web-static/assets/vendor-DRGPi8ui.js +9 -0
- package/dist/web-static/assets/{vendor-charts-BXsEmmv5.js → vendor-charts-9eVsQvUV.js} +4 -4
- package/dist/web-static/assets/{vendor-editor-DYIoTHFO.js → vendor-editor-B1NX2ipj.js} +1 -1
- package/dist/web-static/assets/vendor-flow-srkes8If.js +7 -0
- package/dist/web-static/assets/{vendor-motion-BsfSkSjj.js → vendor-motion-CQmdgnI8.js} +2 -2
- package/dist/web-static/assets/{vendor-query-BF-uT_c5.js → vendor-query-DqPOMnuX.js} +1 -1
- package/dist/web-static/assets/{vendor-react-CXfI0Tes.js → vendor-react-DJI9oneq.js} +1 -1
- package/dist/web-static/index.html +11 -11
- package/package.json +2 -1
- package/dist/web-static/assets/Analytics-BTMAlQBr.js +0 -1
- package/dist/web-static/assets/Dashboard-BS61GjKa.js +0 -1
- package/dist/web-static/assets/Events-DAms_1fs.js +0 -1
- package/dist/web-static/assets/Knowledge-CZhuou1K.js +0 -2
- package/dist/web-static/assets/Pipelines-DEuVx4hF.js +0 -2
- package/dist/web-static/assets/ProjectDetail-Dn01H3zi.js +0 -1
- package/dist/web-static/assets/Projects-D5-BfuFU.js +0 -1
- package/dist/web-static/assets/Quality-wvfdPtGB.js +0 -3
- package/dist/web-static/assets/Skills-CpHL-tyW.js +0 -1
- package/dist/web-static/assets/index-CN_edVMt.js +0 -2
- package/dist/web-static/assets/index-DLMLziRH.css +0 -2
- package/dist/web-static/assets/useDebounce-Bo1fLB5L.js +0 -1
- package/dist/web-static/assets/vendor-BpBCrKSP.js +0 -9
- package/dist/web-static/assets/vendor-flow-D-_WxBha.js +0 -7
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { PlanService } from '../../pipeline/plan-service.js';
|
|
3
|
+
import { logger } from '../../utils/logger.js';
|
|
4
|
+
export function createPlansRouter(storage, aiProvider) {
|
|
5
|
+
const router = Router();
|
|
6
|
+
const planService = aiProvider ? new PlanService(storage, aiProvider) : null;
|
|
7
|
+
// GET /plans/:planId - 获取计划详情
|
|
8
|
+
router.get('/:planId', (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const { planId } = req.params;
|
|
11
|
+
const plan = storage.repositories.pipelinePlans.getById(planId);
|
|
12
|
+
if (!plan)
|
|
13
|
+
return res.status(404).json({ error: 'Plan not found' });
|
|
14
|
+
const nodes = storage.repositories.planNodes.getByPlanId(planId);
|
|
15
|
+
res.json({
|
|
16
|
+
...plan,
|
|
17
|
+
nodes: nodes.map(n => ({
|
|
18
|
+
node_id: n.node_id,
|
|
19
|
+
plan_id: n.plan_id,
|
|
20
|
+
phase: n.phase,
|
|
21
|
+
title: n.title,
|
|
22
|
+
status: n.status,
|
|
23
|
+
attempt_count: n.attempt_count,
|
|
24
|
+
current_strategy_id: n.current_strategy_id,
|
|
25
|
+
timeout_sec: n.timeout_sec,
|
|
26
|
+
completion_rules: n.completion_rules,
|
|
27
|
+
strategy_pool: n.strategy_pool,
|
|
28
|
+
dependencies: n.dependencies,
|
|
29
|
+
created_at: n.created_at,
|
|
30
|
+
updated_at: n.updated_at,
|
|
31
|
+
})),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
res.status(500).json({ error: String(err) });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// GET /plans/by-project/:projectPath - 获取项目的活跃计划
|
|
39
|
+
router.get('/by-project/:projectPath', (req, res) => {
|
|
40
|
+
try {
|
|
41
|
+
const projectPath = decodeURIComponent(req.params.projectPath);
|
|
42
|
+
const plan = storage.repositories.pipelinePlans.getByProjectPath(projectPath);
|
|
43
|
+
if (!plan)
|
|
44
|
+
return res.json(null);
|
|
45
|
+
const nodes = storage.repositories.planNodes.getByPlanId(plan.plan_id);
|
|
46
|
+
res.json({
|
|
47
|
+
...plan,
|
|
48
|
+
nodes: nodes.map(n => ({
|
|
49
|
+
node_id: n.node_id,
|
|
50
|
+
plan_id: n.plan_id,
|
|
51
|
+
phase: n.phase,
|
|
52
|
+
title: n.title,
|
|
53
|
+
status: n.status,
|
|
54
|
+
attempt_count: n.attempt_count,
|
|
55
|
+
current_strategy_id: n.current_strategy_id,
|
|
56
|
+
timeout_sec: n.timeout_sec,
|
|
57
|
+
completion_rules: n.completion_rules,
|
|
58
|
+
strategy_pool: n.strategy_pool,
|
|
59
|
+
dependencies: n.dependencies,
|
|
60
|
+
created_at: n.created_at,
|
|
61
|
+
updated_at: n.updated_at,
|
|
62
|
+
})),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
res.status(500).json({ error: String(err) });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// GET /plans/nodes/:nodeId/attempts - 获取节点执行历史
|
|
70
|
+
router.get('/nodes/:nodeId/attempts', (req, res) => {
|
|
71
|
+
try {
|
|
72
|
+
const { nodeId } = req.params;
|
|
73
|
+
const attempts = storage.repositories.nodeAttempts.getByNodeId(nodeId);
|
|
74
|
+
res.json({
|
|
75
|
+
items: attempts.map(a => ({
|
|
76
|
+
attempt_id: a.attempt_id,
|
|
77
|
+
node_id: a.node_id,
|
|
78
|
+
strategy_id: a.strategy_id,
|
|
79
|
+
attempt_number: a.attempt_number,
|
|
80
|
+
started_at: a.started_at,
|
|
81
|
+
ended_at: a.ended_at,
|
|
82
|
+
status: a.status,
|
|
83
|
+
verification_result: a.verification_result,
|
|
84
|
+
})),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
res.status(500).json({ error: String(err) });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
// POST /plans - 生成新计划(draft 状态,等待用户确认)
|
|
92
|
+
router.post('/', async (req, res) => {
|
|
93
|
+
if (!planService) {
|
|
94
|
+
return res.status(503).json({ error: 'Plan service unavailable (AI provider not configured)' });
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const { goal, project_path, session_id, context } = req.body;
|
|
98
|
+
if (!goal || !project_path || !session_id) {
|
|
99
|
+
return res.status(400).json({ error: 'Missing required fields: goal, project_path, session_id' });
|
|
100
|
+
}
|
|
101
|
+
const generated = await planService.generatePlan({ goal, project_path, session_id, context });
|
|
102
|
+
await planService.savePlan(generated);
|
|
103
|
+
res.json({
|
|
104
|
+
plan_id: generated.plan.plan_id,
|
|
105
|
+
template_id: generated.template_id,
|
|
106
|
+
template_name: generated.template_name,
|
|
107
|
+
status: 'draft',
|
|
108
|
+
nodes: generated.nodes.map(n => ({
|
|
109
|
+
node_id: n.node_id,
|
|
110
|
+
title: n.title,
|
|
111
|
+
phase: n.phase,
|
|
112
|
+
completion_rules: n.completion_rules,
|
|
113
|
+
dependencies: n.dependencies,
|
|
114
|
+
})),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
logger.error(`[PlansRouter] POST / failed: ${err}`);
|
|
119
|
+
res.status(500).json({ error: 'Failed to generate plan' });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
// POST /plans/:planId/approve - 确认计划(draft → approved)
|
|
123
|
+
router.post('/:planId/approve', (req, res) => {
|
|
124
|
+
if (!planService) {
|
|
125
|
+
return res.status(503).json({ error: 'Plan service unavailable' });
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const { planId } = req.params;
|
|
129
|
+
const plan = storage.repositories.pipelinePlans.getById(planId);
|
|
130
|
+
if (!plan)
|
|
131
|
+
return res.status(404).json({ error: 'Plan not found' });
|
|
132
|
+
if (plan.status !== 'draft') {
|
|
133
|
+
return res.status(400).json({ error: `Cannot approve plan in status: ${plan.status}` });
|
|
134
|
+
}
|
|
135
|
+
planService.approvePlan(planId);
|
|
136
|
+
res.json({ success: true, plan_id: planId });
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
logger.error(`[PlansRouter] POST /:planId/approve failed: ${err}`);
|
|
140
|
+
res.status(500).json({ error: 'Failed to approve plan' });
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// POST /plans/:planId/abort - 中止计划
|
|
144
|
+
router.post('/:planId/abort', (req, res) => {
|
|
145
|
+
if (!planService) {
|
|
146
|
+
return res.status(503).json({ error: 'Plan service unavailable' });
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const { planId } = req.params;
|
|
150
|
+
const plan = storage.repositories.pipelinePlans.getById(planId);
|
|
151
|
+
if (!plan)
|
|
152
|
+
return res.status(404).json({ error: 'Plan not found' });
|
|
153
|
+
planService.abortPlan(planId);
|
|
154
|
+
res.json({ success: true, plan_id: planId });
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
logger.error(`[PlansRouter] POST /:planId/abort failed: ${err}`);
|
|
158
|
+
res.status(500).json({ error: 'Failed to abort plan' });
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return router;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=plans.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plans.js","sourceRoot":"","sources":["../../../src/web/routes/plans.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../src/web/routes/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CA0HpE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { logger } from '../../utils/logger.js';
|
|
3
|
+
export function createTemplatesRouter(storage) {
|
|
4
|
+
const router = Router();
|
|
5
|
+
// GET /templates - 获取所有模板
|
|
6
|
+
router.get('/', (req, res) => {
|
|
7
|
+
try {
|
|
8
|
+
const templates = storage.repositories.dynamicPipelineTemplates.getAll();
|
|
9
|
+
res.json({ total: templates.length, items: templates });
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
res.status(500).json({ error: String(err) });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
// GET /templates/:id - 获取模板详情
|
|
16
|
+
router.get('/:id', (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const template = storage.repositories.dynamicPipelineTemplates.getById(req.params.id);
|
|
19
|
+
if (!template)
|
|
20
|
+
return res.status(404).json({ error: 'Template not found' });
|
|
21
|
+
res.json(template);
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
res.status(500).json({ error: String(err) });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
// GET /templates/:id/versions - 获取模板版本历史
|
|
28
|
+
router.get('/:id/versions', (req, res) => {
|
|
29
|
+
try {
|
|
30
|
+
const versions = storage.repositories.templateVersions.getByTemplateId(req.params.id);
|
|
31
|
+
res.json({ total: versions.length, items: versions });
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
logger.error(`[TemplatesRouter] GET /:id/versions failed: ${err}`);
|
|
35
|
+
res.status(500).json({ error: String(err) });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
// POST /templates/:id/rollback - 回滚到指定版本
|
|
39
|
+
router.post('/:id/rollback', (req, res) => {
|
|
40
|
+
try {
|
|
41
|
+
const { version_id } = req.body;
|
|
42
|
+
if (!version_id) {
|
|
43
|
+
return res.status(400).json({ error: 'Missing version_id' });
|
|
44
|
+
}
|
|
45
|
+
const version = storage.repositories.templateVersions.getById(version_id);
|
|
46
|
+
if (!version) {
|
|
47
|
+
return res.status(404).json({ error: 'Version not found' });
|
|
48
|
+
}
|
|
49
|
+
if (version.template_id !== req.params.id) {
|
|
50
|
+
return res.status(400).json({ error: 'Version does not belong to this template' });
|
|
51
|
+
}
|
|
52
|
+
// 回滚:将历史版本内容恢复到主模板表
|
|
53
|
+
const template = storage.repositories.dynamicPipelineTemplates.getById(req.params.id);
|
|
54
|
+
if (!template) {
|
|
55
|
+
return res.status(404).json({ error: 'Template not found' });
|
|
56
|
+
}
|
|
57
|
+
// 更新主模板为历史版本的内容
|
|
58
|
+
storage.repositories.dynamicPipelineTemplates.update(req.params.id, version.content);
|
|
59
|
+
logger.info(`[TemplatesRouter] 模板 ${req.params.id} 已回滚到版本 ${version.version}`);
|
|
60
|
+
res.json({ success: true, version: version.version });
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
logger.error(`[TemplatesRouter] POST /:id/rollback failed: ${err}`);
|
|
64
|
+
res.status(500).json({ error: String(err) });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
// GET /templates/:id/stats - 获取模板执行统计
|
|
68
|
+
router.get('/:id/stats', (req, res) => {
|
|
69
|
+
try {
|
|
70
|
+
const templateId = req.params.id;
|
|
71
|
+
// 查询使用该模板的所有计划
|
|
72
|
+
const db = storage.getDatabase();
|
|
73
|
+
const plans = db.prepare(`
|
|
74
|
+
SELECT status, COUNT(*) as count
|
|
75
|
+
FROM pipeline_plans
|
|
76
|
+
WHERE template_id = ?
|
|
77
|
+
GROUP BY status
|
|
78
|
+
`).all(templateId);
|
|
79
|
+
// 查询平均执行时间
|
|
80
|
+
const avgDuration = db.prepare(`
|
|
81
|
+
SELECT AVG(
|
|
82
|
+
(julianday(updated_at) - julianday(created_at)) * 86400
|
|
83
|
+
) as avg_duration_sec
|
|
84
|
+
FROM pipeline_plans
|
|
85
|
+
WHERE template_id = ? AND status = 'completed'
|
|
86
|
+
`).get(templateId);
|
|
87
|
+
// 查询节点成功率
|
|
88
|
+
const nodeStats = db.prepare(`
|
|
89
|
+
SELECT
|
|
90
|
+
pn.phase,
|
|
91
|
+
COUNT(*) as total_attempts,
|
|
92
|
+
SUM(CASE WHEN pn.status = 'done' THEN 1 ELSE 0 END) as success_count
|
|
93
|
+
FROM plan_nodes pn
|
|
94
|
+
JOIN pipeline_plans pp ON pn.plan_id = pp.plan_id
|
|
95
|
+
WHERE pp.template_id = ?
|
|
96
|
+
GROUP BY pn.phase
|
|
97
|
+
`).all(templateId);
|
|
98
|
+
res.json({
|
|
99
|
+
template_id: templateId,
|
|
100
|
+
total_plans: plans.reduce((sum, p) => sum + p.count, 0),
|
|
101
|
+
status_breakdown: plans,
|
|
102
|
+
avg_duration_sec: avgDuration?.avg_duration_sec ?? null,
|
|
103
|
+
node_stats: nodeStats.map(n => ({
|
|
104
|
+
phase: n.phase,
|
|
105
|
+
success_rate: n.total_attempts > 0 ? n.success_count / n.total_attempts : 0,
|
|
106
|
+
total_attempts: n.total_attempts,
|
|
107
|
+
})),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
logger.error(`[TemplatesRouter] GET /:id/stats failed: ${err}`);
|
|
112
|
+
res.status(500).json({ error: String(err) });
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return router;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/web/routes/templates.ts"],"names":[],"mappings":"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"}
|
package/dist/web/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA0EjD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,sBAAsB,EAAE,cAAc,CAAC;CAChE;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAmB;gBAEtB,OAAO,EAAE,gBAAgB;IAQrC,OAAO,CAAC,eAAe;IAyDvB,OAAO,CAAC,WAAW;IAuDnB,OAAO,CAAC,gBAAgB;IA2CxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IActB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAYtB"}
|
package/dist/web/server.js
CHANGED
|
@@ -22,6 +22,9 @@ import { registerSkillRoutes } from './routes/skills.js';
|
|
|
22
22
|
import { registerConventionsRoutes } from './routes/conventions.js';
|
|
23
23
|
import { registerProjectConventionRoutes } from './routes/project-conventions.js';
|
|
24
24
|
import { registerNodeTypeRoutes } from './routes/node-types.js';
|
|
25
|
+
import { createPlansRouter } from './routes/plans.js';
|
|
26
|
+
import { createTemplatesRouter } from './routes/templates.js';
|
|
27
|
+
import { createEvolutionRouter } from './routes/evolution.js';
|
|
25
28
|
import { authMiddleware } from './middleware/auth.js';
|
|
26
29
|
import { sendError, ErrorCodes } from './utils/error-response.js';
|
|
27
30
|
import { SseBroadcaster, startHeartbeat } from './sse-broadcaster.js';
|
|
@@ -153,6 +156,9 @@ export class WebServer {
|
|
|
153
156
|
registerConventionsRoutes(app, storage);
|
|
154
157
|
registerProjectConventionRoutes(app);
|
|
155
158
|
registerNodeTypeRoutes(app, storage);
|
|
159
|
+
app.use('/api/plans', createPlansRouter(storage, aiProvider));
|
|
160
|
+
app.use('/api/templates', createTemplatesRouter(storage));
|
|
161
|
+
app.use('/api/evolution', createEvolutionRouter(storage));
|
|
156
162
|
};
|
|
157
163
|
// SSE 实时推送端点(不走限流和超时中间件)
|
|
158
164
|
this.app.get('/api/events/stream', (req, res) => {
|
package/dist/web/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e}from"./rolldown-runtime-COnpUsM8.js";import{Dn as t,Ft as n,Gn as r,Ht as i,Rn as a,Vt as o,fn as ee,gr as s,ir as te,o as c,pr as l,s as u,zn as ne}from"./vendor-DRGPi8ui.js";import{S as d,_ as f,c as p,d as m,f as h,g,h as _,l as v,m as y,p as b,s as x,u as S,v as C,x as w,y as T}from"./vendor-charts-9eVsQvUV.js";import{r as E}from"./vendor-query-DqPOMnuX.js";import{c as D}from"./vendor-flow-srkes8If.js";import{J as re,L as ie,St as ae,Y as oe,ht as se,wt as ce,xt as le}from"./client-BhcjNvkG.js";import{a as O,l as k,n as ue,r as A}from"./ui-CDL3BZ13.js";import{t as de}from"./ErrorState-DXHA8lr8.js";import{t as j}from"./exportCsv-CSExJI8h.js";var M=e(s(),1),N=D();function P({children:e,fallback:t,rootMargin:n=`200px`}){let[r,i]=(0,M.useState)(!1),a=(0,M.useRef)(null);return(0,M.useEffect)(()=>{let e=new IntersectionObserver(([t])=>{t.isIntersecting&&(i(!0),e.disconnect())},{rootMargin:n,threshold:.01});return a.current&&e.observe(a.current),()=>e.disconnect()},[n]),(0,N.jsx)(`div`,{ref:a,style:{minHeight:r?`auto`:`400px`},children:r?e:t||(0,N.jsx)(`div`,{className:`flex items-center justify-center h-96 text-gray-400`,children:`加载中...`})})}var F=[`#667eea`,`#10b981`,`#f59e0b`,`#ef4444`,`#8b5cf6`,`#06b6d4`],fe={"7d":7,"30d":30,"90d":90,custom:0};function I(){let[e,s]=(0,M.useState)(`30d`),[D,I]=(0,M.useState)(``),[L,pe]=(0,M.useState)(``),[R,z]=(0,M.useState)(`sessions`),B=fe[e],V=e===`custom`?D?`${D}T00:00:00`:void 0:u(c(new Date,B),`yyyy-MM-dd'T'HH:mm:ss`),H=e===`custom`&&L?`${L}T23:59:59`:void 0,{data:U,isLoading:me,isError:he,refetch:ge}=E({queryKey:[`sessions`,{limit:100,startTime:V,endTime:H}],queryFn:()=>ce({limit:100,start_time:V,end_time:H}).then(e=>e.data)}),{data:W,isLoading:_e,isError:ve,refetch:ye}=E({queryKey:[`events`,{limit:100,startTime:V,endTime:H}],queryFn:()=>oe({limit:100,start_time:V,end_time:H}).then(e=>e.data)}),{data:be,isLoading:xe}=E({queryKey:[`event-stats`],queryFn:()=>re().then(e=>e.data)}),{data:G}=E({queryKey:[`api-usage-stats`,e],queryFn:()=>ie(e===`custom`?90:B).then(e=>e.data),staleTime:6e4}),{data:K}=E({queryKey:[`roi-stats-analytics`],queryFn:()=>ae().then(e=>e.data),staleTime:6e4}),{data:q}=E({queryKey:[`pipelines-analytics`,{limit:100}],queryFn:()=>se({limit:100}).then(e=>e.data),enabled:R===`pipelines`}),{data:J}=E({queryKey:[`quality-history-analytics`,{limit:100}],queryFn:()=>le({limit:100}).then(e=>e.data),enabled:R===`pipelines`}),Se=me||_e||xe,Ce=he||ve,we=()=>{j(`analytics-sessions-${u(new Date,`yyyyMMdd`)}.csv`,[`日期`,`会话数`],Y.map(e=>[e.date,e.count])),j(`analytics-tools-${u(new Date,`yyyyMMdd`)}.csv`,[`工具`,`使用次数`],De.map(e=>[e.name,e.value])),j(`analytics-projects-${u(new Date,`yyyyMMdd`)}.csv`,[`项目`,`事件数`],X.map(e=>[e.name,e.value])),j(`analytics-durations-${u(new Date,`yyyyMMdd`)}.csv`,[`时长区间`,`会话数`],Z.map(e=>[e.range,e.count]))},Y=(0,M.useMemo)(()=>{if(!U?.items)return[];if(e===`custom`){if(!D||!L)return[];let e=new Date(D),t=new Date(L),n=Math.ceil((t.getTime()-e.getTime())/(1e3*60*60*24))+1;return Array.from({length:n},(t,n)=>{let r=u(new Date(e.getTime()+n*24*60*60*1e3),`MM-dd`);return{date:r,count:U.items.filter(e=>u(k(e.start_time),`MM-dd`)===r).length}})}return Array.from({length:B},(e,t)=>{let n=u(c(new Date,B-1-t),`MM-dd`);return{date:n,count:U.items.filter(e=>u(k(e.start_time),`MM-dd`)===n).length}})},[U?.items,B,e,D,L]),Te=(0,M.useMemo)(()=>W?.items?Array.from({length:24},(e,t)=>{let n=W.items.filter(e=>k(e.timestamp).getHours()===t).length;return{hour:`${t}:00`,count:n}}):[],[W?.items]),X=(0,M.useMemo)(()=>{if(!W?.items)return[];let e=W.items.reduce((e,t)=>{let n=t.project_path.split(`/`).pop()||`Unknown`;return e[n]=(e[n]||0)+1,e},{});return Object.entries(e).sort((e,t)=>t[1]-e[1]).slice(0,10).map(([e,t])=>({name:e,value:t}))},[W?.items]),Ee={Bash:`Bash 命令`,Read:`读取文件`,Edit:`编辑文件`,Write:`写入文件`,Grep:`搜索内容`,Glob:`查找文件`,Agent:`子代理`,WebFetch:`网页获取`,WebSearch:`网页搜索`,TodoWrite:`任务管理`,NotebookEdit:`笔记编辑`,stop:`停止`,notification:`通知`,UserPrompt:`用户输入`,TaskCreate:`创建任务`,TaskUpdate:`更新任务`,TaskList:`任务列表`,TaskGet:`获取任务`,TaskStop:`停止任务`,TaskOutput:`任务输出`},De=(0,M.useMemo)(()=>{if(!W?.items)return[];let e=W.items.reduce((e,t)=>{let n=t.tool_name||`N/A`;return e[n]=(e[n]||0)+1,e},{});return Object.entries(e).sort((e,t)=>t[1]-e[1]).slice(0,15).map(([e,t])=>({name:Ee[e]||e,value:t}))},[W?.items]),{sessionDurations:Oe,durationBuckets:Z}=(0,M.useMemo)(()=>{if(!U?.items)return{sessionDurations:[],durationBuckets:[]};let e=U.items.filter(e=>e.end_time).map(e=>{let t=(k(e.end_time).getTime()-k(e.start_time).getTime())/1e3/60;return Math.round(t)});return{sessionDurations:e,durationBuckets:[{range:`0-5分钟`,count:e.filter(e=>e<=5).length},{range:`5-15分钟`,count:e.filter(e=>e>5&&e<=15).length},{range:`15-30分钟`,count:e.filter(e=>e>15&&e<=30).length},{range:`30-60分钟`,count:e.filter(e=>e>30&&e<=60).length},{range:`60+分钟`,count:e.filter(e=>e>60).length}]}},[U?.items]),{avgSessionEvents:ke,avgSessionDuration:Ae}=(0,M.useMemo)(()=>{let e=Oe.filter(e=>e>0&&e<=480),t=e.length>0?e.reduce((e,t)=>e+t,0)/e.length:0,n=U?.items.filter(e=>e.event_count>0&&e.event_count<=500)??[];return{avgSessionEvents:n.length>0?n.reduce((e,t)=>e+t.event_count,0)/n.length:0,avgSessionDuration:t}},[U?.items,Oe]),Q=(0,M.useMemo)(()=>{if(!q?.items)return null;let e=q.items,t=e.filter(e=>e.status===`completed`).length;return{completed:t,failed:e.filter(e=>e.status===`failed`).length,completionRate:e.length>0?(t/e.length*100).toFixed(1):`0`,complexityDist:e.reduce((e,t)=>(e[t.complexity]=(e[t.complexity]||0)+1,e),{}),avgNodes:e.length>0?(e.reduce((e,t)=>e+(t.stats?.totalNodes||0),0)/e.length).toFixed(1):`0`,total:e.length}},[q?.items]),$=(0,M.useMemo)(()=>J?.items?Array.from({length:B},(e,t)=>{let n=u(c(new Date,B-1-t),`MM-dd`),r=J.items.filter(e=>u(k(e.created_at),`MM-dd`)===n);return{date:n,total:r.length,unresolved:r.filter(e=>!e.resolved).length}}):[],[J?.items,B]);return Se?(0,N.jsx)(`div`,{className:`flex items-center justify-center h-96`,children:(0,N.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600`})}):Ce?(0,N.jsx)(de,{message:`分析数据加载失败`,onRetry:()=>{ge(),ye()}}):(0,N.jsxs)(`div`,{className:`space-y-6`,children:[(0,N.jsx)(A,{children:(0,N.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,N.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,N.jsx)(te,{className:`h-4 w-4 text-gray-400`}),(0,N.jsx)(`span`,{className:`text-sm text-gray-600`,children:`时间范围:`}),(0,N.jsx)(`div`,{className:`flex gap-1 border border-gray-200 rounded-lg overflow-hidden`,children:[`7d`,`30d`,`90d`,`custom`].map(t=>(0,N.jsx)(`button`,{onClick:()=>s(t),className:O(`px-3 py-1.5 text-sm transition-colors`,e===t?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50`),children:t===`7d`?`7 天`:t===`30d`?`30 天`:t===`90d`?`90 天`:`自定义`},t))})]}),(0,N.jsx)(ue,{variant:`outline`,size:`sm`,icon:a,onClick:we,children:`导出数据`})]}),e===`custom`&&(0,N.jsxs)(`div`,{className:`flex items-center gap-3 pl-6`,children:[(0,N.jsx)(`label`,{className:`text-sm text-gray-600`,children:`开始日期:`}),(0,N.jsx)(`input`,{type:`date`,value:D,onChange:e=>I(e.target.value),className:`px-3 py-1.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500`}),(0,N.jsx)(`label`,{className:`text-sm text-gray-600`,children:`结束日期:`}),(0,N.jsx)(`input`,{type:`date`,value:L,onChange:e=>pe(e.target.value),className:`px-3 py-1.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500`})]})]})}),(0,N.jsxs)(`div`,{className:`flex gap-1 bg-gray-100 p-1 rounded-lg w-fit`,children:[(0,N.jsxs)(`button`,{onClick:()=>z(`sessions`),className:O(`flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors`,R===`sessions`?`bg-white text-gray-900 shadow-sm`:`text-gray-600 hover:text-gray-900`),children:[(0,N.jsx)(l,{className:`h-4 w-4`}),`会话分析`]}),(0,N.jsxs)(`button`,{onClick:()=>z(`pipelines`),className:O(`flex items-center gap-2 px-4 py-2 rounded-md text-sm font-medium transition-colors`,R===`pipelines`?`bg-white text-gray-900 shadow-sm`:`text-gray-600 hover:text-gray-900`),children:[(0,N.jsx)(t,{className:`h-4 w-4`}),`Pipeline 分析`]})]}),R===`sessions`&&(0,N.jsxs)(`div`,{className:`space-y-6`,children:[K&&(0,N.jsx)(`div`,{className:`grid grid-cols-2 md:grid-cols-3 gap-3`,children:[{label:`本周会话`,curr:K.week.sessions,pct:K.weekOverWeek.sessions},{label:`本周写入操作`,curr:K.week.writeOps,pct:K.weekOverWeek.writeOps},{label:`本周节省时间`,curr:`${K.week.timeSavedHours}h`,pct:K.weekOverWeek.timeSaved},{label:`本周质量拦截`,curr:K.week.qualityBlocked,pct:K.weekOverWeek.qualityBlocked},{label:`本月会话`,curr:K.month.sessions,pct:K.monthOverMonth.sessions},{label:`本月质量拦截`,curr:K.month.qualityBlocked,pct:K.monthOverMonth.qualityBlocked}].map(e=>(0,N.jsxs)(A,{className:`!p-3`,children:[(0,N.jsx)(`div`,{className:`text-xs text-gray-500 mb-1`,children:e.label}),(0,N.jsxs)(`div`,{className:`flex items-end justify-between`,children:[(0,N.jsx)(`span`,{className:`text-xl font-bold text-gray-900`,children:e.curr}),e.pct!==null&&e.pct!==void 0?(0,N.jsxs)(`span`,{className:O(`flex items-center gap-0.5 text-xs font-medium`,e.pct>0?`text-green-600`:e.pct<0?`text-red-500`:`text-gray-400`),children:[e.pct>0?(0,N.jsx)(o,{className:`h-3 w-3`}):e.pct<0?(0,N.jsx)(i,{className:`h-3 w-3`}):(0,N.jsx)(ee,{className:`h-3 w-3`}),e.pct>0?`+`:``,e.pct,`%`]}):(0,N.jsx)(`span`,{className:`text-xs text-gray-300`,children:`—`})]}),(0,N.jsx)(`div`,{className:`text-xs text-gray-400 mt-0.5`,children:`较上期`})]},e.label))}),(0,N.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-4`,children:[(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsx)(l,{className:`h-7 w-7 text-indigo-500 mx-auto mb-2`}),(0,N.jsx)(`div`,{className:`text-2xl font-bold text-gray-900`,children:ke.toFixed(1)}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`平均会话事件数`})]}),(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsx)(r,{className:`h-7 w-7 text-green-500 mx-auto mb-2`}),(0,N.jsx)(`div`,{className:`text-2xl font-bold text-gray-900`,children:Ae.toFixed(1)}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`平均会话时长(分钟)`})]}),(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsx)(n,{className:`h-7 w-7 text-amber-500 mx-auto mb-2`}),(0,N.jsx)(`div`,{className:`text-2xl font-bold text-gray-900`,children:W?.total||0}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`总事件数`})]}),(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsx)(o,{className:`h-7 w-7 text-purple-500 mx-auto mb-2`}),(0,N.jsx)(`div`,{className:`text-2xl font-bold text-gray-900`,children:U?.total||0}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`总会话数`})]})]}),(0,N.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-2 gap-6`,children:[(0,N.jsx)(A,{title:`最近 ${B} 天会话趋势`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(x,{data:Y,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`date`}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{}),(0,N.jsx)(y,{type:`monotone`,dataKey:`count`,stroke:`#667eea`,fill:`#667eea`,fillOpacity:.3})]})})})}),(0,N.jsx)(A,{title:`24 小时事件分布`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(S,{data:Te,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`hour`}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{}),(0,N.jsx)(_,{type:`monotone`,dataKey:`count`,stroke:`#10b981`,strokeWidth:2})]})})})}),(0,N.jsx)(A,{title:`项目活跃度 Top 10`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(v,{data:X,layout:`vertical`,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{type:`number`}),(0,N.jsx)(m,{dataKey:`name`,type:`category`,width:100}),(0,N.jsx)(T,{}),(0,N.jsx)(b,{dataKey:`value`,fill:`#667eea`})]})})})}),(0,N.jsx)(A,{title:`工具使用排行 Top 15`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(v,{data:De,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`name`,angle:-45,textAnchor:`end`,height:80}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{}),(0,N.jsx)(b,{dataKey:`value`,fill:`#10b981`})]})})})}),(0,N.jsx)(A,{title:`会话时长分布`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(p,{children:[(0,N.jsx)(f,{data:Z,cx:`50%`,cy:`50%`,labelLine:!1,label:({range:e,count:t})=>`${e}: ${t}`,outerRadius:80,fill:`#8884d8`,dataKey:`count`,children:Z.map((e,t)=>(0,N.jsx)(C,{fill:F[t%F.length]},`cell-${t}`))}),(0,N.jsx)(T,{})]})})})}),(0,N.jsx)(A,{title:`事件类型趋势`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(x,{data:be?.stats.slice(0,30)||[],children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`date`}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{}),(0,N.jsx)(w,{}),(0,N.jsx)(y,{type:`monotone`,dataKey:`count`,stackId:`1`,stroke:`#667eea`,fill:`#667eea`})]})})})})]}),G&&(0,N.jsxs)(N.Fragment,{children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-2 mt-2`,children:[(0,N.jsx)(ne,{className:`h-5 w-5 text-gray-500`}),(0,N.jsx)(`h2`,{className:`text-base font-semibold text-gray-800`,children:`Token 与费用统计`})]}),(0,N.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-4 gap-4`,children:[(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsxs)(`div`,{className:`text-2xl font-bold text-gray-900`,children:[`$`,G.summary.totalCost.toFixed(4)]}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`总费用(USD)`})]}),(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsxs)(`div`,{className:`text-2xl font-bold text-gray-900`,children:[(G.summary.totalTokens/1e3).toFixed(1),`K`]}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`总 Token 数`})]}),(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsxs)(`div`,{className:`text-2xl font-bold text-gray-900`,children:[(G.summary.totalTokensIn/1e3).toFixed(1),`K`]}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`输入 Token`})]}),(0,N.jsxs)(A,{className:`text-center !p-4`,children:[(0,N.jsxs)(`div`,{className:`text-2xl font-bold text-gray-900`,children:[(G.summary.totalTokensOut/1e3).toFixed(1),`K`]}),(0,N.jsx)(`div`,{className:`text-sm text-gray-500`,children:`输出 Token`})]})]}),(0,N.jsxs)(`div`,{className:`grid grid-cols-1 xl:grid-cols-2 gap-6`,children:[(0,N.jsx)(A,{title:`每日 Token 趋势`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(x,{data:G.dailyTrend,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`date`}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{formatter:e=>`${(e/1e3).toFixed(1)}K`}),(0,N.jsx)(w,{}),(0,N.jsx)(y,{type:`monotone`,dataKey:`tokens_in`,name:`输入`,stroke:`#667eea`,fill:`#667eea`,fillOpacity:.3,stackId:`1`}),(0,N.jsx)(y,{type:`monotone`,dataKey:`tokens_out`,name:`输出`,stroke:`#10b981`,fill:`#10b981`,fillOpacity:.3,stackId:`1`})]})})})}),(0,N.jsx)(A,{title:`每日费用趋势(USD)`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(v,{data:G.dailyTrend,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`date`}),(0,N.jsx)(m,{tickFormatter:e=>`$${e.toFixed(3)}`}),(0,N.jsx)(T,{formatter:e=>`$${e.toFixed(4)}`}),(0,N.jsx)(b,{dataKey:`cost_usd`,name:`费用`,fill:`#f59e0b`})]})})})}),G.byModel.length>0&&(0,N.jsx)(A,{title:`按模型费用分布`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(p,{children:[(0,N.jsx)(f,{data:G.byModel,dataKey:`cost`,nameKey:`model`,cx:`50%`,cy:`50%`,outerRadius:80,label:({model:e,cost:t})=>`${e}: $${t.toFixed(4)}`,children:G.byModel.map((e,t)=>(0,N.jsx)(C,{fill:F[t%F.length]},t))}),(0,N.jsx)(T,{formatter:e=>`$${e.toFixed(4)}`})]})})})})]})]})]}),R===`pipelines`&&Q&&(0,N.jsxs)(`div`,{className:`space-y-6`,children:[(0,N.jsxs)(`div`,{className:`grid grid-cols-1 md:grid-cols-4 gap-4`,children:[(0,N.jsxs)(A,{className:`text-center`,children:[(0,N.jsx)(`div`,{className:`text-3xl font-bold text-blue-600`,children:Q.total}),(0,N.jsx)(`div`,{className:`text-sm text-gray-600 mt-1`,children:`总 Pipeline`})]}),(0,N.jsxs)(A,{className:`text-center`,children:[(0,N.jsxs)(`div`,{className:`text-3xl font-bold text-green-600`,children:[Q.completionRate,`%`]}),(0,N.jsx)(`div`,{className:`text-sm text-gray-600 mt-1`,children:`完成率`})]}),(0,N.jsxs)(A,{className:`text-center`,children:[(0,N.jsx)(`div`,{className:`text-3xl font-bold text-purple-600`,children:Q.avgNodes}),(0,N.jsx)(`div`,{className:`text-sm text-gray-600 mt-1`,children:`平均节点数`})]}),(0,N.jsxs)(A,{className:`text-center`,children:[(0,N.jsx)(`div`,{className:`text-3xl font-bold text-red-600`,children:Q.failed}),(0,N.jsx)(`div`,{className:`text-sm text-gray-600 mt-1`,children:`失败数`})]})]}),(0,N.jsx)(A,{title:`复杂度分布`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(v,{data:Object.entries(Q.complexityDist).map(([e,t])=>({name:e===`simple`?`简单`:e===`moderate`?`中等`:`复杂`,value:t})),children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`name`}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{}),(0,N.jsx)(b,{dataKey:`value`,name:`数量`,fill:`#667eea`})]})})})}),$.length>0&&(0,N.jsx)(A,{title:`质量问题趋势`,children:(0,N.jsx)(P,{children:(0,N.jsx)(d,{width:`100%`,height:250,children:(0,N.jsxs)(S,{data:$,children:[(0,N.jsx)(g,{strokeDasharray:`3 3`}),(0,N.jsx)(h,{dataKey:`date`}),(0,N.jsx)(m,{}),(0,N.jsx)(T,{}),(0,N.jsx)(w,{}),(0,N.jsx)(_,{type:`monotone`,dataKey:`total`,name:`总问题`,stroke:`#667eea`,strokeWidth:2}),(0,N.jsx)(_,{type:`monotone`,dataKey:`unresolved`,name:`未解决`,stroke:`#ef4444`,strokeWidth:2})]})})})})]})]})}export{I as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as e}from"./vendor-flow-srkes8If.js";var t=e();function n({total:e,done:n,label:r=`处理中`}){let i=e>0?Math.round(n/e*100):0;return(0,t.jsxs)(`div`,{className:`flex items-center gap-3 text-sm`,children:[(0,t.jsxs)(`span`,{className:`text-gray-500 whitespace-nowrap`,children:[r,` `,n,`/`,e]}),(0,t.jsx)(`div`,{className:`flex-1 h-1.5 bg-gray-100 rounded-full overflow-hidden min-w-[80px]`,children:(0,t.jsx)(`div`,{className:`h-full bg-blue-500 rounded-full transition-all duration-300`,style:{width:`${i}%`}})}),(0,t.jsxs)(`span`,{className:`text-gray-400 w-8 text-right`,children:[i,`%`]})]})}export{n as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{Qn as e}from"./vendor-DRGPi8ui.js";import{n as t}from"./vendor-react-DJI9oneq.js";import{c as n}from"./vendor-flow-srkes8If.js";var r=n();function i({items:n}){return(0,r.jsx)(`nav`,{className:`flex items-center gap-2 text-sm text-gray-600`,children:n.map((n,i)=>(0,r.jsxs)(`div`,{className:`flex items-center gap-2`,children:[i>0&&(0,r.jsx)(e,{className:`h-3.5 w-3.5 text-gray-400`}),n.path?(0,r.jsx)(t,{to:n.path,className:`hover:text-gray-900 transition-colors`,children:n.label}):(0,r.jsx)(`span`,{className:`text-gray-900 font-medium`,children:n.label})]},i))})}export{i as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-COnpUsM8.js";import{Bt as t,Cn as n,Gn as r,In as i,Lt as a,Nn as o,Pn as s,Qt as c,Rn as l,hn as u,mr as d,nn as f,qn as p,rn as m,s as h,tn as g,zn as _,zt as v}from"./vendor-BpBCrKSP.js";import{a as y,n as b,r as x}from"./vendor-query-BF-uT_c5.js";import{c as S}from"./vendor-flow-D-_WxBha.js";import{B as C,G as w,Gt as T,Ht as E,I as D,It as O,O as ee,Ot as k,V as A,en as j,et as M,f as N,jt as P,n as F,p as I,r as L,tt as R}from"./client-B_-7qCOP.js";import{a as z,n as B,r as V,t as H}from"./ui-B2gvOcFY.js";import{n as U,t as W}from"./vendor-motion-BsfSkSjj.js";import{t as te}from"./ConfirmDialog-CH1HyRaY.js";var G=e(d(),1),K=S();function ne({onConfirm:e}){let t=y(),[r,a]=(0,G.useState)(!1),[c,d]=(0,G.useState)(``),[f,p]=(0,G.useState)(!1),[g,_]=(0,G.useState)({}),{data:v,refetch:S}=x({queryKey:[`backups`],queryFn:()=>k().then(e=>e.data)}),{data:C}=x({queryKey:[`daemon-status`],queryFn:()=>w().then(e=>e.data)}),T=b({mutationFn:()=>L(r?{encrypt:!0,password:c}:{}),onSuccess:()=>{j(`备份创建成功`,`success`),d(``),a(!1),S()},onError:()=>j(`备份创建失败`,`error`)}),E=b({mutationFn:({filename:e,password:t})=>O(e,t),onSuccess:()=>{j(`数据库恢复成功,daemon 将自动重启`,`success`),t.clear()},onError:()=>j(`恢复失败,请检查密码或文件完整性`,`error`)});return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,K.jsx)(`div`,{className:`flex-shrink-0 w-10 h-10 rounded-full bg-blue-50 flex items-center justify-center`,children:(0,K.jsx)(n,{className:`h-5 w-5 text-blue-600`})}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`当前数据库`}),(0,K.jsxs)(`p`,{className:`text-sm text-gray-500 mt-1`,children:[`内存占用:`,C?.memory?`${(C.memory.heapUsed/1024/1024).toFixed(2)} MB`:`加载中...`]})]})]}),(0,K.jsxs)(`div`,{className:`flex flex-col items-end gap-2`,children:[(0,K.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,K.jsxs)(`label`,{className:`flex items-center gap-1.5 text-sm text-gray-600 cursor-pointer`,children:[(0,K.jsx)(`input`,{type:`checkbox`,checked:r,onChange:e=>a(e.target.checked),className:`rounded`}),(0,K.jsx)(u,{className:`h-3.5 w-3.5`}),`加密备份`]})}),r&&(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsx)(`input`,{type:f?`text`:`password`,placeholder:`备份密码(≥8位)`,value:c,onChange:e=>d(e.target.value),className:`px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 pr-8 w-48`}),(0,K.jsx)(`button`,{type:`button`,onClick:()=>p(e=>!e),className:`absolute right-2 top-1/2 -translate-y-1/2 text-gray-400`,children:f?(0,K.jsx)(s,{className:`h-3.5 w-3.5`}):(0,K.jsx)(o,{className:`h-3.5 w-3.5`})})]}),(0,K.jsx)(B,{variant:`primary`,size:`sm`,icon:l,onClick:()=>T.mutate(),loading:T.isPending,disabled:r&&c.length<8,children:`立即备份`})]})]})}),(0,K.jsxs)(V,{children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`备份历史`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:m,onClick:()=>void S(),children:`刷新`})]}),v&&v.items.length>0?(0,K.jsx)(`div`,{className:`space-y-2`,children:v.items.map(t=>(0,K.jsxs)(`div`,{className:`flex flex-col gap-2 py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900 truncate`,children:t.filename}),t.encrypted&&(0,K.jsxs)(`span`,{className:`flex items-center gap-0.5 text-xs text-amber-600 bg-amber-50 px-1.5 py-0.5 rounded`,children:[(0,K.jsx)(u,{className:`h-3 w-3`}),` 已加密`]}),!t.hasChecksum&&(0,K.jsx)(`span`,{className:`text-xs text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded`,children:`无校验`})]}),(0,K.jsxs)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:[h(new Date(t.createdAt),`yyyy-MM-dd HH:mm:ss`),` · `,t.sizeMb,` MB`]})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 ml-3 flex-shrink-0`,children:[(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`恢复数据库`,description:`确定要从 ${t.filename} 恢复数据库吗?当前数据库将被覆盖(会自动备份)。恢复后 daemon 将自动重启。`,onConfirm:()=>E.mutate({filename:t.filename,password:g[t.filename]})}),loading:E.isPending&&E.variables?.filename===t.filename,children:`恢复`}),(0,K.jsx)(`a`,{href:D(t.filename),download:t.filename,children:(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:i,children:`下载`})})]})]}),t.encrypted&&(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(u,{className:`h-3.5 w-3.5 text-amber-500 flex-shrink-0`}),(0,K.jsx)(`input`,{type:`password`,placeholder:`输入解密密码后点击恢复`,value:g[t.filename]||``,onChange:e=>_(n=>({...n,[t.filename]:e.target.value})),className:`flex-1 px-2 py-1 text-xs border border-amber-200 rounded focus:outline-none focus:ring-1 focus:ring-amber-400`})]})]},t.filename))}):(0,K.jsx)(`div`,{className:`text-center py-8 text-gray-400 text-sm`,children:`暂无备份记录`})]}),(0,K.jsxs)(V,{children:[(0,K.jsx)(`div`,{className:`flex items-center justify-between mb-4`,children:(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`数据管理`})}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:`清理历史事件`}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:`删除超过指定天数的事件记录`})]}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`清理历史事件`,description:`确定要清理 30 天前的事件记录吗?此操作不可撤销。`,onConfirm:()=>{F.post(`/events/purge`,{retentionDays:30}).then(()=>j(`事件清理完成`,`success`)).catch(()=>j(`事件清理失败`,`error`))}}),children:`清理 30 天前`})]}),(0,K.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:`数据库优化`}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:`执行 VACUUM 回收空间,提升性能`})]}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`数据库优化`,description:`确定要执行 VACUUM 优化吗?此操作可能需要几分钟。`,onConfirm:()=>{F.post(`/config/vacuum`).then(()=>j(`数据库优化完成`,`success`)).catch(()=>j(`数据库优化失败`,`error`))}}),children:`立即优化`})]})]})]})]})}function re({onConfirm:e}){let{data:t,refetch:n}=x({queryKey:[`memory-caches`],queryFn:()=>M().then(e=>e.data),refetchInterval:5e3}),{data:r}=x({queryKey:[`memory-process`],queryFn:()=>R().then(e=>e.data),refetchInterval:5e3}),i=b({mutationFn:e=>I(e),onSuccess:()=>{j(`缓存已清空`,`success`),n()},onError:()=>j(`清空失败`,`error`)}),a=b({mutationFn:()=>N(),onSuccess:()=>{j(`所有缓存已清空`,`success`),n()},onError:()=>j(`清空失败`,`error`)}),o=b({mutationFn:()=>E(),onSuccess:()=>j(`GC 已触发`,`success`),onError:()=>j(`GC 触发失败`,`error`)});return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between mb-4`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,K.jsx)(`div`,{className:`flex-shrink-0 w-10 h-10 rounded-full bg-purple-50 flex items-center justify-center`,children:(0,K.jsx)(_,{className:`h-5 w-5 text-purple-600`})}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`进程内存`}),r&&(0,K.jsxs)(`div`,{className:`text-sm text-gray-600 mt-2 space-y-1`,children:[(0,K.jsxs)(`div`,{children:[`RSS: `,r.rssMB,` MB`]}),(0,K.jsxs)(`div`,{children:[`堆已用: `,r.heapUsedMB,` MB / `,r.heapTotalMB,` MB`]}),(0,K.jsxs)(`div`,{children:[`外部: `,r.externalMB,` MB`]})]})]})]}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>o.mutate(),loading:o.isPending,children:`触发 GC`})]})}),(0,K.jsxs)(V,{children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`LRU 缓存`}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:m,onClick:()=>void n(),children:`刷新`}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`清空所有缓存`,description:`确定要清空所有 LRU 缓存吗?`,onConfirm:()=>a.mutate()}),loading:a.isPending,children:`清空全部`})]})]}),t&&t.caches.length>0?(0,K.jsx)(`div`,{className:`space-y-2`,children:t.caches.map(e=>(0,K.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{className:`flex-1`,children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:e.name}),(0,K.jsxs)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:[e.size,` / `,e.maxSize,` 条`,e.hitRate!==void 0&&` · 命中率 ${(e.hitRate*100).toFixed(1)}%`]})]}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,onClick:()=>i.mutate(e.name),loading:i.isPending&&i.variables===e.name,children:`清空`})]},e.name))}):(0,K.jsx)(`div`,{className:`text-center py-8 text-gray-400 text-sm`,children:`暂无缓存数据`})]})]})}function ie({currentConfig:e,onRestore:t,onConfirm:n}){let[r,i]=(0,G.useState)(null),{data:a}=x({queryKey:[`config-history`],queryFn:()=>A().then(e=>e.data)});return(0,K.jsxs)(V,{children:[(0,K.jsx)(`div`,{className:`flex items-center justify-between mb-4`,children:(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`最近 10 次配置变更`})}),a&&a.items.length>0?(0,K.jsx)(`div`,{className:`space-y-2`,children:a.items.map(a=>{let o=r===String(a.id),s=e,c=[];if(o&&s){let e=(t,n=``)=>typeof t!=`object`||!t?{[n]:JSON.stringify(t)}:Object.entries(t).reduce((t,[r,i])=>{let a=n?`${n}.${r}`:r;return typeof i==`object`&&i&&!Array.isArray(i)?Object.assign(t,e(i,a)):t[a]=JSON.stringify(i),t},{}),t=e(a.config),n=e(s);new Set([...Object.keys(t),...Object.keys(n)]).forEach(e=>{let r=t[e]??`(无)`,i=n[e]??`(无)`;r!==i&&c.push({key:e,old:r,cur:i})})}return(0,K.jsxs)(`div`,{className:`py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsxs)(`span`,{className:`text-sm font-medium text-gray-900`,children:[`#`,a.id]}),(0,K.jsx)(`span`,{className:`text-xs text-gray-500`,children:h(new Date(a.savedAt),`yyyy-MM-dd HH:mm:ss`)})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(B,{variant:`ghost`,size:`sm`,onClick:()=>i(o?null:String(a.id)),children:o?`收起对比`:`与当前对比`}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>n({title:`确认恢复配置`,description:`确定要恢复到 ${h(new Date(a.savedAt),`yyyy-MM-dd HH:mm:ss`)} 的配置吗?当前配置将被覆盖。`,onConfirm:()=>t(a.config)}),children:`恢复到此版本`})]})]}),(0,K.jsx)(U,{children:o&&(0,K.jsx)(W.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},transition:{duration:.2},className:`overflow-hidden`,children:(0,K.jsxs)(`div`,{className:`mt-3 rounded border border-gray-200 overflow-hidden text-xs font-mono`,children:[(0,K.jsxs)(`div`,{className:`grid grid-cols-3 bg-gray-100 px-3 py-1.5 text-gray-500 font-medium text-xs`,children:[(0,K.jsx)(`span`,{children:`配置项`}),(0,K.jsx)(`span`,{className:`text-red-600`,children:`历史值`}),(0,K.jsx)(`span`,{className:`text-green-600`,children:`当前值`})]}),c.length===0?(0,K.jsx)(`div`,{className:`px-3 py-3 text-gray-400 text-center`,children:`与当前配置完全一致`}):c.map(({key:e,old:t,cur:n})=>(0,K.jsxs)(`div`,{className:`grid grid-cols-3 px-3 py-2 border-t border-gray-100 hover:bg-gray-50`,children:[(0,K.jsx)(`span`,{className:`text-gray-700 truncate`,children:e}),(0,K.jsx)(`span`,{className:`text-red-600 truncate`,children:t}),(0,K.jsx)(`span`,{className:`text-green-600 truncate`,children:n})]},e))]})})})]},a.id)})}):(0,K.jsx)(`div`,{className:`text-center py-8 text-gray-400 text-sm`,children:`暂无历史记录`})]})}function ae({content:e,children:t,className:n}){let[r,i]=(0,G.useState)(!1),[a,o]=(0,G.useState)(`top`),s=(0,G.useRef)(null);return(0,G.useEffect)(()=>{r&&s.current&&o(s.current.getBoundingClientRect().top<80?`bottom`:`top`)},[r]),(0,K.jsxs)(`span`,{ref:s,className:z(`relative inline-flex items-center cursor-help`,n),onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),children:[t,r&&(0,K.jsx)(`span`,{className:z(`absolute z-50 w-max max-w-xs px-2.5 py-1.5 text-xs text-white bg-gray-800 rounded-lg shadow-lg pointer-events-none whitespace-normal`,a===`top`?`bottom-full mb-1.5 left-1/2 -translate-x-1/2`:`top-full mt-1.5 left-1/2 -translate-x-1/2`),children:e})]})}var q={Pipeline:`自动化工作流,将需求分解为多个节点依次执行`,Daemon:`后台守护进程,监听 Claude Code 事件并驱动编排引擎`,Hook:`Claude Code 生命周期钩子,在工具调用前后触发`,Distill:`将会话事件提炼为结构化知识,沉淀到知识图谱`,"Quality Gate":`质量门禁,在关键节点检测代码/文档质量问题`,Convention:`项目规范配置,定义节点类型、技能绑定和质量标准`,Skill:`可复用的 Claude Code 技能脚本,绑定到 Pipeline 节点`,ROI:`投资回报率,统计 AI 辅助节省的时间和 Token 用量`,Token:`LLM 处理的最小文本单元,影响 API 调用成本`,SSE:`Server-Sent Events,服务端向客户端推送实时事件的协议`},J=[{key:`distill`,title:`蒸馏配置`,description:`AI 知识蒸馏的触发条件和参数`,fields:[{key:`provider`,label:`提供商`,type:`select`,options:[{value:`claude`,label:`Claude`},{value:`openai`,label:`OpenAI`},{value:`ollama`,label:`Ollama`}]},{key:`auto_trigger`,label:`自动触发`,type:`boolean`,description:`达到事件阈值时自动蒸馏`},{key:`event_threshold`,label:`事件阈值`,type:`number`,description:`触发蒸馏的最小事件数`,min:1,max:1e4},{key:`timer_interval_minutes`,label:`定时器间隔(分钟)`,type:`number`,min:1,max:1440},{key:`model`,label:`模型`,type:`text`},{key:`api_key`,label:`API Key`,type:`text`,sensitive:!0,description:`留空自动从环境变量获取`},{key:`base_url`,label:`API 地址`,type:`text`,description:`留空使用默认地址`}]},{key:`autopilot`,title:`自动驾驶`,description:`意图分析、质量门禁、Pipeline 编排`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`intent_analysis`,label:`意图分析`,type:`boolean`,description:`AI 分析用户意图和任务复杂度`},{key:`quality_gate`,label:`质量门禁`,type:`boolean`,description:`代码变更时自动审查质量`},{key:`quality_review_interval`,label:`审查间隔`,type:`number`,description:`每 N 次 Write/Edit 触发一次审查`,min:1,max:100},{key:`auto_start_pipeline`,label:`自动启动流水线`,type:`boolean`},{key:`pipeline_confirm_mode`,label:`确认模式`,type:`select`,options:[{value:`prompt`,label:`提示确认`},{value:`auto`,label:`自动启动`},{value:`preview`,label:`仅预览`}]}]},{key:`resume`,title:`会话续接`,description:`中断会话的自动恢复`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`timeout_minutes`,label:`超时时间(分钟)`,type:`number`,min:1,max:1440},{key:`max_age_days`,label:`最大保留天数`,type:`number`,min:1,max:365}]},{key:`claudemd`,title:`CLAUDE.md 管理`,description:`项目级 CLAUDE.md 的自动生成与精炼`,fields:[{key:`auto_generate`,label:`自动生成`,type:`boolean`},{key:`auto_refine`,label:`自动精炼`,type:`boolean`},{key:`refine_interval`,label:`精炼间隔`,type:`number`,description:`每 N 次蒸馏后精炼一次`,min:1,max:100}]},{key:`orchestration`,title:`编排通知`,description:`蒸馏和 CLAUDE.md 更新的通知`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`notify_on_distill`,label:`蒸馏完成通知`,type:`boolean`},{key:`notify_on_claudemd`,label:`CLAUDE.md 更新通知`,type:`boolean`}]},{key:`web`,title:`Web 管理后台`,description:`Web 服务配置`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`port`,label:`端口`,type:`number`,min:1024,max:65535}]},{key:`ai`,title:`AI 模型`,description:`分层模型配置(Haiku/Sonnet/Opus)`,fields:[{key:`models.haiku`,label:`Haiku 模型`,type:`text`},{key:`models.sonnet`,label:`Sonnet 模型`,type:`text`},{key:`models.opus`,label:`Opus 模型`,type:`text`}]},{key:`storage`,title:`存储`,description:`数据库路径和容量限制`,fields:[{key:`path`,label:`数据库路径`,type:`text`},{key:`max_size_mb`,label:`最大容量(MB)`,type:`number`,min:100,max:102400}]},{key:`backup`,title:`备份配置`,description:`数据备份策略`,fields:[{key:`include_profile`,label:`包含用户画像`,type:`boolean`,description:`备份时包含用户画像数据`},{key:`encrypt_by_default`,label:`默认加密`,type:`boolean`,description:`备份文件默认加密`}]},{key:`pattern_engine`,title:`模式引擎`,description:`模式识别与演化配置`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`route_timeout_ms`,label:`路由超时(毫秒)`,type:`number`,min:100,max:6e4},{key:`evolve_interval_days`,label:`演化间隔(天)`,type:`number`,min:1,max:365},{key:`evolve_min_executions`,label:`最小执行次数`,type:`number`,description:`触发演化的最小执行次数`,min:1,max:1e3}]},{key:`ui`,title:`UI 配置`,description:`前端界面参数`,fields:[{key:`skill_repair_limit`,label:`Skill 修复上限`,type:`number`,min:1,max:100},{key:`logs_tail_default`,label:`日志默认条数`,type:`number`,min:10,max:1e3},{key:`pipeline_expire_hours`,label:`Pipeline 过期时间(小时)`,type:`number`,min:1,max:720}]},{key:`history`,title:`配置历史`,description:`查看最近 10 次配置变更记录`,fields:[]}];function Y(){let e=y(),[n,o]=(0,G.useState)(null),[s,l]=(0,G.useState)(`idle`),[u,d]=(0,G.useState)(`distill`),[h,_]=(0,G.useState)(new Set),S=h.size>0,[w,E]=(0,G.useState)(null),[D,O]=(0,G.useState)(new Set),[k,A]=(0,G.useState)({open:!1,title:``,description:``,onConfirm:()=>{}}),{data:M,isLoading:N}=x({queryKey:[`config`],queryFn:()=>C().then(e=>e.data)}),{data:I,refetch:L}=x({queryKey:[`daemon-diagnosis`],queryFn:()=>ee().then(e=>e.data),enabled:u===`environment`}),R=b({mutationFn:()=>P(),onSuccess:e=>{E(e.data),L()}});(0,G.useEffect)(()=>{M&&!n&&o(M)},[M,n]);let Y=b({mutationFn:e=>T(e),onSuccess:()=>{e.invalidateQueries({queryKey:[`config`]}),l(`success`),_(new Set),setTimeout(()=>l(`idle`),3e3)},onError:()=>{l(`error`),setTimeout(()=>l(`idle`),3e3)}}),X=b({mutationFn:()=>F.post(`/config/reset`),onSuccess:()=>{e.invalidateQueries({queryKey:[`config`]}),o(null),l(`success`),setTimeout(()=>l(`idle`),3e3)}});if(N||!n)return(0,K.jsx)(`div`,{className:`flex items-center justify-center h-96`,children:(0,K.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600`})});let Z=(e,t)=>{let r=n[e];if(!r)return``;let i=t.split(`.`),a=r;for(let e of i)a=a?.[e];return a??``},Q=(e,t,n)=>{_(t=>new Set(t).add(e)),o(r=>{if(!r)return r;let i={...r[e]||{}},a=t.split(`.`);if(a.length===1)i[t]=n;else{let e={...i[a[0]]||{}};e[a[1]]=n,i[a[0]]=e}return{...r,[e]:i}})},oe=()=>{if(!n)return;let e={};h.forEach(t=>{e[t]=n[t]}),Y.mutate(e)},se=()=>{o(M),_(new Set)},ce=()=>{let e=JSON.stringify(n,null,2),t=new Blob([e],{type:`application/json`}),r=URL.createObjectURL(t),i=document.createElement(`a`);i.href=r,i.download=`claude-forge-config-${new Date().toISOString().slice(0,10)}.json`,i.click(),URL.revokeObjectURL(r)},le=()=>{let e=document.createElement(`input`);e.type=`file`,e.accept=`.json`,e.onchange=e=>{let t=e.target.files?.[0];if(!t)return;let n=new FileReader;n.onload=e=>{try{o(JSON.parse(e.target?.result)),_(new Set(J.map(e=>e.key)))}catch{j(`配置文件格式错误,请选择有效的 JSON 文件`,`error`)}},n.readAsText(t)},e.click()},$=J.find(e=>e.key===u);return(0,K.jsxs)(`div`,{className:`flex gap-6`,children:[(0,K.jsx)(`div`,{className:`w-56 flex-shrink-0`,children:(0,K.jsx)(V,{className:`!p-2 sticky top-6`,children:(0,K.jsxs)(`nav`,{className:`space-y-1`,children:[J.map(e=>(0,K.jsx)(`button`,{onClick:()=>d(e.key),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors`,u===e.key?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:q[e.title]?(0,K.jsx)(ae,{content:q[e.title],children:e.title}):e.title},e.key)),(0,K.jsx)(`div`,{className:`border-t border-gray-100 my-1`}),(0,K.jsxs)(`button`,{onClick:()=>d(`backup_mgmt`),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors flex items-center gap-2`,u===`backup_mgmt`?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:[(0,K.jsx)(Database,{className:`h-3.5 w-3.5`}),`数据备份`]}),(0,K.jsxs)(`button`,{onClick:()=>d(`memory_mgmt`),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors flex items-center gap-2`,u===`memory_mgmt`?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:[(0,K.jsx)(Cpu,{className:`h-3.5 w-3.5`}),`内存管理`]}),(0,K.jsxs)(`button`,{onClick:()=>d(`environment`),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors flex items-center gap-2`,u===`environment`?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:[(0,K.jsx)(c,{className:`h-3.5 w-3.5`}),`环境检测`]})]})})}),(0,K.jsxs)(`div`,{className:`flex-1 space-y-6`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h2`,{className:`text-lg font-semibold text-gray-900`,children:u===`environment`?`环境检测`:u===`backup_mgmt`?`数据备份`:u===`memory_mgmt`?`内存管理`:u===`history`?`配置历史`:$?.title}),(0,K.jsx)(`p`,{className:`text-sm text-gray-500`,children:u===`environment`?`Hook 脚本与 Claude settings.json 注入状态检测与修复`:u===`backup_mgmt`?`数据库备份与历史备份管理`:u===`memory_mgmt`?`LRU 缓存状态与进程内存管理`:u===`history`?`查看最近 10 次配置变更记录`:$?.description??``})]}),u!==`environment`&&u!==`backup_mgmt`&&u!==`memory_mgmt`&&u!==`history`&&(0,K.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,K.jsxs)(U,{children:[s===`success`&&(0,K.jsxs)(W.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0},className:`flex items-center gap-1.5 text-green-600 text-sm`,children:[(0,K.jsx)(p,{className:`h-4 w-4`}),`已保存`]}),s===`error`&&(0,K.jsxs)(W.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0},className:`flex items-center gap-1.5 text-red-600 text-sm`,children:[(0,K.jsx)(r,{className:`h-4 w-4`}),`保存失败`]})]}),S&&(0,K.jsx)(H,{variant:`warning`,children:`未保存`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:i,onClick:ce,children:`导出`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:v,onClick:le,children:`导入`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:f,onClick:se,disabled:!S,children:`撤销`}),(0,K.jsx)(B,{variant:`primary`,size:`sm`,icon:g,onClick:oe,loading:Y.isPending,disabled:!S,children:`保存`})]})]}),u!==`environment`&&u!==`backup_mgmt`&&u!==`memory_mgmt`&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(V,{children:(0,K.jsx)(`div`,{className:`space-y-6`,children:$?.fields.map(e=>(0,K.jsxs)(`div`,{className:`flex items-start gap-4`,children:[(0,K.jsxs)(`div`,{className:`w-48 flex-shrink-0 pt-2`,children:[(0,K.jsx)(`label`,{className:`text-sm font-medium text-gray-700`,children:e.label}),e.description&&(0,K.jsx)(`p`,{className:`text-xs text-gray-400 mt-0.5`,children:e.description})]}),(0,K.jsx)(`div`,{className:`flex-1`,children:e.type===`boolean`?(0,K.jsx)(`button`,{onClick:()=>Q(u,e.key,!Z(u,e.key)),className:z(`relative inline-flex h-6 w-11 items-center rounded-full transition-colors`,Z(u,e.key)?`bg-blue-600`:`bg-gray-300`),children:(0,K.jsx)(`span`,{className:z(`inline-block h-4 w-4 transform rounded-full bg-white transition-transform`,Z(u,e.key)?`translate-x-6`:`translate-x-1`)})}):e.type===`select`?(0,K.jsx)(`select`,{value:String(Z(u,e.key)||``),onChange:t=>Q(u,e.key,t.target.value),className:`w-full max-w-xs px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm`,children:e.options?.map(e=>(0,K.jsx)(`option`,{value:e.value,children:e.label},e.value))}):e.type===`number`?(0,K.jsx)(`input`,{type:`number`,value:Number(Z(u,e.key))||0,onChange:t=>Q(u,e.key,Number(t.target.value)),min:e.min,max:e.max,className:`w-full max-w-xs px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm`}):(0,K.jsxs)(`div`,{className:`relative flex items-center max-w-xs`,children:[(0,K.jsx)(`input`,{type:e.sensitive&&!D.has(`${u}.${e.key}`)?`password`:`text`,value:String(Z(u,e.key)||``),onChange:t=>Q(u,e.key,t.target.value),className:`w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm pr-9`}),e.sensitive&&(0,K.jsx)(`button`,{type:`button`,onClick:()=>O(t=>{let n=new Set(t),r=`${u}.${e.key}`;return n.has(r)?n.delete(r):n.add(r),n}),className:`absolute right-2 text-gray-400 hover:text-gray-600`,children:D.has(`${u}.${e.key}`)?(0,K.jsx)(EyeOff,{className:`h-4 w-4`}):(0,K.jsx)(Eye,{className:`h-4 w-4`})})]})})]},e.key))})}),(0,K.jsx)(V,{className:`!border-red-200`,children:(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`text-sm font-semibold text-red-600`,children:`重置配置`}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-1`,children:`将所有配置恢复为默认值,此操作不可撤销`})]}),(0,K.jsx)(B,{variant:`danger`,size:`sm`,icon:t,onClick:()=>{A({open:!0,title:`重置配置`,description:`确定要重置所有配置为默认值吗?此操作不可撤销。`,onConfirm:()=>{X.mutate(),A({...k,open:!1})}})},loading:X.isPending,children:`重置`})]})})]}),u===`backup_mgmt`&&(0,K.jsx)(ne,{onConfirm:e=>A({...e,open:!0})}),u===`memory_mgmt`&&(0,K.jsx)(re,{onConfirm:e=>A({...e,open:!0})}),u===`history`&&(0,K.jsx)(ie,{currentConfig:M,onRestore:e=>Y.mutate(e),onConfirm:e=>A({...e,open:!0})}),u===`environment`&&(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900 mb-1`,children:`Hook 环境诊断`}),(0,K.jsx)(`p`,{className:`text-sm text-gray-500`,children:`检测 Forge hooks 脚本与 Claude settings.json 中 Forge 注入是否完整`})]}),(0,K.jsxs)(`div`,{className:`flex gap-2 flex-shrink-0`,children:[(0,K.jsx)(B,{variant:`secondary`,size:`sm`,icon:m,onClick:()=>L(),children:`重新检测`}),(0,K.jsx)(B,{size:`sm`,icon:a,onClick:()=>R.mutate(),disabled:R.isPending||I?.hooksHealthy,children:R.isPending?`修复中...`:`一键修复`})]})]})}),w&&(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-2`,children:[w.hooksHealthy?(0,K.jsx)(p,{className:`h-4 w-4 text-green-500 mt-0.5 flex-shrink-0`}):(0,K.jsx)(t,{className:`h-4 w-4 text-yellow-500 mt-0.5 flex-shrink-0`}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:z(`text-sm font-medium`,w.hooksHealthy?`text-gray-900`:`text-yellow-600`),children:w.hooksHealthy?`Hooks 环境已恢复正常`:`修复后仍有未通过项,请根据下方列表排查`}),w.backupPath&&(0,K.jsxs)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:[`已备份 settings: `,w.backupPath.split(`/`).pop()]})]})]}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:r,onClick:()=>E(null)})]})}),I&&(0,K.jsx)(V,{children:(0,K.jsx)(`div`,{className:`space-y-2`,children:I.items.map(e=>(0,K.jsxs)(`div`,{className:`flex items-start gap-3 py-2 border-b border-gray-50 last:border-0`,children:[(0,K.jsx)(`div`,{className:`flex-shrink-0 mt-0.5`,children:e.ok?(0,K.jsx)(p,{className:`h-4 w-4 text-green-500`}):e.id===`daemon_process`?(0,K.jsx)(t,{className:`h-4 w-4 text-yellow-500`}):(0,K.jsx)(r,{className:`h-4 w-4 text-red-500`})}),(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:e.label}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5 break-all`,children:e.detail})]})]},e.id))})}),I&&(0,K.jsx)(V,{className:I.hooksHealthy?`!border-green-200 !bg-green-50`:`!border-yellow-200 !bg-yellow-50`,children:(0,K.jsx)(`div`,{className:`flex items-center gap-2`,children:I.hooksHealthy?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(p,{className:`h-5 w-5 text-green-600`}),(0,K.jsx)(`p`,{className:`text-sm font-medium text-green-700`,children:`Hooks 相关环境正常`})]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(t,{className:`h-5 w-5 text-yellow-600`}),(0,K.jsx)(`p`,{className:`text-sm font-medium text-yellow-700`,children:`检测到 Hooks 环境不完整,请点击「一键修复」`})]})})})]})]}),(0,K.jsx)(te,{open:k.open,title:k.title,description:k.description,variant:`danger`,onConfirm:k.onConfirm,onCancel:()=>A({...k,open:!1})})]})}export{Y as default};
|
|
1
|
+
import{a as e}from"./rolldown-runtime-COnpUsM8.js";import{Bn as t,Bt as n,Fn as r,In as i,Lt as a,Qt as o,Rn as s,Tn as c,Vn as l,Yn as u,gr as d,hn as f,nn as p,qn as m,rn as h,s as g,tn as _,zt as v}from"./vendor-DRGPi8ui.js";import{a as y,n as b,r as x}from"./vendor-query-DqPOMnuX.js";import{c as S}from"./vendor-flow-srkes8If.js";import{A as C,Bt as w,Gt as T,H as E,Lt as D,Qt as O,R as k,U as A,a as j,at as M,h as N,it as P,m as F,q as I,r as L,tn as ee,un as R}from"./client-BhcjNvkG.js";import{a as z,n as B,r as V,t as te}from"./ui-CDL3BZ13.js";import{n as H,t as U}from"./vendor-motion-CQmdgnI8.js";import{t as W}from"./ConfirmDialog-CVzB7X5y.js";var G=e(d(),1),K=S();function ne({onConfirm:e}){let n=y(),[a,o]=(0,G.useState)(!1),[l,u]=(0,G.useState)(``),[d,p]=(0,G.useState)(!1),[m,_]=(0,G.useState)({}),{data:v,refetch:S}=x({queryKey:[`backups`],queryFn:()=>D().then(e=>e.data)}),{data:C}=x({queryKey:[`daemon-status`],queryFn:()=>I().then(e=>e.data)}),w=b({mutationFn:()=>j(a?{encrypt:!0,password:l}:{}),onSuccess:()=>{R(`备份创建成功`,`success`),u(``),o(!1),S()},onError:()=>R(`备份创建失败`,`error`)}),E=b({mutationFn:({filename:e,password:t})=>T(e,t),onSuccess:()=>{R(`数据库恢复成功,daemon 将自动重启`,`success`),n.clear()},onError:()=>R(`恢复失败,请检查密码或文件完整性`,`error`)});return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,K.jsx)(`div`,{className:`flex-shrink-0 w-10 h-10 rounded-full bg-blue-50 flex items-center justify-center`,children:(0,K.jsx)(c,{className:`h-5 w-5 text-blue-600`})}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`当前数据库`}),(0,K.jsxs)(`p`,{className:`text-sm text-gray-500 mt-1`,children:[`内存占用:`,C?.memory?`${(C.memory.heapUsed/1024/1024).toFixed(2)} MB`:`加载中...`]})]})]}),(0,K.jsxs)(`div`,{className:`flex flex-col items-end gap-2`,children:[(0,K.jsx)(`div`,{className:`flex items-center gap-2`,children:(0,K.jsxs)(`label`,{className:`flex items-center gap-1.5 text-sm text-gray-600 cursor-pointer`,children:[(0,K.jsx)(`input`,{type:`checkbox`,checked:a,onChange:e=>o(e.target.checked),className:`rounded`}),(0,K.jsx)(f,{className:`h-3.5 w-3.5`}),`加密备份`]})}),a&&(0,K.jsxs)(`div`,{className:`relative`,children:[(0,K.jsx)(`input`,{type:d?`text`:`password`,placeholder:`备份密码(≥8位)`,value:l,onChange:e=>u(e.target.value),className:`px-3 py-1.5 text-sm border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 pr-8 w-48`}),(0,K.jsx)(`button`,{type:`button`,onClick:()=>p(e=>!e),className:`absolute right-2 top-1/2 -translate-y-1/2 text-gray-400`,children:d?(0,K.jsx)(i,{className:`h-3.5 w-3.5`}):(0,K.jsx)(r,{className:`h-3.5 w-3.5`})})]}),(0,K.jsx)(B,{variant:`primary`,size:`sm`,icon:t,onClick:()=>w.mutate(),loading:w.isPending,disabled:a&&l.length<8,children:`立即备份`})]})]})}),(0,K.jsxs)(V,{children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`备份历史`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:h,onClick:()=>void S(),children:`刷新`})]}),v&&v.items.length>0?(0,K.jsx)(`div`,{className:`space-y-2`,children:v.items.map(t=>(0,K.jsxs)(`div`,{className:`flex flex-col gap-2 py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900 truncate`,children:t.filename}),t.encrypted&&(0,K.jsxs)(`span`,{className:`flex items-center gap-0.5 text-xs text-amber-600 bg-amber-50 px-1.5 py-0.5 rounded`,children:[(0,K.jsx)(f,{className:`h-3 w-3`}),` 已加密`]}),!t.hasChecksum&&(0,K.jsx)(`span`,{className:`text-xs text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded`,children:`无校验`})]}),(0,K.jsxs)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:[g(new Date(t.createdAt),`yyyy-MM-dd HH:mm:ss`),` · `,t.sizeMb,` MB`]})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2 ml-3 flex-shrink-0`,children:[(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`恢复数据库`,description:`确定要从 ${t.filename} 恢复数据库吗?当前数据库将被覆盖(会自动备份)。恢复后 daemon 将自动重启。`,onConfirm:()=>E.mutate({filename:t.filename,password:m[t.filename]})}),loading:E.isPending&&E.variables?.filename===t.filename,children:`恢复`}),(0,K.jsx)(`a`,{href:k(t.filename),download:t.filename,children:(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:s,children:`下载`})})]})]}),t.encrypted&&(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(f,{className:`h-3.5 w-3.5 text-amber-500 flex-shrink-0`}),(0,K.jsx)(`input`,{type:`password`,placeholder:`输入解密密码后点击恢复`,value:m[t.filename]||``,onChange:e=>_(n=>({...n,[t.filename]:e.target.value})),className:`flex-1 px-2 py-1 text-xs border border-amber-200 rounded focus:outline-none focus:ring-1 focus:ring-amber-400`})]})]},t.filename))}):(0,K.jsx)(`div`,{className:`text-center py-8 text-gray-400 text-sm`,children:`暂无备份记录`})]}),(0,K.jsxs)(V,{children:[(0,K.jsx)(`div`,{className:`flex items-center justify-between mb-4`,children:(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`数据管理`})}),(0,K.jsxs)(`div`,{className:`space-y-3`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:`清理历史事件`}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:`删除超过指定天数的事件记录`})]}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`清理历史事件`,description:`确定要清理 30 天前的事件记录吗?此操作不可撤销。`,onConfirm:()=>{L.post(`/events/purge`,{retentionDays:30}).then(()=>R(`事件清理完成`,`success`)).catch(()=>R(`事件清理失败`,`error`))}}),children:`清理 30 天前`})]}),(0,K.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:`数据库优化`}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:`执行 VACUUM 回收空间,提升性能`})]}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`数据库优化`,description:`确定要执行 VACUUM 优化吗?此操作可能需要几分钟。`,onConfirm:()=>{L.post(`/config/vacuum`).then(()=>R(`数据库优化完成`,`success`)).catch(()=>R(`数据库优化失败`,`error`))}}),children:`立即优化`})]})]})]})]})}function re({onConfirm:e}){let{data:t,refetch:n}=x({queryKey:[`memory-caches`],queryFn:()=>P().then(e=>e.data),refetchInterval:5e3}),{data:r}=x({queryKey:[`memory-process`],queryFn:()=>M().then(e=>e.data),refetchInterval:5e3}),i=b({mutationFn:e=>N(e),onSuccess:()=>{R(`缓存已清空`,`success`),n()},onError:()=>R(`清空失败`,`error`)}),a=b({mutationFn:()=>F(),onSuccess:()=>{R(`所有缓存已清空`,`success`),n()},onError:()=>R(`清空失败`,`error`)}),o=b({mutationFn:()=>O(),onSuccess:()=>R(`GC 已触发`,`success`),onError:()=>R(`GC 触发失败`,`error`)});return(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between mb-4`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,K.jsx)(`div`,{className:`flex-shrink-0 w-10 h-10 rounded-full bg-purple-50 flex items-center justify-center`,children:(0,K.jsx)(l,{className:`h-5 w-5 text-purple-600`})}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`进程内存`}),r&&(0,K.jsxs)(`div`,{className:`text-sm text-gray-600 mt-2 space-y-1`,children:[(0,K.jsxs)(`div`,{children:[`RSS: `,r.rssMB,` MB`]}),(0,K.jsxs)(`div`,{children:[`堆已用: `,r.heapUsedMB,` MB / `,r.heapTotalMB,` MB`]}),(0,K.jsxs)(`div`,{children:[`外部: `,r.externalMB,` MB`]})]})]})]}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>o.mutate(),loading:o.isPending,children:`触发 GC`})]})}),(0,K.jsxs)(V,{children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between mb-4`,children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`LRU 缓存`}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:h,onClick:()=>void n(),children:`刷新`}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>e({title:`清空所有缓存`,description:`确定要清空所有 LRU 缓存吗?`,onConfirm:()=>a.mutate()}),loading:a.isPending,children:`清空全部`})]})]}),t&&t.caches.length>0?(0,K.jsx)(`div`,{className:`space-y-2`,children:t.caches.map(e=>(0,K.jsxs)(`div`,{className:`flex items-center justify-between py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{className:`flex-1`,children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:e.name}),(0,K.jsxs)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:[e.size,` / `,e.maxSize,` 条`,e.hitRate!==void 0&&` · 命中率 ${(e.hitRate*100).toFixed(1)}%`]})]}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,onClick:()=>i.mutate(e.name),loading:i.isPending&&i.variables===e.name,children:`清空`})]},e.name))}):(0,K.jsx)(`div`,{className:`text-center py-8 text-gray-400 text-sm`,children:`暂无缓存数据`})]})]})}function ie({currentConfig:e,onRestore:t,onConfirm:n}){let[r,i]=(0,G.useState)(null),{data:a}=x({queryKey:[`config-history`],queryFn:()=>A().then(e=>e.data)});return(0,K.jsxs)(V,{children:[(0,K.jsx)(`div`,{className:`flex items-center justify-between mb-4`,children:(0,K.jsx)(`h3`,{className:`font-medium text-gray-900`,children:`最近 10 次配置变更`})}),a&&a.items.length>0?(0,K.jsx)(`div`,{className:`space-y-2`,children:a.items.map(a=>{let o=r===String(a.id),s=e,c=[];if(o&&s){let e=(t,n=``)=>typeof t!=`object`||!t?{[n]:JSON.stringify(t)}:Object.entries(t).reduce((t,[r,i])=>{let a=n?`${n}.${r}`:r;return typeof i==`object`&&i&&!Array.isArray(i)?Object.assign(t,e(i,a)):t[a]=JSON.stringify(i),t},{}),t=e(a.config),n=e(s);new Set([...Object.keys(t),...Object.keys(n)]).forEach(e=>{let r=t[e]??`(无)`,i=n[e]??`(无)`;r!==i&&c.push({key:e,old:r,cur:i})})}return(0,K.jsxs)(`div`,{className:`py-3 px-4 bg-gray-50 rounded-lg`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsxs)(`span`,{className:`text-sm font-medium text-gray-900`,children:[`#`,a.id]}),(0,K.jsx)(`span`,{className:`text-xs text-gray-500`,children:g(new Date(a.savedAt),`yyyy-MM-dd HH:mm:ss`)})]}),(0,K.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,K.jsx)(B,{variant:`ghost`,size:`sm`,onClick:()=>i(o?null:String(a.id)),children:o?`收起对比`:`与当前对比`}),(0,K.jsx)(B,{variant:`outline`,size:`sm`,onClick:()=>n({title:`确认恢复配置`,description:`确定要恢复到 ${g(new Date(a.savedAt),`yyyy-MM-dd HH:mm:ss`)} 的配置吗?当前配置将被覆盖。`,onConfirm:()=>t(a.config)}),children:`恢复到此版本`})]})]}),(0,K.jsx)(H,{children:o&&(0,K.jsx)(U.div,{initial:{height:0,opacity:0},animate:{height:`auto`,opacity:1},exit:{height:0,opacity:0},transition:{duration:.2},className:`overflow-hidden`,children:(0,K.jsxs)(`div`,{className:`mt-3 rounded border border-gray-200 overflow-hidden text-xs font-mono`,children:[(0,K.jsxs)(`div`,{className:`grid grid-cols-3 bg-gray-100 px-3 py-1.5 text-gray-500 font-medium text-xs`,children:[(0,K.jsx)(`span`,{children:`配置项`}),(0,K.jsx)(`span`,{className:`text-red-600`,children:`历史值`}),(0,K.jsx)(`span`,{className:`text-green-600`,children:`当前值`})]}),c.length===0?(0,K.jsx)(`div`,{className:`px-3 py-3 text-gray-400 text-center`,children:`与当前配置完全一致`}):c.map(({key:e,old:t,cur:n})=>(0,K.jsxs)(`div`,{className:`grid grid-cols-3 px-3 py-2 border-t border-gray-100 hover:bg-gray-50`,children:[(0,K.jsx)(`span`,{className:`text-gray-700 truncate`,children:e}),(0,K.jsx)(`span`,{className:`text-red-600 truncate`,children:t}),(0,K.jsx)(`span`,{className:`text-green-600 truncate`,children:n})]},e))]})})})]},a.id)})}):(0,K.jsx)(`div`,{className:`text-center py-8 text-gray-400 text-sm`,children:`暂无历史记录`})]})}function ae({content:e,children:t,className:n}){let[r,i]=(0,G.useState)(!1),[a,o]=(0,G.useState)(`top`),s=(0,G.useRef)(null);return(0,G.useEffect)(()=>{r&&s.current&&o(s.current.getBoundingClientRect().top<80?`bottom`:`top`)},[r]),(0,K.jsxs)(`span`,{ref:s,className:z(`relative inline-flex items-center cursor-help`,n),onMouseEnter:()=>i(!0),onMouseLeave:()=>i(!1),children:[t,r&&(0,K.jsx)(`span`,{className:z(`absolute z-50 w-max max-w-xs px-2.5 py-1.5 text-xs text-white bg-gray-800 rounded-lg shadow-lg pointer-events-none whitespace-normal`,a===`top`?`bottom-full mb-1.5 left-1/2 -translate-x-1/2`:`top-full mt-1.5 left-1/2 -translate-x-1/2`),children:e})]})}var q={Pipeline:`自动化工作流,将需求分解为多个节点依次执行`,Daemon:`后台守护进程,监听 Claude Code 事件并驱动编排引擎`,Hook:`Claude Code 生命周期钩子,在工具调用前后触发`,Distill:`将会话事件提炼为结构化知识,沉淀到知识图谱`,"Quality Gate":`质量门禁,在关键节点检测代码/文档质量问题`,Convention:`项目规范配置,定义节点类型、技能绑定和质量标准`,Skill:`可复用的 Claude Code 技能脚本,绑定到 Pipeline 节点`,ROI:`投资回报率,统计 AI 辅助节省的时间和 Token 用量`,Token:`LLM 处理的最小文本单元,影响 API 调用成本`,SSE:`Server-Sent Events,服务端向客户端推送实时事件的协议`},J=[{key:`distill`,title:`蒸馏配置`,description:`AI 知识蒸馏的触发条件和参数`,fields:[{key:`provider`,label:`提供商`,type:`select`,options:[{value:`claude`,label:`Claude`},{value:`openai`,label:`OpenAI`},{value:`ollama`,label:`Ollama`}]},{key:`auto_trigger`,label:`自动触发`,type:`boolean`,description:`达到事件阈值时自动蒸馏`},{key:`event_threshold`,label:`事件阈值`,type:`number`,description:`触发蒸馏的最小事件数`,min:1,max:1e4},{key:`timer_interval_minutes`,label:`定时器间隔(分钟)`,type:`number`,min:1,max:1440},{key:`model`,label:`模型`,type:`text`},{key:`api_key`,label:`API Key`,type:`text`,sensitive:!0,description:`留空自动从环境变量获取`},{key:`base_url`,label:`API 地址`,type:`text`,description:`留空使用默认地址`}]},{key:`autopilot`,title:`自动驾驶`,description:`意图分析、质量门禁、Pipeline 编排`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`intent_analysis`,label:`意图分析`,type:`boolean`,description:`AI 分析用户意图和任务复杂度`},{key:`quality_gate`,label:`质量门禁`,type:`boolean`,description:`代码变更时自动审查质量`},{key:`quality_review_interval`,label:`审查间隔`,type:`number`,description:`每 N 次 Write/Edit 触发一次审查`,min:1,max:100},{key:`auto_start_pipeline`,label:`自动启动流水线`,type:`boolean`},{key:`pipeline_confirm_mode`,label:`确认模式`,type:`select`,options:[{value:`prompt`,label:`提示确认`},{value:`auto`,label:`自动启动`},{value:`preview`,label:`仅预览`}]}]},{key:`resume`,title:`会话续接`,description:`中断会话的自动恢复`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`timeout_minutes`,label:`超时时间(分钟)`,type:`number`,min:1,max:1440},{key:`max_age_days`,label:`最大保留天数`,type:`number`,min:1,max:365}]},{key:`claudemd`,title:`CLAUDE.md 管理`,description:`项目级 CLAUDE.md 的自动生成与精炼`,fields:[{key:`auto_generate`,label:`自动生成`,type:`boolean`},{key:`auto_refine`,label:`自动精炼`,type:`boolean`},{key:`refine_interval`,label:`精炼间隔`,type:`number`,description:`每 N 次蒸馏后精炼一次`,min:1,max:100}]},{key:`orchestration`,title:`编排通知`,description:`蒸馏和 CLAUDE.md 更新的通知`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`notify_on_distill`,label:`蒸馏完成通知`,type:`boolean`},{key:`notify_on_claudemd`,label:`CLAUDE.md 更新通知`,type:`boolean`}]},{key:`web`,title:`Web 管理后台`,description:`Web 服务配置`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`port`,label:`端口`,type:`number`,min:1024,max:65535}]},{key:`ai`,title:`AI 模型`,description:`分层模型配置(Haiku/Sonnet/Opus)`,fields:[{key:`models.haiku`,label:`Haiku 模型`,type:`text`},{key:`models.sonnet`,label:`Sonnet 模型`,type:`text`},{key:`models.opus`,label:`Opus 模型`,type:`text`}]},{key:`storage`,title:`存储`,description:`数据库路径和容量限制`,fields:[{key:`path`,label:`数据库路径`,type:`text`},{key:`max_size_mb`,label:`最大容量(MB)`,type:`number`,min:100,max:102400}]},{key:`backup`,title:`备份配置`,description:`数据备份策略`,fields:[{key:`include_profile`,label:`包含用户画像`,type:`boolean`,description:`备份时包含用户画像数据`},{key:`encrypt_by_default`,label:`默认加密`,type:`boolean`,description:`备份文件默认加密`}]},{key:`pattern_engine`,title:`模式引擎`,description:`模式识别与演化配置`,fields:[{key:`enabled`,label:`启用`,type:`boolean`},{key:`route_timeout_ms`,label:`路由超时(毫秒)`,type:`number`,min:100,max:6e4},{key:`evolve_interval_days`,label:`演化间隔(天)`,type:`number`,min:1,max:365},{key:`evolve_min_executions`,label:`最小执行次数`,type:`number`,description:`触发演化的最小执行次数`,min:1,max:1e3}]},{key:`ui`,title:`UI 配置`,description:`前端界面参数`,fields:[{key:`skill_repair_limit`,label:`Skill 修复上限`,type:`number`,min:1,max:100},{key:`logs_tail_default`,label:`日志默认条数`,type:`number`,min:10,max:1e3},{key:`pipeline_expire_hours`,label:`Pipeline 过期时间(小时)`,type:`number`,min:1,max:720}]},{key:`history`,title:`配置历史`,description:`查看最近 10 次配置变更记录`,fields:[]}];function Y(){let e=y(),[t,r]=(0,G.useState)(null),[i,c]=(0,G.useState)(`idle`),[l,d]=(0,G.useState)(`distill`),[f,g]=(0,G.useState)(new Set),S=f.size>0,[T,D]=(0,G.useState)(null),[O,k]=(0,G.useState)(new Set),[A,j]=(0,G.useState)({open:!1,title:``,description:``,onConfirm:()=>{}}),{data:M,isLoading:N}=x({queryKey:[`config`],queryFn:()=>E().then(e=>e.data)}),{data:P,refetch:F}=x({queryKey:[`daemon-diagnosis`],queryFn:()=>C().then(e=>e.data),enabled:l===`environment`}),I=b({mutationFn:()=>w(),onSuccess:e=>{D(e.data),F()}});(0,G.useEffect)(()=>{M&&!t&&r(M)},[M,t]);let Y=b({mutationFn:e=>ee(e),onSuccess:()=>{e.invalidateQueries({queryKey:[`config`]}),c(`success`),g(new Set),setTimeout(()=>c(`idle`),3e3)},onError:()=>{c(`error`),setTimeout(()=>c(`idle`),3e3)}}),X=b({mutationFn:()=>L.post(`/config/reset`),onSuccess:()=>{e.invalidateQueries({queryKey:[`config`]}),r(null),c(`success`),setTimeout(()=>c(`idle`),3e3)}});if(N||!t)return(0,K.jsx)(`div`,{className:`flex items-center justify-center h-96`,children:(0,K.jsx)(`div`,{className:`animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600`})});let Z=(e,n)=>{let r=t[e];if(!r)return``;let i=n.split(`.`),a=r;for(let e of i)a=a?.[e];return a??``},Q=(e,t,n)=>{g(t=>new Set(t).add(e)),r(r=>{if(!r)return r;let i={...r[e]||{}},a=t.split(`.`);if(a.length===1)i[t]=n;else{let e={...i[a[0]]||{}};e[a[1]]=n,i[a[0]]=e}return{...r,[e]:i}})},oe=()=>{if(!t)return;let e={};f.forEach(n=>{e[n]=t[n]}),Y.mutate(e)},se=()=>{r(M),g(new Set)},ce=()=>{let e=JSON.stringify(t,null,2),n=new Blob([e],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`claude-forge-config-${new Date().toISOString().slice(0,10)}.json`,i.click(),URL.revokeObjectURL(r)},le=()=>{let e=document.createElement(`input`);e.type=`file`,e.accept=`.json`,e.onchange=e=>{let t=e.target.files?.[0];if(!t)return;let n=new FileReader;n.onload=e=>{try{r(JSON.parse(e.target?.result)),g(new Set(J.map(e=>e.key)))}catch{R(`配置文件格式错误,请选择有效的 JSON 文件`,`error`)}},n.readAsText(t)},e.click()},$=J.find(e=>e.key===l);return(0,K.jsxs)(`div`,{className:`flex gap-6`,children:[(0,K.jsx)(`div`,{className:`w-56 flex-shrink-0`,children:(0,K.jsx)(V,{className:`!p-2 sticky top-6`,children:(0,K.jsxs)(`nav`,{className:`space-y-1`,children:[J.map(e=>(0,K.jsx)(`button`,{onClick:()=>d(e.key),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors`,l===e.key?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:q[e.title]?(0,K.jsx)(ae,{content:q[e.title],children:e.title}):e.title},e.key)),(0,K.jsx)(`div`,{className:`border-t border-gray-100 my-1`}),(0,K.jsxs)(`button`,{onClick:()=>d(`backup_mgmt`),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors flex items-center gap-2`,l===`backup_mgmt`?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:[(0,K.jsx)(Database,{className:`h-3.5 w-3.5`}),`数据备份`]}),(0,K.jsxs)(`button`,{onClick:()=>d(`memory_mgmt`),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors flex items-center gap-2`,l===`memory_mgmt`?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:[(0,K.jsx)(Cpu,{className:`h-3.5 w-3.5`}),`内存管理`]}),(0,K.jsxs)(`button`,{onClick:()=>d(`environment`),className:z(`w-full text-left px-3 py-2.5 rounded-lg text-sm transition-colors flex items-center gap-2`,l===`environment`?`bg-blue-50 text-blue-700 font-medium`:`text-gray-600 hover:bg-gray-50 hover:text-gray-900`),children:[(0,K.jsx)(o,{className:`h-3.5 w-3.5`}),`环境检测`]})]})})}),(0,K.jsxs)(`div`,{className:`flex-1 space-y-6`,children:[(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h2`,{className:`text-lg font-semibold text-gray-900`,children:l===`environment`?`环境检测`:l===`backup_mgmt`?`数据备份`:l===`memory_mgmt`?`内存管理`:l===`history`?`配置历史`:$?.title}),(0,K.jsx)(`p`,{className:`text-sm text-gray-500`,children:l===`environment`?`Hook 脚本与 Claude settings.json 注入状态检测与修复`:l===`backup_mgmt`?`数据库备份与历史备份管理`:l===`memory_mgmt`?`LRU 缓存状态与进程内存管理`:l===`history`?`查看最近 10 次配置变更记录`:$?.description??``})]}),l!==`environment`&&l!==`backup_mgmt`&&l!==`memory_mgmt`&&l!==`history`&&(0,K.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,K.jsxs)(H,{children:[i===`success`&&(0,K.jsxs)(U.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0},className:`flex items-center gap-1.5 text-green-600 text-sm`,children:[(0,K.jsx)(u,{className:`h-4 w-4`}),`已保存`]}),i===`error`&&(0,K.jsxs)(U.div,{initial:{opacity:0,x:10},animate:{opacity:1,x:0},exit:{opacity:0},className:`flex items-center gap-1.5 text-red-600 text-sm`,children:[(0,K.jsx)(m,{className:`h-4 w-4`}),`保存失败`]})]}),S&&(0,K.jsx)(te,{variant:`warning`,children:`未保存`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:s,onClick:ce,children:`导出`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:v,onClick:le,children:`导入`}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:p,onClick:se,disabled:!S,children:`撤销`}),(0,K.jsx)(B,{variant:`primary`,size:`sm`,icon:_,onClick:oe,loading:Y.isPending,disabled:!S,children:`保存`})]})]}),l!==`environment`&&l!==`backup_mgmt`&&l!==`memory_mgmt`&&(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(V,{children:(0,K.jsx)(`div`,{className:`space-y-6`,children:$?.fields.map(e=>(0,K.jsxs)(`div`,{className:`flex items-start gap-4`,children:[(0,K.jsxs)(`div`,{className:`w-48 flex-shrink-0 pt-2`,children:[(0,K.jsx)(`label`,{className:`text-sm font-medium text-gray-700`,children:e.label}),e.description&&(0,K.jsx)(`p`,{className:`text-xs text-gray-400 mt-0.5`,children:e.description})]}),(0,K.jsx)(`div`,{className:`flex-1`,children:e.type===`boolean`?(0,K.jsx)(`button`,{onClick:()=>Q(l,e.key,!Z(l,e.key)),className:z(`relative inline-flex h-6 w-11 items-center rounded-full transition-colors`,Z(l,e.key)?`bg-blue-600`:`bg-gray-300`),children:(0,K.jsx)(`span`,{className:z(`inline-block h-4 w-4 transform rounded-full bg-white transition-transform`,Z(l,e.key)?`translate-x-6`:`translate-x-1`)})}):e.type===`select`?(0,K.jsx)(`select`,{value:String(Z(l,e.key)||``),onChange:t=>Q(l,e.key,t.target.value),className:`w-full max-w-xs px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm`,children:e.options?.map(e=>(0,K.jsx)(`option`,{value:e.value,children:e.label},e.value))}):e.type===`number`?(0,K.jsx)(`input`,{type:`number`,value:Number(Z(l,e.key))||0,onChange:t=>Q(l,e.key,Number(t.target.value)),min:e.min,max:e.max,className:`w-full max-w-xs px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm`}):(0,K.jsxs)(`div`,{className:`relative flex items-center max-w-xs`,children:[(0,K.jsx)(`input`,{type:e.sensitive&&!O.has(`${l}.${e.key}`)?`password`:`text`,value:String(Z(l,e.key)||``),onChange:t=>Q(l,e.key,t.target.value),className:`w-full px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm pr-9`}),e.sensitive&&(0,K.jsx)(`button`,{type:`button`,onClick:()=>k(t=>{let n=new Set(t),r=`${l}.${e.key}`;return n.has(r)?n.delete(r):n.add(r),n}),className:`absolute right-2 text-gray-400 hover:text-gray-600`,children:O.has(`${l}.${e.key}`)?(0,K.jsx)(EyeOff,{className:`h-4 w-4`}):(0,K.jsx)(Eye,{className:`h-4 w-4`})})]})})]},e.key))})}),(0,K.jsx)(V,{className:`!border-red-200`,children:(0,K.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`text-sm font-semibold text-red-600`,children:`重置配置`}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-1`,children:`将所有配置恢复为默认值,此操作不可撤销`})]}),(0,K.jsx)(B,{variant:`danger`,size:`sm`,icon:n,onClick:()=>{j({open:!0,title:`重置配置`,description:`确定要重置所有配置为默认值吗?此操作不可撤销。`,onConfirm:()=>{X.mutate(),j({...A,open:!1})}})},loading:X.isPending,children:`重置`})]})})]}),l===`backup_mgmt`&&(0,K.jsx)(ne,{onConfirm:e=>j({...e,open:!0})}),l===`memory_mgmt`&&(0,K.jsx)(re,{onConfirm:e=>j({...e,open:!0})}),l===`history`&&(0,K.jsx)(ie,{currentConfig:M,onRestore:e=>Y.mutate(e),onConfirm:e=>j({...e,open:!0})}),l===`environment`&&(0,K.jsxs)(`div`,{className:`space-y-4`,children:[(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`h3`,{className:`font-medium text-gray-900 mb-1`,children:`Hook 环境诊断`}),(0,K.jsx)(`p`,{className:`text-sm text-gray-500`,children:`检测 Forge hooks 脚本与 Claude settings.json 中 Forge 注入是否完整`})]}),(0,K.jsxs)(`div`,{className:`flex gap-2 flex-shrink-0`,children:[(0,K.jsx)(B,{variant:`secondary`,size:`sm`,icon:h,onClick:()=>F(),children:`重新检测`}),(0,K.jsx)(B,{size:`sm`,icon:a,onClick:()=>I.mutate(),disabled:I.isPending||P?.hooksHealthy,children:I.isPending?`修复中...`:`一键修复`})]})]})}),T&&(0,K.jsx)(V,{children:(0,K.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,K.jsxs)(`div`,{className:`flex items-start gap-2`,children:[T.hooksHealthy?(0,K.jsx)(u,{className:`h-4 w-4 text-green-500 mt-0.5 flex-shrink-0`}):(0,K.jsx)(n,{className:`h-4 w-4 text-yellow-500 mt-0.5 flex-shrink-0`}),(0,K.jsxs)(`div`,{children:[(0,K.jsx)(`p`,{className:z(`text-sm font-medium`,T.hooksHealthy?`text-gray-900`:`text-yellow-600`),children:T.hooksHealthy?`Hooks 环境已恢复正常`:`修复后仍有未通过项,请根据下方列表排查`}),T.backupPath&&(0,K.jsxs)(`p`,{className:`text-xs text-gray-500 mt-0.5`,children:[`已备份 settings: `,T.backupPath.split(`/`).pop()]})]})]}),(0,K.jsx)(B,{variant:`ghost`,size:`sm`,icon:m,onClick:()=>D(null)})]})}),P&&(0,K.jsx)(V,{children:(0,K.jsx)(`div`,{className:`space-y-2`,children:P.items.map(e=>(0,K.jsxs)(`div`,{className:`flex items-start gap-3 py-2 border-b border-gray-50 last:border-0`,children:[(0,K.jsx)(`div`,{className:`flex-shrink-0 mt-0.5`,children:e.ok?(0,K.jsx)(u,{className:`h-4 w-4 text-green-500`}):e.id===`daemon_process`?(0,K.jsx)(n,{className:`h-4 w-4 text-yellow-500`}):(0,K.jsx)(m,{className:`h-4 w-4 text-red-500`})}),(0,K.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,K.jsx)(`p`,{className:`text-sm font-medium text-gray-900`,children:e.label}),(0,K.jsx)(`p`,{className:`text-xs text-gray-500 mt-0.5 break-all`,children:e.detail})]})]},e.id))})}),P&&(0,K.jsx)(V,{className:P.hooksHealthy?`!border-green-200 !bg-green-50`:`!border-yellow-200 !bg-yellow-50`,children:(0,K.jsx)(`div`,{className:`flex items-center gap-2`,children:P.hooksHealthy?(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(u,{className:`h-5 w-5 text-green-600`}),(0,K.jsx)(`p`,{className:`text-sm font-medium text-green-700`,children:`Hooks 相关环境正常`})]}):(0,K.jsxs)(K.Fragment,{children:[(0,K.jsx)(n,{className:`h-5 w-5 text-yellow-600`}),(0,K.jsx)(`p`,{className:`text-sm font-medium text-yellow-700`,children:`检测到 Hooks 环境不完整,请点击「一键修复」`})]})})})]})]}),(0,K.jsx)(W,{open:A.open,title:A.title,description:A.description,variant:`danger`,onConfirm:A.onConfirm,onCancel:()=>j({...A,open:!1})})]})}export{Y as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e}from"./rolldown-runtime-COnpUsM8.js";import{Bt as t,
|
|
1
|
+
import{a as e}from"./rolldown-runtime-COnpUsM8.js";import{Bt as t,Cn as n,Ut as r,gr as i}from"./vendor-DRGPi8ui.js";import{c as a}from"./vendor-flow-srkes8If.js";import{a as o,n as s}from"./ui-CDL3BZ13.js";var c=e(i(),1),l=a();function u({open:e,title:i,description:a,confirmText:u=`确认`,cancelText:d=`取消`,variant:f=`default`,loading:p=!1,count:m,onConfirm:h,onCancel:g}){let[_,v]=(0,c.useState)(``),y=m!==void 0&&m>=5&&m<=20,b=m!==void 0&&m>20,x=y||b,S=b?`DELETE`:String(m),C=!x||_===S;if((0,c.useEffect)(()=>{if(!e){v(``);return}let t=e=>{e.key===`Escape`&&g(),e.key===`Enter`&&C&&h()};return window.addEventListener(`keydown`,t),()=>window.removeEventListener(`keydown`,t)},[e,h,g,C]),!e)return null;let w=f===`danger`?r:f===`warning`?t:n,T=f===`danger`?`text-red-500`:f===`warning`?`text-amber-500`:`text-blue-500`;return(0,l.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm`,onClick:g,children:(0,l.jsxs)(`div`,{className:`bg-white rounded-xl shadow-xl w-full max-w-md mx-4 p-6`,onClick:e=>e.stopPropagation(),children:[(0,l.jsxs)(`div`,{className:`flex items-start gap-4`,children:[(0,l.jsx)(`div`,{className:o(`flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center`,f===`danger`?`bg-red-50`:f===`warning`?`bg-amber-50`:`bg-blue-50`),children:(0,l.jsx)(w,{className:o(`h-5 w-5`,T)})}),(0,l.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,l.jsx)(`h3`,{className:`text-base font-semibold text-gray-900`,children:i}),(0,l.jsx)(`p`,{className:`mt-1 text-sm text-gray-500 leading-relaxed`,children:a})]})]}),x&&(0,l.jsxs)(`div`,{className:`mt-4`,children:[(0,l.jsx)(`p`,{className:`text-sm text-gray-600 mb-2`,children:b?(0,l.jsxs)(l.Fragment,{children:[`请输入 `,(0,l.jsx)(`code`,{className:`px-1 py-0.5 bg-gray-100 rounded text-red-600 font-mono text-xs`,children:`DELETE`}),` 以确认操作`]}):(0,l.jsxs)(l.Fragment,{children:[`请输入数量 `,(0,l.jsx)(`code`,{className:`px-1 py-0.5 bg-gray-100 rounded text-gray-800 font-mono text-xs`,children:m}),` 以确认操作`]})}),(0,l.jsx)(`input`,{autoFocus:!0,type:`text`,value:_,onChange:e=>v(e.target.value),placeholder:S,className:o(`w-full px-3 py-2 border rounded-lg text-sm focus:outline-none focus:ring-2`,_&&!C?`border-red-300 focus:ring-red-400`:`border-gray-200 focus:ring-blue-500`)})]}),(0,l.jsxs)(`div`,{className:`flex justify-end gap-3 mt-6`,children:[(0,l.jsx)(s,{variant:`secondary`,size:`sm`,onClick:g,disabled:p,children:d}),(0,l.jsx)(s,{variant:f===`danger`?`danger`:`primary`,size:`sm`,onClick:h,loading:p,disabled:!C,children:u})]})]})})}export{u as t};
|