openmatrix 0.1.55 → 0.1.57

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 CHANGED
@@ -386,6 +386,27 @@ Accept 阶段由 Reviewer Agent 执行:
386
386
  }
387
387
  ```
388
388
 
389
+ ## 状态存储
390
+
391
+ 任务状态持久化在 `.openmatrix/` 目录:
392
+
393
+ ```
394
+ .openmatrix/
395
+ ├── state.json # 全局状态 (runId, status, config, statistics)
396
+ ├── plan.md # AI 生成的执行计划
397
+ ├── tasks-input.json # 任务输入 (goals, constraints, deliverables)
398
+ ├── tasks/
399
+ │ └── TASK-001/
400
+ │ ├── task.json # 任务定义 + 状态 + 阶段信息
401
+ │ ├── context.md # Agent 上下文 (供后续 Agent 读取)
402
+ │ ├── develop.json # 开发阶段结果
403
+ │ ├── verify.json # 验证阶段结果 (质量门禁)
404
+ │ ├── accept.json # 验收阶段结果
405
+ │ └── artifacts/ # 产出文件 (result.md, quality-report.json 等)
406
+ ├── approvals/ # 审批记录
407
+ └── meetings/ # Meeting 记录
408
+ ```
409
+
389
410
  ---
390
411
 
391
412
  ## 多语言支持
@@ -465,6 +486,9 @@ cd openmatrix && npm install && npm run build && npm test
465
486
  - [x] `/om:brainstorm` 头脑风暴模式
466
487
  - [x] 多语言支持 (Python/Go/Java/TypeScript 等)
467
488
  - [x] E2E 测试支持 (Web/Mobile/GUI)
489
+ - [x] Agent 上下文共享 (Agent Memory)
490
+ - [x] Task 子目录结构 + Phase 结果持久化
491
+ - [x] 执行循环持久化 (`openmatrix step`/`complete` 防上下文压缩丢失)
468
492
  - [ ] VSCode 扩展
469
493
  - [ ] CI/CD 集成
470
494
 
@@ -7,11 +7,20 @@ import type { Task, AgentType, AgentResult } from '../../types/index.js';
7
7
  * - 分析技术方案
8
8
  * - 总结最佳实践
9
9
  * - 提供决策建议
10
+ *
11
+ * 支持动态领域感知,根据任务描述自动适配研究方向
10
12
  */
11
13
  export declare class ResearcherAgent {
12
14
  readonly type: AgentType;
13
15
  readonly capabilities: string[];
14
16
  execute(task: Task): Promise<AgentResult>;
15
- private buildResearchPrompt;
17
+ /**
18
+ * 构建动态领域感知的研究 Prompt
19
+ */
20
+ private buildDynamicResearchPrompt;
21
+ /**
22
+ * 从任务描述中提取研究上下文
23
+ */
24
+ private extractResearchContext;
16
25
  private generateRunId;
17
26
  }
@@ -9,6 +9,8 @@ exports.ResearcherAgent = void 0;
9
9
  * - 分析技术方案
10
10
  * - 总结最佳实践
11
11
  * - 提供决策建议
12
+ *
13
+ * 支持动态领域感知,根据任务描述自动适配研究方向
12
14
  */
13
15
  class ResearcherAgent {
14
16
  type = 'researcher';
@@ -16,7 +18,7 @@ class ResearcherAgent {
16
18
  async execute(task) {
17
19
  const startTime = Date.now();
18
20
  try {
19
- const prompt = this.buildResearchPrompt(task);
21
+ const prompt = this.buildDynamicResearchPrompt(task);
20
22
  return {
21
23
  runId: this.generateRunId(),
22
24
  taskId: task.id,
@@ -44,88 +46,208 @@ class ResearcherAgent {
44
46
  };
45
47
  }
46
48
  }
47
- buildResearchPrompt(task) {
49
+ /**
50
+ * 构建动态领域感知的研究 Prompt
51
+ */
52
+ buildDynamicResearchPrompt(task) {
53
+ // 从任务描述中提取领域和角色信息
54
+ const { domain, role, focus } = this.extractResearchContext(task.description);
48
55
  return `
49
56
  # 调研任务
50
57
 
51
- ## 调研问题
58
+ ## 研究领域
59
+ ${domain}
60
+
61
+ ## 角色定位
62
+ ${role}
63
+
64
+ ## 研究方向
65
+ ${focus}
52
66
 
67
+ ## 原始任务描述
53
68
  ${task.description}
54
69
 
55
70
  ## 调研步骤
