openmatrix 0.1.15 → 0.1.16
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 +14 -10
- package/dist/orchestrator/phase-executor.d.ts +6 -0
- package/dist/orchestrator/phase-executor.js +51 -5
- package/dist/orchestrator/task-planner.d.ts +16 -0
- package/dist/orchestrator/task-planner.js +129 -1
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.js +3 -0
- package/package.json +1 -1
- package/skills/openmatrix.md +2 -0
- package/skills/start.md +60 -12
package/README.md
CHANGED
|
@@ -161,15 +161,15 @@ ls ~/.claude/commands/om/
|
|
|
161
161
|
|
|
162
162
|
### 1️⃣ 三级质量配置 (第一个问题就让你选)
|
|
163
163
|
|
|
164
|
-
| 级别 | TDD | 覆盖率 | Lint | 安全 | AI验收 | 适用场景 |
|
|
165
|
-
|
|
166
|
-
| **strict** | ✅ | >80% | ✅ 严格 | ✅ | ✅ | 🏭 **生产代码** |
|
|
167
|
-
| **balanced** | ❌ | >60% | ✅ | ✅ | ✅ | 📦 日常开发 |
|
|
168
|
-
| **fast** | ❌ | >20% | ❌ | ❌ | ❌ | 🏃 快速原型 |
|
|
164
|
+
| 级别 | TDD | 覆盖率 | Lint | 安全 | E2E测试 | AI验收 | 适用场景 |
|
|
165
|
+
|:----:|:---:|:------:|:----:|:----:|:-------:|:------:|---------|
|
|
166
|
+
| **strict** | ✅ | >80% | ✅ 严格 | ✅ | ❓ 可选 | ✅ | 🏭 **生产代码** |
|
|
167
|
+
| **balanced** | ❌ | >60% | ✅ | ✅ | ❓ 可选 | ✅ | 📦 日常开发 |
|
|
168
|
+
| **fast** | ❌ | >20% | ❌ | ❌ | ❌ | ❌ | 🏃 快速原型 |
|
|
169
169
|
|
|
170
|
-
> strict 可配置为 100%。默认 >80% 覆盖核心业务逻辑。
|
|
170
|
+
> E2E 测试耗时较长,建议根据项目需要选择。strict 可配置为 100%。默认 >80% 覆盖核心业务逻辑。
|
|
171
171
|
|
|
172
|
-
### 2️⃣
|
|
172
|
+
### 2️⃣ 七道质量门禁 (Verify 阶段)
|
|
173
173
|
|
|
174
174
|
```
|
|
175
175
|
┌─────────────────────────────────────────────────────────────┐
|
|
@@ -180,7 +180,8 @@ ls ~/.claude/commands/om/
|
|
|
180
180
|
│ 🚪 Gate 3: 覆盖率检查 >20%/60%/80% → 可配置 │
|
|
181
181
|
│ 🚪 Gate 4: Lint 检查 无 error → 可配置 │
|
|
182
182
|
│ 🚪 Gate 5: 安全扫描 npm audit → 无高危漏洞 │
|
|
183
|
-
│ 🚪 Gate 6:
|
|
183
|
+
│ 🚪 Gate 6: E2E 测试 Playwright等 → 可选 │
|
|
184
|
+
│ 🚪 Gate 7: 验收标准 用户定义 → 必须全部满足 │
|
|
184
185
|
└─────────────────────────────────────────────────────────────┘
|
|
185
186
|
```
|
|
186
187
|
|
|
@@ -378,6 +379,7 @@ Accept 阶段由 Reviewer Agent 执行:
|
|
|
378
379
|
"build": { "success": true },
|
|
379
380
|
"lint": { "errors": 0, "warnings": 3 },
|
|
380
381
|
"security": { "vulnerabilities": [] },
|
|
382
|
+
"e2e": { "passed": 5, "failed": 0, "skipped": 0 },
|
|
381
383
|
"acceptance": { "met": 5, "total": 5 }
|
|
382
384
|
}
|
|
383
385
|
```
|
|
@@ -431,7 +433,8 @@ OpenMatrix 通过 Claude Code Agent 工具**原生支持所有主流编程语言
|
|
|
431
433
|
"tdd": false,
|
|
432
434
|
"minCoverage": 60,
|
|
433
435
|
"strictLint": true,
|
|
434
|
-
"securityScan": true
|
|
436
|
+
"securityScan": true,
|
|
437
|
+
"e2eTests": false
|
|
435
438
|
},
|
|
436
439
|
"approvalPoints": ["plan", "merge"],
|
|
437
440
|
"agents": { "maxConcurrent": 3 }
|
|
@@ -452,12 +455,13 @@ cd openmatrix && npm install && npm run build && npm test
|
|
|
452
455
|
## Roadmap
|
|
453
456
|
|
|
454
457
|
- [x] TDD 模式
|
|
455
|
-
- [x]
|
|
458
|
+
- [x] 7 道质量门禁
|
|
456
459
|
- [x] Meeting 机制
|
|
457
460
|
- [x] 质量报告
|
|
458
461
|
- [x] AI 验收
|
|
459
462
|
- [x] `/om:auto` 全自动模式
|
|
460
463
|
- [x] 多语言支持 (Python/Go/Java/TypeScript 等)
|
|
464
|
+
- [x] E2E 测试支持 (Web/Mobile/GUI)
|
|
461
465
|
- [ ] VSCode 扩展
|
|
462
466
|
- [ ] CI/CD 集成
|
|
463
467
|
|
|
@@ -39,6 +39,7 @@ class PhaseExecutor {
|
|
|
39
39
|
minCoverage: 60,
|
|
40
40
|
strictLint: true,
|
|
41
41
|
securityScan: true,
|
|
42
|
+
e2eTests: false,
|
|
42
43
|
level: 'balanced'
|
|
43
44
|
};
|
|
44
45
|
constructor(stateManager, approvalManager) {
|
|
@@ -86,9 +87,9 @@ class PhaseExecutor {
|
|
|
86
87
|
*/
|
|
87
88
|
setQualityLevel(level) {
|
|
88
89
|
const presets = {
|
|
89
|
-
fast: { tdd: false, minCoverage: 0, strictLint: false, securityScan: false, level: 'fast' },
|
|
90
|
-
balanced: { tdd: false, minCoverage: 60, strictLint: true, securityScan: true, level: 'balanced' },
|
|
91
|
-
strict: { tdd: true, minCoverage: 80, strictLint: true, securityScan: true, level: 'strict' }
|
|
90
|
+
fast: { tdd: false, minCoverage: 0, strictLint: false, securityScan: false, e2eTests: false, level: 'fast' },
|
|
91
|
+
balanced: { tdd: false, minCoverage: 60, strictLint: true, securityScan: true, e2eTests: false, level: 'balanced' },
|
|
92
|
+
strict: { tdd: true, minCoverage: 80, strictLint: true, securityScan: true, e2eTests: false, level: 'strict' }
|
|
92
93
|
};
|
|
93
94
|
this.qualityConfig = presets[level];
|
|
94
95
|
this.minTestCoverage = this.qualityConfig.minCoverage;
|
|
@@ -376,6 +377,7 @@ ${isTDDMode ? '- [ ] 所有测试通过 (GREEN)' : ''}
|
|
|
376
377
|
| 覆盖率 | >= ${qc.minCoverage}% | ${qc.minCoverage > 0 ? '❌ 阻止通过' : '⚠️ 仅警告'} |
|
|
377
378
|
| Lint | ${qc.strictLint ? '无 error' : '无严重 error'} | ${qc.strictLint ? '❌ 阻止通过' : '⚠️ 仅警告'} |
|
|
378
379
|
| 安全 | 无高危漏洞 | ${qc.securityScan ? '❌ 阻止通过' : '⏭️ 跳过'} |
|
|
380
|
+
| E2E | 全部通过 | ${qc.e2eTests ? '❌ 阻止通过' : '⏭️ 跳过'} |
|
|
379
381
|
| 验收标准 | 全部满足 | ❌ 阻止通过 |
|
|
380
382
|
|
|
381
383
|
## 自动化验证命令
|
|
@@ -415,7 +417,21 @@ npm audit --audit-level=high || echo "Security scan skipped"
|
|
|
415
417
|
**要求**: 无 high/critical 漏洞
|
|
416
418
|
**失败后果**: ❌ VERIFY_FAILED` : '⏭️ 已禁用'}
|
|
417
419
|
|
|
418
|
-
### 6.
|
|
420
|
+
### 6. E2E 测试 (端到端测试)
|
|
421
|
+
${qc.e2eTests ? `\`\`\`bash
|
|
422
|
+
# Web 应用: Playwright / Cypress
|
|
423
|
+
npx playwright test || npx cypress run
|
|
424
|
+
|
|
425
|
+
# 移动端: Appium / Detox
|
|
426
|
+
npx appium ... || npx detox test
|
|
427
|
+
|
|
428
|
+
# GUI 桌面应用: 根据项目配置
|
|
429
|
+
npm run test:e2e
|
|
430
|
+
\`\`\`
|
|
431
|
+
**要求**: 所有 E2E 测试通过
|
|
432
|
+
**失败后果**: ❌ VERIFY_FAILED` : '⏭️ 已禁用'}
|
|
433
|
+
|
|
434
|
+
### 7. 验收标准验证`);
|
|
419
435
|
// 注入验收标准
|
|
420
436
|
if (task.acceptanceCriteria && task.acceptanceCriteria.length > 0) {
|
|
421
437
|
parts.push(`
|
|
@@ -458,6 +474,13 @@ ${task.acceptanceCriteria.map((c, i) => `${i + 1}. [ ] ${c}`).join('\n')}
|
|
|
458
474
|
"vulnerabilities": [],
|
|
459
475
|
"status": "pass|fail"
|
|
460
476
|
},
|
|
477
|
+
"e2e": {
|
|
478
|
+
"passed": 0,
|
|
479
|
+
"failed": 0,
|
|
480
|
+
"skipped": 0,
|
|
481
|
+
"duration": 0,
|
|
482
|
+
"status": "pass|fail|skipped"
|
|
483
|
+
},
|
|
461
484
|
"acceptance": {
|
|
462
485
|
"total": ${task.acceptanceCriteria?.length || 0},
|
|
463
486
|
"met": 0,
|
|
@@ -478,6 +501,7 @@ Quality Score: [A/B/C/D/F]
|
|
|
478
501
|
- Build: ✅ Success
|
|
479
502
|
- Lint: ✅ No errors
|
|
480
503
|
- Security: ✅ No vulnerabilities
|
|
504
|
+
${qc.e2eTests ? '- E2E: ✅ X/X passed' : ''}
|
|
481
505
|
- Acceptance: ✅ N/M criteria met
|
|
482
506
|
\`\`\`
|
|
483
507
|
|
|
@@ -712,6 +736,7 @@ ACCEPT_FAILED
|
|
|
712
736
|
build: { success: false, errors: [] },
|
|
713
737
|
lint: { errors: 0, warnings: 0 },
|
|
714
738
|
security: { vulnerabilities: 0 },
|
|
739
|
+
e2e: { passed: 0, failed: 0, skipped: 0, duration: 0 },
|
|
715
740
|
acceptance: { met: 0, total: 0 }
|
|
716
741
|
};
|
|
717
742
|
// 解析测试结果
|
|
@@ -738,13 +763,27 @@ ACCEPT_FAILED
|
|
|
738
763
|
const vulnMatch = output.match(/(\d+)\s*(?:vulnerabilities|vulnerable)/i);
|
|
739
764
|
if (vulnMatch)
|
|
740
765
|
result.security.vulnerabilities = parseInt(vulnMatch[1], 10);
|
|
766
|
+
// 解析 E2E 测试结果
|
|
767
|
+
const e2ePassedMatch = output.match(/(?:e2e|playwright|cypress|appium|detox).*?(\d+)\s*(?:passed|passing)/i);
|
|
768
|
+
if (e2ePassedMatch)
|
|
769
|
+
result.e2e.passed = parseInt(e2ePassedMatch[1], 10);
|
|
770
|
+
const e2eFailedMatch = output.match(/(?:e2e|playwright|cypress|appium|detox).*?(\d+)\s*(?:failed|failing)/i);
|
|
771
|
+
if (e2eFailedMatch)
|
|
772
|
+
result.e2e.failed = parseInt(e2eFailedMatch[1], 10);
|
|
773
|
+
const e2eSkippedMatch = output.match(/(?:e2e|playwright|cypress|appium|detox).*?(\d+)\s*skipped/i);
|
|
774
|
+
if (e2eSkippedMatch)
|
|
775
|
+
result.e2e.skipped = parseInt(e2eSkippedMatch[1], 10);
|
|
776
|
+
const e2eDurationMatch = output.match(/(?:e2e|playwright|cypress|appium|detox).*?(\d+)\s*(?:ms|s|min)/i);
|
|
777
|
+
if (e2eDurationMatch)
|
|
778
|
+
result.e2e.duration = parseInt(e2eDurationMatch[1], 10);
|
|
741
779
|
// 判断是否通过
|
|
742
780
|
const qc = this.qualityConfig;
|
|
743
781
|
const testsPassed = result.tests.failed === 0;
|
|
744
782
|
const coverageOk = result.tests.coverage >= qc.minCoverage;
|
|
745
783
|
const lintOk = qc.strictLint ? result.lint.errors === 0 : true;
|
|
746
784
|
const buildOk = result.build.success;
|
|
747
|
-
|
|
785
|
+
const e2eOk = qc.e2eTests ? result.e2e.failed === 0 : true;
|
|
786
|
+
result.passed = testsPassed && coverageOk && lintOk && buildOk && e2eOk;
|
|
748
787
|
return result;
|
|
749
788
|
}
|
|
750
789
|
/**
|
|
@@ -777,6 +816,13 @@ ACCEPT_FAILED
|
|
|
777
816
|
vulnerabilities: [],
|
|
778
817
|
status: gateResult.security.vulnerabilities === 0 ? 'pass' : 'fail'
|
|
779
818
|
},
|
|
819
|
+
e2e: {
|
|
820
|
+
passed: gateResult.e2e.passed,
|
|
821
|
+
failed: gateResult.e2e.failed,
|
|
822
|
+
skipped: gateResult.e2e.skipped,
|
|
823
|
+
duration: gateResult.e2e.duration,
|
|
824
|
+
status: qc.e2eTests ? (gateResult.e2e.failed === 0 ? 'pass' : 'fail') : 'skipped'
|
|
825
|
+
},
|
|
780
826
|
acceptance: {
|
|
781
827
|
total: task.acceptanceCriteria?.length || 0,
|
|
782
828
|
met: gateResult.acceptance.met,
|
|
@@ -17,6 +17,10 @@ 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';
|
|
20
24
|
}
|
|
21
25
|
/**
|
|
22
26
|
* TaskPlanner - 任务拆解器
|
|
@@ -57,6 +61,18 @@ export declare class TaskPlanner {
|
|
|
57
61
|
* 构建测试任务描述
|
|
58
62
|
*/
|
|
59
63
|
private buildTestDescription;
|
|
64
|
+
/**
|
|
65
|
+
* 构建 E2E 测试任务描述
|
|
66
|
+
*/
|
|
67
|
+
private buildE2ETestDescription;
|
|
68
|
+
/**
|
|
69
|
+
* 获取 E2E 测试类型配置
|
|
70
|
+
*/
|
|
71
|
+
private getE2ETypeConfig;
|
|
72
|
+
/**
|
|
73
|
+
* 生成用户流程测试用例
|
|
74
|
+
*/
|
|
75
|
+
private generateUserFlows;
|
|
60
76
|
/**
|
|
61
77
|
* 解析覆盖率数值
|
|
62
78
|
*/
|
|
@@ -164,7 +164,36 @@ ${parsedTask.deliverables.map(d => `- ${d}`).join('\n')}
|
|
|
164
164
|
]
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
|
-
// 4.
|
|
167
|
+
// 4. E2E 测试任务 (如果启用,作为 verify 阶段的一部分)
|
|
168
|
+
if (userContext.e2eTests) {
|
|
169
|
+
const e2eTaskId = this.generateTaskId();
|
|
170
|
+
const e2eType = userContext.e2eType || 'web';
|
|
171
|
+
// E2E 测试依赖所有开发任务和单元测试任务
|
|
172
|
+
const allTestDependencies = [...devTaskIds];
|
|
173
|
+
breakdowns.forEach(b => {
|
|
174
|
+
if (b.phase === 'verify' && b.title.startsWith('测试:')) {
|
|
175
|
+
allTestDependencies.push(b.taskId);
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
breakdowns.push({
|
|
179
|
+
taskId: e2eTaskId,
|
|
180
|
+
title: '端到端(E2E)测试',
|
|
181
|
+
description: this.buildE2ETestDescription(e2eType, parsedTask, userContext),
|
|
182
|
+
priority: 'P0', // E2E 测试是关键任务
|
|
183
|
+
dependencies: allTestDependencies, // 依赖所有开发任务和单元测试
|
|
184
|
+
estimatedComplexity: 'high',
|
|
185
|
+
assignedAgent: 'tester',
|
|
186
|
+
phase: 'verify',
|
|
187
|
+
acceptanceCriteria: [
|
|
188
|
+
'所有 E2E 测试用例通过',
|
|
189
|
+
'关键用户流程验证完成',
|
|
190
|
+
'跨浏览器/设备兼容性验证',
|
|
191
|
+
'E2E 测试报告已生成',
|
|
192
|
+
'无阻塞级别的缺陷'
|
|
193
|
+
]
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
// 5. 文档任务 (如果需要)
|
|
168
197
|
if (userContext.documentationLevel && userContext.documentationLevel !== '无需文档') {
|
|
169
198
|
breakdowns.push({
|
|
170
199
|
taskId: this.generateTaskId(),
|
|
@@ -196,11 +225,15 @@ ${userContext.documentationLevel}
|
|
|
196
225
|
* 提取用户上下文
|
|
197
226
|
*/
|
|
198
227
|
extractUserContext(answers) {
|
|
228
|
+
const e2eAnswer = answers['E2E测试'] || answers['e2eTests'] || answers['e2e'];
|
|
229
|
+
const e2eTypeAnswer = answers['E2E类型'] || answers['e2eType'];
|
|
199
230
|
return {
|
|
200
231
|
objective: answers['目标'] || answers['objective'],
|
|
201
232
|
techStack: this.parseArrayAnswer(answers['技术栈'] || answers['techStack']),
|
|
202
233
|
testCoverage: answers['测试'] || answers['testCoverage'],
|
|
203
234
|
documentationLevel: answers['文档'] || answers['documentationLevel'],
|
|
235
|
+
e2eTests: e2eAnswer === 'true' || e2eAnswer === '✅ 启用 E2E 测试' || e2eAnswer === '是',
|
|
236
|
+
e2eType: e2eTypeAnswer || 'web',
|
|
204
237
|
additionalContext: answers
|
|
205
238
|
};
|
|
206
239
|
}
|
|
@@ -263,6 +296,101 @@ ${devTaskId}
|
|
|
263
296
|
- 测试报告
|
|
264
297
|
- 覆盖率报告`;
|
|
265
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* 构建 E2E 测试任务描述
|
|
301
|
+
*/
|
|
302
|
+
buildE2ETestDescription(e2eType, parsedTask, userContext) {
|
|
303
|
+
const typeConfig = this.getE2ETypeConfig(e2eType);
|
|
304
|
+
return `## E2E 测试目标
|
|
305
|
+
执行完整的端到端测试,验证关键用户流程
|
|
306
|
+
|
|
307
|
+
## 应用类型
|
|
308
|
+
${typeConfig.description}
|
|
309
|
+
|
|
310
|
+
## 测试框架
|
|
311
|
+
${typeConfig.frameworks.map(f => `- ${f}`).join('\n')}
|
|
312
|
+
|
|
313
|
+
## 测试范围
|
|
314
|
+
${parsedTask.goals.map((g, i) => `${i + 1}. ${g}`).join('\n')}
|
|
315
|
+
|
|
316
|
+
## 关键用户流程
|
|
317
|
+
根据应用功能,测试以下流程:
|
|
318
|
+
${this.generateUserFlows(parsedTask, e2eType)}
|
|
319
|
+
|
|
320
|
+
## 测试环境
|
|
321
|
+
${typeConfig.environments.map(e => `- ${e}`).join('\n')}
|
|
322
|
+
|
|
323
|
+
## 测试要求
|
|
324
|
+
1. **关键路径覆盖**: 所有核心用户流程必须有 E2E 测试
|
|
325
|
+
2. **断言完整**: 每个测试步骤必须有明确的断言
|
|
326
|
+
3. **等待策略**: 使用合理的等待机制,避免硬编码延迟
|
|
327
|
+
4. **数据隔离**: 测试数据独立,不影响其他测试
|
|
328
|
+
5. **清理机制**: 测试后清理创建的数据
|
|
329
|
+
|
|
330
|
+
## 输出要求
|
|
331
|
+
- E2E 测试文件 (tests/e2e/*.spec.ts)
|
|
332
|
+
- 测试执行报告
|
|
333
|
+
- 截图/录像 (失败时)
|
|
334
|
+
- 测试覆盖率报告 (如有)
|
|
335
|
+
|
|
336
|
+
## 运行命令
|
|
337
|
+
\`\`\`bash
|
|
338
|
+
${typeConfig.runCommand}
|
|
339
|
+
\`\`\`
|
|
340
|
+
|
|
341
|
+
## 验收标准
|
|
342
|
+
- [ ] 所有 E2E 测试用例通过
|
|
343
|
+
- [ ] 关键用户流程验证完成
|
|
344
|
+
- [ ] 跨浏览器/设备兼容性验证
|
|
345
|
+
- [ ] E2E 测试报告已生成
|
|
346
|
+
- [ ] 无阻塞级别的缺陷`;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* 获取 E2E 测试类型配置
|
|
350
|
+
*/
|
|
351
|
+
getE2ETypeConfig(type) {
|
|
352
|
+
const configs = {
|
|
353
|
+
web: {
|
|
354
|
+
description: 'Web 应用 (浏览器)',
|
|
355
|
+
frameworks: ['Playwright (推荐)', 'Cypress', 'Selenium WebDriver', 'Puppeteer'],
|
|
356
|
+
environments: ['Chrome', 'Firefox', 'Safari', 'Edge', 'Mobile Viewports'],
|
|
357
|
+
runCommand: 'npx playwright test --reporter=html'
|
|
358
|
+
},
|
|
359
|
+
mobile: {
|
|
360
|
+
description: '移动应用 (iOS/Android)',
|
|
361
|
+
frameworks: ['Appium', 'Detox (React Native)', 'XCUITest (iOS)', 'Espresso (Android)'],
|
|
362
|
+
environments: ['iOS Simulator', 'Android Emulator', 'Real Devices'],
|
|
363
|
+
runCommand: 'npx appium --base-path /wd/hub && npm run test:e2e'
|
|
364
|
+
},
|
|
365
|
+
gui: {
|
|
366
|
+
description: 'GUI 桌面应用 (Electron/Native)',
|
|
367
|
+
frameworks: ['Playwright for Electron', 'Spectron (Electron)', 'Robot Framework', 'PyAutoGUI'],
|
|
368
|
+
environments: ['Windows', 'macOS', 'Linux'],
|
|
369
|
+
runCommand: 'npm run test:e2e'
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
return configs[type];
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* 生成用户流程测试用例
|
|
376
|
+
*/
|
|
377
|
+
generateUserFlows(parsedTask, type) {
|
|
378
|
+
const flows = [];
|
|
379
|
+
const goals = parsedTask.goals;
|
|
380
|
+
// 根据目标生成用户流程
|
|
381
|
+
goals.forEach((goal, i) => {
|
|
382
|
+
flows.push(`\n### 流程 ${i + 1}: ${goal}`);
|
|
383
|
+
flows.push('```gherkin');
|
|
384
|
+
flows.push(`Feature: ${goal}`);
|
|
385
|
+
flows.push('');
|
|
386
|
+
flows.push(' Scenario: 正常流程');
|
|
387
|
+
flows.push(` Given 用户已启动应用`);
|
|
388
|
+
flows.push(` When 用户执行 "${goal}" 操作`);
|
|
389
|
+
flows.push(` Then 操作成功完成`);
|
|
390
|
+
flows.push('```');
|
|
391
|
+
});
|
|
392
|
+
return flows.join('\n');
|
|
393
|
+
}
|
|
266
394
|
/**
|
|
267
395
|
* 解析覆盖率数值
|
|
268
396
|
*/
|
package/dist/types/index.d.ts
CHANGED
|
@@ -107,6 +107,8 @@ export interface QualityConfig {
|
|
|
107
107
|
strictLint: boolean;
|
|
108
108
|
/** 安全扫描 */
|
|
109
109
|
securityScan: boolean;
|
|
110
|
+
/** 端到端测试 (适用于 Web 项目等需要 E2E 测试的场景) */
|
|
111
|
+
e2eTests: boolean;
|
|
110
112
|
/** 质量级别 */
|
|
111
113
|
level: 'fast' | 'balanced' | 'strict';
|
|
112
114
|
}
|
|
@@ -141,6 +143,14 @@ export interface QualityReport {
|
|
|
141
143
|
vulnerabilities: SecurityVulnerability[];
|
|
142
144
|
status: 'pass' | 'fail';
|
|
143
145
|
};
|
|
146
|
+
/** E2E 测试结果 */
|
|
147
|
+
e2e: {
|
|
148
|
+
passed: number;
|
|
149
|
+
failed: number;
|
|
150
|
+
skipped: number;
|
|
151
|
+
duration: number;
|
|
152
|
+
status: 'pass' | 'fail' | 'skipped';
|
|
153
|
+
};
|
|
144
154
|
/** 验收标准检查 */
|
|
145
155
|
acceptance: {
|
|
146
156
|
total: number;
|
package/dist/types/index.js
CHANGED
|
@@ -11,6 +11,7 @@ exports.QUALITY_PRESETS = {
|
|
|
11
11
|
minCoverage: 0,
|
|
12
12
|
strictLint: false,
|
|
13
13
|
securityScan: false,
|
|
14
|
+
e2eTests: false,
|
|
14
15
|
level: 'fast'
|
|
15
16
|
},
|
|
16
17
|
balanced: {
|
|
@@ -18,6 +19,7 @@ exports.QUALITY_PRESETS = {
|
|
|
18
19
|
minCoverage: 60,
|
|
19
20
|
strictLint: true,
|
|
20
21
|
securityScan: true,
|
|
22
|
+
e2eTests: false,
|
|
21
23
|
level: 'balanced'
|
|
22
24
|
},
|
|
23
25
|
strict: {
|
|
@@ -25,6 +27,7 @@ exports.QUALITY_PRESETS = {
|
|
|
25
27
|
minCoverage: 80,
|
|
26
28
|
strictLint: true,
|
|
27
29
|
securityScan: true,
|
|
30
|
+
e2eTests: false, // 让用户选择,因为 E2E 测试耗时
|
|
28
31
|
level: 'strict'
|
|
29
32
|
}
|
|
30
33
|
};
|
package/package.json
CHANGED
package/skills/openmatrix.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: openmatrix
|
|
3
3
|
description: "Invoke /om:start for any implementation task - adding features, fixing bugs, refactoring, creating commands, writing code, building systems. Use this when user describes work to be done, not for questions or information requests."
|
|
4
|
+
priority: high
|
|
5
|
+
always_load: true
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
<objective>
|
package/skills/start.md
CHANGED
|
@@ -54,11 +54,11 @@ description: 启动新的任务执行周期
|
|
|
54
54
|
options: [
|
|
55
55
|
{
|
|
56
56
|
label: "🚀 strict (推荐生产代码)",
|
|
57
|
-
description: "TDD + 80%覆盖率 + 严格Lint + 安全扫描 + AI验收"
|
|
57
|
+
description: "TDD + 80%覆盖率 + 严格Lint + 安全扫描 + AI验收 (E2E可选)"
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
label: "⚖️ balanced (日常开发)",
|
|
61
|
-
description: "60%覆盖率 + Lint + 安全扫描 + AI验收"
|
|
61
|
+
description: "60%覆盖率 + Lint + 安全扫描 + AI验收 (E2E可选)"
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
label: "⚡ fast (快速原型)",
|
|
@@ -70,6 +70,52 @@ description: 启动新的任务执行周期
|
|
|
70
70
|
})
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
**⚠️ 如果用户选择 "strict" 或 "balanced",追问 E2E 测试:**
|
|
74
|
+
```typescript
|
|
75
|
+
AskUserQuestion({
|
|
76
|
+
questions: [{
|
|
77
|
+
question: "是否需要端到端(E2E)测试?(适用于 Web、移动端、GUI 桌面应用等需要完整用户流程测试的场景,较耗时)",
|
|
78
|
+
header: "E2E测试",
|
|
79
|
+
options: [
|
|
80
|
+
{
|
|
81
|
+
label: "✅ 启用 E2E 测试",
|
|
82
|
+
description: "添加端到端测试,验证完整用户流程(Playwright/Cypress/Appium等)"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
label: "❌ 不需要",
|
|
86
|
+
description: "仅运行单元测试和集成测试"
|
|
87
|
+
}
|
|
88
|
+
],
|
|
89
|
+
multiSelect: false
|
|
90
|
+
}]
|
|
91
|
+
})
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**⚠️ 如果用户启用 E2E 测试,追问应用类型:**
|
|
95
|
+
```typescript
|
|
96
|
+
AskUserQuestion({
|
|
97
|
+
questions: [{
|
|
98
|
+
question: "选择应用类型以确定 E2E 测试方案:",
|
|
99
|
+
header: "应用类型",
|
|
100
|
+
options: [
|
|
101
|
+
{
|
|
102
|
+
label: "🌐 Web 应用",
|
|
103
|
+
description: "浏览器应用 - Playwright/Cypress/Selenium"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
label: "📱 移动应用",
|
|
107
|
+
description: "iOS/Android - Appium/Detox/XCUITest/Espresso"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
label: "🖥️ GUI 桌面应用",
|
|
111
|
+
description: "Electron/原生桌面 - Playwright/Spectron/Robot Framework"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
multiSelect: false
|
|
115
|
+
}]
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
73
119
|
**问题 1: 任务目标**
|
|
74
120
|
```typescript
|
|
75
121
|
AskUserQuestion({
|
|
@@ -390,36 +436,38 @@ $ARGUMENTS
|
|
|
390
436
|
<notes>
|
|
391
437
|
## 质量级别详解
|
|
392
438
|
|
|
393
|
-
| 级别 | TDD | 覆盖率 | Lint | 安全扫描 | AI验收 | 适用场景 |
|
|
394
|
-
|
|
395
|
-
| **strict** | ✅ | >80% | ✅ 严格 | ✅ | ✅ | 生产代码、核心功能 |
|
|
396
|
-
| **balanced** | ❌ | >60% | ✅ | ✅ | ✅ | 日常开发 (默认) |
|
|
397
|
-
| **fast** | ❌ | >20% | ❌ | ❌ | ❌ | 快速原型、POC |
|
|
439
|
+
| 级别 | TDD | 覆盖率 | Lint | 安全扫描 | E2E测试 | AI验收 | 适用场景 |
|
|
440
|
+
|------|:---:|:------:|:----:|:--------:|:-------:|:------:|---------|
|
|
441
|
+
| **strict** | ✅ | >80% | ✅ 严格 | ✅ | ❓ 可选 | ✅ | 生产代码、核心功能 |
|
|
442
|
+
| **balanced** | ❌ | >60% | ✅ | ✅ | ❓ 可选 | ✅ | 日常开发 (默认) |
|
|
443
|
+
| **fast** | ❌ | >20% | ❌ | ❌ | ❌ | ❌ | 快速原型、POC |
|
|
398
444
|
|
|
399
|
-
> strict 可配置为 100%。80% 覆盖核心业务逻辑,100% 成本高收益低。
|
|
445
|
+
> E2E 测试耗时较长,即使在严格模式下也建议根据项目需要选择。strict 可配置为 100%。80% 覆盖核心业务逻辑,100% 成本高收益低。
|
|
400
446
|
|
|
401
447
|
### strict 模式 (推荐生产代码)
|
|
402
448
|
```
|
|
403
449
|
🧪 TDD 阶段: 先写测试 (RED) → 测试必须失败
|
|
404
450
|
✨ 开发阶段: 再写代码 (GREEN) → 测试必须通过
|
|
405
|
-
✅ 验证阶段:
|
|
451
|
+
✅ 验证阶段: 7道质量门禁
|
|
406
452
|
├── Gate 1: 编译检查 (必须通过)
|
|
407
453
|
├── Gate 2: 测试运行 (必须通过)
|
|
408
454
|
├── Gate 3: 覆盖率 >= 80% (必须达标)
|
|
409
455
|
├── Gate 4: Lint 无 error (必须通过)
|
|
410
456
|
├── Gate 5: 安全扫描无高危 (必须通过)
|
|
411
|
-
|
|
457
|
+
├── Gate 6: E2E 测试通过 (必须通过,Web项目)
|
|
458
|
+
└── Gate 7: 验收标准全部满足
|
|
412
459
|
🎉 验收阶段: AI Reviewer 最终确认
|
|
413
460
|
```
|
|
414
461
|
|
|
415
462
|
### balanced 模式 (日常开发)
|
|
416
463
|
```
|
|
417
464
|
✨ 开发阶段: 编写代码
|
|
418
|
-
✅ 验证阶段: 4道质量门禁
|
|
465
|
+
✅ 验证阶段: 4-5道质量门禁
|
|
419
466
|
├── Gate 1: 编译检查
|
|
420
467
|
├── Gate 2: 测试运行
|
|
421
468
|
├── Gate 3: 覆盖率 >= 60%
|
|
422
|
-
|
|
469
|
+
├── Gate 4: E2E 测试 (可选,Web项目)
|
|
470
|
+
└── Gate 5: 验收标准
|
|
423
471
|
🎉 验收阶段: AI Reviewer 确认
|
|
424
472
|
```
|
|
425
473
|
|