openmatrix 0.2.1 → 0.2.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.
- package/dist/cli/commands/auto.js +20 -6
- package/dist/cli/commands/complete.js +1 -1
- package/dist/cli/commands/meeting.js +0 -1
- package/dist/cli/commands/start.js +9 -2
- package/dist/cli/commands/status.js +0 -1
- package/dist/orchestrator/ai-reviewer.d.ts +1 -1
- package/dist/orchestrator/ai-reviewer.js +2 -2
- package/dist/orchestrator/answer-mapper.d.ts +1 -0
- package/dist/orchestrator/answer-mapper.js +5 -2
- package/dist/orchestrator/executor.js +9 -3
- package/dist/orchestrator/interactive-question-generator.js +4 -3
- package/dist/orchestrator/phase-executor.js +2 -1
- package/dist/orchestrator/state-machine.js +2 -2
- package/dist/orchestrator/task-planner.d.ts +2 -2
- package/dist/orchestrator/task-planner.js +21 -4
- package/dist/storage/state-manager.js +12 -12
- package/package.json +1 -1
- package/skills/start.md +18 -7
|
@@ -151,26 +151,40 @@ exports.autoCommand = new commander_1.Command('auto')
|
|
|
151
151
|
console.log(`\n📋 任务: ${parsedTask.title}`);
|
|
152
152
|
console.log(` 目标: ${parsedTask.goals.join(', ')}`);
|
|
153
153
|
}
|
|
154
|
+
// 获取质量配置(在 breakdown 之前,因为需要传入)
|
|
155
|
+
const qualityConfig = index_js_1.QUALITY_PRESETS[qualityLevel];
|
|
154
156
|
// 拆解任务
|
|
155
157
|
if (!options.json) {
|
|
156
158
|
console.log('\n🔧 拆解任务...');
|
|
157
159
|
}
|
|
158
160
|
const planner = new task_planner_js_1.TaskPlanner();
|
|
159
|
-
const subTasks = planner.breakdown(parsedTask, {});
|
|
160
|
-
//
|
|
161
|
+
const subTasks = planner.breakdown(parsedTask, {}, qualityConfig);
|
|
162
|
+
// 创建任务到状态管理器,并建立 ID 映射
|
|
163
|
+
// TaskPlanner 生成的 taskId 和 StateManager 创建的 id 不同,
|
|
164
|
+
// 需要映射后才能正确设置 dependencies
|
|
165
|
+
const taskIdMap = new Map();
|
|
161
166
|
for (const subTask of subTasks) {
|
|
162
|
-
await stateManager.createTask({
|
|
167
|
+
const created = await stateManager.createTask({
|
|
163
168
|
title: subTask.title,
|
|
164
169
|
description: subTask.description,
|
|
165
170
|
priority: subTask.priority,
|
|
166
171
|
timeout: subTask.estimatedComplexity === 'high' ? 300000 :
|
|
167
172
|
subTask.estimatedComplexity === 'medium' ? 180000 : 120000,
|
|
168
|
-
dependencies:
|
|
173
|
+
dependencies: [],
|
|
169
174
|
assignedAgent: subTask.assignedAgent
|
|
170
175
|
});
|
|
176
|
+
taskIdMap.set(subTask.taskId, created.id);
|
|
177
|
+
}
|
|
178
|
+
// 映射并更新依赖关系
|
|
179
|
+
for (const subTask of subTasks) {
|
|
180
|
+
const actualId = taskIdMap.get(subTask.taskId);
|
|
181
|
+
const resolvedDeps = subTask.dependencies
|
|
182
|
+
.map(dep => taskIdMap.get(dep))
|
|
183
|
+
.filter((id) => id !== undefined);
|
|
184
|
+
if (resolvedDeps.length > 0) {
|
|
185
|
+
await stateManager.updateTask(actualId, { dependencies: resolvedDeps });
|
|
186
|
+
}
|
|
171
187
|
}
|
|
172
|
-
// 获取质量配置
|
|
173
|
-
const qualityConfig = index_js_1.QUALITY_PRESETS[qualityLevel];
|
|
174
188
|
// auto 模式: 空审批点数组 = bypass permissions
|
|
175
189
|
const approvalPoints = [];
|
|
176
190
|
// 更新状态
|
|
@@ -58,7 +58,7 @@ exports.completeCommand = new commander_1.Command('complete')
|
|
|
58
58
|
const task = await stateManager.getTask(taskId);
|
|
59
59
|
if (!task) {
|
|
60
60
|
console.log(JSON.stringify({ error: `任务 ${taskId} 不存在` }));
|
|
61
|
-
|
|
61
|
+
return;
|
|
62
62
|
}
|
|
63
63
|
const isSuccess = !options.failed;
|
|
64
64
|
const now = new Date().toISOString();
|
|
@@ -59,6 +59,7 @@ exports.startCommand = new commander_1.Command('start')
|
|
|
59
59
|
.option('--docs <level>', '文档级别 (full|basic|minimal|none)')
|
|
60
60
|
.option('--tasks-json <json>', 'AI 已拆分的任务 JSON (跳过自动解析)')
|
|
61
61
|
.option('--e2e-tests', '启用 E2E 测试')
|
|
62
|
+
.option('--e2e-type <type>', 'E2E 测试类型 (web|visual)')
|
|
62
63
|
.option('--research-context <path>', '研究上下文 JSON 路径 (来自 /om:research 的 context.json)')
|
|
63
64
|
.action(async (input, options) => {
|
|
64
65
|
const basePath = process.cwd();
|
|
@@ -266,15 +267,21 @@ async function handleTasksJson(options, stateManager, state, omPath, basePath) {
|
|
|
266
267
|
if (tasksInput.e2eTests || options.e2eTests) {
|
|
267
268
|
qualityConfig.e2eTests = true;
|
|
268
269
|
}
|
|
270
|
+
// E2E 类型(通过 answers 传递给 TaskPlanner)
|
|
271
|
+
const extraAnswers = { ...(resolvedInput.answers || {}) };
|
|
272
|
+
// tasks-input.json 中的 e2eType 或 CLI 参数
|
|
273
|
+
const e2eTypeValue = tasksInput.e2eType || options.e2eType;
|
|
274
|
+
if (e2eTypeValue) {
|
|
275
|
+
extraAnswers.e2eType = e2eTypeValue;
|
|
276
|
+
}
|
|
269
277
|
if (!options.json) {
|
|
270
278
|
console.log(`\n📋 任务: ${parsedTask.title}`);
|
|
271
279
|
console.log(` 目标: ${parsedTask.goals.join(', ')}`);
|
|
272
280
|
console.log('\n🔧 拆解任务...');
|
|
273
281
|
}
|
|
274
282
|
// 使用 TaskPlanner 拆分(保持原有拆分逻辑)
|
|
275
|
-
const answers = resolvedInput.answers || {};
|
|
276
283
|
const planner = new task_planner_js_1.TaskPlanner();
|
|
277
|
-
const subTasks = planner.breakdown(parsedTask,
|
|
284
|
+
const subTasks = planner.breakdown(parsedTask, extraAnswers, qualityConfig, resolvedInput.plan);
|
|
278
285
|
// 创建任务到状态管理器,并建立 ID 映射
|
|
279
286
|
// TaskPlanner 生成的 taskId 和 StateManager 创建的 id 不同,
|
|
280
287
|
// 需要映射后才能正确设置 dependencies
|
|
@@ -171,7 +171,7 @@ AI_REVIEW_REJECTED
|
|
|
171
171
|
/**
|
|
172
172
|
* 解析 AI Review 结果
|
|
173
173
|
*/
|
|
174
|
-
parseReviewResult(output) {
|
|
174
|
+
parseReviewResult(taskId, output) {
|
|
175
175
|
const lines = output.split('\n');
|
|
176
176
|
const issues = [];
|
|
177
177
|
const categories = [];
|
|
@@ -249,7 +249,7 @@ AI_REVIEW_REJECTED
|
|
|
249
249
|
const summaryMatch = output.match(/## 总结\s*([\s\S]*?)(?=```|$)/);
|
|
250
250
|
const summary = summaryMatch ? summaryMatch[1].trim() : '';
|
|
251
251
|
return {
|
|
252
|
-
taskId
|
|
252
|
+
taskId,
|
|
253
253
|
overallStatus,
|
|
254
254
|
categories,
|
|
255
255
|
issues,
|
|
@@ -98,11 +98,14 @@ function extractTasksInputFields(answers) {
|
|
|
98
98
|
if (typeof mode === 'string') {
|
|
99
99
|
result.mode = mode;
|
|
100
100
|
}
|
|
101
|
-
// e2e_tests → e2eTests 布尔字段
|
|
101
|
+
// e2e_tests → e2eTests 布尔字段 + e2eType
|
|
102
102
|
const e2e = answers['e2e_tests'] || answers['e2eTests'] || answers['E2E测试'];
|
|
103
103
|
if (e2e !== undefined) {
|
|
104
104
|
const e2eStr = Array.isArray(e2e) ? e2e[0] : e2e;
|
|
105
|
-
result.e2eTests = e2eStr === 'true' || e2eStr === '启用 E2E 测试' || e2eStr === '是';
|
|
105
|
+
result.e2eTests = e2eStr === 'functional' || e2eStr === 'visual' || e2eStr === 'true' || e2eStr === '启用 E2E 测试' || e2eStr === '是';
|
|
106
|
+
if (result.e2eTests && e2eStr === 'visual') {
|
|
107
|
+
result.e2eType = 'visual';
|
|
108
|
+
}
|
|
106
109
|
}
|
|
107
110
|
return result;
|
|
108
111
|
}
|
|
@@ -318,7 +318,7 @@ class OrchestratorExecutor {
|
|
|
318
318
|
* 处理 Review 结果:解析报告,如有 critical/major 问题则自动创建修复任务
|
|
319
319
|
*/
|
|
320
320
|
async processReviewResult(taskId, output) {
|
|
321
|
-
const report = this.aiReviewer.parseReviewResult(output);
|
|
321
|
+
const report = this.aiReviewer.parseReviewResult(taskId, output);
|
|
322
322
|
const task = await this.stateManager.getTask(taskId);
|
|
323
323
|
if (!task)
|
|
324
324
|
return {};
|
|
@@ -416,10 +416,16 @@ class OrchestratorExecutor {
|
|
|
416
416
|
*/
|
|
417
417
|
async processRetries(failedTasks) {
|
|
418
418
|
let retried = 0;
|
|
419
|
-
|
|
419
|
+
let limit;
|
|
420
|
+
try {
|
|
421
|
+
const state = await this.stateManager.getState();
|
|
422
|
+
limit = state.config.maxRetries;
|
|
423
|
+
}
|
|
424
|
+
catch {
|
|
425
|
+
limit = 3;
|
|
426
|
+
}
|
|
420
427
|
for (const task of failedTasks) {
|
|
421
428
|
const currentRetryCount = task.retryCount || 0;
|
|
422
|
-
const limit = await maxRetries;
|
|
423
429
|
// 先检查是否还有重试次数,再决定是否加入队列
|
|
424
430
|
if (currentRetryCount >= limit) {
|
|
425
431
|
console.log(`⚠️ 任务 ${task.id} 已达到最大重试次数 (${limit}),跳过重试`);
|
|
@@ -313,14 +313,15 @@ class InteractiveQuestionGenerator {
|
|
|
313
313
|
// 7. E2E 测试
|
|
314
314
|
questions.push({
|
|
315
315
|
id: 'e2e_tests',
|
|
316
|
-
question: '
|
|
316
|
+
question: '是否需要端到端 (E2E) 测试?(适用于 Web/Mobile/GUI 项目,耗时较长)',
|
|
317
317
|
type: 'single',
|
|
318
318
|
required: false,
|
|
319
319
|
category: 'quality',
|
|
320
320
|
priority: 7,
|
|
321
321
|
options: [
|
|
322
|
-
{ key: '
|
|
323
|
-
{ key: '
|
|
322
|
+
{ key: 'functional', label: '功能测试 (推荐)', description: '验证业务流程正确性,无需浏览器可视化,速度快' },
|
|
323
|
+
{ key: 'visual', label: '视觉验证', description: '需要浏览器可视化验证,可检查页面样式和布局' },
|
|
324
|
+
{ key: 'false', label: '不需要', description: '仅进行单元测试和集成测试,节省时间' }
|
|
324
325
|
]
|
|
325
326
|
});
|
|
326
327
|
// 8. 风险评估
|
|
@@ -1097,7 +1097,8 @@ ACCEPT_FAILED
|
|
|
1097
1097
|
// 判断是否通过
|
|
1098
1098
|
const qc = this.qualityConfig;
|
|
1099
1099
|
const testsPassed = result.tests.failed === 0;
|
|
1100
|
-
|
|
1100
|
+
// 覆盖率 -1 表示未测量(regex 回退路径下未匹配到覆盖率时保持 -1)
|
|
1101
|
+
const coverageOk = result.tests.coverage < 0 || result.tests.coverage >= qc.minCoverage;
|
|
1101
1102
|
const lintOk = qc.strictLint ? result.lint.errors === 0 : true;
|
|
1102
1103
|
const buildOk = result.build.success;
|
|
1103
1104
|
const e2eOk = qc.e2eTests ? result.e2e.failed === 0 : true;
|
|
@@ -27,8 +27,8 @@ const TRANSITIONS = [
|
|
|
27
27
|
{ from: 'accept', to: 'failed', event: 'fail' },
|
|
28
28
|
// failed → retry_queue
|
|
29
29
|
{ from: 'failed', to: 'retry_queue', event: 'retry' },
|
|
30
|
-
// retry_queue → pending (
|
|
31
|
-
{ from: 'retry_queue', to: 'pending', event: 'retry', condition: (task) => (task.retryCount || 0) <
|
|
30
|
+
// retry_queue → pending (安全上限 100,由 executor 层控制具体 maxRetries)
|
|
31
|
+
{ from: 'retry_queue', to: 'pending', event: 'retry', condition: (task) => (task.retryCount || 0) < 100 },
|
|
32
32
|
// any → pending (cancel and restart)
|
|
33
33
|
{ from: 'scheduled', to: 'pending', event: 'cancel' },
|
|
34
34
|
{ from: 'blocked', to: 'pending', event: 'cancel' },
|
|
@@ -47,8 +47,8 @@ export interface UserAnswers {
|
|
|
47
47
|
additionalContext?: Record<string, string | string[]>;
|
|
48
48
|
/** 是否启用 E2E 测试 */
|
|
49
49
|
e2eTests?: boolean;
|
|
50
|
-
/** E2E 测试类型 (web/mobile/gui) */
|
|
51
|
-
e2eType?: 'web' | 'mobile' | 'gui';
|
|
50
|
+
/** E2E 测试类型 (web/mobile/gui/visual) */
|
|
51
|
+
e2eType?: 'web' | 'mobile' | 'gui' | 'visual';
|
|
52
52
|
/** 质量级别 */
|
|
53
53
|
qualityLevel?: 'fast' | 'balanced' | 'strict';
|
|
54
54
|
}
|
|
@@ -858,13 +858,15 @@ ${userContext.documentationLevel}
|
|
|
858
858
|
const str = (v) => Array.isArray(v) ? v.join(', ') : v;
|
|
859
859
|
const e2eAnswer = str(merged['E2E测试'] || merged['e2eTests'] || merged['e2e']);
|
|
860
860
|
const e2eTypeAnswer = str(merged['E2E类型'] || merged['e2eType']);
|
|
861
|
+
const isE2EEnabled = e2eAnswer === 'true' || e2eAnswer === 'functional' || e2eAnswer === 'visual' || e2eAnswer === '✅ 启用 E2E 测试' || e2eAnswer === '是';
|
|
862
|
+
let e2eTypeValue = e2eAnswer === 'visual' ? 'visual' : e2eTypeAnswer === 'mobile' ? 'mobile' : e2eTypeAnswer === 'gui' ? 'gui' : 'web';
|
|
861
863
|
return {
|
|
862
864
|
objective: str(merged['目标'] || merged['objective']),
|
|
863
865
|
techStack: this.parseArrayAnswer(str(merged['技术栈'] || merged['techStack']) || ''),
|
|
864
866
|
testCoverage: str(merged['测试'] || merged['testCoverage']),
|
|
865
867
|
documentationLevel: str(merged['文档'] || merged['documentationLevel']),
|
|
866
|
-
e2eTests:
|
|
867
|
-
e2eType:
|
|
868
|
+
e2eTests: isE2EEnabled,
|
|
869
|
+
e2eType: e2eTypeValue,
|
|
868
870
|
additionalContext: merged
|
|
869
871
|
};
|
|
870
872
|
}
|
|
@@ -940,8 +942,17 @@ ${devTaskId}
|
|
|
940
942
|
}
|
|
941
943
|
buildE2ETestDescription(e2eType, parsedTask, userContext) {
|
|
942
944
|
const typeConfig = this.getE2ETypeConfig(e2eType);
|
|
945
|
+
const visualSection = e2eType === 'visual' ? `
|
|
946
|
+
## 视觉验证要求
|
|
947
|
+
1. **可视化运行**: 使用有头模式 (headed mode) 运行浏览器,可查看页面渲染
|
|
948
|
+
2. **样式检查**: 验证页面布局、颜色、字体、间距等视觉元素
|
|
949
|
+
3. **响应式测试**: 在不同视口下验证页面布局适配
|
|
950
|
+
4. **交互验证**: 确保动画、过渡效果、hover 状态等交互正常
|
|
951
|
+
5. **截图对比**: 关键页面应生成截图,便于人工审核
|
|
952
|
+
` : '';
|
|
943
953
|
return `## E2E 测试目标
|
|
944
954
|
执行完整的端到端测试,验证关键用户流程
|
|
955
|
+
${e2eType === 'visual' ? '(需可视化验证,检查页面样式和布局)' : ''}
|
|
945
956
|
|
|
946
957
|
## 应用类型
|
|
947
958
|
${typeConfig.description}
|
|
@@ -965,12 +976,12 @@ ${typeConfig.environments.map(e => `- ${e}`).join('\n')}
|
|
|
965
976
|
3. **等待策略**: 使用合理的等待机制,避免硬编码延迟
|
|
966
977
|
4. **数据隔离**: 测试数据独立,不影响其他测试
|
|
967
978
|
5. **清理机制**: 测试后清理创建的数据
|
|
968
|
-
|
|
979
|
+
${visualSection}
|
|
969
980
|
## 输出要求
|
|
970
981
|
- E2E 测试文件 (tests/e2e/*.spec.ts)
|
|
971
982
|
- 测试执行报告
|
|
972
983
|
- 截图/录像 (失败时)
|
|
973
|
-
- 测试覆盖率报告 (如有)
|
|
984
|
+
${e2eType === 'visual' ? '- 关键页面截图 (用于视觉审核)\n' : ''}- 测试覆盖率报告 (如有)
|
|
974
985
|
|
|
975
986
|
## 运行命令
|
|
976
987
|
\`\`\`bash
|
|
@@ -1003,6 +1014,12 @@ ${typeConfig.runCommand}
|
|
|
1003
1014
|
frameworks: ['Playwright for Electron', 'Spectron (Electron)', 'Robot Framework', 'PyAutoGUI'],
|
|
1004
1015
|
environments: ['Windows', 'macOS', 'Linux'],
|
|
1005
1016
|
runCommand: 'npm run test:e2e'
|
|
1017
|
+
},
|
|
1018
|
+
visual: {
|
|
1019
|
+
description: 'Web 应用 (需可视化验证,检查页面样式和布局)',
|
|
1020
|
+
frameworks: ['Playwright (headed mode,推荐)', 'Cypress (headed)', 'Playwright + Percy (视觉回归)', 'Playwright + Chromatic'],
|
|
1021
|
+
environments: ['Chrome (headed)', '不同视口 (desktop/tablet/mobile)', '不同分辨率设备'],
|
|
1022
|
+
runCommand: 'npx playwright test --headed --reporter=html,list'
|
|
1006
1023
|
}
|
|
1007
1024
|
};
|
|
1008
1025
|
return configs[type];
|
|
@@ -110,19 +110,19 @@ class StateManager {
|
|
|
110
110
|
this.stateCache = initialState;
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
|
-
//
|
|
113
|
+
// 合并旧状态的统计字段(兼容旧版本,statistics 可能不存在)
|
|
114
114
|
existing.statistics = {
|
|
115
|
-
totalTasks: existing.statistics
|
|
116
|
-
completed: existing.statistics
|
|
117
|
-
inProgress: existing.statistics
|
|
118
|
-
failed: existing.statistics
|
|
119
|
-
pending: existing.statistics
|
|
120
|
-
scheduled: existing.statistics
|
|
121
|
-
blocked: existing.statistics
|
|
122
|
-
waiting: existing.statistics
|
|
123
|
-
verify: existing.statistics
|
|
124
|
-
accept: existing.statistics
|
|
125
|
-
retry_queue: existing.statistics
|
|
115
|
+
totalTasks: existing.statistics?.totalTasks ?? 0,
|
|
116
|
+
completed: existing.statistics?.completed ?? 0,
|
|
117
|
+
inProgress: existing.statistics?.inProgress ?? 0,
|
|
118
|
+
failed: existing.statistics?.failed ?? 0,
|
|
119
|
+
pending: existing.statistics?.pending ?? 0,
|
|
120
|
+
scheduled: existing.statistics?.scheduled ?? 0,
|
|
121
|
+
blocked: existing.statistics?.blocked ?? 0,
|
|
122
|
+
waiting: existing.statistics?.waiting ?? 0,
|
|
123
|
+
verify: existing.statistics?.verify ?? 0,
|
|
124
|
+
accept: existing.statistics?.accept ?? 0,
|
|
125
|
+
retry_queue: existing.statistics?.retry_queue ?? 0
|
|
126
126
|
};
|
|
127
127
|
this.stateCache = existing;
|
|
128
128
|
}
|
package/package.json
CHANGED
package/skills/start.md
CHANGED
|
@@ -165,12 +165,16 @@ AskUserQuestion: `header: "质量等级"`, `multiSelect: false`
|
|
|
165
165
|
|
|
166
166
|
AskUserQuestion: `header: "E2E 测试"`, `multiSelect: false`
|
|
167
167
|
|
|
168
|
-
**question:**
|
|
168
|
+
**question:** 是否需要端到端 (E2E) 测试?(适用于 Web/Mobile/GUI 项目,耗时较长)
|
|
169
169
|
|
|
170
170
|
| label | description |
|
|
171
171
|
|-------|-------------|
|
|
172
|
-
|
|
|
173
|
-
|
|
|
172
|
+
| `功能测试 (推荐)` | 验证业务流程正确性,无需浏览器可视化,速度快 |
|
|
173
|
+
| `视觉验证` | 需要浏览器可视化验证,可检查页面样式和布局 |
|
|
174
|
+
| `不需要` | 仅进行单元测试和集成测试,节省时间 |
|
|
175
|
+
|
|
176
|
+
> 功能测试是默认推荐,适用于大多数场景(API/逻辑/数据处理)。
|
|
177
|
+
> 视觉验证适用于前端/移动端项目,需要检查 UI 样式、布局、交互效果。
|
|
174
178
|
|
|
175
179
|
#### 4.3 执行模式(所有任务必选)
|
|
176
180
|
|
|
@@ -202,7 +206,7 @@ AskUserQuestion: `header: "执行模式"`, `multiSelect: false`
|
|
|
202
206
|
📊 统计
|
|
203
207
|
Goals: N 个(将生成 N个开发 + N个测试 + 审查)
|
|
204
208
|
质量级别: xxx
|
|
205
|
-
E2E 测试:
|
|
209
|
+
E2E 测试: 功能测试 / 视觉验证 / 不启用
|
|
206
210
|
```
|
|
207
211
|
|
|
208
212
|
### Step 6: AI 提取 goals + 生成 plan
|
|
@@ -242,11 +246,13 @@ AskUserQuestion: `header: "执行模式"`, `multiSelect: false`
|
|
|
242
246
|
"goalTypes": ["development", "testing", "documentation"],
|
|
243
247
|
"constraints": ["约束1"],
|
|
244
248
|
"deliverables": ["src/xxx.ts"],
|
|
245
|
-
"plan": "## 技术方案\n1. ...\n2. ..."
|
|
249
|
+
"plan": "## 技术方案\n1. ...\n2. ...",
|
|
250
|
+
"e2eTests": true,
|
|
251
|
+
"e2eType": "visual"
|
|
246
252
|
}
|
|
247
253
|
```
|
|
248
254
|
|
|
249
|
-
> **注意**: `quality`、`mode
|
|
255
|
+
> **注意**: `quality`、`mode` 通过 CLI 参数传递。`e2eTests` 和 `e2eType` 可写入 tasks-input.json 或通过 CLI 参数传递。
|
|
250
256
|
> **goalTypes** 必须与 goals 数组长度一致,一一对应。
|
|
251
257
|
> **研究上下文集成**: 如果检测到 `.openmatrix/research/context.json`,将研究的 goals/constraints/deliverables 作为基础,与 AI 提取的内容合并(去重后)。
|
|
252
258
|
|
|
@@ -264,11 +270,16 @@ openmatrix start --tasks-json @.openmatrix/tasks-input.json --quality <质量等
|
|
|
264
270
|
openmatrix start --tasks-json @.openmatrix/tasks-input.json --research-context @.openmatrix/research/context.json --quality <质量等级> --mode <执行模式> --json
|
|
265
271
|
```
|
|
266
272
|
|
|
267
|
-
如果启用了 E2E
|
|
273
|
+
如果启用了 E2E 测试(功能测试),加上 `--e2e-tests`:
|
|
268
274
|
```bash
|
|
269
275
|
openmatrix start --tasks-json @.openmatrix/tasks-input.json --quality balanced --mode auto --e2e-tests --json
|
|
270
276
|
```
|
|
271
277
|
|
|
278
|
+
如果选择了视觉验证,加上 `--e2e-tests --e2e-type visual`:
|
|
279
|
+
```bash
|
|
280
|
+
openmatrix start --tasks-json @.openmatrix/tasks-input.json --quality balanced --mode auto --e2e-tests --e2e-type visual --json
|
|
281
|
+
```
|
|
282
|
+
|
|
272
283
|
**非开发任务**(无质量等级):
|
|
273
284
|
```bash
|
|
274
285
|
openmatrix start --tasks-json @.openmatrix/tasks-input.json --mode <执行模式> --json
|