openmatrix 0.1.50 → 0.1.52

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.
@@ -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
  */
@@ -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',
@@ -58,6 +58,7 @@ exports.startCommand = new commander_1.Command('start')
58
58
  .option('-q, --quality <level>', '质量级别 (strict|balanced|fast)')
59
59
  .option('-t, --tech-stack <stack>', '技术栈 (逗号分隔,如 "TypeScript,Vue.js,PostgreSQL")')
60
60
  .option('--docs <level>', '文档级别 (full|basic|minimal|none)')
61
+ .option('--tasks-json <json>', 'AI 已拆分的任务 JSON (跳过自动解析)')
61
62
  .action(async (input, options) => {
62
63
  const basePath = process.cwd();
63
64
  const omPath = path.join(basePath, '.openmatrix');
@@ -101,9 +102,198 @@ exports.startCommand = new commander_1.Command('start')
101
102
  }
102
103
  return;
103
104
  }
105
+ // ============================
106
+ // 路径 A: AI 已拆分 (--tasks-json)
107
+ // ============================
108
+ if (options.tasksJson) {
109
+ await handleTasksJson(options, stateManager, state, omPath);
110
+ return;
111
+ }
112
+ // ============================
113
+ // 路径 B: 自动解析 (fallback)
114
+ // ============================
115
+ await handleAutoParse(input, options, stateManager, state);
116
+ });
117
+ /**
118
+ * 处理 AI 解析的任务 (--tasks-json)
119
+ * AI 提供 ParsedTask 格式的结构化数据,仍由 TaskPlanner 做拆分
120
+ */
121
+ async function handleTasksJson(options, stateManager, state, omPath) {
122
+ let tasksInput;
123
+ try {
124
+ // 支持 @file 语法读取文件
125
+ let jsonStr = options.tasksJson;
126
+ if (jsonStr.startsWith('@')) {
127
+ jsonStr = await fs.readFile(jsonStr.slice(1), 'utf-8');
128
+ }
129
+ tasksInput = JSON.parse(jsonStr);
130
+ }
131
+ catch (e) {
132
+ if (options.json) {
133
+ console.log(JSON.stringify({
134
+ status: 'error',
135
+ message: `--tasks-json 解析失败: ${e instanceof Error ? e.message : e}`
136
+ }));
137
+ }
138
+ else {
139
+ console.log(`❌ --tasks-json 解析失败: ${e instanceof Error ? e.message : e}`);
140
+ }
141
+ return;
142
+ }
143
+ if (!tasksInput.goals || tasksInput.goals.length === 0) {
144
+ if (options.json) {
145
+ console.log(JSON.stringify({ status: 'error', message: '--tasks-json 中 goals 为空' }));
146
+ }
147
+ else {
148
+ console.log('❌ --tasks-json 中 goals 为空');
149
+ }
150
+ return;
151
+ }
152
+ // 保存 AI 生成的执行计划
153
+ if (tasksInput.plan) {
154
+ await fs.writeFile(path.join(omPath, 'plan.md'), tasksInput.plan, 'utf-8');
155
+ }
156
+ // 构建 ParsedTask
157
+ const parsedTask = {
158
+ title: tasksInput.title,
159
+ description: tasksInput.description || '',
160
+ goals: tasksInput.goals,
161
+ constraints: tasksInput.constraints || [],
162
+ deliverables: tasksInput.deliverables || [],
163
+ rawContent: ''
164
+ };
165
+ // 解析质量配置
166
+ const qualityLevel = tasksInput.quality || options.quality || 'balanced';
167
+ const qualityConfig = index_js_1.QUALITY_PRESETS[qualityLevel.toLowerCase()] || index_js_1.QUALITY_PRESETS.balanced;
168
+ if (!options.json) {
169
+ console.log(`\n📋 任务: ${parsedTask.title}`);
170
+ console.log(` 目标: ${parsedTask.goals.join(', ')}`);
171
+ console.log('\n🔧 拆解任务...');
172
+ }
173
+ // 使用 TaskPlanner 拆分(保持原有拆分逻辑)
174
+ const answers = tasksInput.answers || {};
175
+ const planner = new task_planner_js_1.TaskPlanner();
176
+ const subTasks = planner.breakdown(parsedTask, answers, qualityConfig, tasksInput.plan);
177
+ // 创建任务到状态管理器,并建立 ID 映射
178
+ // TaskPlanner 生成的 taskId 和 StateManager 创建的 id 不同,
179
+ // 需要映射后才能正确设置 dependencies
180
+ const taskIdMap = new Map();
181
+ for (const task of subTasks) {
182
+ const created = await stateManager.createTask({
183
+ title: task.title,
184
+ description: task.description,
185
+ priority: task.priority,
186
+ timeout: task.estimatedComplexity === 'high' ? 300000 :
187
+ task.estimatedComplexity === 'medium' ? 180000 : 120000,
188
+ dependencies: [], // 先创建,稍后更新依赖
189
+ assignedAgent: task.assignedAgent
190
+ });
191
+ taskIdMap.set(task.taskId, created.id);
192
+ }
193
+ // 映射并更新依赖关系
194
+ for (const task of subTasks) {
195
+ const actualId = taskIdMap.get(task.taskId);
196
+ const resolvedDeps = task.dependencies
197
+ .map(dep => taskIdMap.get(dep))
198
+ .filter((id) => id !== undefined);
199
+ if (resolvedDeps.length > 0) {
200
+ await stateManager.updateTask(actualId, { dependencies: resolvedDeps });
201
+ }
202
+ }
203
+ // 解析执行模式
204
+ const executionMode = tasksInput.mode || options.mode || 'confirm-key';
205
+ const approvalPoints = resolveApprovalPoints(executionMode);
206
+ await stateManager.updateState({
207
+ status: 'running',
208
+ currentPhase: 'execution',
209
+ config: {
210
+ ...state.config,
211
+ approvalPoints: approvalPoints,
212
+ quality: qualityConfig
213
+ }
214
+ });
215
+ // 创建审批请求(如果有审批点)
216
+ const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
217
+ if (approvalPoints.includes('plan')) {
218
+ const approval = await approvalManager.createPlanApproval('plan-approval', `# 执行计划\n\n${subTasks.map((t, i) => `${i + 1}. ${t.title} (${t.assignedAgent})`).join('\n')}`);
219
+ await stateManager.updateState({ status: 'paused' });
220
+ if (options.json) {
221
+ console.log(JSON.stringify({
222
+ status: 'waiting_approval',
223
+ approvalId: approval.id,
224
+ approvalType: 'plan',
225
+ message: '等待计划审批',
226
+ tasks: subTasks.map((t, i) => ({
227
+ index: i + 1,
228
+ title: t.title,
229
+ priority: t.priority,
230
+ assignedAgent: t.assignedAgent
231
+ })),
232
+ taskInfo: {
233
+ title: tasksInput.title,
234
+ description: tasksInput.description,
235
+ quality: qualityLevel
236
+ }
237
+ }));
238
+ }
239
+ else {
240
+ console.log(`\n📋 ${tasksInput.title} - ${subTasks.length} 个子任务:\n`);
241
+ subTasks.forEach((task, i) => {
242
+ console.log(` ${i + 1}. ${task.title} (${task.priority}, ${task.assignedAgent})`);
243
+ });
244
+ console.log(`\n🎯 执行模式: ${executionMode}`);
245
+ console.log(`⏸️ 等待计划审批 (ID: ${approval.id})`);
246
+ }
247
+ return;
248
+ }
249
+ // 无审批点,直接开始执行
250
+ const executor = new executor_js_1.OrchestratorExecutor(stateManager, approvalManager, {
251
+ maxConcurrent: state.config.maxConcurrentAgents,
252
+ taskTimeout: state.config.timeout * 1000
253
+ });
254
+ const phaseExecutor = executor.getPhaseExecutor();
255
+ if (phaseExecutor) {
256
+ phaseExecutor.setRunId(state.runId);
257
+ if (executionMode === 'auto') {
258
+ phaseExecutor.setAutoMode(true);
259
+ }
260
+ }
261
+ const result = await executor.step();
262
+ if (options.json) {
263
+ console.log(JSON.stringify({
264
+ status: result.status,
265
+ message: result.message,
266
+ statistics: result.statistics,
267
+ subagentTasks: result.subagentTasks.map(t => ({
268
+ subagent_type: t.subagent_type,
269
+ description: t.description,
270
+ prompt: t.prompt,
271
+ isolation: t.isolation,
272
+ taskId: t.taskId,
273
+ agentType: t.agentType,
274
+ timeout: t.timeout
275
+ })),
276
+ taskInfo: {
277
+ title: tasksInput.title,
278
+ description: tasksInput.description,
279
+ quality: qualityLevel
280
+ }
281
+ }));
282
+ }
283
+ else {
284
+ console.log(`\n📋 ${tasksInput.title} - ${subTasks.length} 个子任务已创建`);
285
+ console.log(`🎯 执行模式: ${executionMode}`);
286
+ console.log(` 质量级别: ${qualityLevel}`);
287
+ console.log('\n🚀 开始执行...');
288
+ console.log(' 使用 /om:status 查看进度');
289
+ }
290
+ }
291
+ /**
292
+ * 处理自动解析 (fallback,无 AI 时使用)
293
+ */
294
+ async function handleAutoParse(input, options, stateManager, state) {
104
295
  // 构建任务内容
105
296
  let taskContent = input;
106
- // 如果提供了 --title 和 --description,构建任务内容
107
297
  if (options.title || options.description) {
108
298
  const title = options.title || '未命名任务';
109
299
  const description = options.description || '';
@@ -111,9 +301,8 @@ exports.startCommand = new commander_1.Command('start')
111
301
  const docs = options.docs ? `\n文档要求: ${options.docs}` : '';
112
302
  taskContent = `# ${title}\n\n${description}${techStack}${docs}`;
113
303
  }
114
- // 如果没有任务内容,尝试读取默认文件
115
304
  if (!taskContent) {
116
- const defaultPath = path.join(basePath, 'TASK.md');
305
+ const defaultPath = path.join(process.cwd(), 'TASK.md');
117
306
  try {
118
307
  taskContent = await fs.readFile(defaultPath, 'utf-8');
119
308
  if (!options.json) {
@@ -122,34 +311,21 @@ exports.startCommand = new commander_1.Command('start')
122
311
  }
123
312
  catch {
124
313
  if (options.json) {
125
- console.log(JSON.stringify({
126
- status: 'error',
127
- message: '请提供任务文件路径或描述'
128
- }));
314
+ console.log(JSON.stringify({ status: 'error', message: '请提供任务文件路径或描述' }));
129
315
  }
130
316
  else {
131
317
  console.log('❌ 请提供任务文件路径或描述');
132
- console.log(' 用法: openmatrix start <task.md>');
133
- console.log(' 或创建 TASK.md 文件');
134
- console.log(' 或使用 --title 和 --description 选项');
135
318
  }
136
319
  return;
137
320
  }
138
321
  }
139
322
  else if (taskContent.endsWith('.md')) {
140
- // 读取文件
141
323
  try {
142
324
  taskContent = await fs.readFile(taskContent, 'utf-8');
143
- if (!options.json) {
144
- console.log(`📄 读取任务文件: ${input}`);
145
- }
146
325
  }
147
326
  catch {
148
327
  if (options.json) {
149
- console.log(JSON.stringify({
150
- status: 'error',
151
- message: `无法读取文件: ${input}`
152
- }));
328
+ console.log(JSON.stringify({ status: 'error', message: `无法读取文件: ${input}` }));
153
329
  }
154
330
  else {
155
331
  console.log(`❌ 无法读取文件: ${input}`);
@@ -157,7 +333,6 @@ exports.startCommand = new commander_1.Command('start')
157
333
  return;
158
334
  }
159
335
  }
160
- // 解析任务
161
336
  if (!options.json) {
162
337
  console.log('\n🔍 解析任务...');
163
338
  }
@@ -167,50 +342,44 @@ exports.startCommand = new commander_1.Command('start')
167
342
  console.log(`\n📋 任务: ${parsedTask.title}`);
168
343
  console.log(` 目标: ${parsedTask.goals.join(', ')}`);
169
344
  }
170
- // 拆解任务
171
345
  if (!options.json) {
172
346
  console.log('\n🔧 拆解任务...');
173
347
  }
348
+ let qualityConfig;
349
+ if (options.quality) {
350
+ const qualityLevel = options.quality.toLowerCase();
351
+ if (['strict', 'balanced', 'fast'].includes(qualityLevel)) {
352
+ qualityConfig = index_js_1.QUALITY_PRESETS[qualityLevel];
353
+ }
354
+ }
174
355
  const planner = new task_planner_js_1.TaskPlanner();
175
- const subTasks = planner.breakdown(parsedTask, {});
176
- // 创建任务到状态管理器
356
+ const subTasks = planner.breakdown(parsedTask, {}, qualityConfig);
357
+ // 创建任务,并建立 TaskPlanner ID → StateManager ID 的映射
358
+ const taskIdMap = new Map();
177
359
  for (const subTask of subTasks) {
178
- await stateManager.createTask({
360
+ const created = await stateManager.createTask({
179
361
  title: subTask.title,
180
362
  description: subTask.description,
181
363
  priority: subTask.priority,
182
364
  timeout: subTask.estimatedComplexity === 'high' ? 300000 :
183
365
  subTask.estimatedComplexity === 'medium' ? 180000 : 120000,
184
- dependencies: subTask.dependencies,
366
+ dependencies: [],
185
367
  assignedAgent: subTask.assignedAgent
186
368
  });
369
+ taskIdMap.set(subTask.taskId, created.id);
187
370
  }
188
- // 确定执行模式
189
- const executionMode = options.mode || 'confirm-key';
190
- let approvalPoints = [];
191
- // 根据模式设置审批点
192
- switch (executionMode) {
193
- case 'confirm-all':
194
- approvalPoints = ['plan', 'phase', 'merge', 'deploy'];
195
- break;
196
- case 'confirm-key':
197
- approvalPoints = ['plan', 'merge', 'deploy'];
198
- break;
199
- case 'auto':
200
- approvalPoints = [];
201
- break;
202
- default:
203
- approvalPoints = ['plan', 'merge'];
204
- }
205
- // 处理质量配置
206
- let qualityConfig;
207
- if (options.quality) {
208
- const qualityLevel = options.quality.toLowerCase();
209
- if (['strict', 'balanced', 'fast'].includes(qualityLevel)) {
210
- qualityConfig = index_js_1.QUALITY_PRESETS[qualityLevel];
371
+ // 映射并更新依赖关系
372
+ for (const subTask of subTasks) {
373
+ const actualId = taskIdMap.get(subTask.taskId);
374
+ const resolvedDeps = subTask.dependencies
375
+ .map(dep => taskIdMap.get(dep))
376
+ .filter((id) => id !== undefined);
377
+ if (resolvedDeps.length > 0) {
378
+ await stateManager.updateTask(actualId, { dependencies: resolvedDeps });
211
379
  }
212
380
  }
213
- // 更新状态
381
+ const executionMode = options.mode || 'confirm-key';
382
+ const approvalPoints = resolveApprovalPoints(executionMode);
214
383
  await stateManager.updateState({
215
384
  status: 'running',
216
385
  currentPhase: 'execution',
@@ -220,7 +389,6 @@ exports.startCommand = new commander_1.Command('start')
220
389
  quality: qualityConfig || state.config.quality
221
390
  }
222
391
  });
223
- // 创建审批请求(如果有审批点)
224
392
  const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
225
393
  if (approvalPoints.includes('plan')) {
226
394
  const approval = await approvalManager.createPlanApproval('plan-approval', `# 执行计划\n\n${subTasks.map((t, i) => `${i + 1}. ${t.title}`).join('\n')}`);
@@ -231,12 +399,7 @@ exports.startCommand = new commander_1.Command('start')
231
399
  approvalId: approval.id,
232
400
  approvalType: 'plan',
233
401
  message: '等待计划审批',
234
- tasks: subTasks.map((t, i) => ({
235
- index: i + 1,
236
- title: t.title,
237
- priority: t.priority
238
- })),
239
- // 额外信息供 Skill 使用
402
+ tasks: subTasks.map((t, i) => ({ index: i + 1, title: t.title, priority: t.priority })),
240
403
  taskInfo: {
241
404
  title: options.title || parsedTask.title,
242
405
  description: options.description,
@@ -252,25 +415,14 @@ exports.startCommand = new commander_1.Command('start')
252
415
  console.log(` ${i + 1}. ${task.title} (${task.priority})`);
253
416
  });
254
417
  console.log(`\n🎯 执行模式: ${executionMode}`);
255
- console.log(` 审批点: ${approvalPoints.join(', ')}`);
256
- if (options.quality) {
257
- console.log(` 质量级别: ${options.quality}`);
258
- }
259
- if (options.techStack) {
260
- console.log(` 技术栈: ${options.techStack}`);
261
- }
262
- console.log(`\n⏸️ 等待计划审批`);
263
- console.log(` 审批ID: ${approval.id}`);
264
- console.log(` 使用 /om:approve ${approval.id} 审批`);
418
+ console.log(`⏸️ 等待计划审批 (ID: ${approval.id})`);
265
419
  }
266
420
  return;
267
421
  }
268
- // 创建执行器并获取第一批任务
269
422
  const executor = new executor_js_1.OrchestratorExecutor(stateManager, approvalManager, {
270
423
  maxConcurrent: state.config.maxConcurrentAgents,
271
424
  taskTimeout: state.config.timeout * 1000
272
425
  });
273
- // 设置 PhaseExecutor 的自动模式和 RunId
274
426
  const phaseExecutor = executor.getPhaseExecutor();
275
427
  if (phaseExecutor) {
276
428
  phaseExecutor.setRunId(state.runId);
@@ -280,7 +432,6 @@ exports.startCommand = new commander_1.Command('start')
280
432
  }
281
433
  const result = await executor.step();
282
434
  if (options.json) {
283
- // JSON 输出供 Skill 解析
284
435
  console.log(JSON.stringify({
285
436
  status: result.status,
286
437
  message: result.message,
@@ -294,7 +445,6 @@ exports.startCommand = new commander_1.Command('start')
294
445
  agentType: t.agentType,
295
446
  timeout: t.timeout
296
447
  })),
297
- // 额外信息供 Skill 使用
298
448
  taskInfo: {
299
449
  title: options.title || parsedTask.title,
300
450
  description: options.description,
@@ -305,19 +455,20 @@ exports.startCommand = new commander_1.Command('start')
305
455
  }));
306
456
  }
307
457
  else {
308
- console.log(`\n📋 生成 ${subTasks.length} 个子任务:\n`);
309
- subTasks.forEach((task, i) => {
310
- console.log(` ${i + 1}. ${task.title} (${task.priority})`);
311
- });
312
- console.log(`\n🎯 执行模式: ${executionMode}`);
313
- console.log(` 审批点: ${approvalPoints.length > 0 ? approvalPoints.join(', ') : '无 (全自动)'}`);
314
- if (options.quality) {
315
- console.log(` 质量级别: ${options.quality}`);
316
- }
317
- if (options.techStack) {
318
- console.log(` 技术栈: ${options.techStack}`);
319
- }
458
+ console.log(`\n📋 生成 ${subTasks.length} 个子任务`);
459
+ console.log(`🎯 执行模式: ${executionMode}`);
320
460
  console.log('\n🚀 开始执行...');
321
461
  console.log(' 使用 /om:status 查看进度');
322
462
  }
323
- });
463
+ }
464
+ /**
465
+ * 根据执行模式解析审批点
466
+ */
467
+ function resolveApprovalPoints(mode) {
468
+ switch (mode) {
469
+ case 'confirm-all': return ['plan', 'phase', 'merge', 'deploy'];
470
+ case 'confirm-key': return ['plan', 'merge', 'deploy'];
471
+ case 'auto': return [];
472
+ default: return ['plan', 'merge'];
473
+ }
474
+ }
@@ -1,5 +1,6 @@
1
1
  import { Scheduler } from './scheduler.js';
2
- import { AgentRunner, type SubagentTask } from '../agents/agent-runner.js';
2
+ import { AgentRunner } from '../agents/agent-runner.js';
3
+ import type { SubagentTask } from '../types/index.js';
3
4
  import { StateManager } from '../storage/state-manager.js';
4
5
  import { ApprovalManager } from './approval-manager.js';
5
6
  import { PhaseExecutor } from './phase-executor.js';
@@ -1,6 +1,7 @@
1
1
  import { StateManager } from '../storage/state-manager.js';
2
2
  import { ApprovalManager } from './approval-manager.js';
3
- import { AgentRunner, type SubagentTask, type UserContext } from '../agents/agent-runner.js';
3
+ import { AgentRunner, type UserContext } from '../agents/agent-runner.js';
4
+ import type { SubagentTask } from '../types/index.js';
4
5
  import { GitCommitManager } from './git-commit-manager.js';
5
6
  import type { Task, QualityConfig, QualityReport } from '../types/index.js';
6
7
  export type Phase = 'develop' | 'verify' | 'accept' | 'tdd';