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.
- package/dist/cli/commands/complete.js +55 -48
- package/dist/cli/commands/step.js +61 -47
- package/dist/cli/index.js +4 -0
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
- package/skills/auto.md +22 -15
- package/skills/start.md +19 -13
|
@@ -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>', '任务
|
|
46
|
-
.option('--success', '
|
|
42
|
+
.description('标记任务完成并更新全局统计')
|
|
43
|
+
.argument('<taskId>', '任务ID (如 TASK-001)')
|
|
44
|
+
.option('--success', '标记为成功完成 (默认)', true)
|
|
47
45
|
.option('--failed', '标记为失败')
|
|
48
|
-
.option('--
|
|
49
|
-
.option('--
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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
package/skills/auto.md
CHANGED
|
@@ -126,23 +126,21 @@ CLI 返回的 JSON 中 `subagentTasks` 数组包含每个待执行任务:
|
|
|
126
126
|
❌ **禁止在还有未完成任务时停止** — 即使 Agent 返回了大段输出,也必须继续下一个
|
|
127
127
|
❌ **禁止询问"是否继续"** — 直接执行下一个任务
|
|
128
128
|
❌ **禁止输出"让我知道是否..."后停止** — 继续执行
|
|
129
|
-
❌ **禁止因为上下文压缩而忘记剩余任务** —
|
|
129
|
+
❌ **禁止因为上下文压缩而忘记剩余任务** — 通过 CLI 命令从磁盘获取真实状态
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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.
|
|
144
|
-
2.
|
|
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
|
-
|
|
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
|
-
❌ **禁止因为上下文压缩而忘记剩余任务** —
|
|
177
|
+
❌ **禁止因为上下文压缩而忘记剩余任务** — 通过 `openmatrix step --json` 重新获取状态
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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.
|
|
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.
|
|
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):**
|