56
71
 
57
72
  1. **搜索资料**
58
- - 官方文档
59
- - 技术博客
60
- - GitHub 仓库
61
- - Stack Overflow
73
+ - 使用 WebSearch 搜索领域核心概念
74
+ - 搜索行业标准、最佳实践
75
+ - 搜索主流技术方案和开源项目
76
+ - 搜索常见挑战和解决方案
62
77
 
63
- 2. **分析方案**
78
+ 2. **分析整理**
64
79
  - 功能对比
65
- - 性能对比
66
- - 社区支持
80
+ - 性能特点
81
+ - 社区生态
67
82
  - 学习曲线
83
+ - 适用场景
68
84
 
69
85
  3. **总结发现**
70
- - 关键信息
71
- - 优缺点
72
- - 适用场景
86
+ - 关键信息提炼
87
+ - 优缺点分析
88
+ - 决策建议
73
89
 
74
90
  ## 输出格式
75
91
 
76
92
  \`\`\`markdown
77
- # 调研报告
93
+ # ${domain} 调研报告
78
94
 
79
- ## 问题
80
- [调研的核心问题]
95
+ ## 核心发现
81
96
 
82
- ## 调研方法
83
- - 搜索关键词: ...
84
- - 参考来源: ...
97
+ [3-5 个关键发现,每个用一句话概括]
85
98
 
86
- ## 发现
99
+ 1. ...
100
+ 2. ...
101
+ 3. ...
87
102
 
88
- ### 方案 A: [名称]
89
- - 描述: ...
90
- - 优点:
91
- - ...
92
- - 缺点:
93
- - ...
94
- - 适用场景: ...
103
+ ## 详细分析
95
104
 
96
- ### 方案 B: [名称]
97
- - 描述: ...
98
- - 优点:
105
+ ### 发现 1: [标题]
106
+ - **描述**: ...
107
+ - **关键点**:
99
108
  - ...
100
- - 缺点:
101
- - ...
102
- - 适用场景: ...
109
+ - **注意事项**: ...
110
+
111
+ ### 发现 2: [标题]
112
+ ...
103
113
 
104
- ## 方案对比
114
+ ## 行业最佳实践
105
115
 
106
- | 维度 | 方案 A | 方案 B |
107
- |-----|--------|--------|
108
- | 性能 | ⭐⭐⭐ | ⭐⭐ |
109
- | 易用性 | ⭐⭐ | ⭐⭐⭐ |
110
- | 社区 | ⭐⭐⭐ | ⭐ |
116
+ 1. ...
117
+ 2. ...
118
+ 3. ...
119
+
120
+ ## 关键决策点
121
+
122
+ [用户需要做出的关键决策]
123
+
124
+ 1. **决策 1**: [决策描述]
125
+ - 选项 A: ... (适用场景)
126
+ - 选项 B: ... (适用场景)
127
+ - 建议: ...
128
+
129
+ 2. **决策 2**: ...
111
130
 
112
- ## 建议
131
+ ## 推荐方案
113
132
 
114
- **推荐方案**: [方案 X]
133
+ **首选方案**: ...
115
134
 
116
135
  **理由**:
117
136
  1. ...
118
137
  2. ...
119
138
 
139
+ **备选方案**: ...
140
+
120
141
  ## 参考资料
142
+
121
143
  1. [标题](链接)
144
+ 2. [标题](链接)
122
145
  \`\`\`
123
146
 
124
147
  ## 开始调研
125
148
 
126
149
  请使用 WebSearch 和 WebFetch 工具搜索相关信息。
150
+ 至少搜索 5 个相关关键词,覆盖官方文档、社区讨论、技术博客等维度。
127
151
  `;
128
152
  }
