openmatrix 0.1.85 → 0.1.87

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.
@@ -161,6 +161,7 @@ async function handleTasksJson(options, stateManager, state, omPath, basePath) {
161
161
  title: tasksInput.title,
162
162
  description: tasksInput.description || '',
163
163
  goals: tasksInput.goals,
164
+ goalTypes: tasksInput.goalTypes,
164
165
  constraints: tasksInput.constraints || [],
165
166
  deliverables: tasksInput.deliverables || [],
166
167
  rawContent: ''
@@ -76,4 +76,12 @@ export declare class TaskPlanner {
76
76
  private generateTaskId;
77
77
  private determinePriority;
78
78
  private estimateComplexity;
79
+ /**
80
+ * 分类目标类型
81
+ * - development: 需要编写代码的功能实现 → 拆分为实现+测试对
82
+ * - testing: 已明确是测试任务 → 单个测试任务
83
+ * - documentation: 文档编写 → 单个文档任务
84
+ * - other: 其他类型(配置、优化、部署等) → 单个任务
85
+ */
86
+ private classifyGoal;
79
87
  }
@@ -73,7 +73,7 @@ ${globalContext}
73
73
  ]
74
74
  });
75
75
  }
76
- // 1. 为每个目标创建开发+测试任务(并行,只依赖设计任务)
76
+ // 1. 为每个目标创建任务(根据目标类型决定拆分策略)
77
77
  const devTaskIds = [];
78
78
  for (let i = 0; i < parsedTask.goals.length; i++) {
79
79
  const goal = parsedTask.goals[i];
@@ -82,43 +82,103 @@ ${globalContext}
82
82
  continue;
83
83
  }
84
84
  seenTitles.add(goal);
