openmatrix 0.1.0
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 +512 -0
- package/dist/agents/agent-runner.d.ts +152 -0
- package/dist/agents/agent-runner.js +656 -0
- package/dist/agents/base-agent.d.ts +46 -0
- package/dist/agents/base-agent.js +17 -0
- package/dist/agents/impl/coder-agent.d.ts +17 -0
- package/dist/agents/impl/coder-agent.js +96 -0
- package/dist/agents/impl/executor-agent.d.ts +32 -0
- package/dist/agents/impl/executor-agent.js +168 -0
- package/dist/agents/impl/index.d.ts +6 -0
- package/dist/agents/impl/index.js +17 -0
- package/dist/agents/impl/planner-agent.d.ts +24 -0
- package/dist/agents/impl/planner-agent.js +126 -0
- package/dist/agents/impl/researcher-agent.d.ts +17 -0
- package/dist/agents/impl/researcher-agent.js +133 -0
- package/dist/agents/impl/reviewer-agent.d.ts +17 -0
- package/dist/agents/impl/reviewer-agent.js +120 -0
- package/dist/agents/impl/tester-agent.d.ts +17 -0
- package/dist/agents/impl/tester-agent.js +110 -0
- package/dist/cli/commands/approve.d.ts +2 -0
- package/dist/cli/commands/approve.js +87 -0
- package/dist/cli/commands/meeting.d.ts +2 -0
- package/dist/cli/commands/meeting.js +245 -0
- package/dist/cli/commands/report.d.ts +2 -0
- package/dist/cli/commands/report.js +202 -0
- package/dist/cli/commands/resume.d.ts +2 -0
- package/dist/cli/commands/resume.js +104 -0
- package/dist/cli/commands/retry.d.ts +2 -0
- package/dist/cli/commands/retry.js +79 -0
- package/dist/cli/commands/start.d.ts +2 -0
- package/dist/cli/commands/start.js +252 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.js +226 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +26 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -0
- package/dist/orchestrator/ai-reviewer.d.ts +50 -0
- package/dist/orchestrator/ai-reviewer.js +326 -0
- package/dist/orchestrator/approval-manager.d.ts +62 -0
- package/dist/orchestrator/approval-manager.js +160 -0
- package/dist/orchestrator/executor.d.ts +114 -0
- package/dist/orchestrator/executor.js +325 -0
- package/dist/orchestrator/full-test-runner.d.ts +122 -0
- package/dist/orchestrator/full-test-runner.js +335 -0
- package/dist/orchestrator/git-commit-manager.d.ts +75 -0
- package/dist/orchestrator/git-commit-manager.js +248 -0
- package/dist/orchestrator/interactive-question-generator.d.ts +90 -0
- package/dist/orchestrator/interactive-question-generator.js +312 -0
- package/dist/orchestrator/meeting-manager.d.ts +85 -0
- package/dist/orchestrator/meeting-manager.js +222 -0
- package/dist/orchestrator/phase-executor.d.ts +198 -0
- package/dist/orchestrator/phase-executor.js +796 -0
- package/dist/orchestrator/question-generator.d.ts +22 -0
- package/dist/orchestrator/question-generator.js +102 -0
- package/dist/orchestrator/retry-manager.d.ts +41 -0
- package/dist/orchestrator/retry-manager.js +83 -0
- package/dist/orchestrator/scheduler.d.ts +62 -0
- package/dist/orchestrator/scheduler.js +148 -0
- package/dist/orchestrator/state-machine.d.ts +53 -0
- package/dist/orchestrator/state-machine.js +124 -0
- package/dist/orchestrator/task-parser.d.ts +7 -0
- package/dist/orchestrator/task-parser.js +63 -0
- package/dist/orchestrator/task-planner.d.ts +71 -0
- package/dist/orchestrator/task-planner.js +316 -0
- package/dist/storage/file-store.d.ts +12 -0
- package/dist/storage/file-store.js +80 -0
- package/dist/storage/state-manager.d.ts +31 -0
- package/dist/storage/state-manager.js +202 -0
- package/dist/types/index.d.ts +193 -0
- package/dist/types/index.js +30 -0
- package/dist/utils/logger.d.ts +41 -0
- package/dist/utils/logger.js +166 -0
- package/dist/utils/progress-reporter.d.ts +116 -0
- package/dist/utils/progress-reporter.js +287 -0
- package/package.json +50 -0
- package/scripts/build-check.js +19 -0
- package/scripts/install-skills.js +51 -0
- package/skills/approve.md +253 -0
- package/skills/meeting.md +346 -0
- package/skills/report.md +100 -0
- package/skills/resume.md +68 -0
- package/skills/retry.md +61 -0
- package/skills/start.md +449 -0
- package/skills/status.md +46 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.reportCommand = void 0;
|
|
37
|
+
// src/cli/commands/report.ts
|
|
38
|
+
const commander_1 = require("commander");
|
|
39
|
+
const state_manager_js_1 = require("../../storage/state-manager.js");
|
|
40
|
+
const progress_reporter_js_1 = require("../../utils/progress-reporter.js");
|
|
41
|
+
const fs = __importStar(require("fs/promises"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
exports.reportCommand = new commander_1.Command('report')
|
|
44
|
+
.description('生成任务执行报告')
|
|
45
|
+
.option('-f, --format <format>', '输出格式 (markdown/json/console)', 'console')
|
|
46
|
+
.option('-o, --output <path>', '输出文件路径')
|
|
47
|
+
.option('--efficiency', '包含效率分析')
|
|
48
|
+
.option('--graph', '包含依赖图')
|
|
49
|
+
.action(async (options) => {
|
|
50
|
+
const basePath = process.cwd();
|
|
51
|
+
const omPath = `${basePath}/.openmatrix`;
|
|
52
|
+
const stateManager = new state_manager_js_1.StateManager(omPath);
|
|
53
|
+
await stateManager.initialize();
|
|
54
|
+
const state = await stateManager.getState();
|
|
55
|
+
const tasks = await stateManager.listTasks();
|
|
56
|
+
const approvals = await stateManager.getAllApprovals();
|
|
57
|
+
const reporter = new progress_reporter_js_1.ProgressReporter({ width: 30 });
|
|
58
|
+
// 统计数据
|
|
59
|
+
const stats = {
|
|
60
|
+
total: tasks.length,
|
|
61
|
+
completed: tasks.filter(t => t.status === 'completed').length,
|
|
62
|
+
failed: tasks.filter(t => t.status === 'failed').length,
|
|
63
|
+
inProgress: tasks.filter(t => t.status === 'in_progress').length,
|
|
64
|
+
pending: tasks.filter(t => t.status === 'pending').length,
|
|
65
|
+
blocked: tasks.filter(t => t.status === 'blocked').length
|
|
66
|
+
};
|
|
67
|
+
// 计算效率数据
|
|
68
|
+
const efficiency = {
|
|
69
|
+
totalDuration: tasks
|
|
70
|
+
.filter(t => t.phases?.accept?.duration)
|
|
71
|
+
.reduce((sum, t) => sum + (t.phases?.accept?.duration || 0), 0),
|
|
72
|
+
agentCalls: tasks.length,
|
|
73
|
+
retryCount: tasks.reduce((sum, t) => sum + t.retryCount, 0),
|
|
74
|
+
parallelism: stats.inProgress > 0 ? Math.min(stats.inProgress, 4) : 1,
|
|
75
|
+
targetParallelism: 4
|
|
76
|
+
};
|
|
77
|
+
// 生成报告
|
|
78
|
+
let report;
|
|
79
|
+
if (options.format === 'json') {
|
|
80
|
+
report = JSON.stringify({
|
|
81
|
+
runId: state.runId,
|
|
82
|
+
status: state.status,
|
|
83
|
+
startedAt: state.startedAt,
|
|
84
|
+
statistics: stats,
|
|
85
|
+
efficiency,
|
|
86
|
+
tasks: tasks.map(t => ({
|
|
87
|
+
id: t.id,
|
|
88
|
+
title: t.title,
|
|
89
|
+
status: t.status,
|
|
90
|
+
priority: t.priority,
|
|
91
|
+
duration: t.phases?.accept?.duration || 0,
|
|
92
|
+
error: t.error
|
|
93
|
+
})),
|
|
94
|
+
approvals: approvals.map(a => ({
|
|
95
|
+
id: a.id,
|
|
96
|
+
type: a.type,
|
|
97
|
+
status: a.status,
|
|
98
|
+
decision: a.decision
|
|
99
|
+
}))
|
|
100
|
+
}, null, 2);
|
|
101
|
+
}
|
|
102
|
+
else if (options.format === 'console') {
|
|
103
|
+
// 使用 ProgressReporter 生成控制台报告
|
|
104
|
+
report = reporter.renderFullReport({
|
|
105
|
+
tasks,
|
|
106
|
+
statistics: {
|
|
107
|
+
total: stats.total,
|
|
108
|
+
completed: stats.completed,
|
|
109
|
+
inProgress: stats.inProgress,
|
|
110
|
+
pending: stats.pending,
|
|
111
|
+
failed: stats.failed
|
|
112
|
+
},
|
|
113
|
+
efficiency
|
|
114
|
+
});
|
|
115
|
+
// 可选: 添加依赖图
|
|
116
|
+
if (options.graph && tasks.length > 0) {
|
|
117
|
+
report += '\n\n📊 任务依赖图\n';
|
|
118
|
+
report += '━'.repeat(42) + '\n';
|
|
119
|
+
report += reporter.renderDependencyGraph(tasks);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// markdown 格式
|
|
124
|
+
report = generateMarkdownReport(state, tasks, approvals, stats, efficiency, options);
|
|
125
|
+
}
|
|
126
|
+
// 输出
|
|
127
|
+
if (options.output) {
|
|
128
|
+
const outputPath = path.resolve(basePath, options.output);
|
|
129
|
+
await fs.writeFile(outputPath, report, 'utf-8');
|
|
130
|
+
console.log(`\n📄 报告已保存: ${outputPath}`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.log('\n' + report);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
function generateMarkdownReport(state, tasks, approvals, stats, efficiency, options) {
|
|
137
|
+
const duration = Math.round(efficiency.totalDuration / 1000 / 60); // 转为分钟
|
|
138
|
+
let report = `
|
|
139
|
+
# 📊 OpenMatrix 执行报告
|
|
140
|
+
|
|
141
|
+
**Run ID:** ${state.runId}
|
|
142
|
+
**时间:** ${state.startedAt}
|
|
143
|
+
**状态:** ${state.status}
|
|
144
|
+
|
|
145
|
+
## 统计概览
|
|
146
|
+
|
|
147
|
+
| 状态 | 数量 | 占比 |
|
|
148
|
+
|------|------|------|
|
|
149
|
+
| ✅ 完成 | ${stats.completed} | ${stats.total > 0 ? Math.round(stats.completed / stats.total * 100) : 0}% |
|
|
150
|
+
| ❌ 失败 | ${stats.failed} | ${stats.total > 0 ? Math.round(stats.failed / stats.total * 100) : 0}% |
|
|
151
|
+
| 🔄 进行中 | ${stats.inProgress} | ${stats.total > 0 ? Math.round(stats.inProgress / stats.total * 100) : 0}% |
|
|
152
|
+
| 🔴 阻塞 | ${stats.blocked} | ${stats.total > 0 ? Math.round(stats.blocked / stats.total * 100) : 0}% |
|
|
153
|
+
| ⏳ 待处理 | ${stats.pending} | ${stats.total > 0 ? Math.round(stats.pending / stats.total * 100) : 0}% |
|
|
154
|
+
|
|
155
|
+
## 任务详情
|
|
156
|
+
|
|
157
|
+
### ✅ 已完成
|
|
158
|
+
${tasks
|
|
159
|
+
.filter(t => t.status === 'completed')
|
|
160
|
+
.map(t => `- ${t.id}: ${t.title}`)
|
|
161
|
+
.join('\n') || '_无_'}
|
|
162
|
+
|
|
163
|
+
### ❌ 失败
|
|
164
|
+
${tasks
|
|
165
|
+
.filter(t => t.status === 'failed')
|
|
166
|
+
.map(t => `- ${t.id}: ${t.title}\n 原因: ${t.error || '未知'}`)
|
|
167
|
+
.join('\n') || '_无_'}
|
|
168
|
+
|
|
169
|
+
### 🔴 阻塞
|
|
170
|
+
${tasks
|
|
171
|
+
.filter(t => t.status === 'blocked')
|
|
172
|
+
.map(t => `- ${t.id}: ${t.title}\n 原因: ${t.error || '未知'}`)
|
|
173
|
+
.join('\n') || '_无_'}
|
|
174
|
+
`;
|
|
175
|
+
// 效率分析
|
|
176
|
+
if (options.efficiency) {
|
|
177
|
+
report += `
|
|
178
|
+
## 🏆 效率分析
|
|
179
|
+
|
|
180
|
+
| 指标 | 值 |
|
|
181
|
+
|------|-----|
|
|
182
|
+
| 总耗时 | ${duration} 分钟 |
|
|
183
|
+
| Agent 调用 | ${efficiency.agentCalls} 次 |
|
|
184
|
+
| 重试次数 | ${efficiency.retryCount} 次 |
|
|
185
|
+
| 并行度 | ${efficiency.parallelism} / ${efficiency.targetParallelism} |
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
// 审批记录
|
|
189
|
+
report += `
|
|
190
|
+
## 🔔 审批记录
|
|
191
|
+
|
|
192
|
+
| ID | 类型 | 决策 | 状态 |
|
|
193
|
+
|----|------|------|------|
|
|
194
|
+
${approvals.length > 0
|
|
195
|
+
? approvals.map(a => `| ${a.id} | ${a.type} | ${a.decision || '-'} | ${a.status} |`).join('\n')
|
|
196
|
+
: '| _无_ | | | |'}
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
*报告生成时间: ${new Date().toISOString()}*
|
|
200
|
+
`;
|
|
201
|
+
return report.trim();
|
|
202
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resumeCommand = void 0;
|
|
4
|
+
// src/cli/commands/resume.ts
|
|
5
|
+
const commander_1 = require("commander");
|
|
6
|
+
const state_manager_js_1 = require("../../storage/state-manager.js");
|
|
7
|
+
exports.resumeCommand = new commander_1.Command('resume')
|
|
8
|
+
.description('恢复中断或暂停的任务')
|
|
9
|
+
.argument('[taskId]', '任务ID')
|
|
10
|
+
.option('--all', '恢复所有可恢复任务')
|
|
11
|
+
.action(async (taskId, options) => {
|
|
12
|
+
const basePath = process.cwd();
|
|
13
|
+
const omPath = `${basePath}/.openmatrix`;
|
|
14
|
+
const stateManager = new state_manager_js_1.StateManager(omPath);
|
|
15
|
+
await stateManager.initialize();
|
|
16
|
+
const state = await stateManager.getState();
|
|
17
|
+
// 检查状态
|
|
18
|
+
if (state.status === 'completed') {
|
|
19
|
+
console.log('✅ 所有任务已完成');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// 如果没有提供任务ID,列出可恢复任务
|
|
23
|
+
if (!taskId && !options.all) {
|
|
24
|
+
const tasks = await stateManager.listTasks();
|
|
25
|
+
const resumable = tasks.filter(t => t.status === 'in_progress' ||
|
|
26
|
+
t.status === 'blocked' ||
|
|
27
|
+
t.status === 'waiting' ||
|
|
28
|
+
t.status === 'retry_queue');
|
|
29
|
+
if (resumable.length === 0) {
|
|
30
|
+
console.log('✅ 没有需要恢复的任务');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
console.log('🔄 可恢复任务:\n');
|
|
34
|
+
const statusEmoji = {
|
|
35
|
+
in_progress: '⏸️',
|
|
36
|
+
blocked: '🔴',
|
|
37
|
+
waiting: '⏳',
|
|
38
|
+
retry_queue: '🔄'
|
|
39
|
+
};
|
|
40
|
+
resumable.forEach((task, i) => {
|
|
41
|
+
const emoji = statusEmoji[task.status] || '❓';
|
|
42
|
+
console.log(` [${i + 1}] ${emoji} ${task.id}: ${task.title}`);
|
|
43
|
+
console.log(` 状态: ${task.status} | 优先级: ${task.priority}`);
|
|
44
|
+
});
|
|
45
|
+
console.log('\n💡 使用 openmatrix resume <ID> 恢复指定任务');
|
|
46
|
+
console.log(' 使用 openmatrix resume --all 恢复所有任务');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
// 恢复任务
|
|
50
|
+
if (options.all) {
|
|
51
|
+
const tasks = await stateManager.listTasks();
|
|
52
|
+
const resumable = tasks.filter(t => t.status === 'in_progress' ||
|
|
53
|
+
t.status === 'blocked' ||
|
|
54
|
+
t.status === 'waiting' ||
|
|
55
|
+
t.status === 'retry_queue');
|
|
56
|
+
console.log(`🔄 恢复 ${resumable.length} 个任务...\n`);
|
|
57
|
+
for (const task of resumable) {
|
|
58
|
+
await resumeTask(stateManager, task.id);
|
|
59
|
+
console.log(` ✅ ${task.id}: ${task.title}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else if (taskId) {
|
|
63
|
+
const task = await stateManager.getTask(taskId);
|
|
64
|
+
if (!task) {
|
|
65
|
+
console.log(`❌ 任务 ${taskId} 不存在`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.log(`🔄 恢复任务 ${taskId}...\n`);
|
|
69
|
+
await resumeTask(stateManager, taskId);
|
|
70
|
+
console.log(` ✅ ${task.title}`);
|
|
71
|
+
}
|
|
72
|
+
// 更新全局状态
|
|
73
|
+
await stateManager.updateState({
|
|
74
|
+
status: 'running',
|
|
75
|
+
currentPhase: 'execution'
|
|
76
|
+
});
|
|
77
|
+
console.log('\n✅ 任务已恢复');
|
|
78
|
+
console.log('💡 使用 /om:status 查看执行进度');
|
|
79
|
+
});
|
|
80
|
+
async function resumeTask(stateManager, taskId) {
|
|
81
|
+
const task = await stateManager.getTask(taskId);
|
|
82
|
+
if (!task)
|
|
83
|
+
return;
|
|
84
|
+
// 根据状态决定恢复方式
|
|
85
|
+
switch (task.status) {
|
|
86
|
+
case 'in_progress':
|
|
87
|
+
// 中断的任务,继续执行
|
|
88
|
+
break;
|
|
89
|
+
case 'blocked':
|
|
90
|
+
// 阻塞的任务,检查是否已解决
|
|
91
|
+
await stateManager.updateTask(taskId, { status: 'pending' });
|
|
92
|
+
break;
|
|
93
|
+
case 'waiting':
|
|
94
|
+
// 等待中的任务,检查是否已确认
|
|
95
|
+
break;
|
|
96
|
+
case 'retry_queue':
|
|
97
|
+
// 重试队列,重置为 pending
|
|
98
|
+
await stateManager.updateTask(taskId, {
|
|
99
|
+
status: 'pending',
|
|
100
|
+
retryCount: task.retryCount + 1
|
|
101
|
+
});
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.retryCommand = void 0;
|
|
4
|
+
// src/cli/commands/retry.ts
|
|
5
|
+
const commander_1 = require("commander");
|
|
6
|
+
const state_manager_js_1 = require("../../storage/state-manager.js");
|
|
7
|
+
const retry_manager_js_1 = require("../../orchestrator/retry-manager.js");
|
|
8
|
+
exports.retryCommand = new commander_1.Command('retry')
|
|
9
|
+
.description('重试失败的任务')
|
|
10
|
+
.argument('[taskId]', '任务ID')
|
|
11
|
+
.option('--all', '重试所有失败任务')
|
|
12
|
+
.option('--reset', '重置重试计数')
|
|
13
|
+
.action(async (taskId, options) => {
|
|
14
|
+
const basePath = process.cwd();
|
|
15
|
+
const omPath = `${basePath}/.openmatrix`;
|
|
16
|
+
const stateManager = new state_manager_js_1.StateManager(omPath);
|
|
17
|
+
await stateManager.initialize();
|
|
18
|
+
const retryManager = new retry_manager_js_1.RetryManager({
|
|
19
|
+
maxRetries: 3,
|
|
20
|
+
backoff: 'exponential',
|
|
21
|
+
baseDelay: 10000
|
|
22
|
+
});
|
|
23
|
+
// 如果没有提供任务ID,列出失败任务
|
|
24
|
+
if (!taskId && !options.all) {
|
|
25
|
+
const tasks = await stateManager.listTasks();
|
|
26
|
+
const failed = tasks.filter(t => t.status === 'failed');
|
|
27
|
+
if (failed.length === 0) {
|
|
28
|
+
console.log('✅ 没有失败的任务');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.log('❌ 失败任务列表:\n');
|
|
32
|
+
failed.forEach((task, i) => {
|
|
33
|
+
console.log(` [${i + 1}] ${task.id}: ${task.title}`);
|
|
34
|
+
console.log(` 失败原因: ${task.error || '未知'}`);
|
|
35
|
+
console.log(` 重试次数: ${task.retryCount}/3`);
|
|
36
|
+
console.log(` 失败时间: ${task.updatedAt}`);
|
|
37
|
+
});
|
|
38
|
+
console.log('\n💡 使用 openmatrix retry <ID> 重试指定任务');
|
|
39
|
+
console.log(' 使用 openmatrix retry --all 重试所有任务');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// 重试任务
|
|
43
|
+
if (options.all) {
|
|
44
|
+
const tasks = await stateManager.listTasks();
|
|
45
|
+
const failed = tasks.filter(t => t.status === 'failed');
|
|
46
|
+
console.log(`🔄 重试 ${failed.length} 个失败任务...\n`);
|
|
47
|
+
for (const task of failed) {
|
|
48
|
+
await retryTask(stateManager, retryManager, task.id, options.reset);
|
|
49
|
+
console.log(` ✅ ${task.id}: ${task.title}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (taskId) {
|
|
53
|
+
const task = await stateManager.getTask(taskId);
|
|
54
|
+
if (!task) {
|
|
55
|
+
console.log(`❌ 任务 ${taskId} 不存在`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (task.status !== 'failed') {
|
|
59
|
+
console.log(`❌ 任务 ${taskId} 状态不是失败`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
console.log(`🔄 重试任务 ${taskId}...\n`);
|
|
63
|
+
await retryTask(stateManager, retryManager, taskId, options.reset);
|
|
64
|
+
console.log(` ✅ ${task.title}`);
|
|
65
|
+
}
|
|
66
|
+
console.log('\n💡 使用 /om:resume 继续执行');
|
|
67
|
+
});
|
|
68
|
+
async function retryTask(stateManager, retryManager, taskId, reset) {
|
|
69
|
+
const task = await stateManager.getTask(taskId);
|
|
70
|
+
if (!task)
|
|
71
|
+
return;
|
|
72
|
+
const newRetryCount = reset ? 0 : task.retryCount + 1;
|
|
73
|
+
await stateManager.updateTask(taskId, {
|
|
74
|
+
status: 'pending',
|
|
75
|
+
retryCount: newRetryCount,
|
|
76
|
+
error: null
|
|
77
|
+
});
|
|
78
|
+
retryManager.addToQueue(taskId, 'manual retry');
|
|
79
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startCommand = void 0;
|
|
37
|
+
// src/cli/commands/start.ts
|
|
38
|
+
const commander_1 = require("commander");
|
|
39
|
+
const state_manager_js_1 = require("../../storage/state-manager.js");
|
|
40
|
+
const task_parser_js_1 = require("../../orchestrator/task-parser.js");
|
|
41
|
+
const task_planner_js_1 = require("../../orchestrator/task-planner.js");
|
|
42
|
+
const approval_manager_js_1 = require("../../orchestrator/approval-manager.js");
|
|
43
|
+
const executor_js_1 = require("../../orchestrator/executor.js");
|
|
44
|
+
const fs = __importStar(require("fs/promises"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
exports.startCommand = new commander_1.Command('start')
|
|
47
|
+
.description('启动新的任务执行周期')
|
|
48
|
+
.argument('[input]', '任务文件路径或描述')
|
|
49
|
+
.option('-c, --config <path>', '配置文件路径')
|
|
50
|
+
.option('--skip-questions', '跳过澄清问题')
|
|
51
|
+
.option('--mode <mode>', '执行模式 (confirm-all|confirm-key|auto)')
|
|
52
|
+
.option('--json', '输出 JSON 格式 (供 Skill 解析)')
|
|
53
|
+
.action(async (input, options) => {
|
|
54
|
+
const basePath = process.cwd();
|
|
55
|
+
const omPath = path.join(basePath, '.openmatrix');
|
|
56
|
+
// 确保目录存在
|
|
57
|
+
await fs.mkdir(omPath, { recursive: true });
|
|
58
|
+
await fs.mkdir(path.join(omPath, 'tasks'), { recursive: true });
|
|
59
|
+
await fs.mkdir(path.join(omPath, 'approvals'), { recursive: true });
|
|
60
|
+
const stateManager = new state_manager_js_1.StateManager(omPath);
|
|
61
|
+
await stateManager.initialize();
|
|
62
|
+
const state = await stateManager.getState();
|
|
63
|
+
// 检查是否已有运行中的任务
|
|
64
|
+
if (state.status === 'running') {
|
|
65
|
+
if (options.json) {
|
|
66
|
+
console.log(JSON.stringify({
|
|
67
|
+
status: 'error',
|
|
68
|
+
message: '已有任务在执行中',
|
|
69
|
+
hint: '使用 /om:status 查看状态,或 /om:resume 恢复执行'
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
console.log('⚠️ 已有任务在执行中');
|
|
74
|
+
console.log(' 使用 /om:status 查看状态');
|
|
75
|
+
console.log(' 使用 /om:resume 恢复执行');
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// 获取任务内容
|
|
80
|
+
let taskContent = input;
|
|
81
|
+
if (!taskContent) {
|
|
82
|
+
// 尝试读取默认任务文件
|
|
83
|
+
const defaultPath = path.join(basePath, 'TASK.md');
|
|
84
|
+
try {
|
|
85
|
+
taskContent = await fs.readFile(defaultPath, 'utf-8');
|
|
86
|
+
if (!options.json) {
|
|
87
|
+
console.log(`📄 读取任务文件: ${defaultPath}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
if (options.json) {
|
|
92
|
+
console.log(JSON.stringify({
|
|
93
|
+
status: 'error',
|
|
94
|
+
message: '请提供任务文件路径或描述'
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log('❌ 请提供任务文件路径或描述');
|
|
99
|
+
console.log(' 用法: openmatrix start <task.md>');
|
|
100
|
+
console.log(' 或创建 TASK.md 文件');
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (taskContent.endsWith('.md')) {
|
|
106
|
+
// 读取文件
|
|
107
|
+
try {
|
|
108
|
+
taskContent = await fs.readFile(taskContent, 'utf-8');
|
|
109
|
+
if (!options.json) {
|
|
110
|
+
console.log(`📄 读取任务文件: ${input}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
if (options.json) {
|
|
115
|
+
console.log(JSON.stringify({
|
|
116
|
+
status: 'error',
|
|
117
|
+
message: `无法读取文件: ${input}`
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.log(`❌ 无法读取文件: ${input}`);
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// 解析任务
|
|
127
|
+
if (!options.json) {
|
|
128
|
+
console.log('\n🔍 解析任务...');
|
|
129
|
+
}
|
|
130
|
+
const parser = new task_parser_js_1.TaskParser();
|
|
131
|
+
const parsedTask = parser.parse(taskContent);
|
|
132
|
+
if (!options.json) {
|
|
133
|
+
console.log(`\n📋 任务: ${parsedTask.title}`);
|
|
134
|
+
console.log(` 目标: ${parsedTask.goals.join(', ')}`);
|
|
135
|
+
}
|
|
136
|
+
// 拆解任务
|
|
137
|
+
if (!options.json) {
|
|
138
|
+
console.log('\n🔧 拆解任务...');
|
|
139
|
+
}
|
|
140
|
+
const planner = new task_planner_js_1.TaskPlanner();
|
|
141
|
+
const subTasks = planner.breakdown(parsedTask, {});
|
|
142
|
+
// 创建任务到状态管理器
|
|
143
|
+
for (const subTask of subTasks) {
|
|
144
|
+
await stateManager.createTask({
|
|
145
|
+
title: subTask.title,
|
|
146
|
+
description: subTask.description,
|
|
147
|
+
priority: subTask.priority,
|
|
148
|
+
timeout: subTask.estimatedComplexity === 'high' ? 300000 :
|
|
149
|
+
subTask.estimatedComplexity === 'medium' ? 180000 : 120000,
|
|
150
|
+
dependencies: subTask.dependencies,
|
|
151
|
+
assignedAgent: subTask.assignedAgent
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// 确定执行模式
|
|
155
|
+
const executionMode = options.mode || 'confirm-key';
|
|
156
|
+
let approvalPoints = [];
|
|
157
|
+
// 根据模式设置审批点
|
|
158
|
+
// auto 模式: 空数组,不暂停任何审批点
|
|
159
|
+
// confirm-key 模式: 仅在关键节点暂停
|
|
160
|
+
// confirm-all 模式: 每个阶段都暂停
|
|
161
|
+
switch (executionMode) {
|
|
162
|
+
case 'confirm-all':
|
|
163
|
+
approvalPoints = ['plan', 'phase', 'merge', 'deploy'];
|
|
164
|
+
break;
|
|
165
|
+
case 'confirm-key':
|
|
166
|
+
approvalPoints = ['plan', 'merge', 'deploy'];
|
|
167
|
+
break;
|
|
168
|
+
case 'auto':
|
|
169
|
+
approvalPoints = []; // 全自动模式:无任何审批点
|
|
170
|
+
break;
|
|
171
|
+
default:
|
|
172
|
+
approvalPoints = ['plan', 'merge'];
|
|
173
|
+
}
|
|
174
|
+
// 更新状态
|
|
175
|
+
await stateManager.updateState({
|
|
176
|
+
status: 'running',
|
|
177
|
+
currentPhase: 'execution',
|
|
178
|
+
config: {
|
|
179
|
+
...state.config,
|
|
180
|
+
approvalPoints: approvalPoints
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// 创建审批请求(如果有审批点)
|
|
184
|
+
const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
|
|
185
|
+
if (approvalPoints.includes('plan')) {
|
|
186
|
+
const approval = await approvalManager.createPlanApproval('plan-approval', `# 执行计划\n\n${subTasks.map((t, i) => `${i + 1}. ${t.title}`).join('\n')}`);
|
|
187
|
+
await stateManager.updateState({ status: 'paused' });
|
|
188
|
+
if (options.json) {
|
|
189
|
+
console.log(JSON.stringify({
|
|
190
|
+
status: 'waiting_approval',
|
|
191
|
+
approvalId: approval.id,
|
|
192
|
+
approvalType: 'plan',
|
|
193
|
+
message: '等待计划审批',
|
|
194
|
+
tasks: subTasks.map((t, i) => ({
|
|
195
|
+
index: i + 1,
|
|
196
|
+
title: t.title,
|
|
197
|
+
priority: t.priority
|
|
198
|
+
}))
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
console.log(`\n📋 生成 ${subTasks.length} 个子任务:\n`);
|
|
203
|
+
subTasks.forEach((task, i) => {
|
|
204
|
+
console.log(` ${i + 1}. ${task.title} (${task.priority})`);
|
|
205
|
+
});
|
|
206
|
+
console.log(`\n🎯 执行模式: ${executionMode}`);
|
|
207
|
+
console.log(` 审批点: ${approvalPoints.join(', ')}`);
|
|
208
|
+
console.log(`\n⏸️ 等待计划审批`);
|
|
209
|
+
console.log(` 审批ID: ${approval.id}`);
|
|
210
|
+
console.log(` 使用 /om:approve ${approval.id} 审批`);
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// 创建执行器并获取第一批任务
|
|
215
|
+
const executor = new executor_js_1.OrchestratorExecutor(stateManager, approvalManager, {
|
|
216
|
+
maxConcurrent: state.config.maxConcurrentAgents,
|
|
217
|
+
taskTimeout: state.config.timeout * 1000
|
|
218
|
+
});
|
|
219
|
+
// 设置 PhaseExecutor 的自动模式
|
|
220
|
+
const phaseExecutor = executor.getPhaseExecutor();
|
|
221
|
+
if (phaseExecutor && executionMode === 'auto') {
|
|
222
|
+
phaseExecutor.setAutoMode(true);
|
|
223
|
+
}
|
|
224
|
+
const result = await executor.step();
|
|
225
|
+
if (options.json) {
|
|
226
|
+
// JSON 输出供 Skill 解析
|
|
227
|
+
console.log(JSON.stringify({
|
|
228
|
+
status: result.status,
|
|
229
|
+
message: result.message,
|
|
230
|
+
statistics: result.statistics,
|
|
231
|
+
subagentTasks: result.subagentTasks.map(t => ({
|
|
232
|
+
subagent_type: t.subagent_type,
|
|
233
|
+
description: t.description,
|
|
234
|
+
prompt: t.prompt,
|
|
235
|
+
isolation: t.isolation,
|
|
236
|
+
taskId: t.taskId,
|
|
237
|
+
agentType: t.agentType,
|
|
238
|
+
timeout: t.timeout
|
|
239
|
+
}))
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
console.log(`\n📋 生成 ${subTasks.length} 个子任务:\n`);
|
|
244
|
+
subTasks.forEach((task, i) => {
|
|
245
|
+
console.log(` ${i + 1}. ${task.title} (${task.priority})`);
|
|
246
|
+
});
|
|
247
|
+
console.log(`\n🎯 执行模式: ${executionMode}`);
|
|
248
|
+
console.log(` 审批点: ${approvalPoints.length > 0 ? approvalPoints.join(', ') : '无 (全自动)'}`);
|
|
249
|
+
console.log('\n🚀 开始执行...');
|
|
250
|
+
console.log(' 使用 /om:status 查看进度');
|
|
251
|
+
}
|
|
252
|
+
});
|