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.
Files changed (85) hide show
  1. package/README.md +512 -0
  2. package/dist/agents/agent-runner.d.ts +152 -0
  3. package/dist/agents/agent-runner.js +656 -0
  4. package/dist/agents/base-agent.d.ts +46 -0
  5. package/dist/agents/base-agent.js +17 -0
  6. package/dist/agents/impl/coder-agent.d.ts +17 -0
  7. package/dist/agents/impl/coder-agent.js +96 -0
  8. package/dist/agents/impl/executor-agent.d.ts +32 -0
  9. package/dist/agents/impl/executor-agent.js +168 -0
  10. package/dist/agents/impl/index.d.ts +6 -0
  11. package/dist/agents/impl/index.js +17 -0
  12. package/dist/agents/impl/planner-agent.d.ts +24 -0
  13. package/dist/agents/impl/planner-agent.js +126 -0
  14. package/dist/agents/impl/researcher-agent.d.ts +17 -0
  15. package/dist/agents/impl/researcher-agent.js +133 -0
  16. package/dist/agents/impl/reviewer-agent.d.ts +17 -0
  17. package/dist/agents/impl/reviewer-agent.js +120 -0
  18. package/dist/agents/impl/tester-agent.d.ts +17 -0
  19. package/dist/agents/impl/tester-agent.js +110 -0
  20. package/dist/cli/commands/approve.d.ts +2 -0
  21. package/dist/cli/commands/approve.js +87 -0
  22. package/dist/cli/commands/meeting.d.ts +2 -0
  23. package/dist/cli/commands/meeting.js +245 -0
  24. package/dist/cli/commands/report.d.ts +2 -0
  25. package/dist/cli/commands/report.js +202 -0
  26. package/dist/cli/commands/resume.d.ts +2 -0
  27. package/dist/cli/commands/resume.js +104 -0
  28. package/dist/cli/commands/retry.d.ts +2 -0
  29. package/dist/cli/commands/retry.js +79 -0
  30. package/dist/cli/commands/start.d.ts +2 -0
  31. package/dist/cli/commands/start.js +252 -0
  32. package/dist/cli/commands/status.d.ts +2 -0
  33. package/dist/cli/commands/status.js +226 -0
  34. package/dist/cli/index.d.ts +2 -0
  35. package/dist/cli/index.js +26 -0
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +9 -0
  38. package/dist/orchestrator/ai-reviewer.d.ts +50 -0
  39. package/dist/orchestrator/ai-reviewer.js +326 -0
  40. package/dist/orchestrator/approval-manager.d.ts +62 -0
  41. package/dist/orchestrator/approval-manager.js +160 -0
  42. package/dist/orchestrator/executor.d.ts +114 -0
  43. package/dist/orchestrator/executor.js +325 -0
  44. package/dist/orchestrator/full-test-runner.d.ts +122 -0
  45. package/dist/orchestrator/full-test-runner.js +335 -0
  46. package/dist/orchestrator/git-commit-manager.d.ts +75 -0
  47. package/dist/orchestrator/git-commit-manager.js +248 -0
  48. package/dist/orchestrator/interactive-question-generator.d.ts +90 -0
  49. package/dist/orchestrator/interactive-question-generator.js +312 -0
  50. package/dist/orchestrator/meeting-manager.d.ts +85 -0
  51. package/dist/orchestrator/meeting-manager.js +222 -0
  52. package/dist/orchestrator/phase-executor.d.ts +198 -0
  53. package/dist/orchestrator/phase-executor.js +796 -0
  54. package/dist/orchestrator/question-generator.d.ts +22 -0
  55. package/dist/orchestrator/question-generator.js +102 -0
  56. package/dist/orchestrator/retry-manager.d.ts +41 -0
  57. package/dist/orchestrator/retry-manager.js +83 -0
  58. package/dist/orchestrator/scheduler.d.ts +62 -0
  59. package/dist/orchestrator/scheduler.js +148 -0
  60. package/dist/orchestrator/state-machine.d.ts +53 -0
  61. package/dist/orchestrator/state-machine.js +124 -0
  62. package/dist/orchestrator/task-parser.d.ts +7 -0
  63. package/dist/orchestrator/task-parser.js +63 -0
  64. package/dist/orchestrator/task-planner.d.ts +71 -0
  65. package/dist/orchestrator/task-planner.js +316 -0
  66. package/dist/storage/file-store.d.ts +12 -0
  67. package/dist/storage/file-store.js +80 -0
  68. package/dist/storage/state-manager.d.ts +31 -0
  69. package/dist/storage/state-manager.js +202 -0
  70. package/dist/types/index.d.ts +193 -0
  71. package/dist/types/index.js +30 -0
  72. package/dist/utils/logger.d.ts +41 -0
  73. package/dist/utils/logger.js +166 -0
  74. package/dist/utils/progress-reporter.d.ts +116 -0
  75. package/dist/utils/progress-reporter.js +287 -0
  76. package/package.json +50 -0
  77. package/scripts/build-check.js +19 -0
  78. package/scripts/install-skills.js +51 -0
  79. package/skills/approve.md +253 -0
  80. package/skills/meeting.md +346 -0
  81. package/skills/report.md +100 -0
  82. package/skills/resume.md +68 -0
  83. package/skills/retry.md +61 -0
  84. package/skills/start.md +449 -0
  85. package/skills/status.md +46 -0
