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.
package/README.md CHANGED
@@ -45,25 +45,21 @@
45
45
  | 用户输入 | 触发原因 |
46
46
  |---------|---------|
47
47
  | `实现用户登录功能` | 功能开发 |
48
- | `登录页面报错了` | Bug 修复 (隐含修复意图) |
49
- | `修复下这个脚本` | 包含"修复" |
48
+ | `登录页面报错了` | Bug 修复 |
50
49
  | `性能太慢需要优化` | 性能优化 |
51
50
  | `写个单元测试` | 测试相关 |
52
- | `搞个后台系统` | 包含"搞" |
53
- | `弄个API接口` | 包含"弄" |
54
- | `整个配置文件` | 包含"整" |
51
+ | `做个完整的用户系统` | 多组件任务 |
55
52
  | `从零搭建一个后台` | 多步骤项目 |
53
+ | `前端+后端+数据库` | 全栈工作 |
56
54
 
57
55
  **关键词触发:**
58
56
  - `实现...` / `添加...` / `修复...` / `优化...` / `测试...`
59
- - `帮我...` / `搞个...` / `弄个...` / `整个...` / `写个...`
60
57
  - `支持...` / `需要...` / `想要...` / `要做...`
61
58
  - `implement...` / `add...` / `fix...` / `build...`
62
59
  - 任务文档路径: `docs/task.md`
63
- - 问题诊断: `报错了` / `不工作了` / `太慢了` (隐含修复意图)
64
60
 
65
61
  **不触发的情况:**
66
- - 问问题: "登录是什么?" / "为什么报错" (无行动意图)
62
+ - 问问题: "怎么实现登录?" / "如何配置?"
67
63
  - 查信息: "显示配置" / "列出文件"
68
64
  - 导航: "打开目录" / "进入文件夹"
69
65
 
@@ -1,4 +1,4 @@
1
- import type { Task, AgentType, AgentResult } from '../types/index.js';
1
+ import type { Task, AgentType, AgentResult, SubagentTask, ClaudeCodeSubagentType } from '../types/index.js';
2
2
  import { StateManager } from '../storage/state-manager.js';
3
3
  import { ApprovalManager } from '../orchestrator/approval-manager.js';