85
- // 创建开发任务 所有开发任务并行,仅依赖设计任务
86
- const devTaskId = this.generateTaskId();
87
- devTaskIds.push(devTaskId);
88
- const acceptanceCriteria = this.generateAcceptanceCriteria(goal, userContext);
89
- breakdowns.push({
90
- taskId: devTaskId,
91
- title: `实现: ${goal}`,
92
- description: this.buildTaskDescription(goal, globalContext),
93
- priority: this.determinePriority(i),
94
- // 并行: 所有开发任务只依赖设计任务(如果有),互不依赖
95
- dependencies: designTaskId ? [designTaskId] : [],
96
- estimatedComplexity: this.estimateComplexity(goal),
97
- assignedAgent: 'coder',
98
- phase: 'develop',
99
- acceptanceCriteria,
100
- testTaskId: undefined // 稍后关联
101
- });
102
- // 为每个开发任务创建配对的测试任务
103
- const testTaskId = this.generateTaskId();
104
- breakdowns.push({
105
- taskId: testTaskId,
106
- title: `测试: ${goal}`,
107
- description: this.buildTestDescription(goal, devTaskId, coverageTarget, globalContext),
108
- priority: this.determinePriority(i),
109
- dependencies: [devTaskId], // 测试依赖对应的开发任务
110
- estimatedComplexity: 'medium',
111
- assignedAgent: 'tester',
112
- phase: 'verify',
113
- acceptanceCriteria: [
114
- `单元测试覆盖率 >= ${coverageTarget}%`,
115
- '边界情况已测试',
116
- '异常处理已验证',
117
- '所有测试通过'
118
- ]
119
- });
120
- // 关联测试任务 ID
121
- breakdowns[breakdowns.length - 2].testTaskId = testTaskId;
85
+ // 优先使用 AI 标注的类型,fallback 到关键词检测
86
+ const goalType = parsedTask.goalTypes?.[i] ?? this.classifyGoal(goal);
87
+ const deps = designTaskId ? [designTaskId] : [];
88
+ if (goalType === 'development') {
89
+ // 开发类目标: 拆分为实现 + 测试 对
90
+ const devTaskId = this.generateTaskId();
91
+ devTaskIds.push(devTaskId);
92
+ const acceptanceCriteria = this.generateAcceptanceCriteria(goal, userContext);
93
+ breakdowns.push({
94
+ taskId: devTaskId,
95
+ title: `实现: ${goal}`,
96
+ description: this.buildTaskDescription(goal, globalContext),
97
+ priority: this.determinePriority(i),
98
+ dependencies: deps,
99
+ estimatedComplexity: this.estimateComplexity(goal),
100
+ assignedAgent: 'coder',
101
+ phase: 'develop',
102
+ acceptanceCriteria,
103
+ testTaskId: undefined
104
+ });
105
+ // 配对的测试任务
106
+ const testTaskId = this.generateTaskId();
107
+ breakdowns.push({
108
+ taskId: testTaskId,
109
+ title: `测试: ${goal}`,
110
+ description: this.buildTestDescription(goal, devTaskId, coverageTarget, globalContext),
111
+ priority: this.determinePriority(i),
112
+ dependencies: [devTaskId],
113
+ estimatedComplexity: 'medium',
114
+ assignedAgent: 'tester',
115
+ phase: 'verify',
116
+ acceptanceCriteria: [
117
+ `单元测试覆盖率 >= ${coverageTarget}%`,
118
+ '边界情况已测试',
119
+ '异常处理已验证',
120
+ '所有测试通过'
121
+ ]
122
+ });
123
+ breakdowns[breakdowns.length - 2].testTaskId = testTaskId;
124
+ }
125
+ else if (goalType === 'testing') {
126
+ // 测试类目标: 直接创建单个测试任务
127
+ const taskId = this.generateTaskId();
128
+ breakdowns.push({
129
+ taskId,
130
+ title: goal,
131
+ description: `## 测试目标\n${goal}\n\n${globalContext}\n\n## 测试要求\n- 单元测试覆盖率 >= ${coverageTarget}%\n- 测试正常流程\n- 测试边界情况\n- 测试异常处理\n\n## 输出\n- 测试文件\n- 测试报告\n- 覆盖率报告`,
132
+ priority: this.determinePriority(i),
133
+ dependencies: deps,
134
+ estimatedComplexity: 'medium',
135
+ assignedAgent: 'tester',
136
+ phase: 'verify',
137
+ acceptanceCriteria: [
138
+ `测试覆盖率 >= ${coverageTarget}%`,
139
+ '边界情况已测试',
140
+ '所有测试通过',
141
+ '测试报告已生成'
142
+ ]
143
+ });
144
+ }
145
+ else if (goalType === 'documentation') {
146
+ // 文档类目标: 直接创建单个文档任务
147
+ const taskId = this.generateTaskId();
148
+ breakdowns.push({
149
+ taskId,
150
+ title: goal,
151
+ description: `## 文档目标\n${goal}\n\n${globalContext}\n\n## 输出要求\n- 文档内容完整\n- 格式清晰\n- 示例代码可运行`,
152
+ priority: this.determinePriority(i),
153
+ dependencies: deps,
154
+ estimatedComplexity: 'low',
155
+ assignedAgent: 'executor',
156
+ phase: 'accept',
157
+ acceptanceCriteria: [
158
+ '文档内容完整',
159
+ '格式规范',
160
+ '示例可运行'
161
+ ]
162
+ });
163
+ }
164
+ else {
165
+ // 其他类型(配置、优化等): 单个任务
166
+ const taskId = this.generateTaskId();
167
+ breakdowns.push({
168
+ taskId,
169
+ title: goal,
170
+ description: `## 目标\n${goal}\n\n${globalContext}\n\n## 输出要求\n- 完成目标\n- 验证结果正确`,
171
+ priority: this.determinePriority(i),
172
+ dependencies: deps,
173
+ estimatedComplexity: this.estimateComplexity(goal),
174
+ assignedAgent: 'coder',
175
+ phase: 'develop',
176
+ acceptanceCriteria: [
177
+ `目标 "${goal}" 已完成`,
178
+ '结果已验证'
179
+ ]
180
+ });
181
+ }
122
182
  }
123
183
  // 2. 系统集成任务 (将所有模块组装到入口文件)
124
184
  let integrationTaskId;
@@ -524,5 +584,48 @@ ${typeConfig.runCommand}
524
584
  return 'low';
525
585
  return 'medium';
526
586
  }
