openmatrix 0.2.5 → 0.2.7
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/agents/agent-runner.js +0 -1
- package/dist/cli/commands/analyze.js +8 -7
- package/dist/cli/commands/approve.js +24 -23
- package/dist/cli/commands/brainstorm.d.ts +115 -0
- package/dist/cli/commands/brainstorm.js +358 -255
- package/dist/cli/commands/check.d.ts +25 -0
- package/dist/cli/commands/check.js +69 -44
- package/dist/cli/commands/debug.d.ts +2 -0
- package/dist/cli/commands/debug.js +116 -0
- package/dist/cli/commands/install-skills.js +4 -4
- package/dist/cli/commands/report.d.ts +23 -0
- package/dist/cli/commands/report.js +1 -0
- package/dist/cli/commands/status.d.ts +8 -0
- package/dist/cli/commands/status.js +19 -18
- package/dist/cli/index.js +2 -0
- package/dist/orchestrator/context-collector.d.ts +23 -0
- package/dist/orchestrator/context-collector.js +168 -0
- package/dist/orchestrator/debug-manager.d.ts +52 -0
- package/dist/orchestrator/debug-manager.js +214 -0
- package/dist/orchestrator/debug-reporter.d.ts +25 -0
- package/dist/orchestrator/debug-reporter.js +167 -0
- package/dist/orchestrator/phase-executor.js +21 -0
- package/dist/orchestrator/problem-detector.d.ts +15 -0
- package/dist/orchestrator/problem-detector.js +51 -0
- package/dist/orchestrator/upgrade-detector.js +32 -12
- package/dist/storage/file-store.js +6 -3
- package/dist/types/index.d.ts +44 -0
- package/dist/utils/logger.d.ts +4 -4
- package/package.json +1 -1
- package/skills/auto.md +3 -1
- package/skills/debug.md +451 -0
- package/skills/om.md +2 -1
- package/skills/start.md +40 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DebugSession, DiagnosisReport, ProblemType } from '../types/index.js';
|
|
2
|
+
export interface DebugConfig {
|
|
3
|
+
description?: string;
|
|
4
|
+
taskId?: string;
|
|
5
|
+
diagnoseOnly?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface DebugInitResult {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
status: string;
|
|
10
|
+
problemType: ProblemType;
|
|
11
|
+
report: Partial<DiagnosisReport>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 调试管理器 - 协调整个调试流程
|
|
15
|
+
*/
|
|
16
|
+
export declare class DebugManager {
|
|
17
|
+
private omPath;
|
|
18
|
+
private detector;
|
|
19
|
+
private collector;
|
|
20
|
+
private reporter;
|
|
21
|
+
constructor(omPath: string);
|
|
22
|
+
/**
|
|
23
|
+
* 初始化调试会话
|
|
24
|
+
*/
|
|
25
|
+
initialize(config: DebugConfig): Promise<DebugInitResult>;
|
|
26
|
+
/**
|
|
27
|
+
* 获取会话
|
|
28
|
+
*/
|
|
29
|
+
getSession(sessionId: string): DebugSession | null;
|
|
30
|
+
/**
|
|
31
|
+
* 更新会话
|
|
32
|
+
*/
|
|
33
|
+
updateSession(sessionId: string, updates: Partial<DebugSession>): void;
|
|
34
|
+
/**
|
|
35
|
+
* 完成会话
|
|
36
|
+
*/
|
|
37
|
+
completeSession(sessionId: string): Promise<string | null>;
|
|
38
|
+
/**
|
|
39
|
+
* 列出最近的调试会话
|
|
40
|
+
*/
|
|
41
|
+
listRecent(): {
|
|
42
|
+
id: string;
|
|
43
|
+
status: string;
|
|
44
|
+
description: string;
|
|
45
|
+
createdAt: string;
|
|
46
|
+
}[];
|
|
47
|
+
private collectContext;
|
|
48
|
+
private getTaskError;
|
|
49
|
+
private saveSession;
|
|
50
|
+
private getSessionPath;
|
|
51
|
+
private generateSessionId;
|
|
52
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DebugManager = void 0;
|
|
37
|
+
// src/orchestrator/debug-manager.ts
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const problem_detector_js_1 = require("./problem-detector.js");
|
|
41
|
+
const context_collector_js_1 = require("./context-collector.js");
|
|
42
|
+
const debug_reporter_js_1 = require("./debug-reporter.js");
|
|
43
|
+
/**
|
|
44
|
+
* 调试管理器 - 协调整个调试流程
|
|
45
|
+
*/
|
|
46
|
+
class DebugManager {
|
|
47
|
+
omPath;
|
|
48
|
+
detector;
|
|
49
|
+
collector;
|
|
50
|
+
reporter;
|
|
51
|
+
constructor(omPath) {
|
|
52
|
+
this.omPath = omPath;
|
|
53
|
+
this.detector = new problem_detector_js_1.ProblemDetector();
|
|
54
|
+
this.collector = new context_collector_js_1.ContextCollector(omPath);
|
|
55
|
+
this.reporter = new debug_reporter_js_1.DebugReporter(omPath);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 初始化调试会话
|
|
59
|
+
*/
|
|
60
|
+
async initialize(config) {
|
|
61
|
+
// 如果有任务 ID,尝试读取任务信息
|
|
62
|
+
let taskError = null;
|
|
63
|
+
if (config.taskId) {
|
|
64
|
+
taskError = await this.getTaskError(config.taskId);
|
|
65
|
+
}
|
|
66
|
+
// 判断问题类型
|
|
67
|
+
const problemType = await this.detector.detect({
|
|
68
|
+
description: config.description,
|
|
69
|
+
taskId: config.taskId,
|
|
70
|
+
taskError
|
|
71
|
+
});
|
|
72
|
+
// 收集上下文
|
|
73
|
+
const context = await this.collectContext(problemType, config);
|
|
74
|
+
// 创建会话
|
|
75
|
+
const sessionId = this.generateSessionId();
|
|
76
|
+
const session = {
|
|
77
|
+
id: sessionId,
|
|
78
|
+
status: config.diagnoseOnly ? 'initialized' : 'diagnosing',
|
|
79
|
+
report: {
|
|
80
|
+
id: sessionId,
|
|
81
|
+
problemType,
|
|
82
|
+
trigger: config.taskId ? 'auto' : 'explicit',
|
|
83
|
+
description: config.description || `调试任务 ${config.taskId}`,
|
|
84
|
+
relatedTaskId: config.taskId,
|
|
85
|
+
errorInfo: taskError ? {
|
|
86
|
+
message: taskError,
|
|
87
|
+
timestamp: new Date().toISOString()
|
|
88
|
+
} : undefined,
|
|
89
|
+
relatedFiles: context.projectFiles || [],
|
|
90
|
+
rootCause: '', // 由 Skill 阶段 Agent 填充
|
|
91
|
+
impactScope: [],
|
|
92
|
+
suggestedFix: '', // 由 Skill 阶段 Agent 填充
|
|
93
|
+
diagnosedAt: new Date().toISOString()
|
|
94
|
+
},
|
|
95
|
+
retryCount: 0,
|
|
96
|
+
createdAt: new Date().toISOString(),
|
|
97
|
+
updatedAt: new Date().toISOString()
|
|
98
|
+
};
|
|
99
|
+
// 持久化会话
|
|
100
|
+
this.saveSession(session);
|
|
101
|
+
return {
|
|
102
|
+
sessionId,
|
|
103
|
+
status: session.status,
|
|
104
|
+
problemType,
|
|
105
|
+
report: {
|
|
106
|
+
description: session.report.description,
|
|
107
|
+
relatedTaskId: session.report.relatedTaskId,
|
|
108
|
+
relatedFiles: session.report.relatedFiles,
|
|
109
|
+
errorInfo: session.report.errorInfo
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 获取会话
|
|
115
|
+
*/
|
|
116
|
+
getSession(sessionId) {
|
|
117
|
+
const sessionPath = this.getSessionPath(sessionId);
|
|
118
|
+
if (!fs.existsSync(sessionPath))
|
|
119
|
+
return null;
|
|
120
|
+
try {
|
|
121
|
+
return JSON.parse(fs.readFileSync(sessionPath, 'utf-8'));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 更新会话
|
|
129
|
+
*/
|
|
130
|
+
updateSession(sessionId, updates) {
|
|
131
|
+
const session = this.getSession(sessionId);
|
|
132
|
+
if (!session)
|
|
133
|
+
return;
|
|
134
|
+
Object.assign(session, updates, { updatedAt: new Date().toISOString() });
|
|
135
|
+
this.saveSession(session);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 完成会话
|
|
139
|
+
*/
|
|
140
|
+
async completeSession(sessionId) {
|
|
141
|
+
const session = this.getSession(sessionId);
|
|
142
|
+
if (!session)
|
|
143
|
+
return null;
|
|
144
|
+
session.status = 'completed';
|
|
145
|
+
session.completedAt = new Date().toISOString();
|
|
146
|
+
this.saveSession(session);
|
|
147
|
+
return await this.reporter.generateReport(session);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 列出最近的调试会话
|
|
151
|
+
*/
|
|
152
|
+
listRecent() {
|
|
153
|
+
const debugDir = path.join(this.omPath, 'debug');
|
|
154
|
+
if (!fs.existsSync(debugDir))
|
|
155
|
+
return [];
|
|
156
|
+
const files = fs.readdirSync(debugDir)
|
|
157
|
+
.filter(f => f.endsWith('.json') && f.startsWith('DEBUG-'))
|
|
158
|
+
.sort()
|
|
159
|
+
.reverse()
|
|
160
|
+
.slice(0, 10);
|
|
161
|
+
return files.map(f => {
|
|
162
|
+
const session = JSON.parse(fs.readFileSync(path.join(debugDir, f), 'utf-8'));
|
|
163
|
+
return {
|
|
164
|
+
id: session.id,
|
|
165
|
+
status: session.status,
|
|
166
|
+
description: session.report.description,
|
|
167
|
+
createdAt: session.createdAt
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
async collectContext(problemType, config) {
|
|
172
|
+
switch (problemType) {
|
|
173
|
+
case 'task_failure':
|
|
174
|
+
return config.taskId ? await this.collector.collectForTaskFailure(config.taskId) : {};
|
|
175
|
+
case 'project_bug':
|
|
176
|
+
return await this.collector.collectForProjectBug();
|
|
177
|
+
case 'environment':
|
|
178
|
+
return await this.collector.collectForEnvironment();
|
|
179
|
+
case 'system_bug':
|
|
180
|
+
return await this.collector.collectForSystemBug();
|
|
181
|
+
default:
|
|
182
|
+
return {};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async getTaskError(taskId) {
|
|
186
|
+
const taskPath = path.join(this.omPath, 'tasks', `${taskId}.json`);
|
|
187
|
+
if (!fs.existsSync(taskPath))
|
|
188
|
+
return null;
|
|
189
|
+
try {
|
|
190
|
+
const task = JSON.parse(fs.readFileSync(taskPath, 'utf-8'));
|
|
191
|
+
return task.error || null;
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
saveSession(session) {
|
|
198
|
+
const debugDir = path.join(this.omPath, 'debug');
|
|
199
|
+
if (!fs.existsSync(debugDir)) {
|
|
200
|
+
fs.mkdirSync(debugDir, { recursive: true });
|
|
201
|
+
}
|
|
202
|
+
const sessionPath = this.getSessionPath(session.id);
|
|
203
|
+
fs.writeFileSync(sessionPath, JSON.stringify(session, null, 2), 'utf-8');
|
|
204
|
+
}
|
|
205
|
+
getSessionPath(sessionId) {
|
|
206
|
+
return path.join(this.omPath, 'debug', `${sessionId}.json`);
|
|
207
|
+
}
|
|
208
|
+
generateSessionId() {
|
|
209
|
+
const timestamp = Date.now().toString(36).toUpperCase();
|
|
210
|
+
const random = Math.random().toString(36).substring(2, 5).toUpperCase();
|
|
211
|
+
return `DEBUG-${timestamp}${random}`;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.DebugManager = DebugManager;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DebugSession } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* 生成和保存诊断报告
|
|
4
|
+
*/
|
|
5
|
+
export declare class DebugReporter {
|
|
6
|
+
private debugDir;
|
|
7
|
+
constructor(basePath: string);
|
|
8
|
+
/**
|
|
9
|
+
* 生成诊断报告文件
|
|
10
|
+
*/
|
|
11
|
+
generateReport(session: DebugSession): Promise<string>;
|
|
12
|
+
/**
|
|
13
|
+
* 格式化报告内容为 Markdown
|
|
14
|
+
*/
|
|
15
|
+
private formatReport;
|
|
16
|
+
/**
|
|
17
|
+
* 列出所有诊断报告
|
|
18
|
+
*/
|
|
19
|
+
listReports(): {
|
|
20
|
+
id: string;
|
|
21
|
+
path: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
}[];
|
|
24
|
+
private ensureDir;
|
|
25
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DebugReporter = void 0;
|
|
37
|
+
// src/orchestrator/debug-reporter.ts
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
/**
|
|
41
|
+
* 生成和保存诊断报告
|
|
42
|
+
*/
|
|
43
|
+
class DebugReporter {
|
|
44
|
+
debugDir;
|
|
45
|
+
constructor(basePath) {
|
|
46
|
+
this.debugDir = path.join(basePath, 'debug');
|
|
47
|
+
this.ensureDir();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 生成诊断报告文件
|
|
51
|
+
*/
|
|
52
|
+
async generateReport(session) {
|
|
53
|
+
const report = session.report;
|
|
54
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
55
|
+
const fileName = `${report.id}-report-${timestamp}.md`;
|
|
56
|
+
const filePath = path.join(this.debugDir, fileName);
|
|
57
|
+
const content = this.formatReport(session);
|
|
58
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
59
|
+
return filePath;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 格式化报告内容为 Markdown
|
|
63
|
+
*/
|
|
64
|
+
formatReport(session) {
|
|
65
|
+
const { report, fixResult, verifyResult } = session;
|
|
66
|
+
let md = `# Debug Report\n\n`;
|
|
67
|
+
md += `**会话 ID**: ${session.id}\n`;
|
|
68
|
+
md += `**日期**: ${session.createdAt}\n`;
|
|
69
|
+
md += `**状态**: ${session.status}\n`;
|
|
70
|
+
if (session.completedAt) {
|
|
71
|
+
md += `**完成时间**: ${session.completedAt}\n`;
|
|
72
|
+
}
|
|
73
|
+
md += `\n---\n\n`;
|
|
74
|
+
// 问题描述
|
|
75
|
+
md += `## 问题描述\n\n${report.description}\n\n`;
|
|
76
|
+
// 问题类型
|
|
77
|
+
md += `## 问题类型\n\n\`${report.problemType}\`\n\n`;
|
|
78
|
+
if (report.relatedTaskId) {
|
|
79
|
+
md += `**关联任务**: ${report.relatedTaskId}\n\n`;
|
|
80
|
+
}
|
|
81
|
+
// 诊断结果
|
|
82
|
+
md += `## 诊断结果\n\n`;
|
|
83
|
+
md += `### 根因\n\n${report.rootCause}\n\n`;
|
|
84
|
+
if (report.errorInfo) {
|
|
85
|
+
md += `### 错误信息\n\n`;
|
|
86
|
+
md += `\`\`\`\n${report.errorInfo.message}\n\`\`\`\n\n`;
|
|
87
|
+
if (report.errorInfo.stack) {
|
|
88
|
+
md += `### 错误栈\n\n\`\`\`\n${report.errorInfo.stack}\n\`\`\`\n\n`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// 影响范围
|
|
92
|
+
if (report.impactScope.length > 0) {
|
|
93
|
+
md += `### 影响范围\n\n`;
|
|
94
|
+
report.impactScope.forEach((item) => { md += `- ${item}\n`; });
|
|
95
|
+
md += `\n`;
|
|
96
|
+
}
|
|
97
|
+
// 相关文件
|
|
98
|
+
if (report.relatedFiles && report.relatedFiles.length > 0) {
|
|
99
|
+
md += `### 相关文件\n\n`;
|
|
100
|
+
report.relatedFiles.forEach((file) => { md += `- \`${file}\`\n`; });
|
|
101
|
+
md += `\n`;
|
|
102
|
+
}
|
|
103
|
+
// 修复建议
|
|
104
|
+
md += `## 修复建议\n\n${report.suggestedFix}\n\n`;
|
|
105
|
+
// 修复操作
|
|
106
|
+
if (fixResult) {
|
|
107
|
+
md += `## 修复操作\n\n`;
|
|
108
|
+
if (fixResult.success) {
|
|
109
|
+
md += `✅ 修复成功\n\n`;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
md += `❌ 修复未完全生效\n\n`;
|
|
113
|
+
}
|
|
114
|
+
if (fixResult.modifiedFiles.length > 0) {
|
|
115
|
+
md += `### 修改文件\n\n`;
|
|
116
|
+
fixResult.modifiedFiles.forEach((file) => { md += `- \`${file}\`\n`; });
|
|
117
|
+
md += `\n`;
|
|
118
|
+
}
|
|
119
|
+
if (fixResult.operations.length > 0) {
|
|
120
|
+
md += `### 执行操作\n\n`;
|
|
121
|
+
fixResult.operations.forEach((op) => { md += `- ${op}\n`; });
|
|
122
|
+
md += `\n`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// 验证结果
|
|
126
|
+
if (verifyResult) {
|
|
127
|
+
md += `## 验证结果\n\n`;
|
|
128
|
+
if (verifyResult.passed) {
|
|
129
|
+
md += `✅ 验证通过\n\n`;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
md += `❌ 验证未通过\n\n`;
|
|
133
|
+
}
|
|
134
|
+
md += `${verifyResult.details}\n\n`;
|
|
135
|
+
}
|
|
136
|
+
// 重试信息
|
|
137
|
+
if (session.retryCount > 0) {
|
|
138
|
+
md += `## 重试信息\n\n已尝试 ${session.retryCount} 次修复\n\n`;
|
|
139
|
+
if (session.retryCount >= 3) {
|
|
140
|
+
md += `⚠️ **已尝试 3 次以上修复,建议暂停并质疑架构**\n\n`;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return md;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 列出所有诊断报告
|
|
147
|
+
*/
|
|
148
|
+
listReports() {
|
|
149
|
+
if (!fs.existsSync(this.debugDir))
|
|
150
|
+
return [];
|
|
151
|
+
const files = fs.readdirSync(this.debugDir)
|
|
152
|
+
.filter(f => f.endsWith('-report.md') || f.includes('-report-'))
|
|
153
|
+
.sort()
|
|
154
|
+
.reverse();
|
|
155
|
+
return files.map(f => ({
|
|
156
|
+
id: f.split('-')[0],
|
|
157
|
+
path: path.join(this.debugDir, f),
|
|
158
|
+
createdAt: f
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
ensureDir() {
|
|
162
|
+
if (!fs.existsSync(this.debugDir)) {
|
|
163
|
+
fs.mkdirSync(this.debugDir, { recursive: true });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.DebugReporter = DebugReporter;
|
|
@@ -251,6 +251,12 @@ ${task.acceptanceCriteria?.map((c, i) => `${i + 1}. ${c}`).join('\n') || '根据
|
|
|
251
251
|
## 验证
|
|
252
252
|
运行 \`npm test\` 确认测试失败 (这是正确的!)
|
|
253
253
|
|
|
254
|
+
## ⚠️ Git 提交规范
|
|
255
|
+
|
|
256
|
+
**禁止执行 \`git commit\`**
|
|
257
|
+
|
|
258
|
+
所有代码提交必须通过 \`openmatrix complete\` 命令统一执行。测试文件创建完成后,只需返回结果摘要,**不要执行 git commit**。
|
|
259
|
+
|
|
254
260
|
## 输出格式
|
|
255
261
|
\`\`\`
|
|
256
262
|
TDD_TESTS_CREATED
|
|
@@ -379,6 +385,17 @@ ${task.acceptanceCriteria.map((c, i) => `${i + 1}. [ ] ${c}`).join('\n')}`);
|
|
|
379
385
|
- [ ] 代码风格一致
|
|
380
386
|
- [ ] 验收标准全部满足
|
|
381
387
|
${isTDDMode ? '- [ ] 所有测试通过 (GREEN)' : ''}
|
|
388
|
+
|
|
389
|
+
## ⚠️ Git 提交规范
|
|
390
|
+
|
|
391
|
+
**禁止执行 \`git commit\`**
|
|
392
|
+
|
|
393
|
+
所有代码提交必须通过 \`openmatrix complete\` 命令统一执行,该命令会:
|
|
394
|
+
1. 使用正确的任务标题 (当前任务: ${task.title})
|
|
395
|
+
2. 自动生成规范的提交信息
|
|
396
|
+
3. 避免产生重复或无意义的提交
|
|
397
|
+
|
|
398
|
+
如果代码变更已完成,只需返回结果摘要,**不要执行 git commit**。
|
|
382
399
|
`);
|
|
383
400
|
return parts.join('\n');
|
|
384
401
|
}
|
|
@@ -659,6 +676,7 @@ Fix Required:
|
|
|
659
676
|
- **不要伪造通过结果**
|
|
660
677
|
- 如果项目没有某个脚本,标记为 "⏭️ Skipped" 而非 "❌ Failed"
|
|
661
678
|
- 所有检查结果必须基于实际命令输出
|
|
679
|
+
- **禁止执行 \`git commit\`** — 所有提交统一通过 \`openmatrix complete\` 执行
|
|
662
680
|
|
|
663
681
|
## 🔧 配置检查 (可选但推荐)
|
|
664
682
|
检查以下常见配置问题:
|
|
@@ -792,6 +810,9 @@ ACCEPT_FAILED
|
|
|
792
810
|
失败原因:
|
|
793
811
|
1. [原因]
|
|
794
812
|
\`\`\`
|
|
813
|
+
|
|
814
|
+
## ⚠️ Git 提交规范
|
|
815
|
+
**禁止执行 \`git commit\`** — 所有提交统一通过 \`openmatrix complete\` 执行,确保使用正确的任务标题。
|
|
795
816
|
`);
|
|
796
817
|
return parts.join('\n');
|
|
797
818
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ProblemType } from '../types/index.js';
|
|
2
|
+
export interface ProblemDetectionConfig {
|
|
3
|
+
description?: string;
|
|
4
|
+
taskId?: string;
|
|
5
|
+
taskError?: string | null;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 判断问题类型的检测器
|
|
9
|
+
*/
|
|
10
|
+
export declare class ProblemDetector {
|
|
11
|
+
/**
|
|
12
|
+
* 根据配置判断问题类型
|
|
13
|
+
*/
|
|
14
|
+
detect(config: ProblemDetectionConfig): Promise<ProblemType>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProblemDetector = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 判断问题类型的检测器
|
|
6
|
+
*/
|
|
7
|
+
class ProblemDetector {
|
|
8
|
+
/**
|
|
9
|
+
* 根据配置判断问题类型
|
|
10
|
+
*/
|
|
11
|
+
async detect(config) {
|
|
12
|
+
// 有任务 ID 且任务失败
|
|
13
|
+
if (config.taskId && config.taskError) {
|
|
14
|
+
return 'task_failure';
|
|
15
|
+
}
|
|
16
|
+
// 根据描述判断
|
|
17
|
+
if (config.description) {
|
|
18
|
+
const desc = config.description.toLowerCase();
|
|
19
|
+
// 环境相关关键词
|
|
20
|
+
const envKeywords = [
|
|
21
|
+
'依赖', '安装', '环境', '配置', 'npm install', 'node_modules',
|
|
22
|
+
'env', 'environment', 'dependency', 'install', 'config',
|
|
23
|
+
'path', '版本', 'version', '权限', 'permission'
|
|
24
|
+
];
|
|
25
|
+
// 项目代码相关关键词
|
|
26
|
+
const projectKeywords = [
|
|
27
|
+
'接口', 'api', '函数', 'function', '返回', 'response',
|
|
28
|
+
'数据', 'data', '逻辑', 'logic', '页面', 'page',
|
|
29
|
+
'组件', 'component', '样式', 'style', '渲染', 'render'
|
|
30
|
+
];
|
|
31
|
+
// 系统/OpenMatrix 相关关键词
|
|
32
|
+
const systemKeywords = [
|
|
33
|
+
'openmatrix', 'cli', '命令', 'command', '状态', 'state',
|
|
34
|
+
'任务', 'task', '编排', 'orchestrat', 'agent', '技能', 'skill'
|
|
35
|
+
];
|
|
36
|
+
const hasEnvKeyword = envKeywords.some(kw => desc.includes(kw));
|
|
37
|
+
const hasProjectKeyword = projectKeywords.some(kw => desc.includes(kw));
|
|
38
|
+
const hasSystemKeyword = systemKeywords.some(kw => desc.includes(kw));
|
|
39
|
+
// 优先级:环境 > 项目 > 系统
|
|
40
|
+
if (hasEnvKeyword)
|
|
41
|
+
return 'environment';
|
|
42
|
+
if (hasProjectKeyword)
|
|
43
|
+
return 'project_bug';
|
|
44
|
+
if (hasSystemKeyword)
|
|
45
|
+
return 'system_bug';
|
|
46
|
+
}
|
|
47
|
+
// 默认:系统 bug
|
|
48
|
+
return 'system_bug';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.ProblemDetector = ProblemDetector;
|
|
@@ -37,6 +37,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
37
37
|
exports.UpgradeDetector = exports.DEFAULT_DETECTOR_CONFIG = void 0;
|
|
38
38
|
const fs = __importStar(require("fs/promises"));
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
|
+
/**
|
|
41
|
+
* 已知的绝对路径前缀模式,用于检测代码中的硬编码路径
|
|
42
|
+
* 涵盖 Windows 盘符 (C:\, D:\ 等)、Unix 家目录 (/home/, /Users/) 和常见系统路径
|
|
43
|
+
*/
|
|
44
|
+
const HARDCODED_PATH_PATTERNS = [
|
|
45
|
+
/[A-Za-z]:\\/, // Windows 盘符路径 (C:\, D:\ 等)
|
|
46
|
+
/\/home\/[a-zA-Z_]/, // Linux 家目录
|
|
47
|
+
/\/Users\/[a-zA-Z_]/, // macOS 家目录
|
|
48
|
+
/\/var\/[a-zA-Z_]/, // Linux 系统路径
|
|
49
|
+
/\/etc\//, // Unix 配置路径
|
|
50
|
+
/\/tmp\//, // Unix 临时路径
|
|
51
|
+
/\/opt\//, // Unix 可选软件路径
|
|
52
|
+
/\\Users\\[a-zA-Z_]/, // Windows 风格的 macOS 路径引用
|
|
53
|
+
];
|
|
40
54
|
/**
|
|
41
55
|
* 默认配置
|
|
42
56
|
*/
|
|
@@ -301,7 +315,7 @@ class UpgradeDetector {
|
|
|
301
315
|
const content = await fs.readFile(file, 'utf-8');
|
|
302
316
|
const lines = content.split('\n');
|
|
303
317
|
lines.forEach((line, index) => {
|
|
304
|
-
//
|
|
318
|
+
// 待办标记检测
|
|
305
319
|
const todoMatch = line.match(/\/\/\s*TODO(?:\(([^)]+)\))?:?\s*(.+)/i);
|
|
306
320
|
if (todoMatch) {
|
|
307
321
|
suggestions.push(this.createSuggestion({
|
|
@@ -316,7 +330,7 @@ class UpgradeDetector {
|
|
|
316
330
|
effort: 'small'
|
|
317
331
|
}));
|
|
318
332
|
}
|
|
319
|
-
//
|
|
333
|
+
// 待修复标记检测
|
|
320
334
|
const fixmeMatch = line.match(/\/\/\s*FIXME(?:\(([^)]+)\))?:?\s*(.+)/i);
|
|
321
335
|
if (fixmeMatch) {
|
|
322
336
|
suggestions.push(this.createSuggestion({
|
|
@@ -331,18 +345,21 @@ class UpgradeDetector {
|
|
|
331
345
|
effort: 'medium'
|
|
332
346
|
}));
|
|
333
347
|
}
|
|
334
|
-
//
|
|
335
|
-
const hackMatch = line.match(/\/\/\s*HACK
|
|
348
|
+
// 临时方案标记检测
|
|
349
|
+
const hackMatch = line.match(/\/\/\s*HACK(?:\(([^)]+)\))?:?\s*(.+)/i);
|
|
336
350
|
if (hackMatch) {
|
|
351
|
+
const hackPriority = hackMatch[1] === 'critical' ? 'critical'
|
|
352
|
+
: hackMatch[1] === 'high' ? 'high'
|
|
353
|
+
: 'medium';
|
|
337
354
|
suggestions.push(this.createSuggestion({
|
|
338
355
|
category: 'bug',
|
|
339
|
-
priority:
|
|
340
|
-
title: `临时方案: ${hackMatch[
|
|
341
|
-
description: `发现 HACK
|
|
356
|
+
priority: hackPriority,
|
|
357
|
+
title: `临时方案: ${hackMatch[2]}`,
|
|
358
|
+
description: `发现 HACK 标记,表示使用了临时解决方案: ${hackMatch[2]}`,
|
|
342
359
|
location: { file: this.getRelativePath(file), line: index + 1 },
|
|
343
|
-
suggestion:
|
|
360
|
+
suggestion: `将临时方案替换为正式实现: ${hackMatch[2]}`,
|
|
344
361
|
autoFixable: false,
|
|
345
|
-
impact: '
|
|
362
|
+
impact: '技术债务累积,可能影响长期可维护性',
|
|
346
363
|
effort: 'medium'
|
|
347
364
|
}));
|
|
348
365
|
}
|
|
@@ -407,8 +424,8 @@ class UpgradeDetector {
|
|
|
407
424
|
}));
|
|
408
425
|
}
|
|
409
426
|
}
|
|
410
|
-
// console.log 检测 (
|
|
411
|
-
if (line.includes('console.log') && !file.includes('test') && !file.includes('spec')) {
|
|
427
|
+
// console.log 检测 (生产代码,排除 CLI 命令文件)
|
|
428
|
+
if (line.includes('console.log') && !file.includes('test') && !file.includes('spec') && !file.includes('commands/')) {
|
|
412
429
|
suggestions.push(this.createSuggestion({
|
|
413
430
|
category: 'quality',
|
|
414
431
|
priority: 'low',
|
|
@@ -683,7 +700,10 @@ class UpgradeDetector {
|
|
|
683
700
|
// 检测硬编码字符串
|
|
684
701
|
lines.forEach((line, index) => {
|
|
685
702
|
// 硬编码路径
|
|
686
|
-
if (
|
|
703
|
+
if (HARDCODED_PATH_PATTERNS.some(pattern => pattern.test(line))) {
|
|
704
|
+
const relPath = this.getRelativePath(file);
|
|
705
|
+
if (relPath.includes('upgrade-detector'))
|
|
706
|
+
return;
|
|
687
707
|
if (!line.includes('example') && !line.includes('test')) {
|
|
688
708
|
suggestions.push(this.createSuggestion({
|
|
689
709
|
category: 'common',
|