@@ -0,0 +1,62 @@
1
+ import type { Approval, ApprovalOption } from '../types/index.js';
2
+ import { StateManager } from '../storage/state-manager.js';
3
+ export type ApprovalType = 'plan' | 'merge' | 'deploy' | 'meeting' | 'custom';
4
+ export interface CreateApprovalInput {
5
+ type: ApprovalType;
6
+ taskId: string;
7
+ title: string;
8
+ description: string;
9
+ content: string;
10
+ options?: ApprovalOption[];
11
+ }
12
+ export interface ApprovalDecision {
13
+ approvalId: string;
14
+ decision: 'approve' | 'modify' | 'reject';
15
+ comment?: string;
16
+ decidedBy: string;
17
+ decidedAt: string;
18
+ }
19
+ export declare class ApprovalManager {
20
+ private stateManager;
21
+ constructor(stateManager: StateManager);
22
+ /**
23
+ * 创建审批请求
24
+ */
25
+ createApproval(input: CreateApprovalInput): Promise<Approval>;
26
+ /**
27
+ * 获取待处理的审批
28
+ */
29
+ getPendingApprovals(): Promise<Approval[]>;
30
+ /**
31
+ * 获取指定审批
32
+ */
33
+ getApproval(approvalId: string): Promise<Approval | null>;
34
+ /**
35
+ * 处理审批决策
36
+ */
37
+ processDecision(decision: ApprovalDecision): Promise<Approval>;
38
+ /**
39
+ * 创建 Meeting 审批
40
+ */
41
+ createMeetingApproval(taskId: string, blockingReason: string, impactScope: string[]): Promise<Approval>;
42
+ /**
43
+ * 创建 Plan 审批
44
+ */
45
+ createPlanApproval(taskId: string, planContent: string): Promise<Approval>;
46
+ /**
47
+ * 创建 Merge 审批
48
+ */
49
+ createMergeApproval(taskId: string, changes: string): Promise<Approval>;
50
+ /**
51
+ * 创建 Deploy 审批
52
+ */
53
+ createDeployApproval(taskId: string, deployInfo: string): Promise<Approval>;
54
+ /**
55
+ * 检查是否有待处理的审批
56
+ */
57
+ hasPendingApprovals(): Promise<boolean>;
58
+ /**
59
+ * 获取审批历史
60
+ */
61
+ getApprovalHistory(limit?: number): Promise<Approval[]>;
62
+ }
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApprovalManager = void 0;
4
+ class ApprovalManager {
5
+ stateManager;
6
+ constructor(stateManager) {
7
+ this.stateManager = stateManager;
8
+ }
9
+ /**
10
+ * 创建审批请求
11
+ */
12
+ async createApproval(input) {
13
+ const approvalId = `APPR-${Date.now().toString(36).toUpperCase()}`;
14
+ const defaultOptions = [
15
+ { key: 'approve', label: '✅ 批准' },
16
+ { key: 'modify', label: '✏️ 需要修改' },
17
+ { key: 'reject', label: '❌ 拒绝' }
18
+ ];
19
+ const approval = {
20
+ id: approvalId,
21
+ type: input.type,
22
+ taskId: input.taskId,
23
+ title: input.title,
24
+ description: input.description,
25
+ content: input.content,
26
+ options: input.options || defaultOptions,
27
+ status: 'pending',
28
+ createdAt: new Date().toISOString()
29
+ };
30
+ await this.stateManager.saveApproval(approval);
31
+ return approval;
32
+ }
33
+ /**
34
+ * 获取待处理的审批
35
+ */
36
+ async getPendingApprovals() {
37
+ return this.stateManager.getApprovalsByStatus('pending');
38
+ }
39
+ /**
40
+ * 获取指定审批
41
+ */
42
+ async getApproval(approvalId) {
43
+ return this.stateManager.getApproval(approvalId);
44
+ }
45
+ /**
46
+ * 处理审批决策
47
+ */
48
+ async processDecision(decision) {
49
+ const approval = await this.getApproval(decision.approvalId);
50
+ if (!approval) {
51
+ throw new Error(`审批 ${decision.approvalId} 不存在`);
52
+ }
53
+ if (approval.status !== 'pending') {
54
+ throw new Error(`审批 ${decision.approvalId} 已处理`);
55
+ }
56
+ // 更新审批状态
57
+ const updatedApproval = {
58
+ ...approval,
59
+ status: decision.decision === 'approve' ? 'approved' : 'rejected',
60
+ decision: decision.decision,
61
+ decidedAt: decision.decidedAt
62
+ };
63
+ await this.stateManager.updateApproval(updatedApproval);
64
+ // 如果是 meeting 类型且被批准,解除任务阻塞
65
+ if (approval.type === 'meeting' && decision.decision === 'approve') {
66
+ await this.stateManager.updateTask(approval.taskId, {
67
+ status: 'in_progress',
68
+ error: null
69
+ });
70
+ }
71
+ return updatedApproval;
72
+ }
73
+ /**
74
+ * 创建 Meeting 审批
75
+ */
76
+ async createMeetingApproval(taskId, blockingReason, impactScope) {
77
+ return this.createApproval({
78
+ type: 'meeting',
79
+ taskId,
80
+ title: `🔴 阻塞问题需要解决`,
81
+ description: `任务 ${taskId} 遇到阻塞问题`,
82
+ content: `
83
+ ## 阻塞原因
84
+
85
+ ${blockingReason}
86
+
87
+ ## 影响范围
88
+
89
+ ${impactScope.map(t => `- ${t}`).join('\n')}
90
+
91
+ ## 需要决策
92
+
93
+ 请选择解决方案或提供自定义方案:
94
+ `.trim(),
95
+ options: [
96
+ { key: 'approve', label: '✅ 问题已解决,继续执行' },
97
+ { key: 'modify', label: '🔄 跳过此任务' },
98
+ { key: 'reject', label: '❌ 终止任务链' }
99
+ ]
100
+ });
101
+ }
102
+ /**
103
+ * 创建 Plan 审批
104
+ */
105
+ async createPlanApproval(taskId, planContent) {
106
+ return this.createApproval({
107
+ type: 'plan',
108
+ taskId,
109
+ title: '📋 任务计划审批',
110
+ description: '请审批以下任务计划',
111
+ content: planContent
112
+ });
113
+ }
114
+ /**
115
+ * 创建 Merge 审批
116
+ */
117
+ async createMergeApproval(taskId, changes) {
118
+ return this.createApproval({
119
+ type: 'merge',
120
+ taskId,
121
+ title: '🔀 代码合并审批',
122
+ description: '请审批以下代码变更',
123
+ content: changes
124
+ });
125
+ }
126
+ /**
127
+ * 创建 Deploy 审批
128
+ */
129
+ async createDeployApproval(taskId, deployInfo) {
130
+ return this.createApproval({
131
+ type: 'deploy',
132
+ taskId,
133
+ title: '🚀 部署审批',
134
+ description: '请审批以下部署',
135
+ content: deployInfo,
136
+ options: [
137
+ { key: 'approve', label: '✅ 批准部署' },
138
+ { key: 'reject', label: '❌ 取消部署' }
139
+ ]
140
+ });
141
+ }
142
+ /**
143
+ * 检查是否有待处理的审批
144
+ */
145
+ async hasPendingApprovals() {
146
+ const pending = await this.getPendingApprovals();
147
+ return pending.length > 0;
148
+ }
149
+ /**
150
+ * 获取审批历史
151
+ */
152
+ async getApprovalHistory(limit = 10) {
153
+ const all = await this.stateManager.getAllApprovals();
154
+ return all
155
+ .filter(a => a.status !== 'pending')
156
+ .sort((a, b) => (b.decidedAt || b.createdAt).localeCompare(a.decidedAt || a.createdAt))
157
+ .slice(0, limit);
158
+ }
159
+ }
160
+ exports.ApprovalManager = ApprovalManager;
@@ -0,0 +1,114 @@
1
+ import { Scheduler } from './scheduler.js';
2
+ import { AgentRunner, type SubagentTask } from '../agents/agent-runner.js';
3
+ import { StateManager } from '../storage/state-manager.js';
4
+ import { ApprovalManager } from './approval-manager.js';
5
+ import { PhaseExecutor } from './phase-executor.js';
6
+ export interface ExecutorConfig {
7
+ maxConcurrent: number;
8
+ taskTimeout: number;
9
+ }
10
+ export interface ExecutorStatus {
11
+ running: boolean;
12
+ currentPhase: string;
13
+ pendingTasks: number;
14
+ runningTasks: number;
15
+ waitingApprovals: number;
16
+ }
17
+ export interface ExecutionResult {
18
+ status: 'continue' | 'waiting_approval' | 'completed' | 'failed';
19
+ subagentTasks: SubagentTask[];
20
+ message: string;
21
+ statistics: {
22
+ total: number;
23
+ completed: number;
24
+ inProgress: number;
25
+ pending: number;
26
+ failed: number;
27
+ };
28
+ }
29
+ /**
30
+ * OrchestratorExecutor - 执行循环核心
31
+ *
32
+ * 负责持续调度任务并返回 Subagent 任务列表供 Skills 执行
33
+ */
34
+ export declare class OrchestratorExecutor {
35
+ private scheduler;
36
+ private agentRunner;
37
+ private stateManager;
38
+ private approvalManager;
39
+ private stateMachine;
40
+ private phaseExecutor;
41
+ private config;
42
+ constructor(stateManager: StateManager, approvalManager: ApprovalManager, config?: Partial<ExecutorConfig>);
43
+ /**
44
+ * 获取 PhaseExecutor 实例
45
+ */
46
+ getPhaseExecutor(): PhaseExecutor;
47
+ /**
48
+ * 执行一步 - 返回待执行的 Subagent 任务
49
+ *
50
+ * Skills 调用此方法获取任务,然后使用 Agent 工具执行
51
+ */
52
+ step(): Promise<ExecutionResult>;
53
+ /**
54
+ * 检查审批点
55
+ *
56
+ * 在 auto 模式下 (approvalPoints 为空数组),跳过所有审批
57
+ * 仅在失败/异常时才暂停
58
+ */
59
+ private checkApprovals;
60
+ /**
61
+ * 检查是否所有任务完成
62
+ */
63
+ private checkAllCompleted;
64
+ /**
65
+ * 获取统计信息
66
+ */
67
+ private getStatistics;
68
+ /**
69
+ * 创建等待审批结果
70
+ */
71
+ private createWaitingResult;
72
+ /**
73
+ * 创建完成结果 - 检查是否有待处理的 Meeting
74
+ */
75
+ private createCompletedResult;
76
+ /**
77
+ * 创建需要重试结果
78
+ */
79
+ private createRetryNeededResult;
80
+ /**
81
+ * 处理阻塞任务 - 创建 Meeting 审批并跳过该任务
82
+ *
83
+ * 在 auto 模式下:
84
+ * 1. 标记任务为 blocked 状态
85
+ * 2. 创建 Meeting 审批记录
86
+ * 3. 跳过该任务,继续执行其他可执行任务
87
+ * 4. 所有 Meeting 留到最后统一处理
88
+ */
89
+ private handleBlockedTasks;
90
+ /**
91
+ * 标记任务完成
92
+ */
93
+ completeTask(taskId: string, result: {
94
+ success: boolean;
95
+ output?: string;
96
+ error?: string;
97
+ }): Promise<void>;
98
+ /**
99
+ * 获取当前阶段
100
+ */
101
+ private getCurrentPhase;
102
+ /**
103
+ * 获取执行器状态
104
+ */
105
+ getStatus(): Promise<ExecutorStatus>;
106
+ /**
107
+ * 获取 AgentRunner 实例
108
+ */
109
+ getAgentRunner(): AgentRunner;
110
+ /**
111
+ * 获取 Scheduler 实例
112
+ */
113
+ getScheduler(): Scheduler;
114
+ }
@@ -0,0 +1,325 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrchestratorExecutor = void 0;
4
+ // src/orchestrator/executor.ts
5
+ const scheduler_js_1 = require("./scheduler.js");
6
+ const agent_runner_js_1 = require("../agents/agent-runner.js");
7
+ const state_machine_js_1 = require("./state-machine.js");
8
+ const phase_executor_js_1 = require("./phase-executor.js");
9
+ /**
10
+ * OrchestratorExecutor - 执行循环核心
11
+ *
12
+ * 负责持续调度任务并返回 Subagent 任务列表供 Skills 执行
13
+ */
14
+ class OrchestratorExecutor {
15
+ scheduler;
16
+ agentRunner;
17
+ stateManager;
18
+ approvalManager;
19
+ stateMachine;
20
+ phaseExecutor;
21
+ config;
22
+ constructor(stateManager, approvalManager, config) {
23
+ this.stateManager = stateManager;
24
+ this.approvalManager = approvalManager;
25
+ this.config = {
26
+ maxConcurrent: 3,
27
+ taskTimeout: 120000,
28
+ ...config
29
+ };
30
+ this.scheduler = new scheduler_js_1.Scheduler(stateManager, {
31
+ maxConcurrentTasks: this.config.maxConcurrent,
32
+ taskTimeout: this.config.taskTimeout
33
+ });
34
+ this.agentRunner = new agent_runner_js_1.AgentRunner(stateManager, approvalManager, {
35
+ maxConcurrent: this.config.maxConcurrent,
36
+ taskTimeout: this.config.taskTimeout
37
+ });
38
+ this.stateMachine = new state_machine_js_1.StateMachine();
39
+ this.phaseExecutor = new phase_executor_js_1.PhaseExecutor(stateManager, approvalManager);
40
+ }
41
+ /**
42
+ * 获取 PhaseExecutor 实例
43
+ */
44
+ getPhaseExecutor() {
45
+ return this.phaseExecutor;
46
+ }
47
+ /**
48
+ * 执行一步 - 返回待执行的 Subagent 任务
49
+ *
50
+ * Skills 调用此方法获取任务,然后使用 Agent 工具执行
51
+ */
52
+ async step() {
53
+ const state = await this.stateManager.getState();
54
+ // 1. 检查是否需要审批
55
+ const pendingApprovals = await this.checkApprovals(state);
56
+ if (pendingApprovals.length > 0) {
57
+ return this.createWaitingResult(pendingApprovals, state);
58
+ }
59
+ // 2. 获取可执行任务
60
+ const executableTasks = await this.scheduler.getParallelTasks();
61
+ if (executableTasks.length === 0) {
62
+ // 3. 获取所有任务
63
+ const allTasks = await this.stateManager.listTasks();
64
+ // 4. 检查是否有失败任务需要重试
65
+ const failedTasks = allTasks.filter(t => t.status === 'failed');
66
+ if (failedTasks.length > 0) {
67
+ return this.createRetryNeededResult(failedTasks, state);
68
+ }
69
+ // 5. 检查是否有阻塞任务
70
+ const blockedTasks = allTasks.filter(t => t.status === 'blocked');
71
+ // 6. 检查剩余可执行任务(排除 blocked/failed/completed)
72
+ const remainingTasks = allTasks.filter(t => t.status !== 'blocked' &&
73
+ t.status !== 'failed' &&
74
+ t.status !== 'completed');
75
+ // 7. 如果只剩下阻塞任务或没有剩余任务,算完成
76
+ if (remainingTasks.length === 0) {
77
+ return await this.createCompletedResult(state);
78
+ }
79
+ // 8. 如果有阻塞任务
80
+ if (blockedTasks.length > 0) {
81
+ return await this.handleBlockedTasks(blockedTasks, state);
82
+ }
83
+ // 9. 无任务可执行,等待中
84
+ return this.createWaitingResult([], state);
85
+ }
86
+ // 10. 准备 Subagent 任务
87
+ const subagentTasks = await this.agentRunner.prepareSubagentTasks(executableTasks);
88
+ // 8. 更新任务状态为 scheduled
89
+ for (const task of executableTasks) {
90
+ await this.scheduler.markTaskStarted(task.id);
91
+ }
92
+ return {
93
+ status: 'continue',
94
+ subagentTasks,
95
+ message: `准备执行 ${subagentTasks.length} 个任务`,
96
+ statistics: this.getStatistics(state)
97
+ };
98
+ }
99
+ /**
100
+ * 检查审批点
101
+ *
102
+ * 在 auto 模式下 (approvalPoints 为空数组),跳过所有审批
103
+ * 仅在失败/异常时才暂停
104
+ */
105
+ async checkApprovals(state) {
106
+ // auto 模式: approvalPoints 为空
107
+ if (state.config.approvalPoints.length === 0) {
108
+ // 只自动批准非 meeting 类型
109
+ // meeting 类型保持 pending,供最后统一处理
110
+ const pendingApprovals = await this.stateManager.getApprovalsByStatus('pending');
111
+ for (const approval of pendingApprovals) {
112
+ // meeting 类型不自动批准,保持 pending 状态
113
+ if (approval.type !== 'meeting') {
114
+ await this.approvalManager.processDecision({
115
+ approvalId: approval.id,
116
+ decision: 'approve',
117
+ comment: 'Auto-approved in fully automatic mode',
118
+ decidedBy: 'system',
119
+ decidedAt: new Date().toISOString()
120
+ });
121
+ }
122
+ }
123
+ // 返回非 meeting 类型的 pending 审批(应该已经处理完了)
124
+ return pendingApprovals.filter(a => a.type !== 'meeting');
125
+ }
126
+ const pendingApprovals = await this.stateManager.getApprovalsByStatus('pending');
127
+ // 过滤出当前需要处理的审批
128
+ return pendingApprovals.filter(approval => {
129
+ const approvalPoint = approval.type;
130
+ return state.config.approvalPoints.includes(approvalPoint);
131
+ });
132
+ }
133
+ /**
134
+ * 检查是否所有任务完成
135
+ */
136
+ checkAllCompleted(tasks) {
137
+ if (tasks.length === 0)
138
+ return true;
139
+ return tasks.every(task => task.status === 'completed');
140
+ }
141
+ /**
142
+ * 获取统计信息
143
+ */
144
+ getStatistics(state) {
145
+ return {
146
+ total: state.statistics.totalTasks,
147
+ completed: state.statistics.completed,
148
+ inProgress: state.statistics.inProgress,
149
+ pending: state.statistics.pending,
150
+ failed: state.statistics.failed
151
+ };
152
+ }
153
+ /**
154
+ * 创建等待审批结果
155
+ */
156
+ createWaitingResult(approvals, state) {
157
+ return {
158
+ status: 'waiting_approval',
159
+ subagentTasks: [],
160
+ message: approvals.length > 0
161
+ ? `等待 ${approvals.length} 个审批`
162
+ : '等待中...',
163
+ statistics: this.getStatistics(state)
164
+ };
165
+ }
166
+ /**
167
+ * 创建完成结果 - 检查是否有待处理的 Meeting
168
+ */
169
+ async createCompletedResult(state) {
170
+ // 检查是否有待处理的 meeting 审批
171
+ const pendingApprovals = await this.stateManager.getApprovalsByStatus('pending');
172
+ const pendingMeetings = pendingApprovals.filter(a => a.type === 'meeting');
173
+ if (pendingMeetings.length > 0) {
174
+ return {
175
+ status: 'waiting_approval',
176
+ subagentTasks: [],
177
+ message: `✅ 所有非阻塞任务已完成!\n\n📋 有待确认的 Meeting (${pendingMeetings.length}个):\n${pendingMeetings.map(m => ` - ${m.taskId}: ${m.title}`).join('\n')}\n\n请使用 /om:approve 确认或处理这些阻塞问题`,
178
+ statistics: this.getStatistics(state)
179
+ };
180
+ }
181
+ return {
182
+ status: 'completed',
183
+ subagentTasks: [],
184
+ message: '所有任务已完成!',
185
+ statistics: this.getStatistics(state)
186
+ };
187
+ }
188
+ /**
189
+ * 创建需要重试结果
190
+ */
191
+ createRetryNeededResult(failedTasks, state) {
192
+ return {
193
+ status: 'failed',
194
+ subagentTasks: [],
195
+ message: `${failedTasks.length} 个任务失败,需要重试`,
196
+ statistics: this.getStatistics(state)
197
+ };
198
+ }
199
+ /**
200
+ * 处理阻塞任务 - 创建 Meeting 审批并跳过该任务
201
+ *
202
+ * 在 auto 模式下:
203
+ * 1. 标记任务为 blocked 状态
204
+ * 2. 创建 Meeting 审批记录
205
+ * 3. 跳过该任务,继续执行其他可执行任务
206
+ * 4. 所有 Meeting 留到最后统一处理
207
+ */
208
+ async handleBlockedTasks(blockedTasks, state) {
209
+ const reasons = blockedTasks.map(t => t.error || '未知原因').join('; ');
210
+ for (const task of blockedTasks) {
211
+ // 1. 标记任务为 blocked
212
+ await this.scheduler.markTaskBlocked(task.id, task.error || '未知原因');
213
+ // 2. 检查是否已有该任务的 pending meeting 审批
214
+ const existingApprovals = await this.stateManager.getApprovalsByStatus('pending');
215
+ const hasExistingMeeting = existingApprovals.some(a => a.taskId === task.id && a.type === 'meeting');
216
+ if (!hasExistingMeeting) {
217
+ // 3. 创建 Meeting 审批(但不暂停执行)
218
+ const allTasks = await this.stateManager.listTasks();
219
+ const impactedTasks = allTasks
220
+ .filter(t => t.dependencies.includes(task.id))
221
+ .map(t => `${t.id}: ${t.title}`);
222
+ await this.approvalManager.createMeetingApproval(task.id, task.error || '未知原因', impactedTasks.length > 0 ? impactedTasks : ['无下游任务受影响']);
223
+ console.log(`🔴 任务阻塞,已创建 Meeting: ${task.id} - ${task.error}`);
224
+ }
225
+ }
226
+ // 4. 返回 continue,继续执行其他任务
227
+ // 阻塞的任务被标记为 blocked,调度器会自动跳过它们
228
+ return {
229
+ status: 'continue',
230
+ subagentTasks: [],
231
+ message: `${blockedTasks.length} 个任务被阻塞,已跳过,继续执行其他任务。Meeting 记录待最后统一处理。原因: ${reasons}`,
232
+ statistics: this.getStatistics(state)
233
+ };
234
+ }
235
+ /**
236
+ * 标记任务完成
237
+ */
238
+ async completeTask(taskId, result) {
239
+ const task = await this.stateManager.getTask(taskId);
240
+ if (!task) {
241
+ throw new Error(`Task ${taskId} not found`);
242
+ }
243
+ if (result.success) {
244
+ // 更新阶段状态
245
+ const currentPhase = this.getCurrentPhase(task);
246
+ const updatedPhases = { ...task.phases };
247
+ if (currentPhase === 'develop') {
248
+ updatedPhases.develop = {
249
+ status: 'completed',
250
+ duration: 0,
251
+ completedAt: new Date().toISOString()
252
+ };
253
+ updatedPhases.verify = {
254
+ status: 'in_progress',
255
+ duration: null,
256
+ startedAt: new Date().toISOString()
257
+ };
258
+ await this.stateManager.updateTask(taskId, {
259
+ phases: updatedPhases,
260
+ status: 'verify'
261
+ });
262
+ }
263
+ else if (currentPhase === 'verify') {
264
+ updatedPhases.verify = {
265
+ status: 'completed',
266
+ duration: 0,
267
+ completedAt: new Date().toISOString()
268
+ };
269
+ updatedPhases.accept = {
270
+ status: 'in_progress',
271
+ duration: null,
272
+ startedAt: new Date().toISOString()
273
+ };
274
+ await this.stateManager.updateTask(taskId, {
275
+ phases: updatedPhases,
276
+ status: 'accept'
277
+ });
278
+ }
279
+ else if (currentPhase === 'accept') {
280
+ await this.scheduler.markTaskCompleted(taskId);
281
+ }
282
+ }
283
+ else {
284
+ await this.scheduler.markTaskFailed(taskId, result.error || 'Unknown error');
285
+ }
286
+ }
287
+ /**
288
+ * 获取当前阶段
289
+ */
290
+ getCurrentPhase(task) {
291
+ if (task.phases.develop.status !== 'completed')
292
+ return 'develop';
293
+ if (task.phases.verify.status !== 'completed')
294
+ return 'verify';
295
+ return 'accept';
296
+ }
297
+ /**
298
+ * 获取执行器状态
299
+ */
300
+ async getStatus() {
301
+ const state = await this.stateManager.getState();
302
+ const pendingApprovals = await this.stateManager.getApprovalsByStatus('pending');
303
+ const tasks = await this.stateManager.listTasks();
304
+ return {
305
+ running: state.status === 'running',
306
+ currentPhase: state.currentPhase,
307
+ pendingTasks: tasks.filter(t => t.status === 'pending').length,
308
+ runningTasks: tasks.filter(t => t.status === 'in_progress').length,
309
+ waitingApprovals: pendingApprovals.length
310
+ };
311
+ }
312
+ /**
313
+ * 获取 AgentRunner 实例
314
+ */
315
+ getAgentRunner() {
316
+ return this.agentRunner;
317
+ }
318
+ /**
319
+ * 获取 Scheduler 实例
320
+ */
321
+ getScheduler() {
322
+ return this.scheduler;
323
+ }
324
+ }
325
+ exports.OrchestratorExecutor = OrchestratorExecutor;