openmatrix 0.1.55 → 0.1.56

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.
@@ -37,64 +37,71 @@ exports.completeCommand = void 0;
37
37
  // src/cli/commands/complete.ts
38
38
  const commander_1 = require("commander");
39
39
  const state_manager_js_1 = require("../../storage/state-manager.js");
40
- const approval_manager_js_1 = require("../../orchestrator/approval-manager.js");
41
- const executor_js_1 = require("../../orchestrator/executor.js");
42
40
  const path = __importStar(require("path"));
43
41
  exports.completeCommand = new commander_1.Command('complete')
44
- .description('标记任务完成或失败')
45
- .argument('<taskId>', '任务 ID')
46
- .option('--success', '标记为成功')
42
+ .description('标记任务完成并更新全局统计')
43
+ .argument('<taskId>', '任务ID (如 TASK-001)')
44
+ .option('--success', '标记为成功完成 (默认)', true)
47
45
  .option('--failed', '标记为失败')
48
- .option('--error <message>', '错误信息')
49
- .option('--output <text>', '执行输出')
50
- .option('--json', 'JSON 输出')
46
+ .option('--output <text>', '执行结果摘要')
47
+ .option('--error <text>', '错误信息 (失败时)')
51
48
  .action(async (taskId, options) => {
52
49
  const basePath = process.cwd();
53
50
  const omPath = path.join(basePath, '.openmatrix');
54
51
  const stateManager = new state_manager_js_1.StateManager(omPath);
55
52
  await stateManager.initialize();
56
- const state = await stateManager.getState();
57
- // 构建执行器
58
- const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
59
- const executor = new executor_js_1.OrchestratorExecutor(stateManager, approvalManager, {
60
- maxConcurrent: state.config.maxConcurrentAgents,
61
- taskTimeout: state.config.timeout * 1000
62
- });
63
- const success = options.success || !options.failed;
64
- // 标记任务完成
65
- await executor.completeTask(taskId, {
66
- success,
67
- output: options.output,
68
- error: options.error
69
- });
70
- if (options.json) {
71
- // 获取下一批可执行任务
72
- const nextResult = await executor.step();
73
- const updatedTask = await stateManager.getTask(taskId);
74
- console.log(JSON.stringify({
75
- status: success ? 'completed' : 'failed',
76
- taskId,
77
- taskStatus: updatedTask?.status,
78
- nextBatch: {
79
- status: nextResult.status,
80
- subagentTasks: nextResult.subagentTasks.map(t => ({
81
- subagent_type: t.subagent_type,
82
- description: t.description,
83
- prompt: t.prompt,
84
- isolation: t.isolation,
85
- taskId: t.taskId,
86
- agentType: t.agentType,
87
- timeout: t.timeout
88
- })),
89
- statistics: nextResult.statistics
53
+ // 1. 读取任务
54
+ const task = await stateManager.getTask(taskId);
55
+ if (!task) {
56
+ console.log(JSON.stringify({ error: `任务 ${taskId} 不存在` }));
57
+ process.exit(1);
58
+ }
59
+ const isSuccess = !options.failed;
60
+ const now = new Date().toISOString();
61
+ if (isSuccess) {
62
+ // 2a. 标记任务完成 - 更新所有阶段
63
+ await stateManager.updateTask(taskId, {
64
+ status: 'completed',
65
+ phases: {
66
+ develop: { status: 'completed', duration: 0, completedAt: now },
67
+ verify: { status: 'completed', duration: 0, completedAt: now },
68
+ accept: { status: 'completed', duration: 0, completedAt: now }
90
69
  }
91
- }));
70
+ });
92
71
  }
93
72
  else {
94
- const emoji = success ? '✅' : '❌';
95
- console.log(`${emoji} 任务 ${taskId} ${success ? '完成' : '失败'}`);
96
- if (!success && options.error) {
97
- console.log(` 错误: ${options.error}`);
98
- }
73
+ // 2b. 标记任务失败
74
+ await stateManager.updateTask(taskId, {
75
+ status: 'failed',
76
+ error: options.error || 'Task failed'
77
+ });
99
78
  }
79
+ // 3. 重新计算全局统计(从实际任务文件统计,避免累积误差)
80
+ const allTasks = await stateManager.listTasks();
81
+ const stats = {
82
+ totalTasks: allTasks.length,
83
+ completed: allTasks.filter(t => t.status === 'completed').length,
84
+ inProgress: allTasks.filter(t => t.status === 'in_progress').length,
85
+ failed: allTasks.filter(t => t.status === 'failed').length,
86
+ pending: allTasks.filter(t => t.status === 'pending' || t.status === 'scheduled').length
87
+ };
88
+ // 4. 更新全局状态
89
+ const allDone = stats.completed + stats.failed === stats.totalTasks;
90
+ await stateManager.updateState({
91
+ statistics: stats,
92
+ status: allDone ? 'completed' : 'running',
93
+ currentPhase: allDone ? 'completed' : 'execution',
94
+ ...(allDone ? { completedAt: now } : {})
95
+ });
96
+ // 5. 输出结果
97
+ const result = {
98
+ taskId,
99
+ status: isSuccess ? 'completed' : 'failed',
100
+ statistics: stats,
101
+ allDone,
102
+ message: isSuccess
103
+ ? `${taskId} 完成 (${stats.completed}/${stats.totalTasks})`
104
+ : `${taskId} 失败: ${options.error || 'Unknown error'}`
105
+ };
106
+ console.log(JSON.stringify(result, null, 2));
100
107
  });
@@ -35,68 +35,82 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.stepCommand = void 0;
37
37
  // src/cli/commands/step.ts
38
+ // 循环状态持久化 - 防止上下文压缩导致循环丢失
38
39
  const commander_1 = require("commander");
39
40
  const state_manager_js_1 = require("../../storage/state-manager.js");
40
- const approval_manager_js_1 = require("../../orchestrator/approval-manager.js");
41
- const executor_js_1 = require("../../orchestrator/executor.js");
42
41
  const path = __importStar(require("path"));
43
42
  exports.stepCommand = new commander_1.Command('step')
44
- .description('获取下一批可执行任务')
45
- .option('--json', 'JSON 输出')
43
+ .description('获取下一个待执行任务(持久化循环状态)')
44
+ .option('--json', '输出 JSON 格式')
46
45
  .action(async (options) => {
47
46
  const basePath = process.cwd();
48
47
  const omPath = path.join(basePath, '.openmatrix');
49
48
  const stateManager = new state_manager_js_1.StateManager(omPath);
50
49
  await stateManager.initialize();
51
50
  const state = await stateManager.getState();
52
- if (state.status !== 'running') {
53
- if (options.json) {
54
- console.log(JSON.stringify({
55
- status: 'error',
56
- message: '没有正在执行的任务',
57
- currentState: state.status
58
- }));
59
- }
60
- else {
61
- console.log('⚠️ 没有正在执行的任务');
62
- console.log(` 当前状态: ${state.status}`);
63
- }
51
+ // 检查是否已完成
52
+ if (state.status === 'completed') {
53
+ console.log(JSON.stringify({ status: 'done', message: '所有任务已完成' }));
64
54
  return;
65
55
  }
66
- const approvalManager = new approval_manager_js_1.ApprovalManager(stateManager);
67
- const executor = new executor_js_1.OrchestratorExecutor(stateManager, approvalManager, {
68
- maxConcurrent: state.config.maxConcurrentAgents,
69
- taskTimeout: state.config.timeout * 1000
70
- });
71
- const phaseExecutor = executor.getPhaseExecutor();
72
- if (phaseExecutor) {
73
- phaseExecutor.setRunId(state.runId);
74
- }
75
- const result = await executor.step();
76
- if (options.json) {
56
+ // 获取所有任务
57
+ const allTasks = await stateManager.listTasks();
58
+ const nextTask = allTasks.find(t => t.status === 'pending' ||
59
+ t.status === 'scheduled' ||
60
+ t.status === 'in_progress');
61
+ if (!nextTask) {
62
+ // 所有任务都完成了或被阻塞
63
+ const completed = allTasks.filter(t => t.status === 'completed').length;
64
+ const total = allTasks.length;
65
+ // 自动更新统计
66
+ const stats = {
67
+ totalTasks: total,
68
+ completed: completed,
69
+ inProgress: allTasks.filter(t => t.status === 'in_progress').length,
70
+ failed: allTasks.filter(t => t.status === 'failed').length,
71
+ pending: allTasks.filter(t => t.status === 'pending').length
72
+ };
73
+ const allDone = completed + stats.failed === total;
74
+ await stateManager.updateState({
75
+ statistics: stats,
76
+ status: allDone ? 'completed' : 'running',
77
+ currentPhase: allDone ? 'completed' : 'execution'
78
+ });
77
79
  console.log(JSON.stringify({
78
- status: result.status,
79
- message: result.message,
80
- statistics: result.statistics,
81
- subagentTasks: result.subagentTasks.map(t => ({
82
- subagent_type: t.subagent_type,
83
- description: t.description,
84
- prompt: t.prompt,
85
- isolation: t.isolation,
86
- taskId: t.taskId,
87
- agentType: t.agentType,
88
- timeout: t.timeout
89
- }))
80
+ status: allDone ? 'done' : 'blocked',
81
+ statistics: stats,
82
+ message: allDone
83
+ ? `所有任务已完成 (${completed}/${total})`
84
+ : `没有可执行任务 (${completed}/${total} 完成, ${stats.failed} 失败, ${stats.pending} 等待)`
90
85
  }));
86
+ return;
91
87
  }
92
- else {
93
- console.log(`状态: ${result.status}`);
94
- console.log(`消息: ${result.message}`);
95
- if (result.subagentTasks.length > 0) {
96
- console.log(`\n📋 待执行任务 (${result.subagentTasks.length}):`);
97
- result.subagentTasks.forEach((t, i) => {
98
- console.log(` ${i + 1}. [${t.agentType}] ${t.description.slice(0, 60)}`);
99
- });
88
+ // 输出下一个任务信息
89
+ const result = {
90
+ status: 'next',
91
+ task: {
92
+ id: nextTask.id,
93
+ title: nextTask.title,
94
+ description: nextTask.description,
95
+ status: nextTask.status,
96
+ assignedAgent: nextTask.assignedAgent,
97
+ dependencies: nextTask.dependencies,
98
+ acceptanceCriteria: nextTask.acceptanceCriteria
99
+ },
100
+ statistics: {
101
+ total: allTasks.length,
102
+ completed: allTasks.filter(t => t.status === 'completed').length,
103
+ remaining: allTasks.filter(t => t.status === 'pending' ||
104
+ t.status === 'scheduled' ||
105
+ t.status === 'in_progress').length,
106
+ failed: allTasks.filter(t => t.status === 'failed').length
100
107
  }
108
+ };
109
+ if (options.json) {
110
+ console.log(JSON.stringify(result, null, 2));
111
+ }
112
+ else {
113
+ console.log(`📌 下一个任务: ${nextTask.id} - ${nextTask.title}`);
114
+ console.log(` 进度: ${result.statistics.completed}/${result.statistics.total} 完成, ${result.statistics.remaining} 剩余`);
101
115
  }
102
116
  });
package/dist/cli/index.js CHANGED
@@ -15,6 +15,8 @@ const check_js_1 = require("./commands/check.js");
15
15
  const check_gitignore_js_1 = require("./commands/check-gitignore.js");
16
16
  const analyze_js_1 = require("./commands/analyze.js");
17
17
  const brainstorm_js_1 = require("./commands/brainstorm.js");
18
+ const complete_js_1 = require("./commands/complete.js");
19
+ const step_js_1 = require("./commands/step.js");
18
20
  const program = new commander_1.Command();
19
21
  program
20
22
  .name('openmatrix')
@@ -29,6 +31,8 @@ program.addCommand(retry_js_1.retryCommand);
29
31
  program.addCommand(report_js_1.reportCommand);
30
32
  program.addCommand(meeting_js_1.meetingCommand);
31
33
  program.addCommand(auto_js_1.autoCommand);
34
+ program.addCommand(complete_js_1.completeCommand);
35
+ program.addCommand(step_js_1.stepCommand);
32
36
  program.addCommand(install_skills_js_1.installSkillsCommand);
33
37
  program.addCommand(check_js_1.checkCommand);
34
38
  program.addCommand(check_gitignore_js_1.checkGitignoreCommand);
@@ -75,7 +75,7 @@ export interface GlobalState {
75
75
  version: string;
76
76
  runId: string;
77
77
  status: RunStatus;
78
- currentPhase: 'planning' | 'execution' | 'verification' | 'acceptance';
78
+ currentPhase: 'planning' | 'execution' | 'verification' | 'acceptance' | 'completed';
79
79
  startedAt: string;
80
80
  config: AppConfig;
81
81
  statistics: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmatrix",
3
- "version": "0.1.55",
3
+ "version": "0.1.56",
4
4
  "description": "AI Agent task orchestration system with Claude Code Skills integration",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/skills/auto.md CHANGED
@@ -126,23 +126,21 @@ CLI 返回的 JSON 中 `subagentTasks` 数组包含每个待执行任务:
126
126
  ❌ **禁止在还有未完成任务时停止** — 即使 Agent 返回了大段输出,也必须继续下一个
127
127
  ❌ **禁止询问"是否继续"** — 直接执行下一个任务
128
128
  ❌ **禁止输出"让我知道是否..."后停止** — 继续执行
129
- ❌ **禁止因为上下文压缩而忘记剩余任务** — 每完成一个任务后,重新读取 state.json 确认剩余任务
129
+ ❌ **禁止因为上下文压缩而忘记剩余任务** — 通过 CLI 命令从磁盘获取真实状态
130
130
 
131
- **执行循环伪代码:**
132
- ```
133
- remaining = subagentTasks 中 status !== 'completed' 的任务
134
- while (remaining.length > 0) {
135
- task = remaining[0]
136
- result = Agent(task) // 执行
137
- 更新任务状态为 completed
138
- remaining = 从 state.json 重新读取未完成任务
139
- }
131
+ **文件持久化循环(防止上下文压缩丢失状态):**
132
+ ```bash
133
+ # 每个 Agent 完成后执行:
134
+ openmatrix complete TASK-XXX --success # 标记完成 + 更新统计
135
+ openmatrix step --json # 获取下一个任务 + 检查是否全部完成
140
136
  ```
137
+ `openmatrix step` 从磁盘读取真实状态,不依赖上下文记忆。
141
138
 
142
139
  **中断恢复:** 如果会话中断,再次执行 `/om:auto` 时:
143
- 1. 读取 `.openmatrix/state.json`
144
- 2. 如果 `status === 'running'`,读取所有任务,找到 status 不是 completed 的任务
145
- 3. 从中断的任务继续执行,不需要重新开始
140
+ 1. 执行 `openmatrix step --json`
141
+ 2. 如果返回 `status: "next"` 从返回的任务继续执行
142
+ 3. 如果返回 `status: "done"` → 所有任务已完成
143
+ 4. 如果返回 `status: "blocked"` → 有阻塞任务需要处理
146
144
  </LOOP-ENFORCEMENT>
147
145
 
148
146
  对 `subagentTasks` 列表中的每个任务,调用 Agent 工具执行:
@@ -176,8 +174,17 @@ Agent({
176
174
  - [下一个 Agent 应该注意什么]
177
175
  ```
178
176
 
179
- 2. 更新任务状态
180
- 3. **立即检查是否还有未完成任务** — 读取 `.openmatrix/state.json` 中的 statistics,如果 completed < totalTasks,继续执行下一个
177
+ 2. **标记完成并更新统计(必须执行):**
178
+ ```bash
179
+ openmatrix complete TASK-XXX --success
180
+ ```
181
+ 3. **获取下一个任务(防止上下文压缩丢失):**
182
+ ```bash
183
+ openmatrix step --json
184
+ ```
185
+ 如果返回 `status: "next"` → 继续执行返回的 task
186
+ 如果返回 `status: "done"` → 所有任务完成,进入最终提交
187
+ 如果返回 `status: "blocked"` → 有阻塞任务,处理 Meeting
181
188
  4. Git 自动提交(**必须使用 HEREDOC 格式**):
182
189
 
183
190
  **Agent 上下文共享机制 (Agent Memory):**
package/skills/start.md CHANGED
@@ -174,18 +174,15 @@ CLI 返回 JSON 中 `subagentTasks` 数组包含待执行任务。
174
174
  ❌ **禁止在还有未完成任务时停止** — 即使 Agent 返回了大段输出,也必须继续下一个
175
175
  ❌ **禁止询问"是否继续"** — 直接执行下一个任务
176
176
  ❌ **禁止输出"让我知道是否..."后停止** — 继续执行
177
- ❌ **禁止因为上下文压缩而忘记剩余任务** — 每完成一个任务后,重新读取 state.json 确认剩余任务
177
+ ❌ **禁止因为上下文压缩而忘记剩余任务** — 通过 `openmatrix step --json` 重新获取状态
178
178
 
179
- **执行循环伪代码:**
180
- ```
181
- remaining = subagentTasks 中 status !== 'completed' 的任务
182
- while (remaining.length > 0) {
183
- task = remaining[0]
184
- result = Agent(task) // 执行
185
- 更新任务状态为 completed
186
- remaining = 从 state.json 重新读取未完成任务
187
- }
179
+ **文件持久化循环(防止上下文压缩丢失状态):**
180
+ ```bash
181
+ # 每个 Agent 完成后执行:
182
+ openmatrix complete TASK-XXX --success # 标记完成 + 更新统计
183
+ openmatrix step --json # 获取下一个任务 + 检查是否全部完成
188
184
  ```
185
+ `openmatrix step` 会从磁盘读取真实状态,不依赖上下文记忆。
189
186
  </LOOP-ENFORCEMENT>
190
187
 
191
188
  对每个任务调用 Agent 工具:
@@ -200,7 +197,11 @@ Agent({
200
197
  ```
201
198
 
202
199
  每个 Agent 完成后:
203
- 1. **保存 Agent 上下文** — 将执行结果摘要写入 `.openmatrix/tasks/TASK-XXX/context.md`,格式如下:
200
+ 1. **标记完成并更新统计(必须执行):**
201
+ ```bash
202
+ openmatrix complete TASK-XXX --success
203
+ ```
204
+ 2. **保存 Agent 上下文** — 将执行结果摘要写入 `.openmatrix/tasks/TASK-XXX/context.md`,格式如下:
204
205
 
205
206
  ```markdown
206
207
  ## 任务: TASK-XXX 任务标题
@@ -219,9 +220,14 @@ Agent({
219
220
  - [下一个 Agent 应该注意什么]
220
221
  ```
221
222
 
222
- 2. 更新任务状态: `openmatrix complete <taskId>` 或更新 state
223
223
  3. Git 自动提交(必须使用下方统一提交格式)
224
- 4. **立即检查是否还有未完成任务** — 读取 `.openmatrix/state.json` 中的 statistics,如果 completed < totalTasks,继续执行下一个
224
+ 4. **获取下一个任务(防止上下文压缩丢失):**
225
+ ```bash
226
+ openmatrix step --json
227
+ ```
228
+ 如果返回 `status: "next"` → 继续执行返回的 task
229
+ 如果返回 `status: "done"` → 所有任务完成,进入最终提交
230
+ 如果返回 `status: "blocked"` → 有阻塞任务,处理 Meeting
225
231
  5. 检查审批点(auto 模式自动批准,其他模式按配置暂停)
226
232
 
227
233
  **Agent 上下文共享机制 (Agent Memory):**