4
4
  export interface AgentRunnerConfig {
@@ -10,31 +10,6 @@ export interface SubagentPrompt {
10
10
  context: string;
11
11
  instructions: string;
12
12
  }
13
- /**
14
- * Claude Code Subagent 类型
15
- */
16
- export type ClaudeCodeSubagentType = 'general-purpose' | 'Explore' | 'Plan';
17
- /**
18
- * Subagent 任务配置 - 用于 Agent 工具调用
19
- */
20
- export interface SubagentTask {
21
- /** Subagent 类型 */
22
- subagent_type: ClaudeCodeSubagentType;
23
- /** 简短描述 (3-5 词) */
24
- description: string;
25
- /** 完整任务提示词 */
26
- prompt: string;
27
- /** 是否使用隔离 worktree */
28
- isolation?: 'worktree';
29
- /** 任务 ID (用于追踪) */
30
- taskId: string;
31
- /** 原始 Agent 类型 */
32
- agentType: AgentType;
33
- /** 超时时间 (ms) */
34
- timeout: number;
35
- /** 是否需要审批 */
36
- needsApproval: boolean;
37
- }
38
13
  /**
39
14
  * 用户上下文信息
40
15
  */
@@ -7,8 +7,7 @@ const smart_question_analyzer_js_1 = require("../../orchestrator/smart-question-
7
7
  exports.analyzeCommand = new commander_1.Command('analyze')
8
8
  .description('智能分析任务,推断配置,返回需要确认的问题列表')
9
9
  .argument('[task]', '任务描述')
10
- .option('--json', '输出 JSON 格式(供程序解析)')
11
- .option('--markdown', '输出 Markdown 格式(默认)')
10
+ .option('--json', '输出 JSON 格式')
12
11
  .action(async (task, options) => {
13
12
  const analyzer = new smart_question_analyzer_js_1.SmartQuestionAnalyzer(process.cwd());
14
13
  if (!task) {
@@ -32,8 +31,8 @@ exports.analyzeCommand = new commander_1.Command('analyze')
32
31
  console.log(JSON.stringify(output, null, 2));
33
32
  }
34
33
  else {
35
- // 默认输出 Markdown 格式
36
- console.log('\n' + analyzer.generateMarkdown(result));
34
+ // 输出人类可读格式
35
+ console.log('\n' + analyzer.generateSummary(result));
37
36
  }
38
37
  }
39
38
  catch (error) {
@@ -79,12 +79,6 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
79
79
  }
80
80
  }
81
81
  await fs.writeFile(brainstormPath, JSON.stringify(session, null, 2));
82
- // 构建下一个步骤的命令
83
- const brainstormAnswers = JSON.stringify({
84
- answers: session.answers,
85
- insights: session.insights,
86
- designNotes: session.designNotes
87
- });
88
82
  if (options.json) {
89
83
  console.log(JSON.stringify({
90
84
  status: 'ready_to_start',
@@ -94,23 +88,7 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
94
88
  answers: session.answers,
95
89
  insights: session.insights,
96
90
  designNotes: session.designNotes,
97
- // 关键:告诉 Agent 下一步必须执行什么
98
- nextStep: {
99
- required: true,
100
- description: '必须调用此命令开始任务执行',
101
- command: 'openmatrix',
102
- args: ['start', session.taskInput.slice(0, 100)],
103
- options: {
104
- 'brainstorm-answers': brainstormAnswers
105
- },
106
- hint: '使用 /om:start 开始执行任务'
107
- },
108
- // 强制执行标记 - Agent 必须执行 nextStep
109
- _meta: {
110
- requiresAction: true,
111
- actionType: 'cli_command',
112
- blocking: true
113
- }
91
+ hint: '使用 /om:start 开始执行任务'
114
92
  }));
115
93
  }
116
94
  else {
@@ -238,71 +216,71 @@ exports.brainstormCommand = new commander_1.Command('brainstorm')
238
216
  });
239
217
  /**
240
218
  * 根据任务内容生成头脑风暴问题
241
- *
242
- * 基于"底层逻辑"方法论,不使用固定模板
243
219
  */
244
220
  function generateBrainstormQuestions(taskContent, taskTitle) {
245
221
  const questions = [];
246
- // ========== 第一层:价值逻辑 ==========
247
- // 1. 核心目标
222
+ const content = taskContent.toLowerCase();
223
+ // 问题 1: 核心目标
248
224
  questions.push({
249
225
  id: 'core_objective',
250
226
  question: '这个任务的核心目标是什么?想要解决什么问题?',
251
227
  header: '核心目标',
252
228
  options: [
253
- { label: '创建新系统', description: '从零开始构建新的系统或应用' },
254
- { label: '添加新功能', description: '在现有系统上增加新能力' },
255
- { label: '修复问题', description: '解决 Bug 或已知问题' },
256
- { label: '优化改进', description: '提升性能、体验或代码质量' }
229
+ { label: '实现新功能', description: '添加新的功能特性,扩展系统能力' },
230
+ { label: '修复问题', description: '修复 Bug 或解决已知问题' },
231
+ { label: '重构优化', description: '改进代码结构、性能或可维护性' },
232
+ { label: '技术探索', description: '探索新技术方案,验证可行性' }
257
233
  ],
258
234
  multiSelect: false,
259
- why: '明确核心目标有助于选择正确的实现策略'
235
+ why: '明确核心目标有助于选择正确的实现策略和质量标准'
260
236
  });
261
- // 2. 用户价值
237
+ // 问题 2: 用户价值
262
238
  questions.push({
263
239
  id: 'user_value',
264
- question: '这个任务为谁创造价值?最终用户是谁?',
240
+ question: '这个任务为用户带来什么价值?最终用户是谁?',
265
241
  header: '用户价值',
266
242
  options: [
267
- { label: '终端用户', description: '产品的最终使用者,需要良好体验' },
268
- { label: '开发者', description: '技术用户,需要清晰的 API 和文档' },
269
- { label: '团队内部', description: '内部工具,追求效率' },
270
- { label: '业务方', description: '满足业务需求,关注指标' }
243
+ { label: '开发者', description: '主要用户是开发者,需要清晰的 API 和文档' },
244
+ { label: '终端用户', description: '主要用户是终端用户,需要良好的用户体验' },
245
+ { label: '运维人员', description: '主要用户是运维,需要稳定性和可观测性' },
246
+ { label: '内部团队', description: '主要用户是内部团队,需要高效协作支持' }
271
247
  ],
272
248
  multiSelect: false,
273
- why: '了解目标用户有助于设计合适的方案'
249
+ why: '了解目标用户有助于设计合适的接口和交互方式'
274
250
  });
275
- // ========== 第二层:架构逻辑 ==========
276
- // 3. 复杂度评估
277
- questions.push({
278
- id: 'complexity',
279
- question: '这个任务的复杂度如何?涉及哪些关键组件?',
280
- header: '复杂度',
281
- options: [
282
- { label: '简单', description: '单一功能,少量代码' },
283
- { label: '中等', description: '多个组件协作,有依赖关系' },
284
- { label: '复杂', description: '涉及架构设计,需要仔细规划' },
285
- { label: '非常复杂', description: '大型系统,需要分阶段实施' }
286
- ],
287
- multiSelect: false,
288
- why: '复杂度决定是否需要分阶段实施'
289
- });
290
- // 4. 技术约束
291
- questions.push({
292
- id: 'tech_constraints',
293
- question: '有哪些技术约束或偏好?',
294
- header: '技术约束',
295
- options: [
296
- { label: '使用现有技术栈', description: '不引入新依赖' },
297
- { label: '可以引入新技术', description: '允许引入新的库或框架' },
298
- { label: '需要技术调研', description: '技术选型待定,先调研' },
299
- { label: '无特殊约束', description: '自由选择最合适的方案' }
300
- ],
301
- multiSelect: false,
302
- why: '技术约束影响实现方案选择'
303
- });
304
- // ========== 第三层:风险逻辑 ==========
305
- // 5. 风险识别
251
+ // 问题 3: 实现复杂度 - 如果任务内容包含复杂关键词
252
+ if (content.includes('架构') || content.includes('系统') || content.includes('集成') || content.includes('多个')) {
253
+ questions.push({
254
+ id: 'complexity',
255
+ question: '这个任务的实现复杂度如何?需要哪些关键组件?',
256
+ header: '复杂度',
257
+ options: [
258
+ { label: '简单', description: '单一功能,少量代码修改' },
259
+ { label: '中等', description: '需要多个组件协作,有依赖关系' },
260
+ { label: '复杂', description: '涉及架构调整,需要仔细规划' },
261
+ { label: '非常复杂', description: '大型重构或新系统,需要分阶段实施' }
262
+ ],
263
+ multiSelect: false,
264
+ why: '复杂度评估有助于决定是否需要分阶段实施和额外的设计审查'
265
+ });
266
+ }
267
+ // 问题 4: 技术约束 - 如果涉及技术选型
268
+ if (content.includes('技术') || content.includes('框架') || content.includes('库')) {
269
+ questions.push({
270
+ id: 'tech_constraints',
271
+ question: '有哪些技术约束或偏好?需要使用/避免什么技术?',
272
+ header: '技术约束',
273
+ options: [
274
+ { label: '使用现有技术栈', description: '复用项目已有的技术选择' },
275
+ { label: '引入新技术', description: '需要引入新的库或框架' },
276
+ { label: '保持技术中立', description: '不引入新依赖,使用原生方案' },
277
+ { label: '需要技术调研', description: '技术选型不确定,需要先调研' }
278
+ ],
279
+ multiSelect: false,
280
+ why: '技术约束影响实现方案和后续维护成本'
281
+ });
282
+ }
283
+ // 问题 5: 风险评估
306
284
  questions.push({
307
285
  id: 'risks',
308
286
  question: '这个任务可能面临哪些风险或挑战?',
@@ -316,7 +294,7 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
316
294
  multiSelect: true,
317
295
  why: '识别风险有助于提前规划应对策略'
318
296
  });
319
- // 6. 验收标准
297
+ // 问题 6: 验收标准
320
298
  questions.push({
321
299
  id: 'acceptance',
322
300
  question: '如何判断任务完成?有哪些验收标准?',
@@ -330,15 +308,15 @@ function generateBrainstormQuestions(taskContent, taskTitle) {
330
308
  multiSelect: true,
331
309
  why: '明确的验收标准有助于判断任务完成度'
332
310
  });
333
- // 7. 优先级
311
+ // 问题 7: 实现优先级
334
312
  questions.push({
335
313
  id: 'priority',
336
- question: '这个任务的优先级如何?实施策略是什么?',
314
+ question: '这个任务的优先级如何?是否需要 MVP 版本?',
337
315
  header: '优先级',
338
316
  options: [
339
317
  { label: '高优先级', description: '需要尽快完成,影响其他工作' },
340
318
  { label: '中优先级', description: '计划内任务,按正常节奏推进' },
341
- { label: '低优先级', description: '可延后处理' },
319
+ { label: '低优先级', description: '可延后处理,有更重要的任务' },
342
320
  { label: '需要 MVP', description: '先实现最小可用版本,再迭代' }
343
321
  ],
344
322
  multiSelect: false,
@@ -38,6 +38,7 @@ exports.meetingCommand = void 0;
38
38
  const commander_1 = require("commander");
39
39
  const state_manager_js_1 = require("../../storage/state-manager.js");
40
40
  const approval_manager_js_1 = require("../../orchestrator/approval-manager.js");
41
+ const meeting_manager_js_1 = require("../../orchestrator/meeting-manager.js");
41
42
  const path = __importStar(require("path"));
42
43
  exports.meetingCommand = new commander_1.Command('meeting')
43
44
  .description('查看和处理待确认的 Meeting')
@@ -55,23 +56,26 @@ exports.meetingCommand = new commander_1.Command('meeting')
55
56
  const stateManager = new state_manager_js_1.StateManager(omPath);
56
57
  await stateManager.initialize();
57
58
  const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
59
+ const meetingManager = new meeting_manager_js_1.MeetingManager(stateManager, approvalManager);
58
60
  try {
59
- // 获取所有 pending 的 meeting
61
+ // 获取所有 pending 的 meeting approvals
60
62
  const pendingApprovals = await stateManager.getApprovalsByStatus('pending');
61
- const meetings = pendingApprovals.filter(a => a.type === 'meeting');
63
+ const meetingApprovals = pendingApprovals.filter(a => a.type === 'meeting');
62
64
  // 列出所有 Meeting
63
65
  if (options.list || (!meetingId && !options.skipAll)) {
64
- if (meetings.length === 0) {
66
+ // 同时获取 MeetingManager 中的详细 Meeting 信息
67
+ const pendingMeetings = await meetingManager.getPendingMeetings();
68
+ if (meetingApprovals.length === 0 && pendingMeetings.length === 0) {
65
69
  console.log('✅ 没有待处理的 Meeting\n');
66
- console.log('当前状态:');
67
70
  const allApprovals = await stateManager.getApprovalsByStatus('approved');
68
- const meetingApprovals = allApprovals.filter(a => a.type === 'meeting');
69
- console.log(` - 已解决: ${meetingApprovals.length}`);
70
- console.log(` - 总计: ${meetingApprovals.length}`);
71
+ const resolvedMeetings = allApprovals.filter(a => a.type === 'meeting');
72
+ console.log('当前状态:');
73
+ console.log(` - 已解决: ${resolvedMeetings.length}`);
74
+ console.log(` - 总计: ${resolvedMeetings.length}`);
71
75
  return;
72
76
  }
73
- console.log(`\n📋 待处理 Meeting (${meetings.length}个)\n`);
74
- meetings.forEach((meeting, index) => {
77
+ console.log(`\n📋 待处理 Meeting (${meetingApprovals.length}个)\n`);
78
+ meetingApprovals.forEach((meeting, index) => {
75
79
  const icon = meeting.title.includes('决策') ? '🤔' : '🔴';
76
80
  const shortTitle = meeting.title.slice(0, 40);
77
81
  console.log(` [${index + 1}] ${icon} ${meeting.id} - ${shortTitle}`);
@@ -87,8 +91,8 @@ exports.meetingCommand = new commander_1.Command('meeting')
87
91
  }
88
92
  // 批量跳过
89
93
  if (options.skipAll) {
90
- console.log(`\n⏭️ 批量跳过 ${meetings.length} 个 Meeting...\n`);
91
- for (const meeting of meetings) {
94
+ console.log(`\n⏭️ 批量跳过 ${meetingApprovals.length} 个 Meeting...\n`);
95
+ for (const meeting of meetingApprovals) {
92
96
  await approvalManager.processDecision({
93
97
  approvalId: meeting.id,
94
98
  decision: 'approve',
@@ -96,6 +100,16 @@ exports.meetingCommand = new commander_1.Command('meeting')
96
100
  decidedBy: 'user',
97
101
  decidedAt: new Date().toISOString()
98
102
  });
103
+ // 尝试通过 MeetingManager 解决关联的 Meeting
104
+ try {
105
+ const parsed = JSON.parse(meeting.content || '{}');
106
+ if (parsed.meetingId) {
107
+ await meetingManager.cancelMeeting(parsed.meetingId, options.message || '批量跳过');
108
+ }
109
+ }
110
+ catch {
111
+ // content 可能不是 JSON,跳过 Meeting 更新
112
+ }
99
113
  // 更新关联任务状态为 skipped
100
114
  const task = await stateManager.getTask(meeting.taskId);
101
115
  if (task) {
@@ -114,7 +128,7 @@ exports.meetingCommand = new commander_1.Command('meeting')
114
128
  console.log('❌ 请指定 Meeting ID 或使用 --list');
115
129
  return;
116
130
  }
117
- const meeting = meetings.find(m => m.id === meetingId);
131
+ const meeting = meetingApprovals.find(m => m.id === meetingId);
118
132
  if (!meeting) {
119
133
  console.log(`❌ Meeting ${meetingId} 不存在或已处理`);
120
134
  return;
@@ -123,7 +137,7 @@ exports.meetingCommand = new commander_1.Command('meeting')
123
137
  console.log(`\n📋 Meeting: ${meeting.id}`);
124
138
  console.log(`🎯 任务: ${meeting.taskId}`);
125
139
  console.log(`\n## 详情\n`);
126
- console.log(meeting.content || '无详细内容');
140
+ console.log(meeting.description || '无详细内容');
127
141
  console.log('');
128
142
  // 执行操作
129
143
  const action = options.action;
@@ -137,6 +151,15 @@ exports.meetingCommand = new commander_1.Command('meeting')
137
151
  console.log(' --action cancel --message "..."');
138
152
  return;
139
153
  }
154
+ // 解析关联的 Meeting ID
155
+ let internalMeetingId;
156
+ try {
157
+ const parsed = JSON.parse(meeting.content || '{}');
158
+ internalMeetingId = parsed.meetingId;
159
+ }
160
+ catch {
161
+ // content 可能不是 JSON
162
+ }
140
163
  switch (action) {
141
164
  case 'provide-info':
142
165
  if (!options.info) {
@@ -150,6 +173,10 @@ exports.meetingCommand = new commander_1.Command('meeting')
150
173
  decidedBy: 'user',
151
174
  decidedAt: new Date().toISOString()
152
175
  });
176
+ // 通过 MeetingManager 解决关联 Meeting
177
+ if (internalMeetingId) {
178
+ await meetingManager.resolveMeeting(internalMeetingId, `提供信息: ${options.info}`);
179
+ }
153
180
  console.log('✅ 信息已记录,任务将恢复执行');
154
181
  break;
155
182
  case 'skip':
@@ -160,6 +187,9 @@ exports.meetingCommand = new commander_1.Command('meeting')
160
187
  decidedBy: 'user',
161
188
  decidedAt: new Date().toISOString()
162
189
  });
190
+ if (internalMeetingId) {
191
+ await meetingManager.cancelMeeting(internalMeetingId, options.message || '跳过');
192
+ }
163
193
  // 标记任务为跳过
164
194
  const skipTask = await stateManager.getTask(meeting.taskId);
165
195
  if (skipTask) {
@@ -178,6 +208,9 @@ exports.meetingCommand = new commander_1.Command('meeting')
178
208
  decidedBy: 'user',
179
209
  decidedAt: new Date().toISOString()
180
210
  });
211
+ if (internalMeetingId) {
212
+ await meetingManager.resolveMeeting(internalMeetingId, '重试任务');
213
+ }
181
214
  // 重置任务状态
182
215
  await stateManager.updateTask(meeting.taskId, {
183
216
  status: 'retry_queue',
@@ -197,6 +230,9 @@ exports.meetingCommand = new commander_1.Command('meeting')
197
230
  decidedBy: 'user',
198
231
  decidedAt: new Date().toISOString()
199
232
  });
233
+ if (internalMeetingId) {
234
+ await meetingManager.resolveMeeting(internalMeetingId, `修改方案: ${options.newPlan}`);
235
+ }
200
236
  // 更新任务描述
201
237
  const modifyTask = await stateManager.getTask(meeting.taskId);
202
238
  if (modifyTask) {
@@ -216,6 +252,9 @@ exports.meetingCommand = new commander_1.Command('meeting')
216
252
  decidedBy: 'user',
217
253
  decidedAt: new Date().toISOString()
218
254
  });
255
+ if (internalMeetingId) {
256
+ await meetingManager.resolveMeeting(internalMeetingId, `决策: ${options.reason || '已做出决策'}`);
257
+ }
219
258
  console.log('✅ 决策已记录');
220
259
  break;
221
260
  case 'cancel':
@@ -226,6 +265,9 @@ exports.meetingCommand = new commander_1.Command('meeting')
226
265
  decidedBy: 'user',
227
266
  decidedAt: new Date().toISOString()
228
267
  });
268
+ if (internalMeetingId) {
269
+ await meetingManager.cancelMeeting(internalMeetingId, options.message || '用户取消');
270
+ }
229
271
  // 标记任务为失败
230
272
  await stateManager.updateTask(meeting.taskId, {
231
273
  status: 'failed',