587
+ /**
588
+ * 分类目标类型
589
+ * - development: 需要编写代码的功能实现 → 拆分为实现+测试对
590
+ * - testing: 已明确是测试任务 → 单个测试任务
591
+ * - documentation: 文档编写 → 单个文档任务
592
+ * - other: 其他类型(配置、优化、部署等) → 单个任务
593
+ */
594
+ classifyGoal(goal) {
595
+ const g = goal.toLowerCase();
596
+ // 测试类关键词
597
+ const testKeywords = [
598
+ '测试', 'test', 'testing', 'tdd', 'e2e', 'e2e测试',
599
+ '单元测试', '集成测试', '端到端', '覆盖率', 'coverage',
600
+ 'vitest', 'jest', 'mocha', 'playwright', 'cypress',
601
+ ];
602
+ if (testKeywords.some(kw => g.includes(kw))) {
603
+ return 'testing';
604
+ }
605
+ // 文档类关键词
606
+ const docKeywords = [
607
+ '文档', 'document', 'documentation', 'readme', '说明',
608
+ '指南', 'guide', 'tutorial', 'api文档',
609
+ ];
610
+ if (docKeywords.some(kw => g.includes(kw))) {
611
+ return 'documentation';
612
+ }
613
+ // 非开发类关键词(配置、部署等)
614
+ const nonDevKeywords = [
615
+ '配置', 'config', 'deploy', '部署', 'ci/cd', '发布',
616
+ 'release', '优化', '监控', 'monitor', '日志',
617
+ ];
618
+ // 如果只包含非开发关键词而不包含开发关键词,归为 other
619
+ const devKeywords = [
620
+ '实现', '开发', '编写', '创建', '构建', '添加', '修复',
621
+ 'implement', 'develop', 'build', 'create', 'add', 'fix',
622
+ '功能', 'feature', '模块', '组件', 'component', '系统',
623
+ ];
624
+ if (nonDevKeywords.some(kw => g.includes(kw)) && !devKeywords.some(kw => g.includes(kw))) {
625
+ return 'other';
626
+ }
627
+ // 默认为开发类
628
+ return 'development';
629
+ }
527
630
  }
528
631
  exports.TaskPlanner = TaskPlanner;
@@ -204,10 +204,14 @@ export interface ParsedTask {
204
204
  title: string;
205
205
  description: string;
206
206
  goals: string[];
207
+ /** 每个 goal 的类型标注 (由 AI 在提取时标注),与 goals 数组一一对应 */
208
+ goalTypes?: GoalType[];
207
209
  constraints: string[];
208
210
  deliverables: string[];
209
211
  rawContent: string;
210
212
  }
213
+ /** 目标类型 */
214
+ export type GoalType = 'development' | 'testing' | 'documentation' | 'other';
211
215
  export interface ResearchAgentConfig {
212
216
  role: string;
213
217
  focus: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmatrix",
3
- "version": "0.1.85",
3
+ "version": "0.1.87",
4
4
  "description": "AI Agent task orchestration system with Claude Code Skills integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/skills/start.md CHANGED
@@ -230,10 +230,25 @@ AskUserQuestion({
230
230
 
231
231
  从任务描述中提取:
232
232
  - **goals**: 至少 3-8 个明确功能目标,每个是独立可交付模块
233
+ - **goalTypes**: 为每个 goal 标注类型,影响任务拆分策略:
234
+ - `development` — 需要编写代码的功能/模块实现 → 拆分为"实现+测试"任务对
235
+ - `testing` — 明确的测试任务(如"编写 E2E 测试"、"所有模块的单元测试")→ 单个测试任务
236
+ - `documentation` — 文档编写(如"编写 API 文档"、"更新 README")→ 单个文档任务
237
+ - `other` — 配置、部署、优化等非编码任务 → 单个任务
233
238
  - **constraints**: 技术栈、兼容性等约束
234
239
  - **deliverables**: 交付物列表
235
240
  - **plan**: 技术方案、模块划分、接口设计、关键决策
236
241
 
242
+ **goalTypes 标注示例:**
243
+
244
+ | Goal | Type | 理由 |
245
+ |------|------|------|
246
+ | "项目脚手架: Vite+TS 配置" | development | 需要写代码搭建 |
247
+ | "GameLoop 60fps 游戏循环" | development | 功能实现 |
248
+ | "所有核心模块的单元测试" | testing | 已是测试任务 |
249
+ | "API 文档编写" | documentation | 文档类 |
250
+ | "CI/CD 流水线配置" | other | 配置类 |
251
+
237
252
  ### Step 7: 写入 tasks-input.json
238
253
 
239
254
  用 Write 工具写入 `.openmatrix/tasks-input.json`:
@@ -243,6 +258,7 @@ AskUserQuestion({
243
258
  "title": "任务标题",
244
259
  "description": "整体描述",
245
260
  "goals": ["目标1", "目标2", "目标3"],
261
+ "goalTypes": ["development", "testing", "documentation"],
246
262
  "constraints": ["约束1"],
247
263
  "deliverables": ["src/xxx.ts"],
248
264
  "plan": "## 技术方案\n1. ...\n2. ..."
@@ -250,6 +266,7 @@ AskUserQuestion({
250
266
  ```
251
267
 
252
268
  > **注意**: `quality`、`mode`、`e2eTests` 不写入文件,由 Step 8 的 CLI 参数传递。
269
+ > **goalTypes** 必须与 goals 数组长度一致,一一对应。
253
270
 
254
271
  ### Step 8: 调用 CLI 创建任务 ⚠️ 不可跳过
255
272