@winspan/claude-forge 1.4.6 → 1.6.3

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.
Files changed (78) hide show
  1. package/README.md +23 -2
  2. package/dist/cli/commands/status.d.ts +3 -0
  3. package/dist/cli/commands/status.d.ts.map +1 -0
  4. package/dist/cli/commands/status.js +64 -0
  5. package/dist/cli/commands/status.js.map +1 -0
  6. package/dist/cli/commands/web.d.ts +3 -0
  7. package/dist/cli/commands/web.d.ts.map +1 -0
  8. package/dist/cli/commands/web.js +30 -0
  9. package/dist/cli/commands/web.js.map +1 -0
  10. package/dist/cli/index.js +4 -0
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/config/defaults.d.ts.map +1 -1
  13. package/dist/config/defaults.js +5 -0
  14. package/dist/config/defaults.js.map +1 -1
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +1 -0
  17. package/dist/config/index.js.map +1 -1
  18. package/dist/config/schema.d.ts +5 -0
  19. package/dist/config/schema.d.ts.map +1 -1
  20. package/dist/config/schema.js +12 -0
  21. package/dist/config/schema.js.map +1 -1
  22. package/dist/daemon/index.d.ts.map +1 -1
  23. package/dist/daemon/index.js +30 -0
  24. package/dist/daemon/index.js.map +1 -1
  25. package/dist/pipeline/index.d.ts.map +1 -1
  26. package/dist/pipeline/index.js +7 -0
  27. package/dist/pipeline/index.js.map +1 -1
  28. package/dist/storage/repositories/knowledge-repository.d.ts.map +1 -1
  29. package/dist/storage/repositories/knowledge-repository.js +22 -9
  30. package/dist/storage/repositories/knowledge-repository.js.map +1 -1
  31. package/dist/storage/repositories/task-repository.d.ts +10 -0
  32. package/dist/storage/repositories/task-repository.d.ts.map +1 -1
  33. package/dist/storage/repositories/task-repository.js +8 -0
  34. package/dist/storage/repositories/task-repository.js.map +1 -1
  35. package/dist/storage/sqlite.d.ts +10 -0
  36. package/dist/storage/sqlite.d.ts.map +1 -1
  37. package/dist/storage/sqlite.js +3 -0
  38. package/dist/storage/sqlite.js.map +1 -1
  39. package/dist/web/middleware/auth.d.ts +3 -0
  40. package/dist/web/middleware/auth.d.ts.map +1 -0
  41. package/dist/web/middleware/auth.js +11 -0
  42. package/dist/web/middleware/auth.js.map +1 -0
  43. package/dist/web/routes/config.d.ts +4 -0
  44. package/dist/web/routes/config.d.ts.map +1 -0
  45. package/dist/web/routes/config.js +102 -0
  46. package/dist/web/routes/config.js.map +1 -0
  47. package/dist/web/routes/events.d.ts +4 -0
  48. package/dist/web/routes/events.d.ts.map +1 -0
  49. package/dist/web/routes/events.js +71 -0
  50. package/dist/web/routes/events.js.map +1 -0
  51. package/dist/web/routes/knowledge.d.ts +4 -0
  52. package/dist/web/routes/knowledge.d.ts.map +1 -0
  53. package/dist/web/routes/knowledge.js +76 -0
  54. package/dist/web/routes/knowledge.js.map +1 -0
  55. package/dist/web/routes/pipelines.d.ts +4 -0
  56. package/dist/web/routes/pipelines.d.ts.map +1 -0
  57. package/dist/web/routes/pipelines.js +40 -0
  58. package/dist/web/routes/pipelines.js.map +1 -0
  59. package/dist/web/routes/quality.d.ts +4 -0
  60. package/dist/web/routes/quality.d.ts.map +1 -0
  61. package/dist/web/routes/quality.js +72 -0
  62. package/dist/web/routes/quality.js.map +1 -0
  63. package/dist/web/routes/sessions.d.ts +4 -0
  64. package/dist/web/routes/sessions.d.ts.map +1 -0
  65. package/dist/web/routes/sessions.js +207 -0
  66. package/dist/web/routes/sessions.js.map +1 -0
  67. package/dist/web/routes/stats.d.ts +4 -0
  68. package/dist/web/routes/stats.d.ts.map +1 -0
  69. package/dist/web/routes/stats.js +145 -0
  70. package/dist/web/routes/stats.js.map +1 -0
  71. package/dist/web/server.d.ts +18 -0
  72. package/dist/web/server.d.ts.map +1 -0
  73. package/dist/web/server.js +93 -0
  74. package/dist/web/server.js.map +1 -0
  75. package/dist/web-static/assets/index-3Sw33EKn.js +62 -0
  76. package/dist/web-static/assets/index-wxH-x453.css +2 -0
  77. package/dist/web-static/index.html +13 -0
  78. package/package.json +31 -2
