openmatrix 0.1.49 → 0.1.51

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.
@@ -20,24 +20,10 @@ export interface ProjectContext {
20
20
  packageManager: 'npm' | 'yarn' | 'pnpm' | 'pip' | 'go-mod' | 'cargo' | 'unknown';
21
21
  dependencies: Record<string, string>;
22
22
  }
23
- /**
24
- * 任务理解
25
- */
26
- export interface TaskUnderstanding {
27
- taskType: 'feature' | 'bugfix' | 'refactor' | 'docs' | 'test' | 'config' | 'unknown';
28
- taskTypeLabel: string;
29
- scope: string[];
30
- scopeLabel: string;
31
- complexity: 'simple' | 'medium' | 'complex';
32
- complexityLabel: string;
33
- estimatedCommits: string;
34
- suggestions: string[];
35
- }
36
23
  /**
37
24
  * 分析结果
38
25
  */
39
26
  export interface AnalysisResult {
40
- understanding: TaskUnderstanding;
41
27
  inferences: QuestionInference[];
42
28
  questionsToAsk: string[];
43
29
  skippedQuestions: string[];
@@ -65,26 +51,6 @@ export declare class SmartQuestionAnalyzer {
65
51
  * 获取项目上下文
66
52
  */
67
53
  getProjectContext(): Promise<ProjectContext>;
68
- /**
69
- * 分析任务理解
70
- */
71
- private analyzeTaskUnderstanding;
72
- /**
73
- * 检测任务类型
74
- */
75
- private detectTaskType;
76
- /**
77
- * 检测影响范围
78
- */
79
- private detectScope;
80
- /**
81
- * 检测复杂度
82
- */
83
- private detectComplexity;
84
- /**
85
- * 生成建议
86
- */
87
- private generateSuggestions;
88
54
  /**
89
55
  * 推断问题答案
90
56
  */
@@ -113,8 +79,4 @@ export declare class SmartQuestionAnalyzer {
113
79
  * 生成推断摘要
114
80
  */
115
81
  generateSummary(result: AnalysisResult): string;
116
- /**
117
- * 生成 Markdown 格式输出
118
- */
119
- generateMarkdown(result: AnalysisResult): string;
120
82
  }
@@ -58,11 +58,9 @@ class SmartQuestionAnalyzer {
58
58
  async analyze(taskDescription, parsedTask) {
59
59
  // 1. 获取项目上下文
60
60
  const projectContext = await this.getProjectContext();
61
- // 2. 分析任务理解
62
- const understanding = this.analyzeTaskUnderstanding(taskDescription, projectContext);
63
- // 3. 执行推断
61
+ // 2. 执行推断
64
62
  const inferences = this.inferAnswers(taskDescription, projectContext);
65
- // 4. 筛选需要提问的问题
63
+ // 3. 筛选需要提问的问题
66
64
  const questionsToAsk = inferences
67
65
  .filter(i => i.confidence === 'low' || !i.inferredAnswer)
68
66
  .map(i => i.questionId);
@@ -70,7 +68,6 @@ class SmartQuestionAnalyzer {
70
68
  .filter(i => i.confidence !== 'low' && i.inferredAnswer)
71
69
  .map(i => i.questionId);
72
70
  return {
73
- understanding,
74
71
  inferences,
75
72
  questionsToAsk,
76
73
  skippedQuestions,
@@ -163,199 +160,6 @@ class SmartQuestionAnalyzer {
163
160
  this.cachedContext = context;
164
161
  return context;
165
162
  }
166
- /**
167
- * 分析任务理解
168
- */
169
- analyzeTaskUnderstanding(taskDescription, context) {
170
- const desc = taskDescription.toLowerCase();
171
- // 1. 判断任务类型
172
- const taskType = this.detectTaskType(desc);
173
- // 2. 判断影响范围
174
- const scope = this.detectScope(desc, context);
175
- // 3. 判断复杂度
176
- const complexity = this.detectComplexity(desc, taskType, scope);
177
- // 4. 生成建议
178
- const suggestions = this.generateSuggestions(taskType, complexity, desc);
179
- return {
180
- taskType: taskType.type,
181
- taskTypeLabel: taskType.label,
182
- scope: scope.areas,
183
- scopeLabel: scope.label,
184
- complexity: complexity.level,
185
- complexityLabel: complexity.label,
186
- estimatedCommits: complexity.estimatedCommits,
187
- suggestions
188
- };
189
- }
190
- /**
191
- * 检测任务类型
192
- */
193
- detectTaskType(desc) {
194
- // Bug 修复
195
- if (/(fix|bug|修复|hotfix|patch|问题|报错|错误|异常)/i.test(desc)) {
196
- return { type: 'bugfix', label: 'Bug 修复' };
197
- }
198
- // 重构
199
- if (/(refactor|重构|优化|improve|改进)/i.test(desc)) {
200
- return { type: 'refactor', label: '重构优化' };
201
- }
202
- // 文档
203
- if (/(doc|文档|readme|文档|注释)/i.test(desc)) {
204
- return { type: 'docs', label: '文档编写' };
205
- }
206
- // 测试
207
- if (/(test|测试|单元|unit|coverage|覆盖率)/i.test(desc)) {
208
- return { type: 'test', label: '测试编写' };
209
- }
210
- // 配置
211
- if (/(config|配置|设置|setup|初始化)/i.test(desc)) {
212
- return { type: 'config', label: '配置修改' };
213
- }
214
- // 新功能 (默认)
215
- if (/(implement|add|新功能|实现|开发|feature|添加|创建)/i.test(desc)) {
216
- return { type: 'feature', label: '新功能开发' };
217
- }
218
- return { type: 'unknown', label: '待确认' };
219
- }
220
- /**
221
- * 检测影响范围
222
- */
223
- detectScope(desc, context) {
224
- const areas = [];
225
- // 从描述中检测
226
- if (/(前端|页面|ui|样式|css|html|react|vue|component)/i.test(desc)) {
227
- areas.push('前端');
228
- }
229
- if (/(后端|api|服务|server|接口|数据库|database)/i.test(desc)) {
230
- areas.push('后端');
231
- }
232
- if (/(cli|命令行|终端|terminal)/i.test(desc)) {
233
- areas.push('CLI');
234
- }
235
- if (/(测试|test|spec)/i.test(desc)) {
236
- areas.push('测试');
237
- }
238
- if (/(文档|doc|readme)/i.test(desc)) {
239
- areas.push('文档');
240
- }
241
- if (/(配置|config)/i.test(desc)) {
242
- areas.push('配置');
243
- }
244
- // 从项目上下文补充
245
- if (areas.length === 0) {
246
- if (context.hasFrontend)
247
- areas.push('前端');
248
- if (context.hasBackend)
249
- areas.push('后端');
250
- }
251
- // 默认
252
- if (areas.length === 0) {
253
- areas.push('代码');
254
- }
255
- const label = areas.join('、');
256
- return { areas, label };
257
- }
258
- /**
259
- * 检测复杂度
260
- */
261
- detectComplexity(desc, taskType, scope) {
262
- // 简单任务关键词
263
- const simpleKeywords = /(fix|bug|修复|改|调整|样式|变量名|文案|按钮|颜色|字体)/i;
264
- // 复杂任务关键词 - 需要更精确
265
- const complexKeywords = /(系统|架构|集成|完整|从零|优化整体|多模块|全栈)/i;
266
- const multiScope = scope.areas.length >= 3;
267
- // Bug 修复
268
- if (taskType.type === 'bugfix') {
269
- if (simpleKeywords.test(desc) || desc.length < 50) {
270
- return { level: 'simple', label: '简单', estimatedCommits: '预计 1 个 commit' };
271
- }
272
- return { level: 'medium', label: '中等', estimatedCommits: '预计 1-2 个 commit' };
273
- }
274
- // 文档、配置
275
- if (taskType.type === 'docs' || taskType.type === 'config') {
276
- return { level: 'simple', label: '简单', estimatedCommits: '预计 1 个 commit' };
277
- }
278
- // 测试
279
- if (taskType.type === 'test') {
280
- if (multiScope) {
281
- return { level: 'medium', label: '中等', estimatedCommits: '预计 2-3 个 commit' };
282
- }
283
- return { level: 'simple', label: '简单', estimatedCommits: '预计 1 个 commit' };
284
- }
285
- // 复杂关键词检测
286
- if (complexKeywords.test(desc) || multiScope) {
287
- return { level: 'complex', label: '复杂', estimatedCommits: '预计 3+ 个 commit' };
288
- }
289
- // 新功能 - 默认 medium
290
- if (taskType.type === 'feature') {
291
- // 只有非常简单的单文件修改才判断为 simple
292
- if (desc.length < 20 && scope.areas.length === 1 && /(按钮|链接|文案|颜色)/.test(desc)) {
293
- return { level: 'simple', label: '简单', estimatedCommits: '预计 1 个 commit' };
294
- }
295
- if (desc.length > 100 || scope.areas.length >= 2) {
296
- return { level: 'medium', label: '中等', estimatedCommits: '预计 2-3 个 commit' };
297
- }
298
- return { level: 'medium', label: '中等', estimatedCommits: '预计 2-3 个 commit' };
299
- }
300
- // 重构 - 默认 medium
301
- if (taskType.type === 'refactor') {
302
- if (multiScope || /(整体|全部|系统)/.test(desc)) {
303
- return { level: 'complex', label: '复杂', estimatedCommits: '预计 3+ 个 commit' };
304
- }
305
- return { level: 'medium', label: '中等', estimatedCommits: '预计 2-3 个 commit' };
306
- }
307
- // 默认中等
308
- return { level: 'medium', label: '中等', estimatedCommits: '预计 1-2 个 commit' };
309
- }
310
- /**
311
- * 生成建议
312
- */
313
- generateSuggestions(taskType, complexity, desc) {
314
- const suggestions = [];
315
- // 复杂任务优先建议头脑风暴
316
- if (complexity.level === 'complex') {
317
- suggestions.push('建议先头脑风暴,明确需求');
318
- }
319
- // 根据任务类型建议
320
- switch (taskType.type) {
321
- case 'bugfix':
322
- suggestions.push('直接修复,无需 TDD');
323
- suggestions.push('使用 fast 模式');
324
- break;
325
- case 'feature':
326
- if (complexity.level === 'complex') {
327
- suggestions.push('使用 strict 模式保证质量');
328
- }
329
- else {
330
- suggestions.push('使用 balanced 模式');
331
- }
332
- break;
333
- case 'refactor':
334
- suggestions.push('确保测试覆盖');
335
- suggestions.push('使用 balanced 模式');
336
- break;
337
- case 'test':
338
- suggestions.push('使用 fast 或 balanced 模式');
339
- break;
340
- case 'docs':
341
- suggestions.push('无需测试');
342
- suggestions.push('使用 fast 模式');
343
- break;
344
- case 'config':
345
- suggestions.push('注意配置安全');
346
- suggestions.push('使用 fast 模式');
347
- break;
348
- default:
349
- if (complexity.level !== 'complex') {
350
- suggestions.push('根据实际情况选择模式');
351
- }
352
- }
353
- // 确保至少有一个建议
354
- if (suggestions.length === 0) {
355
- suggestions.push('建议先确认任务需求');
356
- }
357
- return suggestions;
358
- }
359
163
  /**
360
164
  * 推断问题答案
361
165
  */
@@ -584,21 +388,7 @@ class SmartQuestionAnalyzer {
584
388
  * 生成推断摘要
585
389
  */
586
390
  generateSummary(result) {
587
- const lines = [];
588
- // 任务理解
589
- lines.push('🔍 我理解的任务:\n');
590
- lines.push(`📋 类型: ${result.understanding.taskTypeLabel}`);
591
- lines.push(`📁 范围: ${result.understanding.scopeLabel}`);
592
- lines.push(`⚡ 复杂度: ${result.understanding.complexityLabel} (${result.understanding.estimatedCommits})`);
593
- // 建议
594
- if (result.understanding.suggestions.length > 0) {
595
- lines.push('\n💡 建议执行方式:');
596
- for (const suggestion of result.understanding.suggestions) {
597
- lines.push(` • ${suggestion}`);
598
- }
599
- }
600
- // 推断结果
601
- lines.push('\n📊 配置推断:');
391
+ const lines = ['📊 AI 推断结果:\n'];
602
392
  for (const inference of result.inferences) {
603
393
  const icon = inference.confidence === 'high' ? '✅' :
604
394
  inference.confidence === 'medium' ? '🤔' : '❓';
@@ -606,55 +396,15 @@ class SmartQuestionAnalyzer {
606
396
  ? inference.inferredAnswer.join(', ')
607
397
  : inference.inferredAnswer || '待确认';
608
398
  lines.push(`${icon} ${inference.questionId}: ${answer}`);
609
- }
610
- if (result.questionsToAsk.length > 0) {
611
- lines.push(`\n❓ 需要确认: ${result.questionsToAsk.join(', ')}`);
612
- }
613
- else {
614
- lines.push('\n✅ 配置已推断,可直接执行');
615
- }
616
- return lines.join('\n');
617
- }
618
- /**
619
- * 生成 Markdown 格式输出
620
- */
621
- generateMarkdown(result) {
622
- const lines = [];
623
- lines.push('## 🔍 我理解的任务\n');
624
- lines.push(`| 属性 | 值 |`);
625
- lines.push(`|------|-----|`);
626
- lines.push(`| 📋 类型 | ${result.understanding.taskTypeLabel} |`);
627
- lines.push(`| 📁 范围 | ${result.understanding.scopeLabel} |`);
628
- lines.push(`| ⚡ 复杂度 | ${result.understanding.complexityLabel} |`);
629
- lines.push(`| ⏱️ 预计 | ${result.understanding.estimatedCommits} |`);
630
- // 建议
631
- if (result.understanding.suggestions.length > 0) {
632
- lines.push('\n## 💡 建议执行方式\n');
633
- for (const suggestion of result.understanding.suggestions) {
634
- lines.push(`- ${suggestion}`);
399
+ if (inference.reason) {
400
+ lines.push(` └─ ${inference.reason}`);
635
401
  }
636
402
  }
637
- // 推断的配置
638
- lines.push('\n## 📊 推荐配置\n');
639
- lines.push(`| 配置项 | 推荐值 | 置信度 |`);
640
- lines.push(`|--------|--------|--------|`);
641
- for (const inference of result.inferences) {
642
- const answer = Array.isArray(inference.inferredAnswer)
643
- ? inference.inferredAnswer.join(', ')
644
- : inference.inferredAnswer || '待确认';
645
- const confidenceIcon = inference.confidence === 'high' ? '✅' :
646
- inference.confidence === 'medium' ? '🤔' : '❓';
647
- lines.push(`| ${inference.questionId} | ${answer} | ${confidenceIcon} |`);
648
- }
649
- // 需要确认的问题
650
403
  if (result.questionsToAsk.length > 0) {
651
- lines.push('\n## 需要确认\n');
652
- for (const q of result.questionsToAsk) {
653
- lines.push(`- ${q}`);
654
- }
404
+ lines.push(`\n❓ 需要确认的问题: ${result.questionsToAsk.join(', ')}`);
655
405
  }
656
406
  else {
657
- lines.push('\n✅ **所有配置已推断,可直接执行**');
407
+ lines.push('\n✅ 所有问题已推断,无需额外确认');
658
408
  }
659
409
  return lines.join('\n');
660
410
  }
@@ -1,15 +1,29 @@
1
1
  import type { ParsedTask } from '../types/index.js';
2
- /**
3
- * TaskParser - 任务解析器
4
- *
5
- * 职责:解析用户输入的任务描述,提取结构化信息
6
- *
7
- * 注意:TaskParser 只负责格式解析,不做业务逻辑判断
8
- * 任务拆解的智能逻辑应该由 TaskPlanner (调用 AI) 来完成
9
- */
10
2
  export declare class TaskParser {
11
3
  parse(content: string): ParsedTask;
12
4
  private extractTitle;
13
5
  private extractDescription;
14
6
  private extractSection;
7
+ /**
8
+ * 从纯文本中智能提取 goals
9
+ *
10
+ * 策略优先级:
11
+ * 1. 有序列表 (1. xxx, 2. xxx)
12
+ * 2. 无序列表 (- xxx, * xxx)
13
+ * 3. 分号/换行分隔的多行描述
14
+ * 4. 将标题作为唯一 goal
15
+ */
16
+ private extractGoalsFromPlainText;
17
+ /**
18
+ * 提取有序列表项
19
+ */
20
+ private extractOrderedItems;
21
+ /**
22
+ * 提取无序列表项
23
+ */
24
+ private extractUnorderedItems;
25
+ /**
26
+ * 从文本中提取句子作为 goals
27
+ */
28
+ private extractSentences;
15
29
  }
@@ -1,14 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TaskParser = void 0;
4
- /**
5
- * TaskParser - 任务解析器
6
- *
7
- * 职责:解析用户输入的任务描述,提取结构化信息
8
- *
9
- * 注意:TaskParser 只负责格式解析,不做业务逻辑判断
10
- * 任务拆解的智能逻辑应该由 TaskPlanner (调用 AI) 来完成
11
- */
12
4
  class TaskParser {
13
5
  parse(content) {
14
6
  const title = this.extractTitle(content);
@@ -16,53 +8,61 @@ class TaskParser {
16
8
  const constraints = this.extractSection(content, '约束');
17
9
  const deliverables = this.extractSection(content, '交付物');
18
10
  const description = this.extractDescription(content);
11
+ // Fallback: 当 markdown section 未提取到 goals 时,智能提取
12
+ const finalGoals = goals.length > 0
13
+ ? goals
14
+ : this.extractGoalsFromPlainText(content, title);
15
+ // Fallback: 当无 deliverables 时,从 goals 推断
16
+ const finalDeliverables = deliverables.length > 0
17
+ ? deliverables
18
+ : finalGoals.map(g => `${g} 的实现`);
19
19
  return {
20
20
  title,
21
- description,
22
- goals: [...new Set(goals)], // 去重
23
- constraints: [...new Set(constraints)], // 去重
24
- deliverables: [...new Set(deliverables)], // 去重
21
+ description: description || (finalGoals.length > 0 ? finalGoals[0] : title),
22
+ goals: [...new Set(finalGoals)],
23
+ constraints: [...new Set(constraints)],
24
+ deliverables: [...new Set(finalDeliverables)],
25
25
  rawContent: content
26
26
  };
27
27
  }
28
28
  extractTitle(content) {
29
- // 1. 从第一个 # 标题提取
30
- const headerMatch = content.match(/^#\s+(.+)$/m);
31
- if (headerMatch) {
32
- return headerMatch[1].trim();
33
- }
34
- // 2. 没有标题,取第一行非空内容(截断到 50 字符)
35
- const firstLine = content.split('\n').find(l => l.trim());
36
- return firstLine ? firstLine.trim().slice(0, 50) : 'Untitled Task';
29
+ const match = content.match(/^#\s+(.+)$/m);
30
+ return match ? match[1].trim() : 'Untitled Task';
37
31
  }
38
32
  extractDescription(content) {
39
- // 移除标题和 sections,获取第一段
40
- let desc = content
41
- .replace(/^#\s+.+$/m, '')
42
- .replace(/^##\s+.+$/gm, '')
43
- .replace(/^- .+$/gm, '')
44
- .trim();
45
- // 获取第一个非空行
33
+ // Remove title line
34
+ let desc = content.replace(/^#\s+.+$/m, '').trim();
35
+ // Remove section headers
36
+ desc = desc.replace(/^##\s+.+$/gm, '').trim();
37
+ // Get first non-empty, non-list line as description
46
38
  const lines = desc.split('\n').filter(l => l.trim());
47
- return lines.length > 0 ? lines[0].trim() : '';
39
+ for (const line of lines) {
40
+ const trimmed = line.trim();
41
+ // Skip list items, section headers
42
+ if (/^[-*]\s+/.test(trimmed))
43
+ continue;
44
+ if (/^\d+\.\s+/.test(trimmed))
45
+ continue;
46
+ if (trimmed.length > 0) {
47
+ return trimmed;
48
+ }
49
+ }
50
+ return '';
48
51
  }
49
52
  extractSection(content, sectionName) {
50
53
  const lines = content.split('\n');
51
54
  const items = [];
52
55
  let inSection = false;
53
56
  for (const line of lines) {
54
- // 检查是否进入目标 section
55
57
  if (line.match(new RegExp(`^##\\s+${sectionName}\\s*$`))) {
56
58
  inSection = true;
57
59
  continue;
58
60
  }
59
- // 检查是否进入其他 section
60
61
  if (line.match(/^##\s+/)) {
61
62
  if (inSection)
62
63
  break;
63
64
  continue;
64
65
  }
65
- // 提取列表项
66
66
  if (inSection) {
67
67
  const itemMatch = line.match(/^-\s+(.+)$/);
68
68
  if (itemMatch) {
@@ -72,5 +72,92 @@ class TaskParser {
72
72
  }
73
73
  return items;
74
74
  }
75
+ /**
76
+ * 从纯文本中智能提取 goals
77
+ *
78
+ * 策略优先级:
79
+ * 1. 有序列表 (1. xxx, 2. xxx)
80
+ * 2. 无序列表 (- xxx, * xxx)
81
+ * 3. 分号/换行分隔的多行描述
82
+ * 4. 将标题作为唯一 goal
83
+ */
84
+ extractGoalsFromPlainText(content, title) {
85
+ const goals = [];
86
+ const cleanContent = content
87
+ .replace(/^#\s+.+$/m, '') // 去标题
88
+ .replace(/^##\s+.+$/gm, '') // 去section标题
89
+ .trim();
90
+ // 策略1: 有序列表 (1. xxx, 2. xxx, ...)
91
+ const orderedItems = this.extractOrderedItems(cleanContent);
92
+ if (orderedItems.length > 0) {
93
+ return orderedItems;
94
+ }
95
+ // 策略2: 无序列表 (- xxx, * xxx)
96
+ const unorderedItems = this.extractUnorderedItems(cleanContent);
97
+ if (unorderedItems.length > 0) {
98
+ return unorderedItems;
99
+ }
100
+ // 策略3: 多行文本,按句号/分号拆分为多个 goal
101
+ const sentences = this.extractSentences(cleanContent);
102
+ if (sentences.length > 1) {
103
+ return sentences;
104
+ }
105
+ // 策略4: 单个句子作为唯一 goal
106
+ if (sentences.length === 1 && sentences[0].length > 0) {
107
+ return sentences;
108
+ }
109
+ // 策略5: 将标题作为唯一 goal
110
+ if (title && title !== 'Untitled Task') {
111
+ return [title];
112
+ }
113
+ return goals;
114
+ }
115
+ /**
116
+ * 提取有序列表项
117
+ */
118
+ extractOrderedItems(text) {
119
+ const items = [];
120
+ const lines = text.split('\n');
121
+ for (const line of lines) {
122
+ const match = line.trim().match(/^\d+[.、)\s]+(.+)$/);
123
+ if (match) {
124
+ const item = match[1].trim();
125
+ if (item.length > 0) {
126
+ items.push(item);
127
+ }
128
+ }
129
+ }
130
+ return items;
131
+ }
132
+ /**
133
+ * 提取无序列表项
134
+ */
135
+ extractUnorderedItems(text) {
136
+ const items = [];
137
+ const lines = text.split('\n');
138
+ for (const line of lines) {
139
+ const match = line.trim().match(/^[-*]\s+(.+)$/);
140
+ if (match) {
141
+ const item = match[1].trim();
142
+ if (item.length > 0) {
143
+ items.push(item);
144
+ }
145
+ }
146
+ }
147
+ return items;
148
+ }
149
+ /**
150
+ * 从文本中提取句子作为 goals
151
+ */
152
+ extractSentences(text) {
153
+ if (!text || text.trim().length === 0)
154
+ return [];
155
+ // 按中文句号、英文句号、分号拆分
156
+ const sentences = text
157
+ .split(/[。;\n]/)
158
+ .map(s => s.replace(/[.;]/g, '').trim())
159
+ .filter(s => s.length > 2); // 过滤太短的片段
160
+ return sentences;
161
+ }
75
162
  }
76
163
  exports.TaskParser = TaskParser;
@@ -1,4 +1,4 @@
1
- import type { ParsedTask } from '../types/index.js';
1
+ import type { ParsedTask, QualityConfig } from '../types/index.js';
2
2
  export interface TaskBreakdown {
3
3
  taskId: string;
4
4
  title: string;
@@ -17,34 +17,61 @@ export interface UserAnswers {
17
17
  testCoverage?: string;
18
18
  documentationLevel?: string;
19
19
  additionalContext?: Record<string, string>;
20
+ /** 是否启用 E2E 测试 */
21
+ e2eTests?: boolean;
22
+ /** E2E 测试类型 (web/mobile/gui) */
23
+ e2eType?: 'web' | 'mobile' | 'gui';
24
+ /** 质量级别 */
25
+ qualityLevel?: 'fast' | 'balanced' | 'strict';
20
26
  }
21
27
  /**
22
28
  * TaskPlanner - 任务拆解器
23
29
  *
24
- * 1. 按 goals 拆分为多个 coder + tester 任务对
25
- * 2. goals 为空时退化为 3 任务模式 (planner → coder → tester)
26
- * 3. 自动注入用户上下文和验收标准
30
+ * 增强版特性:
31
+ * 1. 更细粒度的任务拆分 (每个目标拆分为设计+实现+测试)
32
+ * 2. 测试任务配对 (每个开发任务自动生成对应测试任务)
33
+ * 3. 验收标准注入 (从用户回答中提取)
34
+ * 4. 用户上下文注入 (将用户回答注入任务描述)
35
+ * 5. 依赖关系分析 (自动分析任务间依赖)
36
+ * 6. 并行执行 (独立任务互不依赖)
37
+ * 7. 质量级别感知 (根据配置调整测试覆盖率)
27
38
  */
28
39
  export declare class TaskPlanner {
40
+ private userAnswers;
41
+ private taskCounter;
42
+ constructor(userAnswers?: UserAnswers);
43
+ /**
44
+ * 设置用户回答
45
+ */
46
+ setUserAnswers(answers: UserAnswers): void;
29
47
  /**
30
48
  * Break down a parsed task into sub-tasks
31
49
  */
32
- breakdown(parsedTask: ParsedTask, answers: Record<string, string>): TaskBreakdown[];
50
+ breakdown(parsedTask: ParsedTask, answers: Record<string, string>, qualityConfig?: QualityConfig, plan?: string): TaskBreakdown[];
51
+ /**
52
+ * 判断是否需要设计阶段
53
+ *
54
+ * 条件: 多个 goal,或 goal 包含复杂关键词
55
+ */
56
+ private needsDesignPhase;
33
57
  /**
34
- * 按 goals 拆分: 每个 goal 一个 coder + 一个 tester
58
+ * 获取测试覆盖率目标
35
59
  */
36
- private breakdownByGoals;
60
+ private getCoverageTarget;
37
61
  /**
38
- * 无 goals 时的退化模式: planner → coder → tester
39
- * 把 rawContent 整体交给 planner 分析,生成 PLAN.md
40
- * coder 基于 PLAN.md 实现
62
+ * 提取用户上下文
41
63
  */
42
- private breakdownFallback;
43
64
  private extractUserContext;
44
65
  private parseArrayAnswer;
66
+ /**
67
+ * 构建全局上下文块(注入到每个子任务描述中)
68
+ */
69
+ private buildGlobalContext;
45
70
  private buildTaskDescription;
46
71
  private buildTestDescription;
47
- private parseCoverage;
72
+ private buildE2ETestDescription;
73
+ private getE2ETypeConfig;
74
+ private generateUserFlows;
48
75
  private generateAcceptanceCriteria;
49
76
  private generateTaskId;
50
77
  private determinePriority;