153
+ /**
154
+ * 从任务描述中提取研究上下文
155
+ */
156
+ extractResearchContext(description) {
157
+ const lower = description.toLowerCase();
158
+ // 领域关键词映射
159
+ const domainMap = [
160
+ {
161
+ keywords: ['游戏', 'game', 'gamedev', 'unity', 'unreal'],
162
+ domain: '游戏开发',
163
+ aspects: ['游戏类型', '目标平台', '技术架构', '美术风格', '盈利模式']
164
+ },
165
+ {
166
+ keywords: ['网站', 'website', 'web app', '门户'],
167
+ domain: 'Web 网站开发',
168
+ aspects: ['功能需求', '用户体验', '技术栈', 'SEO', '性能优化']
169
+ },
170
+ {
171
+ keywords: ['app', '移动应用', 'ios', 'android', 'flutter'],
172
+ domain: '移动应用开发',
173
+ aspects: ['平台选择', '用户界面', '性能优化', '发布流程', '用户增长']
174
+ },
175
+ {
176
+ keywords: ['支付', 'payment', 'stripe', '支付宝'],
177
+ domain: '支付系统',
178
+ aspects: ['支付方式', '安全合规', '风控策略', '对账结算', '国际化']
179
+ },
180
+ {
181
+ keywords: ['电商', 'ecommerce', 'shop', '商城'],
182
+ domain: '电商系统',
183
+ aspects: ['商品管理', '购物流程', '库存物流', '营销工具', '数据分析']
184
+ },
185
+ {
186
+ keywords: ['社交', 'social', 'community', '论坛'],
187
+ domain: '社交平台',
188
+ aspects: ['用户关系', '内容互动', '实时通讯', '内容审核', '推荐算法']
189
+ },
190
+ {
191
+ keywords: ['安全', 'security', 'auth', '认证', '加密'],
192
+ domain: '安全领域',
193
+ aspects: ['威胁模型', '认证授权', '数据保护', '审计监控', '合规要求']
194
+ },
195
+ {
196
+ keywords: ['后台', 'admin', 'dashboard', 'cms', '管理'],
197
+ domain: '后台管理系统',
198
+ aspects: ['权限模型', '数据看板', '工作流程', 'API 设计', '多租户']
199
+ },
200
+ {
201
+ keywords: ['ai', '人工智能', 'ml', '机器学习', '大模型', 'llm'],
202
+ domain: 'AI/机器学习',
203
+ aspects: ['模型选择', '数据处理', '训练部署', '性能优化', '伦理合规']
204
+ },
205
+ {
206
+ keywords: ['区块链', 'blockchain', 'web3', 'defi', 'nft'],
207
+ domain: '区块链',
208
+ aspects: ['链选择', '智能合约', '安全审计', '性能扩展', '合规监管']
209
+ },
210
+ {
211
+ keywords: ['音视频', 'streaming', '直播', 'rtc', 'webrtc'],
212
+ domain: '音视频',
213
+ aspects: ['编解码', '传输协议', '延迟优化', '存储分发', '实时互动']
214
+ }
215
+ ];
216
+ // 查找匹配的领域
217
+ for (const { keywords, domain, aspects } of domainMap) {
218
+ if (keywords.some(kw => lower.includes(kw))) {
219
+ return {
220
+ domain,
221
+ role: `${domain}专家`,
222
+ focus: `请重点调研以下方面: ${aspects.join('、')}`
223
+ };
224
+ }
225
+ }
226
+ // 通用领域:尝试从"做X"模式提取
227
+ const actionPatterns = [
228
+ /做(一个|个)(.+?)(的|app|网站|系统|平台|工具|应用|$)/,
229
+ /开发(一个|个)?(.+?)(系统|应用|平台|工具|$)/,
230
+ /构建(一个|个)?(.+?)(系统|应用|平台|工具|$)/,
231
+ /build (a |an )?(.+?)(app|website|system|tool|platform|$)/i,
232
+ ];
233
+ for (const pattern of actionPatterns) {
234
+ const match = description.match(pattern);
235
+ if (match && match[2]) {
236
+ const extracted = match[2].trim();
237
+ return {
238
+ domain: extracted,
239
+ role: `${extracted}领域专家`,
240
+ focus: `请调研 ${extracted} 的核心概念、技术方案、最佳实践、常见挑战`
241
+ };
242
+ }
243
+ }
244
+ // 默认:使用原始描述
245
+ return {
246
+ domain: '项目开发',
247
+ role: '技术顾问',
248
+ focus: '请调研相关技术方案、最佳实践、实现路径'
249
+ };
250
+ }
129
251
  generateRunId() {
130
252
  return `researcher-${Date.now().toString(36)}`;
131
253
  }
@@ -177,6 +177,8 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
177
177
  }
178
178
  // 生成头脑风暴问题
179
179
  const questions = generateBrainstormQuestions(taskContent, taskTitle);
180
+ // 检测是否涉及垂直领域
181
+ const domainDetection = detectVerticalDomain(taskContent);
180
182
  // 创建会话
181
183
  const session = {
182
184
  status: 'brainstorming',
@@ -185,12 +187,13 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
185
187
  questions,
186
188
  answers: {},
187
189
  insights: [],
188
- designNotes: []
190
+ designNotes: [],
191
+ suggestResearch: domainDetection.isVertical ? domainDetection.domain : undefined
189
192
  };