@@ -0,0 +1,145 @@
1
+ export function registerStatsRoutes(app, storage) {
2
+ // ROI 效率指标
3
+ app.get('/api/stats/roi', (req, res) => {
4
+ try {
5
+ const sessions = storage.querySessions({ limit: 1000 });
6
+ const events = storage.queryEvents({ limit: 10000 });
7
+ const now = Date.now();
8
+ const weekAgo = now - 7 * 24 * 60 * 60 * 1000;
9
+ const monthAgo = now - 30 * 24 * 60 * 60 * 1000;
10
+ // 本周会话
11
+ const weekSessions = sessions.filter(s => new Date(s.start_time).getTime() > weekAgo);
12
+ const monthSessions = sessions.filter(s => new Date(s.start_time).getTime() > monthAgo);
13
+ // 本周事件
14
+ const weekEvents = events.filter(e => new Date(e.timestamp).getTime() > weekAgo);
15
+ // 写入操作数(代表 AI 产出)
16
+ const weekWriteOps = weekEvents.filter(e => e.tool_name === 'Write' || e.tool_name === 'Edit').length;
17
+ // AI 调用统计
18
+ const apiUsage = storage.getApiUsageSummary();
19
+ const weekCost = apiUsage.reduce((sum, u) => sum + (u.cost_usd || 0), 0);
20
+ // 质量拦截
21
+ const qualityHistory = storage.getQualityHistory();
22
+ const weekQuality = qualityHistory.filter(q => new Date(q.created_at).getTime() > weekAgo);
23
+ const qualityBlocked = weekQuality.filter(q => q.level === 'fail' || q.level === 'error').length;
24
+ const qualityResolved = weekQuality.filter(q => q.resolved).length;
25
+ // 知识沉淀量
26
+ const knowledgeNodes = storage.searchKnowledgeNodes('', '', 10000);
27
+ // 估算节省时间(每个写入操作约节省 2 分钟,每次质量拦截约节省 15 分钟)
28
+ const estimatedTimeSavedMinutes = weekWriteOps * 2 + qualityBlocked * 15;
29
+ // Pipeline 完成率
30
+ const pipelines = storage.getTaskSessionsByType('pipeline');
31
+ const weekPipelines = pipelines.filter(p => new Date(p.created_at).getTime() > weekAgo);
32
+ const completedPipelines = weekPipelines.filter(p => p.status === 'completed').length;
33
+ // 满意度
34
+ const avgSatisfaction = storage.getAverageSatisfaction();
35
+ res.json({
36
+ week: {
37
+ sessions: weekSessions.length,
38
+ events: weekEvents.length,
39
+ writeOps: weekWriteOps,
40
+ timeSavedMinutes: estimatedTimeSavedMinutes,
41
+ timeSavedHours: +(estimatedTimeSavedMinutes / 60).toFixed(1),
42
+ costUsd: +weekCost.toFixed(4),
43
+ qualityBlocked,
44
+ qualityResolved,
45
+ pipelinesTotal: weekPipelines.length,
46
+ pipelinesCompleted: completedPipelines,
47
+ },
48
+ month: {
49
+ sessions: monthSessions.length,
50
+ },
51
+ totals: {
52
+ sessions: sessions.length,
53
+ events: events.length,
54
+ knowledgeNodes: knowledgeNodes.length,
55
+ satisfaction: avgSatisfaction,
56
+ },
57
+ // 趋势数据(最近 7 天每天)
58
+ dailyTrend: Array.from({ length: 7 }, (_, i) => {
59
+ const dayStart = new Date(now - (6 - i) * 24 * 60 * 60 * 1000);
60
+ const dayEnd = new Date(dayStart.getTime() + 24 * 60 * 60 * 1000);
61
+ const dayStr = dayStart.toISOString().split('T')[0];
62
+ const daySessions = sessions.filter(s => {
63
+ const t = new Date(s.start_time).getTime();
64
+ return t >= dayStart.getTime() && t < dayEnd.getTime();
65
+ }).length;
66
+ const dayEvents = events.filter(e => {
67
+ const t = new Date(e.timestamp).getTime();
68
+ return t >= dayStart.getTime() && t < dayEnd.getTime();
69
+ }).length;
70
+ const dayWrites = events.filter(e => {
71
+ const t = new Date(e.timestamp).getTime();
72
+ return t >= dayStart.getTime() && t < dayEnd.getTime() &&
73
+ (e.tool_name === 'Write' || e.tool_name === 'Edit');
74
+ }).length;
75
+ return { date: dayStr.slice(5), sessions: daySessions, events: dayEvents, writes: dayWrites };
76
+ }),
77
+ });
78
+ }
79
+ catch (err) {
80
+ res.status(500).json({ error: String(err) });
81
+ }
82
+ });
83
+ // 系统概览(Dashboard 用)
84
+ app.get('/api/stats/overview', (req, res) => {
85
+ try {
86
+ const sessions = storage.querySessions({ limit: 100 });
87
+ const events = storage.queryEvents({ limit: 500 });
88
+ const qualityHistory = storage.getQualityHistory();
89
+ const pipelines = storage.getTaskSessionsByType('pipeline');
90
+ const activeSessions = sessions.filter(s => s.status === 'active').length;
91
+ // 最近活动
92
+ const recentActivity = events.slice(0, 20).map(e => ({
93
+ time: e.timestamp,
94
+ type: e.hook_type,
95
+ tool: e.tool_name || null,
96
+ project: e.project_path.split('/').pop() || '',
97
+ sessionId: e.session_id.slice(0, 8),
98
+ }));
99
+ // 智能推荐
100
+ const recommendations = [];
101
+ const unresolvedQuality = qualityHistory.filter(q => !q.resolved);
102
+ if (unresolvedQuality.length > 0) {
103
+ recommendations.push({
104
+ type: 'warning',
105
+ title: `${unresolvedQuality.length} 个未修复的质量问题`,
106
+ description: `最近的问题:${unresolvedQuality[0]?.message?.slice(0, 80) || ''}`,
107
+ action: '/quality',
108
+ priority: 1,
109
+ });
110
+ }
111
+ if (activeSessions === 0 && sessions.length > 0) {
112
+ recommendations.push({
113
+ type: 'info',
114
+ title: '当前无活跃会话',
115
+ description: `共 ${sessions.length} 个历史会话,可查看复盘报告获取改进建议`,
116
+ action: '/analytics',
117
+ priority: 3,
118
+ });
119
+ }
120
+ const stalePipelines = pipelines.filter(p => p.status === 'active' &&
121
+ new Date(p.created_at).getTime() < Date.now() - 2 * 60 * 60 * 1000);
122
+ if (stalePipelines.length > 0) {
123
+ recommendations.push({
124
+ type: 'warning',
125
+ title: `${stalePipelines.length} 个流水线超时未完成`,
126
+ description: '可能需要手动干预或清理',
127
+ action: '/pipelines',
128
+ priority: 2,
129
+ });
130
+ }
131
+ res.json({
132
+ activeSessions,
133
+ totalSessions: sessions.length,
134
+ totalEvents: events.length,
135
+ totalPipelines: pipelines.length,
136
+ recentActivity,
137
+ recommendations: recommendations.sort((a, b) => a.priority - b.priority),
138
+ });
139
+ }
140
+ catch (err) {
141
+ res.status(500).json({ error: String(err) });
142
+ }
143
+ });
144
+ }
145
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/web/routes/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { SQLiteStorage } from '../storage/sqlite.js';
2
+ export interface WebServerOptions {
3
+ port: number;
4
+ authToken?: string;
5
+ storage: SQLiteStorage;
6
+ }
7
+ export declare class WebServer {
8
+ private app;
9
+ private server;
10
+ private options;
11
+ constructor(options: WebServerOptions);
12
+ private setupMiddleware;
13
+ private setupRoutes;
14
+ private setupStaticFiles;
15
+ start(): Promise<void>;
16
+ stop(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +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;AAa1D,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;CACxB;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;IAUvB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,gBAAgB;IAgBxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAatB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAYtB"}
@@ -0,0 +1,93 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import path from 'path';
4
+ import fs from 'fs';
5
+ import { fileURLToPath } from 'url';
6
+ import { logger } from '../utils/logger.js';
7
+ import { registerConfigRoutes } from './routes/config.js';
8
+ import { registerPipelineRoutes } from './routes/pipelines.js';
9
+ import { registerQualityRoutes } from './routes/quality.js';
10
+ import { registerEventRoutes } from './routes/events.js';
11
+ import { registerSessionRoutes } from './routes/sessions.js';
12
+ import { registerStatsRoutes } from './routes/stats.js';
13
+ import { registerKnowledgeRoutes } from './routes/knowledge.js';
14
+ import { authMiddleware } from './middleware/auth.js';
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = path.dirname(__filename);
17
+ export class WebServer {
18
+ app;
19
+ server = null;
20
+ options;
21
+ constructor(options) {
22
+ this.options = options;
23
+ this.app = express();
24
+ this.setupMiddleware();
25
+ this.setupRoutes();
26
+ this.setupStaticFiles();
27
+ }
28
+ setupMiddleware() {
29
+ this.app.use(cors());
30
+ this.app.use(express.json());
31
+ // 认证中间件(仅 API 路由)
32
+ if (this.options.authToken) {
33
+ this.app.use('/api', authMiddleware(this.options.authToken));
34
+ }
35
+ }
36
+ setupRoutes() {
37
+ const { storage } = this.options;
38
+ // API 路由
39
+ registerConfigRoutes(this.app, storage);
40
+ registerPipelineRoutes(this.app, storage);
41
+ registerQualityRoutes(this.app, storage);
42
+ registerEventRoutes(this.app, storage);
43
+ registerSessionRoutes(this.app, storage);
44
+ registerStatsRoutes(this.app, storage);
45
+ registerKnowledgeRoutes(this.app, storage);
46
+ // 健康检查
47
+ this.app.get('/api/health', (req, res) => {
48
+ res.json({ status: 'ok', timestamp: new Date().toISOString() });
49
+ });
50
+ }
51
+ setupStaticFiles() {
52
+ // 静态文件(Vite 打包后的前端)
53
+ const webDir = path.join(__dirname, '../../dist/web-static');
54
+ this.app.use(express.static(webDir));
55
+ // SPA fallback - 所有未匹配的路由返回 index.html
56
+ this.app.use((req, res) => {
57
+ const indexPath = path.join(webDir, 'index.html');
58
+ if (fs.existsSync(indexPath)) {
59
+ res.sendFile(indexPath);
60
+ }
61
+ else {
62
+ res.status(200).json({ message: 'Claude Forge Web API 运行中,前端未构建。运行 npx vite build 构建前端。' });
63
+ }
64
+ });
65
+ }
66
+ start() {
67
+ return new Promise((resolve, reject) => {
68
+ try {
69
+ this.server = this.app.listen(this.options.port, () => {
70
+ logger.info(`[Web] 管理后台已启动:http://localhost:${this.options.port}`);
71
+ resolve();
72
+ });
73
+ }
74
+ catch (err) {
75
+ reject(err);
76
+ }
77
+ });
78
+ }
79
+ stop() {
80
+ return new Promise((resolve) => {
81
+ if (this.server) {
82
+ this.server.close(() => {
83
+ logger.info('[Web] 管理后台已停止');
84
+ resolve();
85
+ });
86
+ }
87
+ else {
88
+ resolve();
89
+ }
90
+ });
91
+ }
92
+ }
93
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"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"}