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.
- package/dist/agents/agent-runner.d.ts +1 -26
- package/dist/cli/commands/meeting.js +55 -13
- package/dist/cli/commands/start.js +233 -82
- package/dist/orchestrator/executor.d.ts +2 -1
- package/dist/orchestrator/phase-executor.d.ts +2 -1
- package/dist/orchestrator/task-parser.d.ts +22 -0
- package/dist/orchestrator/task-parser.js +117 -17
- package/dist/orchestrator/task-planner.d.ts +18 -26
- package/dist/orchestrator/task-planner.js +190 -165
- package/dist/storage/state-manager.js +9 -9
- package/package.json +1 -1
- package/skills/approve.md +10 -10
- package/skills/auto.md +137 -187
- package/skills/meeting.md +3 -1
- package/skills/start.md +240 -626
|
@@ -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
|
|
63
|
+
const meetingApprovals = pendingApprovals.filter(a => a.type === 'meeting');
|
|
62
64
|
// 列出所有 Meeting
|
|
63
65
|
if (options.list || (!meetingId && !options.skipAll)) {
|
|
64
|
-
|
|
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
|
|
69
|
-
console.log(
|
|
70
|
-
console.log(` -
|
|
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 (${
|
|
74
|
-
|
|
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⏭️ 批量跳过 ${
|
|
91
|
-
for (const meeting of
|
|
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 =
|
|
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.
|
|
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(
|
|
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:
|
|
366
|
+
dependencies: [],
|
|
185
367
|
assignedAgent: subTask.assignedAgent
|
|
186
368
|
});
|
|
369
|
+
taskIdMap.set(subTask.taskId, created.id);
|
|
187
370
|
}
|
|
188
|
-
//
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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(
|
|
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}
|
|
309
|
-
|
|
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
|
|
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
|
|
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';
|