190
193
  await fs.writeFile(brainstormPath, JSON.stringify(session, null, 2));
191
194
  if (options.json) {
192
195
  // JSON 输出供 Skill 解析
193
- console.log(JSON.stringify({
196
+ const output = {
194
197
  status: 'brainstorming',
195
198
  message: '开始头脑风暴',
196
199
  taskTitle,
@@ -202,11 +205,21 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
202
205
  multiSelect: q.multiSelect
203
206
  })),
204
207
  hint: '请逐一回答问题,完成后再调用 --complete'
205
- }));
208
+ };
209
+ // 如果检测到垂直领域,添加建议
210
+ if (domainDetection.isVertical) {
211
+ output.suggestResearch = domainDetection.domain;
212
+ output.researchHint = `检测到垂直领域「${domainDetection.domain}」,建议先进行领域调研`;
213
+ }
214
+ console.log(JSON.stringify(output));
206
215
  }
207
216
  else {
208
217
  console.log('\n🧠 开始头脑风暴...\n');
209
218
  console.log(`📋 任务: ${taskTitle}\n`);
219
+ if (domainDetection.isVertical) {
220
+ console.log(`🔍 检测到垂直领域: ${domainDetection.domain}`);
221
+ console.log(' 建议使用 /om:research 进行领域调研\n');
222
+ }
210
223
  console.log('需要探索以下问题:');
211
224
  questions.forEach((q, i) => {
212
225
  console.log(` ${i + 1}. ${q.question}`);
@@ -214,6 +227,37 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
214
227
  console.log('\n💡 使用 /om:brainstorm 技能进行交互式问答');
215
228
  }
216
229
  });
230
+ /**
231
+ * 检测是否可能需要领域调研
232
+ * 不硬编码领域,只判断是否像垂直领域任务
233
+ */
234
+ function detectVerticalDomain(taskContent) {
235
+ const lower = taskContent.toLowerCase();
236
+ // 检测"做X"模式 - 这是垂直领域任务的典型特征
237
+ const actionPatterns = [
238
+ /做(一个|个)(.+?)(的|app|网站|系统|平台|工具|应用|游戏|$)/,
239
+ /开发(一个|个)?(.+?)(系统|应用|平台|工具|游戏|$)/,
240
+ /构建(一个|个)?(.+?)(系统|应用|平台|工具|$)/,
241
+ /build (a |an )?(.+?)(app|website|system|tool|platform|game|$)/i,
242
+ /create (a |an )?(.+?)(app|website|system|tool|platform|game|$)/i,
243
+ ];
244
+ for (const pattern of actionPatterns) {
245
+ const match = taskContent.match(pattern);
246
+ if (match && match[2]) {
247
+ const extracted = match[2].trim();
248
+ // 如果提取的内容有意义,认为是垂直领域任务
249
+ if (extracted.length > 1) {
250
+ return { isVertical: true, domain: extracted };
251
+ }
252
+ }
253
+ }
254
+ // 检测是否包含"系统"、"平台"、"应用"等大词
255
+ const systemKeywords = ['系统', '平台', '应用', 'system', 'platform', 'app'];
256
+ if (systemKeywords.some(kw => lower.includes(kw))) {
257
+ return { isVertical: true, domain: '待分析' };
258
+ }
259
+ return { isVertical: false, domain: '' };
260
+ }
217
261
  /**
218
262
  * 根据任务内容生成头脑风暴问题
219
263
  */
@@ -37,64 +37,71 @@ exports.completeCommand = void 0;
37
37
  // src/cli/commands/complete.ts
38
38
  const commander_1 = require("commander");
39
39
  const state_manager_js_1 = require("../../storage/state-manager.js");
40
- const approval_manager_js_1 = require("../../orchestrator/approval-manager.js");
41
- const executor_js_1 = require("../../orchestrator/executor.js");
42
40
  const path = __importStar(require("path"));
43
41
  exports.completeCommand = new commander_1.Command('complete')
44
- .description('标记任务完成或失败')
45
- .argument('<taskId>', '任务 ID')
46
- .option('--success', '标记为成功')
42
+ .description('标记任务完成并更新全局统计')
43
+ .argument('<taskId>', '任务ID (如 TASK-001)')
44
+ .option('--success', '标记为成功完成 (默认)', true)
47
45
  .option('--failed', '标记为失败')
