openmatrix 0.2.31 → 0.2.33
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/README.md +154 -154
- package/dist/cli/commands/approve.js +35 -1
- package/dist/cli/commands/auto.js +2 -2
- package/dist/cli/commands/check-gitignore.js +34 -30
- package/dist/cli/commands/check.js +1 -1
- package/dist/cli/commands/complete.js +35 -7
- package/dist/cli/commands/debug.js +2 -1
- package/dist/cli/commands/deploy.js +1 -1
- package/dist/cli/commands/install-skills.js +3 -0
- package/dist/cli/commands/meeting.js +37 -1
- package/dist/cli/commands/report.js +1 -1
- package/dist/cli/commands/resume.js +35 -1
- package/dist/cli/commands/retry.js +130 -56
- package/dist/cli/commands/start.js +1 -1
- package/dist/cli/commands/status.js +32 -29
- package/dist/cli/commands/step.js +4 -1
- package/dist/orchestrator/ai-reviewer.d.ts +5 -0
- package/dist/orchestrator/ai-reviewer.js +9 -2
- package/dist/orchestrator/context-collector.js +17 -5
- package/dist/orchestrator/executor.d.ts +8 -0
- package/dist/orchestrator/executor.js +24 -5
- package/dist/orchestrator/phase-executor.d.ts +4 -0
- package/dist/orchestrator/phase-executor.js +21 -4
- package/dist/storage/file-store.js +8 -0
- package/dist/storage/state-manager.js +52 -19
- package/dist/test/generator.js +113 -113
- package/dist/utils/error-handler.d.ts +18 -0
- package/dist/utils/error-handler.js +32 -0
- package/dist/utils/worktree-sync.js +24 -3
- package/package.json +61 -61
- package/skills/SKILL.md +53 -53
- package/skills/auto.md +410 -413
- package/skills/brainstorm.md +19 -12
- package/skills/debug.md +694 -691
- package/skills/deploy.md +658 -658
- package/skills/feature.md +713 -686
- package/skills/plan.md +298 -296
- package/skills/report.md +9 -5
- package/skills/resume.md +292 -287
- package/skills/start.md +32 -20
- package/skills/status.md +5 -4
- package/skills/test.md +875 -875
- package/dist/agents/base-agent.d.ts +0 -46
- package/dist/agents/base-agent.js +0 -17
- package/dist/cli/commands/analyze.d.ts +0 -2
- package/dist/cli/commands/analyze.js +0 -50
- package/dist/orchestrator/smart-question-analyzer.d.ts +0 -90
- package/dist/orchestrator/smart-question-analyzer.js +0 -512
|
@@ -1,512 +0,0 @@
|
|
|
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.SmartQuestionAnalyzer = void 0;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const path = __importStar(require("path"));
|
|
39
|
-
/**
|
|
40
|
-
* SmartQuestionAnalyzer - 智能问答分析器
|
|
41
|
-
*
|
|
42
|
-
* 根据任务描述和项目上下文智能推断问题答案,减少不必要的问答
|
|
43
|
-
*
|
|
44
|
-
* 使用方式:
|
|
45
|
-
* 1. 分析项目文件获取上下文
|
|
46
|
-
* 2. 根据任务关键词推断答案
|
|
47
|
-
* 3. 返回需要提问的问题列表
|
|
48
|
-
*/
|
|
49
|
-
class SmartQuestionAnalyzer {
|
|
50
|
-
projectRoot;
|
|
51
|
-
cachedContext = null;
|
|
52
|
-
constructor(projectRoot = process.cwd()) {
|
|
53
|
-
this.projectRoot = projectRoot;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* 分析任务,返回推断结果
|
|
57
|
-
*/
|
|
58
|
-
async analyze(taskDescription, parsedTask) {
|
|
59
|
-
// 1. 获取项目上下文
|
|
60
|
-
const projectContext = await this.getProjectContext();
|
|
61
|
-
// 2. 如果 parsedTask 有 goalTypes,优先使用
|
|
62
|
-
let goalTypeOverride;
|
|
63
|
-
if (parsedTask?.goalTypes && parsedTask.goalTypes.length > 0) {
|
|
64
|
-
goalTypeOverride = parsedTask.goalTypes[0];
|
|
65
|
-
}
|
|
66
|
-
// 3. 执行推断
|
|
67
|
-
const inferences = this.inferAnswers(taskDescription, projectContext, goalTypeOverride);
|
|
68
|
-
// 4. 筛选需要提问的问题
|
|
69
|
-
const questionsToAsk = inferences
|
|
70
|
-
.filter(i => i.confidence === 'low' || !i.inferredAnswer)
|
|
71
|
-
.map(i => i.questionId);
|
|
72
|
-
const skippedQuestions = inferences
|
|
73
|
-
.filter(i => i.confidence !== 'low' && i.inferredAnswer)
|
|
74
|
-
.map(i => i.questionId);
|
|
75
|
-
return {
|
|
76
|
-
inferences,
|
|
77
|
-
questionsToAsk,
|
|
78
|
-
skippedQuestions,
|
|
79
|
-
projectContext
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* 获取项目上下文
|
|
84
|
-
*/
|
|
85
|
-
async getProjectContext() {
|
|
86
|
-
if (this.cachedContext) {
|
|
87
|
-
return this.cachedContext;
|
|
88
|
-
}
|
|
89
|
-
const context = {
|
|
90
|
-
projectType: 'unknown',
|
|
91
|
-
frameworks: [],
|
|
92
|
-
hasFrontend: false,
|
|
93
|
-
hasBackend: false,
|
|
94
|
-
hasTests: false,
|
|
95
|
-
packageManager: 'unknown',
|
|
96
|
-
dependencies: {}
|
|
97
|
-
};
|
|
98
|
-
// 检测项目类型和依赖
|
|
99
|
-
const packageJsonPath = path.join(this.projectRoot, 'package.json');
|
|
100
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
101
|
-
try {
|
|
102
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
103
|
-
context.packageManager = 'npm';
|
|
104
|
-
context.dependencies = {
|
|
105
|
-
...packageJson.dependencies,
|
|
106
|
-
...packageJson.devDependencies
|
|
107
|
-
};
|
|
108
|
-
// 检测 TypeScript
|
|
109
|
-
if (context.dependencies['typescript'] || fs.existsSync(path.join(this.projectRoot, 'tsconfig.json'))) {
|
|
110
|
-
context.projectType = 'typescript';
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
context.projectType = 'javascript';
|
|
114
|
-
}
|
|
115
|
-
// 检测框架
|
|
116
|
-
const frameworkDeps = {
|
|
117
|
-
'react': 'React',
|
|
118
|
-
'vue': 'Vue',
|
|
119
|
-
'svelte': 'Svelte',
|
|
120
|
-
'angular': 'Angular',
|
|
121
|
-
'next': 'Next.js',
|
|
122
|
-
'nuxt': 'Nuxt.js',
|
|
123
|
-
'express': 'Express',
|
|
124
|
-
'fastify': 'Fastify',
|
|
125
|
-
'nestjs': 'NestJS',
|
|
126
|
-
'koa': 'Koa',
|
|
127
|
-
'electron': 'Electron'
|
|
128
|
-
};
|
|
129
|
-
for (const [dep, name] of Object.entries(frameworkDeps)) {
|
|
130
|
-
if (context.dependencies[dep]) {
|
|
131
|
-
context.frameworks.push(name);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// 检测前端/后端
|
|
135
|
-
context.hasFrontend = ['react', 'vue', 'svelte', 'angular', 'next', 'nuxt', 'electron']
|
|
136
|
-
.some(dep => context.dependencies[dep]);
|
|
137
|
-
context.hasBackend = ['express', 'fastify', 'nestjs', 'koa']
|
|
138
|
-
.some(dep => context.dependencies[dep]);
|
|
139
|
-
// 检测测试
|
|
140
|
-
context.hasTests = ['vitest', 'jest', 'mocha', 'pytest', 'testing']
|
|
141
|
-
.some(dep => context.dependencies[dep]) ||
|
|
142
|
-
fs.existsSync(path.join(this.projectRoot, 'tests')) ||
|
|
143
|
-
fs.existsSync(path.join(this.projectRoot, 'test'));
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
// 忽略解析错误
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
// 检测 Python 项目
|
|
150
|
-
if (fs.existsSync(path.join(this.projectRoot, 'requirements.txt')) ||
|
|
151
|
-
fs.existsSync(path.join(this.projectRoot, 'pyproject.toml'))) {
|
|
152
|
-
context.projectType = 'python';
|
|
153
|
-
context.packageManager = 'pip';
|
|
154
|
-
}
|
|
155
|
-
// 检测 Go 项目
|
|
156
|
-
if (fs.existsSync(path.join(this.projectRoot, 'go.mod'))) {
|
|
157
|
-
context.projectType = 'go';
|
|
158
|
-
context.packageManager = 'go-mod';
|
|
159
|
-
}
|
|
160
|
-
// 检测 Rust 项目
|
|
161
|
-
if (fs.existsSync(path.join(this.projectRoot, 'Cargo.toml'))) {
|
|
162
|
-
context.projectType = 'rust';
|
|
163
|
-
context.packageManager = 'cargo';
|
|
164
|
-
}
|
|
165
|
-
this.cachedContext = context;
|
|
166
|
-
return context;
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* 推断问题答案
|
|
170
|
-
*/
|
|
171
|
-
inferAnswers(taskDescription, context, goalTypeOverride) {
|
|
172
|
-
const inferences = [];
|
|
173
|
-
const desc = taskDescription.toLowerCase();
|
|
174
|
-
// 1. 推断质量级别
|
|
175
|
-
inferences.push(this.inferQualityLevel(desc, context));
|
|
176
|
-
// 2. 推断技术栈
|
|
177
|
-
inferences.push(this.inferTechStack(desc, context));
|
|
178
|
-
// 3. 推断文档级别
|
|
179
|
-
inferences.push(this.inferDocLevel(desc, context));
|
|
180
|
-
// 4. 推断 E2E 测试
|
|
181
|
-
inferences.push(this.inferE2ETest(desc, context));
|
|
182
|
-
// 5. 推断执行模式
|
|
183
|
-
inferences.push(this.inferExecutionMode(desc, context));
|
|
184
|
-
// 6. 推断任务目标类型
|
|
185
|
-
inferences.push(this.inferObjective(desc, context));
|
|
186
|
-
// 7. 推断测试覆盖率级别
|
|
187
|
-
inferences.push(this.inferTestCoverage(desc, context));
|
|
188
|
-
// 8. 如果有 goalTypeOverride,覆盖 objective 推断
|
|
189
|
-
if (goalTypeOverride) {
|
|
190
|
-
const objectiveInference = inferences.find(i => i.questionId === 'objective');
|
|
191
|
-
if (objectiveInference) {
|
|
192
|
-
objectiveInference.inferredAnswer = goalTypeOverride;
|
|
193
|
-
objectiveInference.confidence = 'high';
|
|
194
|
-
objectiveInference.reason = '来自 AI 任务解析的目标类型标注';
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return inferences;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* 推断质量级别
|
|
201
|
-
*/
|
|
202
|
-
inferQualityLevel(desc, context) {
|
|
203
|
-
const inference = {
|
|
204
|
-
questionId: 'quality_level',
|
|
205
|
-
confidence: 'low',
|
|
206
|
-
reason: ''
|
|
207
|
-
};
|
|
208
|
-
// Bug 修复 -> balanced
|
|
209
|
-
if (/(fix|bug|修复|hotfix|patch|问题)/i.test(desc)) {
|
|
210
|
-
inference.inferredAnswer = 'balanced';
|
|
211
|
-
inference.confidence = 'high';
|
|
212
|
-
inference.reason = '任务涉及 Bug 修复';
|
|
213
|
-
return inference;
|
|
214
|
-
}
|
|
215
|
-
// 原型/POC -> fast
|
|
216
|
-
if (/(prototype|poc|demo|快速|原型|示例|sample)/i.test(desc)) {
|
|
217
|
-
inference.inferredAnswer = 'fast';
|
|
218
|
-
inference.confidence = 'high';
|
|
219
|
-
inference.reason = '任务涉及原型或演示';
|
|
220
|
-
return inference;
|
|
221
|
-
}
|
|
222
|
-
// 测试相关 -> strict
|
|
223
|
-
if (/(test|测试|单元|unit|coverage|覆盖率)/i.test(desc)) {
|
|
224
|
-
inference.inferredAnswer = 'strict';
|
|
225
|
-
inference.confidence = 'high';
|
|
226
|
-
inference.reason = '任务涉及测试';
|
|
227
|
-
return inference;
|
|
228
|
-
}
|
|
229
|
-
// 新功能/生产代码 -> strict
|
|
230
|
-
if (/(implement|add|新功能|实现|开发|feature|生产)/i.test(desc)) {
|
|
231
|
-
inference.inferredAnswer = 'strict';
|
|
232
|
-
inference.confidence = 'medium';
|
|
233
|
-
inference.reason = '任务涉及新功能开发';
|
|
234
|
-
return inference;
|
|
235
|
-
}
|
|
236
|
-
// 重构 -> balanced
|
|
237
|
-
if (/(refactor|优化|重构|improve)/i.test(desc)) {
|
|
238
|
-
inference.inferredAnswer = 'balanced';
|
|
239
|
-
inference.confidence = 'medium';
|
|
240
|
-
inference.reason = '任务涉及代码重构';
|
|
241
|
-
return inference;
|
|
242
|
-
}
|
|
243
|
-
inference.reason = '无法确定任务类型';
|
|
244
|
-
return inference;
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* 推断技术栈
|
|
248
|
-
*/
|
|
249
|
-
inferTechStack(desc, context) {
|
|
250
|
-
const inference = {
|
|
251
|
-
questionId: 'tech_stack',
|
|
252
|
-
confidence: 'low',
|
|
253
|
-
reason: ''
|
|
254
|
-
};
|
|
255
|
-
const detected = [];
|
|
256
|
-
// 从项目上下文检测
|
|
257
|
-
if (context.projectType === 'typescript') {
|
|
258
|
-
detected.push('typescript');
|
|
259
|
-
}
|
|
260
|
-
else if (context.projectType === 'python') {
|
|
261
|
-
detected.push('python');
|
|
262
|
-
}
|
|
263
|
-
else if (context.projectType === 'go') {
|
|
264
|
-
detected.push('go');
|
|
265
|
-
}
|
|
266
|
-
else if (context.projectType === 'rust') {
|
|
267
|
-
detected.push('rust');
|
|
268
|
-
}
|
|
269
|
-
// 从任务描述检测
|
|
270
|
-
const techKeywords = {
|
|
271
|
-
'typescript': ['typescript', 'ts', 'tsx'],
|
|
272
|
-
'javascript': ['javascript', 'js', 'jsx'],
|
|
273
|
-
'react': ['react', 'reactjs'],
|
|
274
|
-
'vue': ['vue', 'vuejs', 'vue3'],
|
|
275
|
-
'node': ['node', 'nodejs', 'express', 'koa'],
|
|
276
|
-
'python': ['python', 'py', 'django', 'flask', 'fastapi'],
|
|
277
|
-
'go': ['golang', 'go'],
|
|
278
|
-
'rust': ['rust', 'cargo']
|
|
279
|
-
};
|
|
280
|
-
for (const [tech, keywords] of Object.entries(techKeywords)) {
|
|
281
|
-
if (keywords.some(kw => desc.includes(kw))) {
|
|
282
|
-
if (!detected.includes(tech)) {
|
|
283
|
-
detected.push(tech);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
// 从项目框架检测
|
|
288
|
-
for (const framework of context.frameworks) {
|
|
289
|
-
const normalized = framework.toLowerCase();
|
|
290
|
-
if (!detected.includes(normalized)) {
|
|
291
|
-
detected.push(normalized);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
if (detected.length > 0) {
|
|
295
|
-
inference.inferredAnswer = detected;
|
|
296
|
-
inference.confidence = context.projectType !== 'unknown' ? 'high' : 'medium';
|
|
297
|
-
inference.reason = `检测到技术栈: ${detected.join(', ')}`;
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
inference.reason = '无法检测技术栈';
|
|
301
|
-
}
|
|
302
|
-
return inference;
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* 推断文档级别
|
|
306
|
-
*/
|
|
307
|
-
inferDocLevel(desc, context) {
|
|
308
|
-
const inference = {
|
|
309
|
-
questionId: 'doc_level',
|
|
310
|
-
confidence: 'low',
|
|
311
|
-
reason: ''
|
|
312
|
-
};
|
|
313
|
-
// Bug 修复 -> 无需文档
|
|
314
|
-
if (/(fix|bug|修复|hotfix)/i.test(desc)) {
|
|
315
|
-
inference.inferredAnswer = 'none';
|
|
316
|
-
inference.confidence = 'high';
|
|
317
|
-
inference.reason = 'Bug 修复通常不需要文档';
|
|
318
|
-
return inference;
|
|
319
|
-
}
|
|
320
|
-
// 重构 -> 最小文档
|
|
321
|
-
if (/(refactor|优化|重构)/i.test(desc)) {
|
|
322
|
-
inference.inferredAnswer = 'minimal';
|
|
323
|
-
inference.confidence = 'medium';
|
|
324
|
-
inference.reason = '重构任务通常需要最小文档';
|
|
325
|
-
return inference;
|
|
326
|
-
}
|
|
327
|
-
// API/模块/库 -> 完整文档
|
|
328
|
-
if (/(api|module|library|组件|库|sdk)/i.test(desc)) {
|
|
329
|
-
inference.inferredAnswer = 'full';
|
|
330
|
-
inference.confidence = 'medium';
|
|
331
|
-
inference.reason = 'API/模块开发需要完整文档';
|
|
332
|
-
return inference;
|
|
333
|
-
}
|
|
334
|
-
// 新功能 -> 基础文档
|
|
335
|
-
if (/(implement|add|新功能|实现|开发|feature)/i.test(desc)) {
|
|
336
|
-
inference.inferredAnswer = 'basic';
|
|
337
|
-
inference.confidence = 'medium';
|
|
338
|
-
inference.reason = '新功能开发需要基础文档';
|
|
339
|
-
return inference;
|
|
340
|
-
}
|
|
341
|
-
inference.reason = '无法确定文档需求';
|
|
342
|
-
return inference;
|
|
343
|
-
}
|
|
344
|
-
/**
|
|
345
|
-
* 推断 E2E 测试
|
|
346
|
-
*/
|
|
347
|
-
inferE2ETest(desc, context) {
|
|
348
|
-
const inference = {
|
|
349
|
-
questionId: 'e2e_test',
|
|
350
|
-
confidence: 'low',
|
|
351
|
-
reason: ''
|
|
352
|
-
};
|
|
353
|
-
// 文档/skill 文件 -> 不需要 E2E
|
|
354
|
-
if (/(skill|\.md|文档|readme|document|说明|指南)/i.test(desc)) {
|
|
355
|
-
inference.inferredAnswer = 'false';
|
|
356
|
-
inference.confidence = 'high';
|
|
357
|
-
inference.reason = '文档或 skill 文件修改不需要 E2E 测试';
|
|
358
|
-
return inference;
|
|
359
|
-
}
|
|
360
|
-
// CLI/后端 -> 不需要 E2E
|
|
361
|
-
if (/(cli|api|backend|后端|命令行)/i.test(desc) && !context.hasFrontend) {
|
|
362
|
-
inference.inferredAnswer = 'false';
|
|
363
|
-
inference.confidence = 'high';
|
|
364
|
-
inference.reason = 'CLI/后端任务不需要 E2E 测试';
|
|
365
|
-
return inference;
|
|
366
|
-
}
|
|
367
|
-
// 前端页面 -> 询问
|
|
368
|
-
if (context.hasFrontend || /(page|ui|前端|界面|web)/i.test(desc)) {
|
|
369
|
-
inference.confidence = 'low';
|
|
370
|
-
inference.reason = '前端任务可能需要 E2E 测试,需要用户确认';
|
|
371
|
-
return inference;
|
|
372
|
-
}
|
|
373
|
-
// 默认不需要
|
|
374
|
-
inference.inferredAnswer = 'false';
|
|
375
|
-
inference.confidence = 'medium';
|
|
376
|
-
inference.reason = '默认不需要 E2E 测试';
|
|
377
|
-
return inference;
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* 推断执行模式
|
|
381
|
-
*/
|
|
382
|
-
inferExecutionMode(desc, context) {
|
|
383
|
-
const inference = {
|
|
384
|
-
questionId: 'execution_mode',
|
|
385
|
-
confidence: 'low',
|
|
386
|
-
reason: ''
|
|
387
|
-
};
|
|
388
|
-
// 快速原型 -> 全自动
|
|
389
|
-
if (/(prototype|poc|demo|快速|原型)/i.test(desc)) {
|
|
390
|
-
inference.inferredAnswer = 'auto';
|
|
391
|
-
inference.confidence = 'medium';
|
|
392
|
-
inference.reason = '原型任务适合全自动执行';
|
|
393
|
-
return inference;
|
|
394
|
-
}
|
|
395
|
-
// 简单修复 -> 全自动
|
|
396
|
-
if (/(fix|bug|修复|hotfix)/i.test(desc) && desc.length < 100) {
|
|
397
|
-
inference.inferredAnswer = 'auto';
|
|
398
|
-
inference.confidence = 'medium';
|
|
399
|
-
inference.reason = '简单 Bug 修复适合全自动执行';
|
|
400
|
-
return inference;
|
|
401
|
-
}
|
|
402
|
-
// 新功能 -> 每阶段确认
|
|
403
|
-
if (/(implement|add|新功能|实现|开发)/i.test(desc)) {
|
|
404
|
-
inference.inferredAnswer = 'phase';
|
|
405
|
-
inference.confidence = 'medium';
|
|
406
|
-
inference.reason = '新功能开发适合每阶段确认';
|
|
407
|
-
return inference;
|
|
408
|
-
}
|
|
409
|
-
inference.reason = '无法确定执行模式';
|
|
410
|
-
return inference;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* 推断任务目标类型
|
|
414
|
-
*/
|
|
415
|
-
inferObjective(desc, context) {
|
|
416
|
-
const inference = {
|
|
417
|
-
questionId: 'objective',
|
|
418
|
-
confidence: 'low',
|
|
419
|
-
reason: ''
|
|
420
|
-
};
|
|
421
|
-
// 文档类任务 -> documentation
|
|
422
|
-
if (/(文档|document|readme|skill|\.md|说明|指南)/i.test(desc)) {
|
|
423
|
-
inference.inferredAnswer = 'documentation';
|
|
424
|
-
inference.confidence = 'high';
|
|
425
|
-
inference.reason = '任务涉及文档或 skill 文件';
|
|
426
|
-
return inference;
|
|
427
|
-
}
|
|
428
|
-
if (/(fix|bug|修复|hotfix|patch)/i.test(desc)) {
|
|
429
|
-
inference.inferredAnswer = 'development';
|
|
430
|
-
inference.confidence = 'medium';
|
|
431
|
-
inference.reason = '任务描述包含修复关键词(bug 修复属于开发)';
|
|
432
|
-
}
|
|
433
|
-
else if (/(implement|add|新功能|实现|开发|feature|新增)/i.test(desc)) {
|
|
434
|
-
inference.inferredAnswer = 'development';
|
|
435
|
-
inference.confidence = 'medium';
|
|
436
|
-
inference.reason = '任务描述包含新功能关键词';
|
|
437
|
-
}
|
|
438
|
-
else if (/(refactor|优化|重构|improve|性能)/i.test(desc)) {
|
|
439
|
-
inference.inferredAnswer = 'development';
|
|
440
|
-
inference.confidence = 'medium';
|
|
441
|
-
inference.reason = '任务描述包含重构关键词(重构属于开发)';
|
|
442
|
-
}
|
|
443
|
-
else if (/(test|测试|coverage|覆盖)/i.test(desc)) {
|
|
444
|
-
inference.inferredAnswer = 'testing';
|
|
445
|
-
inference.confidence = 'medium';
|
|
446
|
-
inference.reason = '任务描述包含测试关键词';
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
inference.reason = '无法确定任务目标类型';
|
|
450
|
-
}
|
|
451
|
-
return inference;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* 推断测试覆盖率级别
|
|
455
|
-
*/
|
|
456
|
-
inferTestCoverage(desc, context) {
|
|
457
|
-
const inference = {
|
|
458
|
-
questionId: 'test_coverage',
|
|
459
|
-
confidence: 'low',
|
|
460
|
-
reason: ''
|
|
461
|
-
};
|
|
462
|
-
if (context.hasTests && /(test|测试)/i.test(desc)) {
|
|
463
|
-
inference.inferredAnswer = 'high';
|
|
464
|
-
inference.confidence = 'medium';
|
|
465
|
-
inference.reason = '项目已有测试,且任务涉及测试';
|
|
466
|
-
}
|
|
467
|
-
else if (/(implement|add|新功能|实现|feature)/i.test(desc)) {
|
|
468
|
-
inference.inferredAnswer = 'medium';
|
|
469
|
-
inference.confidence = 'low';
|
|
470
|
-
inference.reason = '新功能任务,中等测试覆盖率';
|
|
471
|
-
}
|
|
472
|
-
else if (/(fix|bug|修复)/i.test(desc)) {
|
|
473
|
-
inference.inferredAnswer = 'low';
|
|
474
|
-
inference.confidence = 'medium';
|
|
475
|
-
inference.reason = 'Bug 修复,需要回归测试但覆盖率要求不高';
|
|
476
|
-
}
|
|
477
|
-
else if (/(prototype|poc|demo|快速|原型)/i.test(desc)) {
|
|
478
|
-
inference.inferredAnswer = 'none';
|
|
479
|
-
inference.confidence = 'medium';
|
|
480
|
-
inference.reason = '原型任务,不需要测试';
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
inference.reason = '无法确定测试覆盖率级别';
|
|
484
|
-
}
|
|
485
|
-
return inference;
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* 生成推断摘要
|
|
489
|
-
*/
|
|
490
|
-
generateSummary(result) {
|
|
491
|
-
const lines = ['📊 AI 推断结果:\n'];
|
|
492
|
-
for (const inference of result.inferences) {
|
|
493
|
-
const icon = inference.confidence === 'high' ? '✅' :
|
|
494
|
-
inference.confidence === 'medium' ? '🤔' : '❓';
|
|
495
|
-
const answer = Array.isArray(inference.inferredAnswer)
|
|
496
|
-
? inference.inferredAnswer.join(', ')
|
|
497
|
-
: inference.inferredAnswer || '待确认';
|
|
498
|
-
lines.push(`${icon} ${inference.questionId}: ${answer}`);
|
|
499
|
-
if (inference.reason) {
|
|
500
|
-
lines.push(` └─ ${inference.reason}`);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
if (result.questionsToAsk.length > 0) {
|
|
504
|
-
lines.push(`\n❓ 需要确认的问题: ${result.questionsToAsk.join(', ')}`);
|
|
505
|
-
}
|
|
506
|
-
else {
|
|
507
|
-
lines.push('\n✅ 所有问题已推断,无需额外确认');
|
|
508
|
-
}
|
|
509
|
-
return lines.join('\n');
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
exports.SmartQuestionAnalyzer = SmartQuestionAnalyzer;
|