48
- .option('--error <message>', '错误信息')
49
- .option('--output <text>', '执行输出')
50
- .option('--json', 'JSON 输出')
46
+ .option('--output <text>', '执行结果摘要')
47
+ .option('--error <text>', '错误信息 (失败时)')
51
48
  .action(async (taskId, options) => {
52
49
  const basePath = process.cwd();
53
50
  const omPath = path.join(basePath, '.openmatrix');
54
51
  const stateManager = new state_manager_js_1.StateManager(omPath);
55
52
  await stateManager.initialize();
56
- const state = await stateManager.getState();
57
- // 构建执行器
58
- const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
59
- const executor = new executor_js_1.OrchestratorExecutor(stateManager, approvalManager, {
60
- maxConcurrent: state.config.maxConcurrentAgents,
61
- taskTimeout: state.config.timeout * 1000
62
- });
63
- const success = options.success || !options.failed;
64
- // 标记任务完成
65
- await executor.completeTask(taskId, {
66
- success,
67
- output: options.output,
68
- error: options.error
69
- });
70
- if (options.json) {
71
- // 获取下一批可执行任务
72
- const nextResult = await executor.step();
73
- const updatedTask = await stateManager.getTask(taskId);
74
- console.log(JSON.stringify({
75
- status: success ? 'completed' : 'failed',
76
- taskId,
77
- taskStatus: updatedTask?.status,
78
- nextBatch: {
79
- status: nextResult.status,
80
- subagentTasks: nextResult.subagentTasks.map(t => ({
81
- subagent_type: t.subagent_type,
82
- description: t.description,
83
- prompt: t.prompt,
84
- isolation: t.isolation,
85
- taskId: t.taskId,
86
- agentType: t.agentType,
87
- timeout: t.timeout
88
- })),
89
- statistics: nextResult.statistics
53
+ // 1. 读取任务
54
+ const task = await stateManager.getTask(taskId);
55
+ if (!task) {
56
+ console.log(JSON.stringify({ error: `任务 ${taskId} 不存在` }));
57
+ process.exit(1);
58
+ }
59
+ const isSuccess = !options.failed;
60
+ const now = new Date().toISOString();
61
+ if (isSuccess) {
62
+ // 2a. 标记任务完成 - 更新所有阶段
63
+ await stateManager.updateTask(taskId, {
64
+ status: 'completed',
65
+ phases: {
66
+ develop: { status: 'completed', duration: 0, completedAt: now },
67
+ verify: { status: 'completed', duration: 0, completedAt: now },
68
+ accept: { status: 'completed', duration: 0, completedAt: now }
90
69
  }
91
- }));
70
+ });
92
71
  }
93
72
  else {
94
- const emoji = success ? '✅' : '❌';
95
- console.log(`${emoji} 任务 ${taskId} ${success ? '完成' : '失败'}`);
96
- if (!success && options.error) {
97
- console.log(` 错误: ${options.error}`);
98
- }
73
+ // 2b. 标记任务失败
74
+ await stateManager.updateTask(taskId, {
75
+ status: 'failed',
76
+ error: options.error || 'Task failed'
77
+ });
99
78
  }
79
+ // 3. 重新计算全局统计(从实际任务文件统计,避免累积误差)
80
+ const allTasks = await stateManager.listTasks();
81
+ const stats = {
82
+ totalTasks: allTasks.length,
83
+ completed: allTasks.filter(t => t.status === 'completed').length,
84
+ inProgress: allTasks.filter(t => t.status === 'in_progress').length,
85
+ failed: allTasks.filter(t => t.status === 'failed').length,
86
+ pending: allTasks.filter(t => t.status === 'pending' || t.status === 'scheduled').length
87
+ };
88
+ // 4. 更新全局状态
89
+ const allDone = stats.completed + stats.failed === stats.totalTasks;
90
+ await stateManager.updateState({
91
+ statistics: stats,
92
+ status: allDone ? 'completed' : 'running',
93
+ currentPhase: allDone ? 'completed' : 'execution',
94
+ ...(allDone ? { completedAt: now } : {})
95
+ });
96
+ // 5. 输出结果
97
+ const result = {
98
+ taskId,
99
+ status: isSuccess ? 'completed' : 'failed',
100
+ statistics: stats,
101
+ allDone,
102
+ message: isSuccess
103
+ ? `${taskId} 完成 (${stats.completed}/${stats.totalTasks})`
104
+ : `${taskId} 失败: ${options.error || 'Unknown error'}`
105
+ };
106
+ console.log(JSON.stringify(result, null, 2));
100
107
  });
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const researchCommand: Command;